Allow reset queries to run even if extended queries do not end.
authorTatsuo Ishii <ishii@sraoss.co.jp>
Wed, 20 Mar 2024 22:31:29 +0000 (07:31 +0900)
committerTatsuo Ishii <ishii@sraoss.co.jp>
Thu, 21 Mar 2024 00:32:20 +0000 (09:32 +0900)
Commit 240c668d "Guard against inappropriate protocol data." caused
reset queries fail if extended query messages do not end. This commit
fix that by checking whether we are running reset queries in
SimpleQuery(). Also add the test case for this.

src/protocol/pool_proto_modules.c
src/test/regression/tests/082.guard_against_bad_protocol/pgproto2.data [new file with mode: 0644]
src/test/regression/tests/082.guard_against_bad_protocol/test.sh

index 439bcf83cd9b9b18c8f26462b65e5fb07ad146cc..13b952163146361d33a118f41fe6f4e6d7c8182b 100644 (file)
@@ -3,7 +3,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2023     PgPool Global Development Group
+ * Copyright (c) 2003-2024     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -181,6 +181,7 @@ process_pg_terminate_backend_func(POOL_QUERY_CONTEXT * query_context)
 /*
  * Process Query('Q') message
  * Query messages include an SQL string.
+ * If frontend == NULL, we are called in case of reset queries.
  */
 POOL_STATUS
 SimpleQuery(POOL_CONNECTION * frontend,
@@ -223,11 +224,14 @@ SimpleQuery(POOL_CONNECTION * frontend,
        /*
         * Check if extended query protocol message ended.  If not, reject the
         * query and raise an error to terminate the session to avoid hanging up.
+        * However if we are processing a reset query (frontend == NULL), we skip
+        * the check as we don't want to raise a error.
         */
        if (SL_MODE)
        {
-               if (pool_is_doing_extended_query_message() ||
-                       pool_pending_message_head_message())
+               if (frontend != NULL &&
+                       (pool_is_doing_extended_query_message() ||
+                        pool_pending_message_head_message()))
 
                        ereport(FATAL,
                                        (errmsg("simple query \"%s\" arrived before ending an extended query message",
diff --git a/src/test/regression/tests/082.guard_against_bad_protocol/pgproto2.data b/src/test/regression/tests/082.guard_against_bad_protocol/pgproto2.data
new file mode 100644 (file)
index 0000000..f4edbb4
--- /dev/null
@@ -0,0 +1,4 @@
+'P'    ""      "SELECT 1"      0
+'B'    ""      ""      0       0       0
+'E'    ""      0
+'X'
index 5192c32f3fac1e05ab04347fd6479bd4f068c0d1..f1d16e6f36c45444faec0cd5da353d692185fda8 100755 (executable)
@@ -26,6 +26,7 @@ source ./bashrc.ports
 ./startall
 wait_for_pgpool_startup
 
+# test1:
 # Wait for 1 seconds before pgproto ended.
 # Usually 1 seconds should be enough to finish pgproto.
 # If test suceeded, pgpool emits an error message:
@@ -35,9 +36,21 @@ timeout 1 $PGPROTO -d $PGDATABASE -p $PGPOOL_PORT -f ../pgproto.data |& grep 'si
 
 if [ $? != 0 ];then
 # timeout happened or pgproto returned non 0 status
-    echo "test failed."
+    echo "test1 failed."
     ./shutdownall
     exit 1
 fi
+
+# test2:
+# Check if reset queries can be executed even if extended query messages
+# do not end.
+timeout 1 $PGPROTO -d $PGDATABASE -p $PGPOOL_PORT -f ../pgproto2.data
+if [ $? != 0 ];then
+# timeout happened or pgproto returned non 0 status
+    echo "test2 failed."
+    ./shutdownall
+    exit 1
+fi
+
 ./shutdownall
 exit 0