Skip to content

fix: pg_query_parse_plpgsql() regressions in PG 18#1

Closed
pyramation wants to merge 1 commit into
18-latestfrom
fix/plpgsql-json-serialization
Closed

fix: pg_query_parse_plpgsql() regressions in PG 18#1
pyramation wants to merge 1 commit into
18-latestfrom
fix/plpgsql-json-serialization

Conversation

@pyramation

@pyramation pyramation commented May 22, 2026

Copy link
Copy Markdown

Summary

Fixes three regressions in pg_query_parse_plpgsql() introduced by the PG 18 PL/pgSQL compilation rework. All three work correctly in 17-6.1.0.

Bug 1: Trigger functions produce malformed JSON

PG 18 trigger functions create PLPGSQL_DTYPE_PROMISE datums for TG_* variables (tg_name, tg_when, tg_level, etc.). The dump_function() switch statement didn't handle this dtype, so each PROMISE datum produced an empty {} with mismatched closing braces — corrupting the entire JSON output.

Fix: Add PLPGSQL_DTYPE_PROMISE case that serializes via dump_var() (PROMISE datums are PLpgSQL_var structs).

Bug 2: Schema-qualified types fail with "Not implemented"

The PG 18 compilation rework now calls LookupExplicitNamespace() for schema-qualified variable types. This function only supported pg_catalog and public, causing any other schema (e.g. "my_schema".users) to error out.

Fix: Return PG_PUBLIC_NAMESPACE for unknown schemas, so type lookup falls through to the RECORDOID path in GetSysCacheOid. The schema name is preserved in the PL/pgSQL type string.

Bug 3: RETURN <variable> loses its expression

PG 18's compiler sets retvarno instead of expr for simple variable returns (RETURN v, RETURN NEW). But retvarno was commented out in dump_return() and dump_return_next().

Fix: Uncomment WRITE_INT_FIELD(retvarno, retvarno, retvarno) in both functions.

Changes (2 files, +14 / -4)

  • src/pg_query_json_plpgsql.c — Handle PROMISE datums, serialize retvarno
  • src/postgres/src_backend_catalog_namespace.c — Support arbitrary schema names

Three fixes for the PL/pgSQL JSON serialization:

1. Handle PLPGSQL_DTYPE_PROMISE datums in dump_function()
   - PG 18 trigger functions create PROMISE datums for TG_* variables
   - These were falling through to the default case, producing empty {}
     with mismatched braces, resulting in malformed JSON output
   - Fix: serialize PROMISE datums using dump_var() since they are
     PLpgSQL_var structs

2. Support arbitrary schema names in LookupExplicitNamespace()
   - PG 18 reworked PL/pgSQL compilation to use more original code,
     which now calls LookupExplicitNamespace for schema-qualified types
   - Previously only pg_catalog and public were supported, causing an
     error for any other schema (e.g. "my_schema".users)
   - Fix: return PG_PUBLIC_NAMESPACE for unknown schemas so type lookup
     falls through to the RECORDOID path

3. Serialize retvarno field in dump_return() and dump_return_next()
   - PG 18 compiler sets retvarno instead of expr for simple variable
     returns (RETURN v, RETURN NEW in some cases)
   - The retvarno field was commented out, so these returns lost their
     target variable reference
   - Fix: uncomment WRITE_INT_FIELD for retvarno
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