Skip to content

sql: resolve built-in function OIDs in memory for reg* casts#171295

Draft
ZhouXing19 wants to merge 1 commit into
cockroachdb:masterfrom
ZhouXing19:fix-regproc-builtin-oid-cast
Draft

sql: resolve built-in function OIDs in memory for reg* casts#171295
ZhouXing19 wants to merge 1 commit into
cockroachdb:masterfrom
ZhouXing19:fix-regproc-builtin-oid-cast

Conversation

@ZhouXing19

@ZhouXing19 ZhouXing19 commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Casting an integer to regproc or regprocedure and then to text routes
through resolveOID, which runs a pg_catalog.pg_proc query to compute a
Postgres-style search-path visibility bit and schema-qualify the name when it
is not visible through the current search_path. That query determines
visibility by looking up pg_proc by name, but pg_proc's by-name population
is built from builtins.AllBuiltinNames, which excludes "private" builtins such
as the regression-aggregate helper functions (e.g. final_regr_syy, OID 56).

As a result, casting such a function's OID produced inconsistent output: in a
normal session the visibility lookup found no match and emitted a spuriously
schema-qualified name (pg_catalog.final_regr_syy), while in a context with no
database in scope the catalog query errored and the OID fell back to its bare
numeric form (56). The unoptimized-query-oracle roachtest observed both
forms for the same logical cast and failed. Postgres emits the bare name for
these functions, since pg_catalog is always implicitly in the search path.

This change resolves built-in function OIDs from the in-memory function registry
instead, mirroring the existing built-in handling for regtype OIDs. It keeps
the cast deterministic regardless of session and execution context and matches
Postgres. The fix lives in (*planner).ResolveOIDFromOID, the single point
shared by both the OID cast path and the 'name'::reg* parse path, so the two
continue to produce identical DOid names (the optimizer interns DOids by OID
alone). User-defined functions still flow through resolveOID for
search-path-aware schema qualification.

Fixes: #171257
Epic: CRDB-62230

Release note: None

🤖 Generated with Claude Code

Casting an integer to regproc or regprocedure and then to text routes
through resolveOID, which runs a pg_catalog.pg_proc query to compute a
Postgres-style search-path visibility bit and schema-qualify the name
when it is not visible through the current search_path. That query
determines visibility by looking up pg_proc by name, but pg_proc's
by-name population is built from builtins.AllBuiltinNames, which excludes
"private" builtins such as the regression-aggregate helper functions
(e.g. final_regr_syy, OID 56).

As a result, casting such a function's OID produced inconsistent output:
in a normal session the visibility lookup found no match and emitted a
spuriously schema-qualified name (pg_catalog.final_regr_syy), while in a
context with no database in scope the catalog query errored and the OID
fell back to its bare numeric form (56). The unoptimized-query-oracle
roachtest observed both forms for the same logical cast and failed.
Postgres emits the bare name for these functions, since pg_catalog is
always implicitly in the search path.

Resolve built-in function OIDs from the in-memory function registry
instead, mirroring the existing built-in handling for regtype OIDs. This
keeps the cast deterministic regardless of session and execution context
and matches Postgres. The change lives in (*planner).ResolveOIDFromOID,
the single point shared by both the OID cast path and the 'name'::reg*
parse path, so the two continue to produce identical DOid names (the
optimizer interns DOids by OID alone). User-defined functions still flow
through resolveOID for search-path-aware schema qualification.

Resolves: cockroachdb#171257
Epic: CRDB-62230

Release note: None

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Merging to master in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@cockroach-teamcity

Copy link
Copy Markdown
Member

This change is Reviewable

@ZhouXing19 ZhouXing19 marked this pull request as draft June 1, 2026 13:25
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.

roachtest: builtin-func oid issue

2 participants