Skip to content

sql: reject out-of-range routine placeholders - #174718

Open
Alignyx wants to merge 1 commit into
cockroachdb:masterfrom
Alignyx:fix-172995-routine-placeholder-scope
Open

sql: reject out-of-range routine placeholders#174718
Alignyx wants to merge 1 commit into
cockroachdb:masterfrom
Alignyx:fix-172995-routine-placeholder-scope

Conversation

@Alignyx

@Alignyx Alignyx commented Sep 5, 2026

Copy link
Copy Markdown

Fixes #172995.

Root cause

Routine placeholder lookup returned nil for two different states: no active routine-argument scope, and an active scope in which the requested ordinal was out of range. The placeholder visitor could not distinguish those states, so an invalid routine placeholder fell through to ordinary prepared-statement placeholder construction. When the surrounding statement had a value for that ordinal, the routine body could read and fold the caller's placeholder value instead of raising an undefined-parameter error.

How I tracked it down

The two higher-level lazy routine paths from the report are not currently executable on master: nested routine DDL is rejected by the routine DDL safety check, and dynamic EXECUTE is not implemented. I therefore isolated the shared optbuilder transition under an active outer placeholder assignment. The control cases showed that an ordinary prepared placeholder correctly became a constant and a valid routine ordinal correctly became a routine parameter column, while an out-of-range routine ordinal incorrectly became the caller's constant. That placed the first invalid transition at the boundary between routine scope lookup and generic placeholder handling rather than in lazy body construction itself.

Fix

The existing single-value scope lookup remains available to its other callers, and a companion lookup now reports whether an ordinal is definitively out of range. Placeholder resolution uses that result to preserve valid routine parameter columns and to raise the existing no value provided for placeholder error before generic placeholder construction when an active routine scope rejects the ordinal.

Test coverage

  • Added TestRoutineParamOrdinalIsolation with three arms: ordinary prepared placeholders still use their assigned values, valid routine ordinals still resolve to parameter columns, and invalid routine ordinals return SQLSTATE 42P02 even when the caller has a value at that position.
  • Ran the full optbuilder test target and the existing regression_143887 and regression_144020 routine-placeholder logic regressions.
  • Ran the complete PL/pgSQL UDF logic suite in local, fake-distributed, and local-prepared configurations, plus the complete SQL UDF logic suite locally.

When a routine body was built while an enclosing prepared query's values were
active, an invalid ordinal fell through function argument resolution. Scalar
building could then fold it from the caller's evaluation context.

Preserve the distinction between no function-argument scope and a routine
ordinal known to be out of range. Reject the latter with the existing
undefined-parameter error before generic placeholder construction.

Fixes cockroachdb#172995

Release note (bug fix): Fixed PL/pgSQL routine bodies with out-of-range ordinal
parameter references reading placeholder values from an enclosing prepared
query when the body was built lazily.
@Alignyx
Alignyx requested a review from a team as a code owner September 5, 2026 01:23
@Alignyx
Alignyx requested review from DrewKimball and removed request for a team September 5, 2026 01:23
@blathers-crl

blathers-crl Bot commented Sep 5, 2026

Copy link
Copy Markdown

Thank you for contributing to CockroachDB. Please ensure you have followed the guidelines for creating a PR.

My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI.

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

@blathers-crl blathers-crl Bot added the O-community Originated from the community label Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

O-community Originated from the community

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sql/plpgsql: out-of-range placeholder in a lazily built routine body reads the caller's placeholder value

1 participant