-
Notifications
You must be signed in to change notification settings - Fork 202
feat(extensions): add unsigned integer extension types (u8, u16, u32, u64) #953
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
benbellick
merged 34 commits into
substrait-io:main
from
kadinrabo:feat/unsigned-extension-types
Aug 3, 2026
Merged
Changes from 23 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
d19c87a
feat(extensions): add unsigned integer extension types (u8, u16, u32,…
kadinrabo a413f3e
feat(extensions): add arithmetic function impls for unsigned types
kadinrabo b4bd79b
feat(tests): add UDT argument support in test framework
kadinrabo 719ddb5
chore: regenerate ANTLR parsers
kadinrabo 37a1a40
feat(tests): add unsigned integer test cases
kadinrabo 41cee40
chore: update test counts and baseline
kadinrabo 10baf81
chore: add dependency on extension_types_numeric
kadinrabo 078ddbc
qualify UDT references with dependency alias
kadinrabo 0d4aa26
rename type file to unsigned_integers, update URN
kadinrabo 8d37e9e
add string structure encoding for unsigned types
kadinrabo ec638bf
move unsigned functions into self-contained extension file
kadinrabo b7990a8
remove redundant hardcoded UDT type mappings
kadinrabo a14d6d7
remove unused dependency alias grammar changes
kadinrabo 856e63d
split unsigned tests into separate files, fix test framework
kadinrabo dbd3c8e
Merge remote-tracking branch 'upstream/main' into feat/unsigned-exten…
kadinrabo 62a4767
remove pycache from tracking
kadinrabo 7f577ce
revert gitignore change
kadinrabo 4bec245
add comment explaining extension file scanner change
kadinrabo 215fcee
improve type descriptions and divide description
kadinrabo cd6b2a8
add overflow and null handling test cases
kadinrabo fce64b0
remove overflow option from unsigned divide
kadinrabo 04a8882
remove modulus function and tests
kadinrabo 7c4c54a
merge upstream/main, regenerate parser and baseline
kadinrabo 3ac870f
merge upstream/main, fix UDT nullability and grammar ordering
kadinrabo cb9f001
Merge branch 'main' into feat/unsigned-extension-types
vbarua 7a4c243
Updated URNs
vbarua e34e296
Removed udtArg code from parsing in favour of userDefinedArg
vbarua 95ba784
Update tests to utilize standardized UDT literal format
vbarua 47c411d
Add missing nullability marker to literal
vbarua cccaacb
Use full-type name for string
vbarua 9da8233
Update baseline.json
vbarua ad3d5a8
lint
vbarua 6a5e5d3
Update tests/coverage/extensions.py
benbellick 08dca16
fix: remove obsolete unknown extension exclusion
benbellick File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,309 @@ | ||
| %YAML 1.2 | ||
| --- | ||
| urn: "extension:io.substrait:unsigned_integers" | ||
|
|
||
| types: | ||
|
kadinrabo marked this conversation as resolved.
|
||
| - name: u8 | ||
| description: > | ||
| Unsigned 8-bit integer (0 to 255). | ||
| Values are encoded as decimal strings in the structure representation. | ||
| structure: | ||
| value: str | ||
| - name: u16 | ||
| description: > | ||
| Unsigned 16-bit integer (0 to 65535). | ||
| Values are encoded as decimal strings in the structure representation. | ||
| structure: | ||
| value: str | ||
| - name: u32 | ||
| description: > | ||
| Unsigned 32-bit integer (0 to 4294967295). | ||
| Values are encoded as decimal strings in the structure representation. | ||
| structure: | ||
| value: str | ||
| - name: u64 | ||
| description: > | ||
| Unsigned 64-bit integer (0 to 18446744073709551615). | ||
| Values are encoded as decimal strings in the structure representation. | ||
| structure: | ||
| value: str | ||
|
|
||
| scalar_functions: | ||
|
vbarua marked this conversation as resolved.
|
||
| - | ||
| name: "add" | ||
| description: "Add two unsigned integer values." | ||
| impls: | ||
| - args: | ||
| - name: x | ||
| value: u!u8 | ||
| - name: y | ||
| value: u!u8 | ||
| options: | ||
| overflow: | ||
|
kadinrabo marked this conversation as resolved.
|
||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u8 | ||
| - args: | ||
| - name: x | ||
| value: u!u16 | ||
| - name: y | ||
| value: u!u16 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u16 | ||
| - args: | ||
| - name: x | ||
| value: u!u32 | ||
| - name: y | ||
| value: u!u32 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u32 | ||
| - args: | ||
| - name: x | ||
| value: u!u64 | ||
| - name: y | ||
| value: u!u64 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u64 | ||
| - | ||
| name: "subtract" | ||
| description: "Subtract one unsigned integer value from another." | ||
| impls: | ||
| - args: | ||
| - name: x | ||
| value: u!u8 | ||
| - name: y | ||
| value: u!u8 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u8 | ||
| - args: | ||
| - name: x | ||
| value: u!u16 | ||
| - name: y | ||
| value: u!u16 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u16 | ||
| - args: | ||
| - name: x | ||
| value: u!u32 | ||
| - name: y | ||
| value: u!u32 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u32 | ||
| - args: | ||
| - name: x | ||
| value: u!u64 | ||
| - name: y | ||
| value: u!u64 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u64 | ||
| - | ||
| name: "multiply" | ||
| description: "Multiply two unsigned integer values." | ||
| impls: | ||
| - args: | ||
| - name: x | ||
| value: u!u8 | ||
| - name: y | ||
| value: u!u8 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u8 | ||
| - args: | ||
| - name: x | ||
| value: u!u16 | ||
| - name: y | ||
| value: u!u16 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u16 | ||
| - args: | ||
| - name: x | ||
| value: u!u32 | ||
| - name: y | ||
| value: u!u32 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u32 | ||
| - args: | ||
| - name: x | ||
| value: u!u64 | ||
| - name: y | ||
| value: u!u64 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| return: u!u64 | ||
| - | ||
| name: "divide" | ||
| description: > | ||
| Divide x by y. Partial values are truncated (i.e. rounded towards 0). | ||
| The `on_division_by_zero` option governs behavior in cases where y is 0. | ||
| If either x or y are out of range, behavior will be governed by `on_domain_error`. | ||
| impls: | ||
| - args: | ||
| - name: x | ||
| value: u!u8 | ||
| - name: y | ||
| value: u!u8 | ||
| options: | ||
| on_domain_error: | ||
| values: [ "NULL", ERROR ] | ||
| on_division_by_zero: | ||
| values: [ "NULL", ERROR ] | ||
| return: u!u8 | ||
| - args: | ||
| - name: x | ||
| value: u!u16 | ||
| - name: y | ||
| value: u!u16 | ||
| options: | ||
| on_domain_error: | ||
| values: [ "NULL", ERROR ] | ||
| on_division_by_zero: | ||
| values: [ "NULL", ERROR ] | ||
| return: u!u16 | ||
| - args: | ||
| - name: x | ||
| value: u!u32 | ||
| - name: y | ||
| value: u!u32 | ||
| options: | ||
| on_domain_error: | ||
| values: [ "NULL", ERROR ] | ||
| on_division_by_zero: | ||
| values: [ "NULL", ERROR ] | ||
| return: u!u32 | ||
| - args: | ||
| - name: x | ||
| value: u!u64 | ||
| - name: y | ||
| value: u!u64 | ||
| options: | ||
| on_domain_error: | ||
| values: [ "NULL", ERROR ] | ||
| on_division_by_zero: | ||
| values: [ "NULL", ERROR ] | ||
| return: u!u64 | ||
|
|
||
| aggregate_functions: | ||
| - name: "sum" | ||
| description: Sum a set of unsigned integer values. The sum of zero elements yields null. | ||
|
kadinrabo marked this conversation as resolved.
|
||
| impls: | ||
| - args: | ||
| - name: x | ||
| value: u!u8 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u64? | ||
| return: u!u64? | ||
| - args: | ||
| - name: x | ||
| value: u!u16 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u64? | ||
| return: u!u64? | ||
| - args: | ||
| - name: x | ||
| value: u!u32 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u64? | ||
| return: u!u64? | ||
| - args: | ||
| - name: x | ||
| value: u!u64 | ||
| options: | ||
| overflow: | ||
| values: [ SILENT, SATURATE, ERROR ] | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u64? | ||
| return: u!u64? | ||
| - name: "min" | ||
| description: Min of a set of unsigned integer values. | ||
| impls: | ||
| - args: | ||
| - name: x | ||
| value: u!u8 | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u8? | ||
| return: u!u8? | ||
| - args: | ||
| - name: x | ||
| value: u!u16 | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u16? | ||
| return: u!u16? | ||
| - args: | ||
| - name: x | ||
| value: u!u32 | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u32? | ||
| return: u!u32? | ||
| - args: | ||
| - name: x | ||
| value: u!u64 | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u64? | ||
| return: u!u64? | ||
| - name: "max" | ||
| description: Max of a set of unsigned integer values. | ||
| impls: | ||
| - args: | ||
| - name: x | ||
| value: u!u8 | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u8? | ||
| return: u!u8? | ||
| - args: | ||
| - name: x | ||
| value: u!u16 | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u16? | ||
| return: u!u16? | ||
| - args: | ||
| - name: x | ||
| value: u!u32 | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u32? | ||
| return: u!u32? | ||
| - args: | ||
| - name: x | ||
| value: u!u64 | ||
| nullability: DECLARED_OUTPUT | ||
| decomposable: MANY | ||
| intermediate: u!u64? | ||
| return: u!u64? | ||
|
kadinrabo marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,7 +21,7 @@ def write_markdown(file_obj: dict, file_name: str) -> None: | |
| mdFile.new_line(f"{key}: {value}") | ||
|
|
||
| for function_classification, value in file_obj.items(): | ||
| if function_classification == "urn": | ||
| if function_classification in ("urn", "dependencies"): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this change is not strictly necessary for this PR by the way. Probably still a reasonable change though. |
||
| continue | ||
| function_classification_str = function_classification.replace("_", " ").title() | ||
| mdFile.new_header(level=2, title=f"{function_classification_str}") | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,16 @@ | ||
| { | ||
| "registry": { | ||
| "extension_count": 15, | ||
| "dependency_count": 15, | ||
| "extension_count": 16, | ||
| "dependency_count": 18, | ||
| "function_count": 174, | ||
| "num_aggregate_functions": 29, | ||
| "num_scalar_functions": 170, | ||
| "num_aggregate_functions": 32, | ||
| "num_scalar_functions": 174, | ||
| "num_window_functions": 11, | ||
| "num_function_overloads": 533 | ||
| "num_function_overloads": 561 | ||
| }, | ||
| "coverage": { | ||
| "total_test_count": 1168, | ||
| "num_function_variants": 533, | ||
| "num_covered_function_variants": 245 | ||
| "total_test_count": 1237, | ||
| "num_function_variants": 561, | ||
| "num_covered_function_variants": 273 | ||
| } | ||
| } |
|
benbellick marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| ### SUBSTRAIT_SCALAR_TEST: v1.0 | ||
|
vbarua marked this conversation as resolved.
|
||
| ### SUBSTRAIT_INCLUDE: '/extensions/unsigned_integers.yaml' | ||
|
|
||
| # basic: Basic unsigned integer examples | ||
| add('200'::u!u8, '50'::u!u8) = '250'::u!u8 | ||
| add('50000'::u!u16, '10000'::u!u16) = '60000'::u!u16 | ||
| add('3000000000'::u!u32, '1000000000'::u!u32) = '4000000000'::u!u32 | ||
| add('10000000000000000000'::u!u64, '1000000000000000000'::u!u64) = '11000000000000000000'::u!u64 | ||
|
|
||
| # overflow: Examples demonstrating overflow behavior | ||
| add('200'::u!u8, '100'::u!u8) [overflow:ERROR] = <!ERROR> | ||
| add('60000'::u!u16, '10000'::u!u16) [overflow:ERROR] = <!ERROR> | ||
| add('4000000000'::u!u32, '1000000000'::u!u32) [overflow:ERROR] = <!ERROR> | ||
| add('18446744073709551615'::u!u64, '1'::u!u64) [overflow:ERROR] = <!ERROR> | ||
| add('200'::u!u8, '100'::u!u8) [overflow:SATURATE] = '255'::u!u8 | ||
| add('200'::u!u8, '100'::u!u8) [overflow:SILENT] = <!UNDEFINED> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| ### SUBSTRAIT_SCALAR_TEST: v1.0 | ||
| ### SUBSTRAIT_INCLUDE: '/extensions/unsigned_integers.yaml' | ||
|
|
||
| # basic: Basic unsigned integer examples | ||
| divide('250'::u!u8, '5'::u!u8) = '50'::u!u8 | ||
| divide('60000'::u!u16, '100'::u!u16) = '600'::u!u16 | ||
| divide('4000000000'::u!u32, '200'::u!u32) = '20000000'::u!u32 | ||
| divide('10000000000000000000'::u!u64, '5000'::u!u64) = '2000000000000000'::u!u64 | ||
|
|
||
| # division_by_zero: Examples demonstrating division by zero | ||
| divide('5'::u!u8, '0'::u!u8) [on_division_by_zero:NULL] = null::u!u8 | ||
| divide('5'::u!u8, '0'::u!u8) [on_division_by_zero:ERROR] = <!ERROR> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI I think in the current state of this PR, we won't auto generate docs for
unsigned_integers(example of generated docs for functions_boolean).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#1144
^ made another in the interest of getting this in.