Skip to content

Conversation

@ajstorm
Copy link
Collaborator

@ajstorm ajstorm commented Nov 20, 2025

Fixes #144013

When set-returning UDFs with OUT parameters are called directly in a SELECT list (e.g., SELECT f()), CockroachDB wraps multiple result columns into a single tuple column. During this transformation, two functions created new scopes without preserving ordering information, causing ORDER BY clauses in the UDF body to be ignored.

Solution

This PR fixes the issue by calling copyOrdering() in two places in pkg/sql/opt/optbuilder/routine.go:

  1. combineRoutineColsIntoTuple - preserves ordering when wrapping columns into a tuple
  2. maybeAddRoutineAssignmentCasts - preserves ordering when adding type casts

The copyOrdering() method not only copies the ordering metadata but also adds the columns referenced by the ordering to extraCols, ensuring they remain available for the optimizer to enforce the ordering.

Testing

Added a new regression test out_params_ordering in pkg/sql/logictest/testdata/logic_test/udf_setof that verifies ORDER BY is preserved for both ascending and descending order with OUT parameters.

Release note

Release note (bug fix): Fixed a bug where ORDER BY clauses in set-returning SQL user-defined functions with OUT parameters were ignored when the function was called directly in a SELECT list (e.g., SELECT f()). The ordering is now properly preserved and enforced.

@blathers-crl
Copy link

blathers-crl bot commented Nov 20, 2025

Your pull request contains more than 1000 changes. It is strongly encouraged to split big PRs into smaller chunks.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

When set-returning UDFs with OUT parameters are called directly in a
SELECT list (e.g., SELECT f()), CockroachDB wraps multiple result
columns into a single tuple column. During this transformation, two
functions created new scopes without preserving ordering information,
causing ORDER BY clauses in the UDF body to be ignored.

This commit fixes the issue by calling copyOrdering() in two places:
1. combineRoutineColsIntoTuple - when wrapping columns into a tuple
2. maybeAddRoutineAssignmentCasts - when adding type casts

The copyOrdering() method not only copies the ordering metadata but
also adds the columns referenced by the ordering to extraCols, ensuring
they remain available for the optimizer to enforce the ordering.

Fixes cockroachdb#144013

Release note (bug fix): Fixed a bug where ORDER BY clauses in
set-returning SQL user-defined functions with OUT parameters were
ignored when the function was called directly in a SELECT list
(e.g., SELECT f()). The ordering is now properly preserved and
enforced.

Epic: None
@ajstorm ajstorm force-pushed the ajstorm/fix-udf-ordering-144013 branch from 81d8fff to 7bb47fa Compare November 21, 2025 00:14
@ajstorm ajstorm marked this pull request as ready for review November 21, 2025 00:18
@ajstorm ajstorm requested a review from a team as a code owner November 21, 2025 00:18
@ajstorm ajstorm requested review from DrewKimball and removed request for a team November 21, 2025 00:18
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.

sql: set-returning udfs don't always respect ordering

2 participants