Answer a generated registration in the type the SQL surface declares - #360
Merged
estebanzimanyi merged 1 commit intoSep 2, 2026
Conversation
A registration takes its return type from the C kernel rather than from the CREATE FUNCTION the catalog reads, so one SQL name served by several typed kernels registers several return types: nad_tint_tint, nad_tbigint_tbigint and nad_tfloat_tfloat return int, int64 and double against nearestApproachDistance(...) RETURNS float for every one of them, and the six integer-operand signatures of that name and their |=| operator forms answer INTEGER and BIGINT where MobilityDB answers float. The registration type and the type its executor writes are now one decision per shape - scalar_ret4 for a by-value return, outprim_ret3 for a scalar out-parameter, box_ret3 for a temporal against a box - so a registration cannot declare one type while its executor writes another, which DuckDB reports as Expected vector of type X, but found vector of type Y. scalar_ret_duck and scalar_emit3 are projections of the first, and the other two shapes read theirs at both sites. Three returns keep the type the kernel states. An unsigned one does because PostgreSQL has no unsigned SQL type and declares a uint32 hash integer for want of one, and registering that signed makes DuckDB range-check the cast and flip the sign of every hash at or above 2**31. A return needing a marshaller rather than a cast does because its branch already answers the declared type through TakeText, FromMeosDate or TakeTimestamp. And the no-distance sentinel is the maximum of the type MEOS returns, so the test for it precedes the conversion. The registration set holds 6121 entries on either side, of which 12 change and none is added or removed: the six nearestApproachDistance signatures over a temporal integer or big integer and their six |=| forms. 081_nearest_approach_box states the type MobilityDB declares for a temporal integer against an integer box, which resolves to the one NAD_tnumber_tbox wrapper that declares float for the temporal float too. The suite reads 2695 assertions in 102 test cases.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
A registration takes its return type from the C kernel rather than from the
CREATE FUNCTION the catalog reads, so one SQL name served by several typed
kernels registers several return types: nad_tint_tint, nad_tbigint_tbigint and
nad_tfloat_tfloat return int, int64 and double against
nearestApproachDistance(...) RETURNS float for every one of them, and the six
integer-operand signatures of that name and their |=| operator forms answer
INTEGER and BIGINT where MobilityDB answers float.
The registration type and the type its executor writes are now one decision per
shape - scalar_ret4 for a by-value return, outprim_ret3 for a scalar
out-parameter, box_ret3 for a temporal against a box - so a registration cannot
declare one type while its executor writes another, which DuckDB reports as
Expected vector of type X, but found vector of type Y. scalar_ret_duck and
scalar_emit3 are projections of the first, and the other two shapes read theirs
at both sites.
Three returns keep the type the kernel states. An unsigned one does because
PostgreSQL has no unsigned SQL type and declares a uint32 hash integer for want
of one, and registering that signed makes DuckDB range-check the cast and flip
the sign of every hash at or above 2**31. A return needing a marshaller rather
than a cast does because its branch already answers the declared type through
TakeText, FromMeosDate or TakeTimestamp. And the no-distance sentinel is the
maximum of the type MEOS returns, so the test for it precedes the conversion.
The registration set holds 6121 entries on either side, of which 12 change and
none is added or removed: the six nearestApproachDistance signatures over a
temporal integer or big integer and their six |=| forms. 081_nearest_approach_box
states the type MobilityDB declares for a temporal integer against an integer
box, which resolves to the one NAD_tnumber_tbox wrapper that declares float for
the temporal float too. The suite reads 2695 assertions in 102 test cases.