PL/pgSQL: "missing X at end of SQL expression" is never reported at end of input

From: Jeevan Chalke <jeevan(dot)chalke(at)enterprisedb(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: PL/pgSQL: "missing X at end of SQL expression" is never reported at end of input
Date: 2026-10-30 06:59:41
Message-ID: CAM2+6=WcWycVx0j-zw=0jFJxfazFHtZadqZbBedEg2AQkGasfQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

read_sql_construct() in pl_gram.y takes up to three terminator tokens.
Callers pass 0 for the ones they don't use, but 0 is also the token code
for end of input. The loop compares against until2 and until3 before it
gets to its own "tok == 0" check, which is what produces the
missing "%s" at end of SQL expression/statement
error.

So when a function body ends in the middle of a construct, EOF is taken as
a valid terminator and the helpful message is skipped. The text read so
far is then handed to the core parser or the next grammar rule, which
reports something generic or misleading:

do $$ begin if true $$;
ERROR: syntax error at end of input

do $$ begin while true $$;
ERROR: syntax error at end of input

do $$ begin case 1 $$;
ERROR: missing expression at end of input

do $$ declare x int; begin x := 1 $$;
ERROR: syntax error at end of input

The attached patch only compares against until2/until3 when they are
non-zero (until is always non-zero for every caller). With it:

do $$ begin if true $$;
ERROR: missing "THEN" at end of SQL expression

do $$ begin while true $$;
ERROR: missing "LOOP" at end of SQL expression

do $$ begin case 1 $$;
ERROR: missing "WHEN" at end of SQL expression

do $$ declare x int; begin x := 1 $$;
ERROR: missing ";" at end of SQL statement

The error position is the same as before (end of input). I added the four
statements above to plpgsql.sql; no existing expected output changes.

Since this only changes error message text, which tests and external tools
may match on, I think master only is the safer choice (or v19 as it is not
yet released), but I'm happy to hear
other opinions.

Thanks,

--
*Jeevan Chalke*
*Senior Principal Engineer, Engineering Manager*
*Product Development*

enterprisedb.com <https://www.enterprisedb.com>

Attachment Content-Type Size
v1-0001-Fix-PL-pgSQL-missing-X-at-end-of-SQL-expression-e.patch application/octet-stream 3.4 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Hunaid Sohail 2026-10-30 07:06:31 Re: Proposal: SELECT * EXCLUDE (...) command
Previous Message Ayush Tiwari 2026-10-30 06:58:51 Re: 041_checkpoint_at_promote.pl might fail due to race condition on child kill