Skip to content

Return errors for PL/pgSQL statements without bodies (cherry-pick of upstream #363) - #14

Open
pyramation wants to merge 1 commit into
18-constructivefrom
feat/plpgsql-no-body-18
Open

pyramation wants to merge 1 commit into
18-constructivefrom
feat/plpgsql-no-body-18

Conversation

@pyramation

@pyramation pyramation commented Oct 25, 2026 •

Copy link
Copy Markdown

Summary

pg_query_parse_plpgsql aborted with assert(proc_source != NULL) on any CREATE FUNCTION/PROCEDURE without an AS clause. That includes valid SQL-standard bodies:

CREATE FUNCTION f() RETURNS int LANGUAGE sql BEGIN ATOMIC SELECT 1; END;  -- abort
CREATE FUNCTION f() RETURNS int LANGUAGE sql;                              -- abort
CREATE PROCEDURE p() LANGUAGE plpgsql;                                     -- abort

In the WASM build (libpg-query 18.x parsePlPgSQL) this surfaces as RuntimeError: Aborted(Assertion failed: proc_source != NULL …).

This is a clean cherry-pick (-x) of upstream e275398 (pganalyze#363):

  • compile_create_function_stmt_via_callback checks the language first. Non-PL/pgSQL functions are skipped as before (palloc0 function), so LANGUAGE sql … BEGIN ATOMIC returns a result.
  • For PL/pgSQL, missing and duplicate bodies raise upstream's interpret_AS_clause errors: no function body specified / duplicate function body specified.
  • compile_do_stmt raises no inline code specified instead of asserting.
  • New regression cases in test/parse_plpgsql.c.

17-constructive has the same two asserts, but libpg-query 17 doesn't export parsePlPgSQL, so this PR only targets 18.

CI: every build passes, local make test passes. The valgrind jobs fail only on test/parse_plpgsql, with the 192-byte still-reachable block from pg_query_plpgsql_record_alias (pg_query_json_plpgsql.c:826). That failure is not caused by this PR:

The node pin is left to the combined fork/node PR.

Link to Devin session: https://app.devin.ai/sessions/b32426e30a71409594f003cf94c9e560
Open in Devin Desktop: https://app.devin.ai/desktop/session/b32426e30a71409594f003cf94c9e560?variant=devin
Requested by: @pyramation

* Fix PL/pgSQL parsing without function bodies

Return PostgreSQL errors when CREATE FUNCTION or DO omits its AS clause instead of asserting or dereferencing a null source pointer in release builds.

Add regression coverage for both malformed statement types.

Fixes pganalyze#362.

* Skip non-PL/pgSQL functions before checking for a body, add more checks

Check the language before requiring an AS clause, so that valid
SQL-standard function bodies (LANGUAGE sql RETURN ... / BEGIN ATOMIC)
are skipped as before instead of returning an error. For PL/pgSQL
functions, also raise upstream's "duplicate function body specified"
and "inline SQL function body only valid for language SQL" errors, as
in Postgres' interpret_AS_clause function.

In passing, fix a related memory leak for raw parser's stderr buffer when
the input contains no CREATE FUNCTION or DO statements, which previously
leaked.

---------

Co-authored-by: Darren Carreras <[email protected]>
Co-authored-by: Lukas Fittl <[email protected]>
(cherry picked from commit e275398)
@devin-ai-integration

Copy link
Copy Markdown

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@tenki-reviewer

tenki-reviewer Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Review complete. No blocking issues — approved ✅; 1 nitpick below.

🧹 Nitpicks (1) — 🟢 1 low
  • 🟢 Body checks skipped for non-plpgsql languages (pg_query_parse_plpgsql.c:440) — The new checks mirroring upstream interpret_AS_clause sit after the strcmp(language, "plpgsql") != 0 early return at src/pg_query_parse_plpgsql.c:437, so they only run for plpgsql.

The PR ports upstream interpret_AS_clause body-existence and format checks into the plpgsql parser for CREATE FUNCTION and DO statements, so statements without bodies now return errors instead of silently parsing, and updates the test suite accordingly.

Files Change
src/pg_query_parse_plpgsql.c Adds body checks (no function body specified, duplicate function body specified, inline SQL body restricted to LANGUAGE SQL) in the CREATE FUNCTION path and a proc_source check in the DO path.
test/parse_plpgsql.c Adds test fixtures covering missing and duplicate function bodies and missing DO inline code.

Reviewed commit: 99174d9

@devin-ai-integration

Copy link
Copy Markdown

Folded into #13

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.

2 participants