Skip to content

Answer a generated registration in the type the SQL surface declares - #360

Merged
estebanzimanyi merged 1 commit into
MobilityDB:mainfrom
estebanzimanyi:duck/outparam-return-type-from-catalog
Sep 2, 2026
Merged

Answer a generated registration in the type the SQL surface declares#360
estebanzimanyi merged 1 commit into
MobilityDB:mainfrom
estebanzimanyi:duck/outparam-return-type-from-catalog

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

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.

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.
@estebanzimanyi
estebanzimanyi merged commit 185b506 into MobilityDB:main Sep 2, 2026
10 checks passed
@estebanzimanyi
estebanzimanyi deleted the duck/outparam-return-type-from-catalog branch September 2, 2026 12:48
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