Skip to content

fix(typecheck): don't substitute output columns or qualified columns as parameters - #838

Merged
psteinroe merged 2 commits into
mainfrom
fix/typecheck-qualified-returns-table-column
Oct 6, 2026
Merged

psteinroe merged 2 commits into
mainfrom
fix/typecheck-qualified-returns-table-column

Conversation

@psteinroe

Copy link
Copy Markdown
Collaborator

The database type check no longer replaces RETURNS TABLE/OUT columns, or qualified column references like r.received_at, with parameter literals in LANGUAGE sql bodies. The issue's function no longer reports non-integer constant in ORDER BY.

Only input parameters are in scope

get_sql_fn_signature collected every parameter, OUT and TABLE included. Postgres only exposes input parameters (IN, INOUT, VARIADIC) to the body, by name and as $n (get_func_input_arg_names, called from prepare_sql_fn_parse_info). Output columns are now skipped. That also fixes $n numbering when an OUT parameter comes before an input, and the static resolver: SELECT x with OUT x int is now reported as an unknown column, as Postgres does. Before, x counted as a parameter and nothing was reported.

Qualified names follow Postgres' rules

find_matching_identifier used to match a parameter name at any position in a dotted path, so r.received_at matched a parameter named received_at. It now accepts only the forms in sql_fn_post_column_ref: param, fn_name.param, param.field and fn_name.param.field, with fn_name.param taking precedence. Any other qualifier is a column reference and is left alone. Qualified references are not excluded outright, because fn_name.param and composite fields (#705) are valid parameter references.

Not in this PR

Postgres never lets a parameter override a table column (if (var != NULL) return NULL). The EXPLAIN check doesn't know which columns are in scope, so an unqualified reference that names both an input parameter and a column, e.g. f(id bigint) … ORDER BY id, is still replaced by a literal. The same applies to param.field when param is also a FROM alias. Fixing this needs scope information from the resolver, so it is left for a follow-up.

Fixes #835

…stgres accepts

RETURNS TABLE and OUT parameters were collected as parameters of SQL function bodies, and a parameter name matched at any position of a qualified reference, so `r.received_at` was replaced by a literal when an output column was named `received_at`.

Fixes #835
@psteinroe
psteinroe merged commit 4cc9407 into main Oct 6, 2026
9 checks passed
@psteinroe
psteinroe deleted the fix/typecheck-qualified-returns-table-column branch October 6, 2026 06:00
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.

typecheck: "non-integer constant in ORDER BY" when a qualified column shares a name with a RETURNS TABLE column

1 participant