Skip to content

Accept primitive arrays in AttributeWriter's DataType check - #2118

Merged
kevinherron merged 1 commit into
integration/1.2from
perf/attribute-writer-primitive-arrays
Oct 12, 2026
Merged

kevinherron merged 1 commit into
integration/1.2from
perf/attribute-writer-primitive-arrays

Conversation

@kevinherron

@kevinherron kevinherron commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Part 1 of 6 (#2118 to #2123) of a stack of server performance changes, found by profiling the Milo server in the o6-automation/opcua-benchmarks suite. This one is a correctness fix that the rest of the stack does not depend on; it is at the bottom because it is the smallest and safest.

Problem

Variant holds primitive arrays such as int[] and double[], for example from Variant.ofInt32Array(int[]), and the binary encoder writes them. A write of one through AttributeWriter still failed with Bad_TypeMismatch.

AttributeWriter.validateDataType took the array's component class, int.class for an int[], and asked DataTypeTree.isAssignable whether it fits the Variable's DataType. The tree only knows boxed backing classes such as Integer, so the answer was always no.

Two writes hit this:

  • Server code that writes a primitive array through AttributeWriter, for example Variant.ofDoubleArray(new double[] {1, 2}) into a Double array Variable.
  • A client Write with an IndexRange into a Variable whose stored value is a primitive array. The decoded update is a boxed Double[], but NumericRange.writeToValueAtRange merges it into a copy of the stored array, which keeps the primitive double[] form, and the merged value failed the check.

Whole-value client Writes were not affected, because the binary decoder always produces boxed arrays.

Change

validateDataType now uses ArrayUtil.getBoxedType, so a primitive array is accepted wherever its boxed form is. Boxed arrays, scalars, and Matrix values with boxed elements are checked exactly as before.

Tests

New cases in AttributeWriterTest (integration-tests):

  • writePrimitiveArrayToVariableOfMatchingDataType: a double[] written to a Double array Variable is accepted and stored as double[].
  • writePrimitiveMatrixToVariableOfMatchingDataType: a Matrix of int[][] written to an Int32 rank-2 Variable is accepted and stored.
  • indexRangeWriteIntoStoredPrimitiveArrayUpdatesTheElement: a client Write of Double[] {9} at IndexRange "1" into a stored double[] {1, 2, 3} succeeds and stores double[] {1, 9, 3}.
  • rejectPrimitiveArrayOfAnotherDataType (control): an int[] written to a Double Variable is still rejected.

On the unfixed base, the three positive tests fail with Bad_TypeMismatch.

Not changed

An IndexRange write whose update has the wrong element type, such as double[] into an int[], is reported as Bad_IndexRangeNoData instead of Bad_TypeMismatch, because NumericRange.writeToValueAtRange wraps every failure in Bad_IndexRangeNoData. That behavior predates this PR and is unchanged here.

Verification

  • mvn -q -pl opc-ua-sdk/integration-tests -am test -Dtest=AttributeWriterTest: 45 tests pass.
  • The full build with tests on the top of the stack (mvn -q -pl opc-ua-sdk/integration-tests -am verify): 451 test classes, 5,792 tests, no failures, 4 skipped.
  • Reviewed independently by GPT-6.1-Sol (Codex) in two rounds; its findings (commit message scope, the IndexRange case, the Matrix assertion) are addressed above.

Variant holds primitive arrays such as int[] and double[], for example
from Variant.ofInt32Array, and the binary encoder writes them. A write
of one through AttributeWriter still failed with Bad_TypeMismatch:
validateDataType took the array's component class, int.class, and
DataTypeTree.isAssignable only knows boxed backing classes such as
Integer.

Two writes hit this. Server code that writes a primitive array through
AttributeWriter was rejected. A client Write with an IndexRange into a
Variable whose stored value is a primitive array was rejected too: the
decoded update is boxed, but NumericRange merges it into a copy of the
stored array, which keeps the primitive form. Whole-value client Writes
were not affected, because the decoder always produces boxed arrays.

The check now uses the boxed component type, so a primitive array is
accepted wherever its boxed form is.
@greptile-apps

greptile-apps Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

AttributeWriter now checks primitive arrays against their boxed element types, allowing matching arrays and matrices without changing their stored form.

  • Primitive arrays pass value checks when their element types match.

No actionable issues were found. Tests were inspected but not run.

Reviews (1) · Last reviewed commit: "Accept primitive arrays in AttributeWrit..." · Reviewed by Greptile

@kevinherron
kevinherron merged commit 9da7adc into integration/1.2 Oct 12, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant