Skip to content

catalog: scope pg_description classoid lookups to pg_catalog schema#37071

Open
aljoscha wants to merge 2 commits into
MaterializeInc:mainfrom
aljoscha:fix-sql-278-pg-description-schema-scope
Open

catalog: scope pg_description classoid lookups to pg_catalog schema#37071
aljoscha wants to merge 2 commits into
MaterializeInc:mainfrom
aljoscha:fix-sql-278-pg-description-schema-scope

Conversation

@aljoscha

Copy link
Copy Markdown
Contributor

Motivation

Fixes SQL-278.

Creating any user object named pg_class, pg_type, or pg_namespace
in any schema broke pg_catalog.pg_description for everyone:

db error: ERROR: Evaluation error: more than one record produced in subquery

pg_description derives each comment's classoid from
mz_internal.pg_description_all_databases, which looked up the system
catalog oids with unscoped scalar subqueries (WHERE relname = 'pg_class', etc.). A user object sharing one of those names made the
scalar subquery match multiple rows, so the whole view errored.

Description

Scope the pg_class/pg_type/pg_namespace lookups to the
pg_catalog schema via a small pg_catalog_class CTE. The pg_catalog
schema is ambient and reserved (users cannot create a schema with the
pg_ prefix), so each lookup resolves to exactly one row. Only the
classoid derivation needed scoping; no other builtin view has the same
unscoped-lookup pattern.

This matches PostgreSQL, where pg_description is a real catalog table
and is unaffected by user objects that happen to share those names.

Verification

Verified against PostgreSQL 16: creating public.pg_class does not
affect pg_description; a commented user table's comment is still
returned.

Added a regression test to test/sqllogictest/comment.slt that creates
user tables named pg_class, pg_type, and pg_namespace and asserts
pg_description still returns a user object's comment instead of
erroring.

`pg_catalog.pg_description` derives each comment's `classoid` from
`mz_internal.pg_description_all_databases`, which looked up the
`pg_class`/`pg_type`/`pg_namespace` system catalog oids with unscoped
scalar subqueries (`WHERE relname = 'pg_class'`, etc.). A user object
named after one of those catalogs, in any schema, made the scalar
subquery match multiple rows, so `pg_description` errored with "more
than one record produced in subquery" for everyone.

Scope the lookups to the `pg_catalog` schema via a small CTE. The
`pg_catalog` schema is ambient and reserved (users cannot create a
schema with the `pg_` prefix), so the lookup resolves to exactly one
row. This matches PostgreSQL, where `pg_description` is a real catalog
table and is unaffected by user objects sharing those names.

Fixes SQL-278.
@aljoscha aljoscha requested a review from a team as a code owner June 16, 2026 12:09
@ggevay ggevay self-requested a review June 16, 2026 12:35
…ption

The pg_description_all_databases optimized plan changed because the
classoid lookups are now scoped to the pg_catalog schema. Regenerated
the golden EXPLAIN output.

Fixes SQL-278.
cte l1 =
→Differential Join %1[#0] » %0:l0[#1{relname}]
→Arranged l0
→Differential Join %1[#0] » %0:pg_namespace_all_databases[#1{nspname}]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ggevay I think you added these recently? I see that we're doing things differently now, which makes sense because we have an additional lookup. But couldn't say whether that's fine or not

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