Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Avoid Assert failure when processing empty statement in aborted xact.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 21 Jun 2023 15:07:11 +0000 (11:07 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 21 Jun 2023 15:07:11 +0000 (11:07 -0400)
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

src/backend/utils/cache/plancache.c
src/test/regress/expected/psql.out
src/test/regress/sql/psql.sql

index 6767eae8f204e050fe6e0899f88244697787b218..e1a873967f09f980ff6ef5c9c75e841a38171505 100644 (file)
 /*
  * 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))
 
 /*
index a15db7c78edee0880d64593173da49d4e66a4836..265518de1ffc0b4848b4cc25c2bf85f8a0a5da9f 100644 (file)
@@ -237,6 +237,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)
index 338a904ec772b37e4e4d9607eba1d5c0c7d2b63f..26ffe0644038eeefc1dfec3ec4c63574231852c1 100644 (file)
@@ -119,6 +119,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);