Skip to content

did.query: fix shape-strict eqlen check on struct input#134

Merged
stevevanhooser merged 1 commit into
V2from
claude/add-did2-ndi-support-zOLcy
May 20, 2026
Merged

did.query: fix shape-strict eqlen check on struct input#134
stevevanhooser merged 1 commit into
V2from
claude/add-did2-ndi-support-zOLcy

Conversation

@stevevanhooser
Copy link
Copy Markdown
Contributor

Summary

did.query's one-arg struct-input branch validates that the input struct carries exactly {field, operation, param1, param2}. The check used a shape-strict comparison:

eqlen(sort(fieldnames(field)), sort({'field','operation','param1','param2'}))

sort(fieldnames(...)) returns a 4x1 cell; the literal is 1x4. eqlen routes through sizeeq, which requires identical sizes, so the validator rejected every well-formed struct input regardless of field membership. The struct-input form has been latent-broken since this code was written.

Surfaced by VH-Lab/NDI-matlab#799 (the [did2 #6] read-time augmentation work): an acceptance test that constructed ndi.query from a pre-built searchstructure tripped the check. NDI-matlab side worked around it by swapping the test to the cell-input form, but the underlying did.query bug remained.

Fix

Build the expected-fields literal as a column ({'field';'operation';...}) so sort() returns 4x1 on both sides. Field-set semantics are unchanged — membership and count are still strict.

Test plan

  • test_struct_input_accepted — a well-formed searchstructure now round-trips through did.query(struct) as documented in the header comment of the constructor.
  • test_struct_input_rejects_unknown_fields — an extra field still errors (regression guard so the shape fix doesn't accidentally loosen the validator).

The existing 4 tests in test_query.m continue to pass.


Generated by Claude Code

did.query's one-arg struct-input branch validates that the input
struct carries exactly {field, operation, param1, param2}. The
check used a shape-strict comparison:

    eqlen(sort(fieldnames(field)), sort({'field','operation','param1','param2'}))

sort(fieldnames(...)) returns a 4x1 cell; the literal is a 1x4
cell. eqlen routes through sizeeq, which requires identical
sizes, so the validator rejected every well-formed struct input
regardless of field membership.

Surfaced by VH-Lab/NDI-matlab PR #799 (the did2 #6 read-time
augmentation work): an acceptance test that constructed
ndi.query from a pre-built searchstructure tripped the check.
NDI-matlab side worked around it by swapping the test to the
cell-input form, but the underlying did.query bug remained.

Fix: build the literal as a column ({'field';'operation';...})
so sort() returns 4x1 on both sides. Field-set semantics are
unchanged (membership and count still strict).

Tests:
- test_struct_input_accepted: a well-formed searchstructure now
  round-trips through did.query(struct) as documented.
- test_struct_input_rejects_unknown_fields: an extra field still
  errors (regression guard so the shape fix doesn't accidentally
  loosen the validator).
@stevevanhooser stevevanhooser merged commit bad941b into V2 May 20, 2026
3 checks passed
@stevevanhooser stevevanhooser deleted the claude/add-did2-ndi-support-zOLcy branch May 20, 2026 18:35
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.

2 participants