Gateway AtTime returns AVEVA interpolation unchanged (NULL handling, drift, no Interpolated bit) #693
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by the #689–#691 live AVEVA gate (2026-10-13). Pre-existing.
Gateway HistoryRead AtTime passes AVEVA's interpolated answer through, which breaks the AtTime rules the SQL backends follow (Part 11 §6.5.4, stepped/interpolated with the Interpolated bit):
HistGW.LiveTest.Gate68519:00:03 ⇒ 107).Suggested: serve Gateway AtTime from raw reads (prior/next sample via the #686/#691.1 bound lookups) with the shared evaluator the SQL backends use, as #681 did for per-sample aggregates; or at minimum return exact stored samples as stored and set the Interpolated bit.
Evidence: scratchpad
livegate-aveva-689.md(F2).Fixed on master
66a2b0c3(mergea5a04961; commits37390139,0d249f3e,68a1f313,2609c546). Live AVEVA gate PASS (2026-10-13).Fix: Gateway AtTime is now worked out from raw reads by the same
AtTimeEvaluatorthe SQL backends use (GatewayAtTimeReader):Live (Gate685):
Ten dense timestamps cost 1 read when exact, 3 when interpolated. Kill switch
ServerHistorian:GatewayAtTimeFromRaw=falsereproduces AVEVA's native answers exactly.Type hint: the node manager passes the node's scalar type (new default-interface overload
ReadAtTimeAsync(…, TypeCode? valueType, …)). Gateway rows are converted before evaluation:Also fixed (client-visible, SQL backends too): the shared evaluator returned interpolated Int64 AtTime values as Double (
cond ? (long)x : vwidens to double). They are now Int64. The conformance test asserts the type, because ShouldlyShouldBecompares across numeric types and hid it.Known differences (documented): SqlServer/QuestDB return Int64 for any integer node (they ignore the hint); Gateway Raw still returns Double 0/1 for Boolean nodes; DateTime nodes on Gateway step but keep the gateway's Double value.
Read cap: 64 + 16 reads per distinct time (runaway guard;
HistoryReadDeadlinebounds wall-clock); a strict ceiling below 4 rows is refused with a message naming it.Tests: 45
GatewayAtTimeTestsagainst a wire-faithful fake. Differential fuzz vs the SQL evaluator: 0 diffs over 16,500 cases.Follow-ups: #696 (future-time prior-search cost), #698 (value types across backends).