]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Put libpq_pipeline cancel test back
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 18 Mar 2024 12:14:55 +0000 (13:14 +0100)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 18 Mar 2024 12:14:55 +0000 (13:14 +0100)
I disabled it in cc6e64afda53 because it was unstable; hopefully the
changes here make it more stable.  (Jelte proposed to submit the queries
using simple query protocol, but I chose to instead make the monitor
connection wait until the PgSleep wait event is seen.  This is probably
not a terribly meaningful increase in coverage ...)

Discussion: https://postgr.es/m/CAGECzQRQh_5tSy+5cndgv08eNJ2O0Zpwn2YddJtSsmC=Wpy1BQ@mail.gmail.com

src/test/modules/libpq_pipeline/libpq_pipeline.c

index e730ad376985a7967a2267f4febc2a59bb456fef..b7e7a0947cbb5ba78857b0c0aee3ffcedf30aa6d 100644 (file)
@@ -116,27 +116,37 @@ confirm_query_canceled_impl(int line, PGconn *conn)
 
 /*
  * Using monitorConn, query pg_stat_activity to see that the connection with
- * the given PID is in the given state.  We never stop until it does.
+ * the given PID is either in the given state, or waiting on the given event
+ * (only one of them can be given).
  */
 static void
-wait_for_connection_state(int line, PGconn *monitorConn, int procpid, char *state)
+wait_for_connection_state(int line, PGconn *monitorConn, int procpid,
+                                                 char *state, char *event)
 {
        const Oid       paramTypes[] = {INT4OID, TEXTOID};
        const char *paramValues[2];
        char       *pidstr = psprintf("%d", procpid);
 
+       Assert((state == NULL) ^ (event == NULL));
+
        paramValues[0] = pidstr;
-       paramValues[1] = state;
+       paramValues[1] = state ? state : event;
 
        while (true)
        {
                PGresult   *res;
                char       *value;
 
-               res = PQexecParams(monitorConn,
-                                                  "SELECT count(*) FROM pg_stat_activity WHERE "
-                                                  "pid = $1 AND state = $2",
-                                                  2, paramTypes, paramValues, NULL, NULL, 1);
+               if (state != NULL)
+                       res = PQexecParams(monitorConn,
+                                                          "SELECT count(*) FROM pg_stat_activity WHERE "
+                                                          "pid = $1 AND state = $2",
+                                                          2, paramTypes, paramValues, NULL, NULL, 0);
+               else
+                       res = PQexecParams(monitorConn,
+                                                          "SELECT count(*) FROM pg_stat_activity WHERE "
+                                                          "pid = $1 AND wait_event = $2",
+                                                          2, paramTypes, paramValues, NULL, NULL, 0);
 
                if (PQresultStatus(res) != PGRES_TUPLES_OK)
                        pg_fatal_impl(line, "could not query pg_stat_activity: %s", PQerrorMessage(monitorConn));
@@ -145,7 +155,7 @@ wait_for_connection_state(int line, PGconn *monitorConn, int procpid, char *stat
                if (PQnfields(res) != 1)
                        pg_fatal_impl(line, "unexpected number of columns received: %d", PQnfields(res));
                value = PQgetvalue(res, 0, 0);
-               if (value[0] != '0')
+               if (strcmp(value, "0") != 0)
                {
                        PQclear(res);
                        break;
@@ -172,7 +182,7 @@ send_cancellable_query_impl(int line, PGconn *conn, PGconn *monitorConn)
         * connection below is reliable, instead of possibly seeing an outdated
         * state.
         */
-       wait_for_connection_state(line, monitorConn, PQbackendPID(conn), "idle");
+       wait_for_connection_state(line, monitorConn, PQbackendPID(conn), "idle", NULL);
 
        env_wait = getenv("PG_TEST_TIMEOUT_DEFAULT");
        if (env_wait == NULL)
@@ -183,10 +193,10 @@ send_cancellable_query_impl(int line, PGconn *conn, PGconn *monitorConn)
                pg_fatal_impl(line, "failed to send query: %s", PQerrorMessage(conn));
 
        /*
-        * Wait for the query to start, because if the query is not running yet
-        * the cancel request that we send won't have any effect.
+        * Wait for the sleep to be active, because if the query is not running
+        * yet, the cancel request that we send won't have any effect.
         */
-       wait_for_connection_state(line, monitorConn, PQbackendPID(conn), "active");
+       wait_for_connection_state(line, monitorConn, PQbackendPID(conn), NULL, "PgSleep");
 }
 
 /*
@@ -2098,10 +2108,7 @@ usage(const char *progname)
 static void
 print_test_list(void)
 {
-#if 0
-       /* Commented out until further stabilized */
        printf("cancel\n");
-#endif
        printf("disallowed_in_pipeline\n");
        printf("multi_pipelines\n");
        printf("nosync\n");