Skip to content

Commit

Permalink
Avoid Assert failure when processing empty statement in aborted xact.
Browse files Browse the repository at this point in the history
exec_parse_message() wants to create a cached plan in all cases,
including for empty input.  The empty-input path does not have
a test for being in an aborted transaction, making it possible
that plancache.c will fail due to trying to do database lookups
even though there's no real work to do.

One solution would be to throw an aborted-transaction error in
this path too, but it's not entirely clear whether the lack of
such an error was intentional or whether some clients might be
relying on non-error behavior.  Instead, let's hack plancache.c
so that it treats empty statements with the same logic it
already had for transaction control commands, ensuring that it
can soldier through even in an already-aborted transaction.

Per bug #17983 from Alexander Lakhin.  Back-patch to all
supported branches.

Discussion: https://postgr.es/m/17983-da4569fcb878672e@postgresql.org
  • Loading branch information
tglsfdc committed Jun 21, 2023
1 parent 3d9fd1a commit 555b929
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/backend/utils/cache/plancache.c
Expand Up @@ -78,9 +78,11 @@
/*
* We must skip "overhead" operations that involve database access when the
* cached plan's subject statement is a transaction control command.
* For the convenience of postgres.c, treat empty statements as control
* commands too.
*/
#define IsTransactionStmtPlan(plansource) \
((plansource)->raw_parse_tree && \
((plansource)->raw_parse_tree == NULL || \
IsA((plansource)->raw_parse_tree->stmt, TransactionStmt))

/*
Expand Down
11 changes: 11 additions & 0 deletions src/test/regress/expected/psql.out
Expand Up @@ -268,6 +268,17 @@ SELECT 3 AS x, 'Hello', 4 AS y, true AS "dirty\name" \gdesc \g
3 | Hello | 4 | t
(1 row)

-- test for server bug #17983 with empty statement in aborted transaction
set search_path = default;
begin;
bogus;
ERROR: syntax error at or near "bogus"
LINE 1: bogus;
^
;
\gdesc
The command has no result, or the result has no columns.
rollback;
-- \gexec
create temporary table gexec_test(a int, b text, c date, d float);
select format('create index on gexec_test(%I)', attname)
Expand Down
8 changes: 8 additions & 0 deletions src/test/regress/sql/psql.sql
Expand Up @@ -133,6 +133,14 @@ SELECT 1 AS x, 'Hello', 2 AS y, true AS "dirty\name"
-- all on one line
SELECT 3 AS x, 'Hello', 4 AS y, true AS "dirty\name" \gdesc \g

-- test for server bug #17983 with empty statement in aborted transaction
set search_path = default;
begin;
bogus;
;
\gdesc
rollback;

-- \gexec

create temporary table gexec_test(a int, b text, c date, d float);
Expand Down

0 comments on commit 555b929

Please sign in to comment.