Re: BUG #15727: PANIC: cannot abort transaction 295144144, it was already committed - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #15727: PANIC: cannot abort transaction 295144144, it was already committed
Date
Msg-id 19321.1554567786@sss.pgh.pa.us
Whole thread Raw
In response to Re: BUG #15727: PANIC: cannot abort transaction 295144144, it wasalready committed  (r.zharkov@postgrespro.ru)
Responses Re: BUG #15727: PANIC: cannot abort transaction 295144144, it wasalready committed  (Andres Freund <andres@anarazel.de>)
Re: BUG #15727: PANIC: cannot abort transaction 295144144, it wasalready committed  (Amit Langote <Langote_Amit_f8@lab.ntt.co.jp>)
List pgsql-bugs
It seems that there may be some connection between this problem and
EPQ.  I was working on committing Amit's fix for bug #15677, which
demonstrated that EPQ doesn't work for partitioned-table target rels.
It seemed like there really needed to be regression test coverage for
that, so I tried to convert his crasher example into an isolation test.
It does indeed crash without Amit's fix ... but with it, lookee what
I get:

+error in steps c1 complexpartupdate: ERROR:  unexpected table_lock_tuple status: 1

That seems fully reproducible in this test.  I haven't looked into
exactly what's causing that, but now that we have a reproducible
example, somebody should.

I'm not quite sure if I should commit this as-is or wait till the
other problem is fixed.  A crash is probably worse than a bogus
error, but I don't like committing obviously-wrong "expected" output.
Thoughts?

            regards, tom lane

diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 602a08e..5c4b3f4 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2799,15 +2799,24 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
     estate->es_output_cid = parentestate->es_output_cid;
     if (parentestate->es_num_result_relations > 0)
     {
-        int            numResultRelations = parentestate->es_num_result_relations;
+        int            numResultRels = parentestate->es_num_result_relations;
+        int            numRootResultRels = parentestate->es_num_root_result_relations;
         ResultRelInfo *resultRelInfos;

         resultRelInfos = (ResultRelInfo *)
-            palloc(numResultRelations * sizeof(ResultRelInfo));
+            palloc(numResultRels * sizeof(ResultRelInfo));
         memcpy(resultRelInfos, parentestate->es_result_relations,
-               numResultRelations * sizeof(ResultRelInfo));
+               numResultRels * sizeof(ResultRelInfo));
         estate->es_result_relations = resultRelInfos;
-        estate->es_num_result_relations = numResultRelations;
+        estate->es_num_result_relations = numResultRels;
+
+        /* Also transfer partitioned root result relations. */
+        resultRelInfos = (ResultRelInfo *)
+            palloc(numRootResultRels * sizeof(ResultRelInfo));
+        memcpy(resultRelInfos, parentestate->es_root_result_relations,
+               numRootResultRels * sizeof(ResultRelInfo));
+        estate->es_root_result_relations = resultRelInfos;
+        estate->es_num_root_result_relations = numRootResultRels;
     }
     /* es_result_relation_info must NOT be copied */
     /* es_trig_target_relations must NOT be copied */
diff --git a/src/test/isolation/expected/eval-plan-qual.out b/src/test/isolation/expected/eval-plan-qual.out
index c09e97f..47843d7 100644
--- a/src/test/isolation/expected/eval-plan-qual.out
+++ b/src/test/isolation/expected/eval-plan-qual.out
@@ -562,3 +562,16 @@ step multireadwcte: <... completed>
 subid          id

 1              1
+
+starting permutation: simplepartupdate complexpartupdate c1 c2
+step simplepartupdate:
+    update parttbl set a = a;
+
+step complexpartupdate:
+    with u as (update parttbl set a = a returning parttbl.*)
+    update parttbl set a = u.a from u;
+ <waiting ...>
+step c1: COMMIT;
+step complexpartupdate: <... completed>
+error in steps c1 complexpartupdate: ERROR:  unexpected table_lock_tuple status: 1
+step c2: COMMIT;
diff --git a/src/test/isolation/specs/eval-plan-qual.spec b/src/test/isolation/specs/eval-plan-qual.spec
index 41c8d56..7d3f1f6 100644
--- a/src/test/isolation/specs/eval-plan-qual.spec
+++ b/src/test/isolation/specs/eval-plan-qual.spec
@@ -29,6 +29,10 @@ setup

  CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data;
  CREATE INDEX ON jointest(id);
+
+ CREATE TABLE parttbl (a int) PARTITION BY LIST (a);
+ CREATE TABLE parttbl1 PARTITION OF parttbl FOR VALUES IN (1);
+ INSERT INTO parttbl VALUES (1);
 }

 teardown
@@ -37,6 +41,7 @@ teardown
  DROP TABLE accounts_ext;
  DROP TABLE p CASCADE;
  DROP TABLE table_a, table_b, jointest;
+ DROP TABLE parttbl;
 }

 session "s1"
@@ -133,6 +138,12 @@ step "selectresultforupdate"    {
       where jt.id = y for update of jt, ss1, ss2;
 }

+# test for EPQ on a partitioned result table
+
+step "simplepartupdate"    {
+    update parttbl set a = a;
+}
+

 session "s2"
 setup        { BEGIN ISOLATION LEVEL READ COMMITTED; }
@@ -170,6 +181,10 @@ step "updateforcip3"    {
 }
 step "wrtwcte"    { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
 step "wrjt"    { UPDATE jointest SET data = 42 WHERE id = 7; }
+step "complexpartupdate"    {
+    with u as (update parttbl set a = a returning parttbl.*)
+    update parttbl set a = u.a from u;
+}
 step "c2"    { COMMIT; }
 step "r2"    { ROLLBACK; }

@@ -234,3 +249,5 @@ permutation "wrtwcte" "readwcte" "c1" "c2"
 permutation "wrjt" "selectjoinforupdate" "c2" "c1"
 permutation "wrjt" "selectresultforupdate" "c2" "c1"
 permutation "wrtwcte" "multireadwcte" "c1" "c2"
+
+permutation "simplepartupdate" "complexpartupdate" "c1" "c2"

pgsql-bugs by date:

Previous
From: Etsuro Fujita
Date:
Subject: Re: BUG #15724: Can't create foreign table as partition
Next
From: Andres Freund
Date:
Subject: Re: BUG #15727: PANIC: cannot abort transaction 295144144, it wasalready committed