Fix ROLLBACK TO command to work in aborted transaction.
authorTatsuo Ishii <ishii@sraoss.co.jp>
Fri, 25 Nov 2022 07:33:17 +0000 (16:33 +0900)
committerTatsuo Ishii <ishii@sraoss.co.jp>
Fri, 25 Nov 2022 09:23:26 +0000 (18:23 +0900)
Commit:

https://git.postgresql.org/gitweb/?p=pgpool2.git;a=commit;h=eea522ebfcf791a623e865deaa1aa6fb59e3c50b

fixed some cases in aborted transaction so that SQL commands except
COMMIT/ROLLBACK are not forwarded to backend. But it missed ROLLBACK
TO command. As a result even if ROLLBACK TO command is issued, the
command was not forwarded to backend and the transaction keeps on in
aborted state.
Back patched through 4.3 which the commit was brought in.
Also add a test case for ROLLBACK TO to test 078.
Discussion:
https://www.pgpool.net/pipermail/pgpool-general-jp/2022-November/001715.html

src/include/protocol/pool_proto_modules.h
src/protocol/pool_process_query.c
src/protocol/pool_proto_modules.c
src/test/regression/tests/078.aborted_transaction/expected.txt
src/test/regression/tests/078.aborted_transaction/test.sh

index 1fd6f8c68663c52bb28c5c0db8f08bf6d59ffe90..57280a3e315062845feada9bfbcd49126321cc38 100644 (file)
@@ -153,6 +153,7 @@ extern bool is_select_query(Node *node, char *sql);
 extern bool is_commit_query(Node *node);
 extern bool is_rollback_query(Node *node);
 extern bool is_commit_or_rollback_query(Node *node);
+extern bool is_rollback_to_query(Node *node);
 extern bool is_strict_query(Node *node);       /* returns non 0 if this is strict
                                                                                         * query */
 extern int     need_insert_lock(POOL_CONNECTION_POOL * backend, char *query, Node *node);
index 8d1c0c819c074f97c6410454dcbc07590cce2f61..f2db65eabe80eb9af33a08812955ab1010435c3e 100644 (file)
@@ -1246,7 +1246,7 @@ is_select_query(Node *node, char *sql)
 bool
 is_commit_or_rollback_query(Node *node)
 {
-       return is_commit_query(node) || is_rollback_query(node);
+       return is_commit_query(node) || is_rollback_query(node) || is_rollback_to_query(node);
 }
 
 /*
@@ -1281,6 +1281,21 @@ is_rollback_query(Node *node)
        return stmt->kind == TRANS_STMT_ROLLBACK;
 }
 
+/*
+ * Returns true if SQL is transaction rollback to command
+ */
+bool
+is_rollback_to_query(Node *node)
+{
+       TransactionStmt *stmt;
+
+       if (node == NULL || !IsA(node, TransactionStmt))
+               return false;
+
+       stmt = (TransactionStmt *) node;
+       return stmt->kind == TRANS_STMT_ROLLBACK_TO;
+}
+
 /*
  * send error message to frontend
  */
index a20aa6922088c0456d472d878915e31748ce0394..255cc4fad6749a7b680779fa78c9ac5531d4a502 100644 (file)
@@ -310,7 +310,7 @@ SimpleQuery(POOL_CONNECTION * frontend,
                /*
                 * Check if the transaction is in abort status. If so, we do nothing
                 * and just return an error message to frontend, execpt for
-                * transaction commit or abort command.
+                * transaction COMMIT or ROLLBACK (TO) command.
                 */
                if (check_transaction_state_and_abort(contents, node, frontend, backend) == false)
                {
index be37381b4c0f77ebc32b3171cd08c16adfb93c0f..f70e6716e61c20e5abc0defd6c499a2e2c243b6d 100644 (file)
@@ -26,3 +26,21 @@ SELECT 1;
         1
 (1 row)
 
+BEGIN;
+BEGIN
+SAVEPOINT s1;
+SAVEPOINT
+aaa;
+ERROR:  syntax error at or near "aaa"
+LINE 1: aaa;
+        ^
+ROLLBACK TO s1;
+ROLLBACK
+SELECT 1;
+ ?column? 
+----------
+        1
+(1 row)
+
+END;
+COMMIT
index 47bd280c1efb9da57b1ca7337a43d563f75b173f..7c8eca38796f4d0f00bc9a8862df4c6253cd0e19 100755 (executable)
@@ -33,6 +33,12 @@ aaa;
 SELECT 1;
 END;
 SELECT 1;
+BEGIN;
+SAVEPOINT s1;
+aaa;
+ROLLBACK TO s1;
+SELECT 1;
+END;
 EOF
 
 if cmp ../expected.txt results.txt >/dev/null