Skip to content

fix(tests): correct decimal sum and nullif results#1048

Open
bvolpato wants to merge 2 commits into
substrait-io:mainfrom
bvolpato:fix/strict-type-parameter-checker
Open

fix(tests): correct decimal sum and nullif results#1048
bvolpato wants to merge 2 commits into
substrait-io:mainfrom
bvolpato:fix/strict-type-parameter-checker

Conversation

@bvolpato

@bvolpato bvolpato commented Apr 13, 2026

Copy link
Copy Markdown
Member

Summary

Correct two inconsistent expected result types in the function test corpus:

  • decimal sum preserves input scale S, so dec<2,1> returns dec?<38,1>
  • nullif(any1, any1) -> any1?, so decimal arguments return nullable decimal rather than nullable boolean

The earlier strict type-checker implementation has been removed. A future checker can reuse the generated ANTLR type grammar without adding a second parser.

Testing

  • pixi run lint
  • pixi run test (137 passed)

This change is Reviewable

@bvolpato-dd bvolpato-dd force-pushed the fix/strict-type-parameter-checker branch from 086041e to 85d16cd Compare April 14, 2026 04:35
@bvolpato bvolpato marked this pull request as ready for review April 14, 2026 15:04
Comment thread tests/coverage/type_checker.py Outdated
@bvolpato

bvolpato commented May 5, 2026

Copy link
Copy Markdown
Member Author

[review-prs-verification]
Head: 2e77365
Ready to merge: yes

Files reviewed:

  • tests/cases/arithmetic_decimal/sum_decimal.test
  • tests/cases/comparison/nullif.test

Changes:

  • narrowed the PR to two verified testcase corrections
  • removed the handwritten type parser and strict-checker integration
  • updated PR title and description to match final scope
  • replied to and resolved the ANTLR reuse review thread

Tests/checks:

  • local: pixi run lint passed
  • local: pixi run test passed (137 passed)
  • GitHub: all checks passed, including style, tests, dry-run release, protobuf, YAML, title, license, and CLA
  • both branch commits have valid signatures

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has not had
recent activity. It will be closed in 7 days if no further activity occurs.

@github-actions github-actions Bot added the Stale label Jul 5, 2026
@bvolpato bvolpato force-pushed the fix/strict-type-parameter-checker branch from 85d16cd to 8cfd889 Compare July 10, 2026 19:14
@bvolpato bvolpato removed the Stale label Jul 10, 2026
@bvolpato bvolpato requested a review from benbellick July 10, 2026 19:14
bvolpato added 2 commits July 10, 2026 19:26
…sults

The coverage checker's `is_same_type` compared only the base type name
and stripped all parameters, so decimal precision/scale, varchar length,
and list/map element types were never actually validated against the
extension YAML return formulas. Two wrong test cases had been sitting
in-tree because of this:

- `sum((2.5, 0, 5.0, -2.5, -7.5)::dec<2, 1>) = -2.5::dec<38, 2>` in
  `tests/cases/arithmetic_decimal/sum_decimal.test`. `sum` returns
  `DECIMAL?<38,S>`, so with input scale 1 the output must be
  `dec?<38, 1>`, not `dec?<38, 2>`.
- `nullif(null::dec?<38, 0>, null::dec?<38, 0>) = null::bool?` in
  `tests/cases/comparison/nullif.test`. `nullif` is `any1, any1 -> any1?`,
  so with both args `dec<38, 0>` the result must be `dec?<38, 0>`, not
  `bool?`. Looks like a copy-paste from the bool cases above.

Both wrong results date back to the original BFT port (substrait-io#738). They are
not undoing prior work: substrait-io#913 only touched the `basic` i8/i16 block at
the top of `nullif.test`, and substrait-io#989 rewrote both lines only to add `?`
nullability markers, preserving the underlying wrong `38,2` and wrong
`bool` base type. This change keeps every `?` marker from substrait-io#989 and
only fixes the parameter substrait-io#989 wasn't looking at.

To prevent regressions, this adds `tests/coverage/type_checker.py` — a
symbolic unifier plus evaluator for the YAML return-formula mini-language
(assignments, `min`/`max`, `cond ? a : b` ternary). The new module:

- parses type strings like `decimal<P1,S1>`, `list<any2>`, `STRUCT<...>`,
  `func<any1 -> boolean?>` into tagged tuples;
- unifies an impl-declared type against a concrete test type, binding
  variables like `P1`, `S1`, and polymorphic `any1`/`any2`;
- evaluates multi-line return formulas (add/sub/mul/div/mod, min/max,
  sum, `any1?`, etc.) with the bindings and compares structurally to
  the test's declared result type.

`FunctionOverload`/`FunctionVariant` now carry the raw YAML arg types
and return formula alongside the existing short-form fingerprint.
`FunctionRegistry.get_function` runs the strict check after the legacy
loose match, so the wider test suite's base-type fallback still applies
when the caller hasn't supplied full parameterized types. When the
formula cannot be evaluated (unbound variable, unusual syntax), the
strict check falls back to success, preserving compatibility with the
current extensions and leaving room to tighten further.

`test_type_checker.py` covers parsing, unification, formula evaluation
for add/divide, the two specific bugs above, and the tolerant behavior
for tests that omit optional decimal parameters (e.g. `power(dec, dec<38,0>)`).
Keep the two verified testcase corrections and defer strict parameter validation until it can reuse the generated ANTLR grammar.
@bvolpato bvolpato force-pushed the fix/strict-type-parameter-checker branch from 7881c4a to 2e77365 Compare July 10, 2026 23:27
@bvolpato bvolpato changed the title test(coverage): strict type-parameter checking, catch 2 wrong test results fix(tests): correct decimal sum and nullif results Jul 10, 2026
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