Historian value types differ across backends for integer/Boolean nodes (SQL backends Int64, Gateway node type; Gateway Raw Boolean as Double) #698

Closed
opened 2026-10-13 02:12:08 -04:00 by dohertj2 · 1 comment
Owner

Follow-up from #693 (review L4). Low; consistency.

Since #693 the node manager passes the node's scalar type to ReadAtTimeAsync, and only the Gateway uses it:

Read Gateway SqlServer / QuestDB
AtTime, integer node node's own integer type (Int32 → int) Int64 (hint ignored)
Raw, Boolean node Double 0/1 —
AtTime, Boolean node bool —
AtTime, DateTime node steps, but keeps the gateway's Double value DateTime

Proposal: decide one rule — return values in the node's DataType on every backend and every read kind — and apply it, e.g. a shared conversion step in the node manager using the same type mapping as AtTimeValueType.

Test gap: add ShouldBeOfType assertions to the shared conformance suite. Shouldly ShouldBe compares across numeric types, which is how the Int64-as-Double evaluator bug survived until #693.

Follow-up from #693 (review L4). Low; consistency. Since #693 the node manager passes the node's scalar type to `ReadAtTimeAsync`, and only the Gateway uses it: | Read | Gateway | SqlServer / QuestDB | |---|---|---| | AtTime, integer node | node's own integer type (`Int32` → `int`) | Int64 (hint ignored) | | Raw, Boolean node | Double 0/1 | — | | AtTime, Boolean node | `bool` | — | | AtTime, DateTime node | steps, but keeps the gateway's Double value | `DateTime` | **Proposal:** decide one rule — return values in the node's DataType on every backend and every read kind — and apply it, e.g. a shared conversion step in the node manager using the same type mapping as `AtTimeValueType`. **Test gap:** add `ShouldBeOfType` assertions to the shared conformance suite. Shouldly `ShouldBe` compares across numeric types, which is how the Int64-as-Double evaluator bug survived until #693.
Author
Owner

Implemented at the node-manager response boundary on all backends: Raw, Modified and AtTime non-null scalar values match the node DataType. Failed conversions yield per-sample null/BadTypeMismatch with timestamps and modification metadata preserved. Array nodes retain stored values; Processed values retain aggregate-specific types. Tests explicitly inspect runtime types for Boolean, Int32 and Float, plus overflow, unknown numeric DateTime encoding, null/array preservation, modified audit metadata and Count on a Boolean node. Ready in the pushed branch; this issue closes when PR #699 merges.

Pushed commit 97668d26; PR: #699.

Full solution verified: 14,581 passed, 609 skipped, 0 failed across 62 suites (dotnet test ZB.MOM.WW.OtOpcUa.slnx --verbosity quiet, exit 0). Independent final review found no important defects. New fixes have not been deployed or live-tested end to end through OPC UA.

Implemented at the node-manager response boundary on all backends: Raw, Modified and AtTime non-null scalar values match the node DataType. Failed conversions yield per-sample null/BadTypeMismatch with timestamps and modification metadata preserved. Array nodes retain stored values; Processed values retain aggregate-specific types. Tests explicitly inspect runtime types for Boolean, Int32 and Float, plus overflow, unknown numeric DateTime encoding, null/array preservation, modified audit metadata and Count on a Boolean node. Ready in the pushed branch; this issue closes when PR #699 merges. Pushed commit `97668d26`; PR: https://gitea.dohertylan.com/dohertj2/lmxopcua/pulls/699. Full solution verified: 14,581 passed, 609 skipped, 0 failed across 62 suites (`dotnet test ZB.MOM.WW.OtOpcUa.slnx --verbosity quiet`, exit 0). Independent final review found no important defects. New fixes have not been deployed or live-tested end to end through OPC UA.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#698