From a89571fae6e91077050fc2ee6f0997376f1708fb Mon Sep 17 00:00:00 2001 From: Jelte Fennema-Nio Date: Thu, 14 Mar 2024 10:45:51 +0100 Subject: [PATCH v38 1/3] Use simple query protocol for cancel test The new cancel test was randomly failing on the build farm. It turns out that using the extended query protocol was the cause of this, because it was possible for the cancel to arrive in between the Bind and Execute messages. This fixes that by using the simple query protocol to send the query that should be cancelled. Reported-By: Jacob Champion --- .../modules/libpq_pipeline/libpq_pipeline.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/test/modules/libpq_pipeline/libpq_pipeline.c b/src/test/modules/libpq_pipeline/libpq_pipeline.c index e730ad37698..83f9caca726 100644 --- a/src/test/modules/libpq_pipeline/libpq_pipeline.c +++ b/src/test/modules/libpq_pipeline/libpq_pipeline.c @@ -165,7 +165,7 @@ static void send_cancellable_query_impl(int line, PGconn *conn, PGconn *monitorConn) { const char *env_wait; - const Oid paramTypes[1] = {INT4OID}; + char *query; /* * Wait for the connection to be idle, so that our check for an active @@ -178,10 +178,21 @@ send_cancellable_query_impl(int line, PGconn *conn, PGconn *monitorConn) if (env_wait == NULL) env_wait = "180"; - if (PQsendQueryParams(conn, "SELECT pg_sleep($1)", 1, paramTypes, - &env_wait, NULL, NULL, 0) != 1) + /* + * We cannot use PQsendQueryParams here because it uses the extended + * protocol to send the query. And it turns out there exists a race + * condition where would send the cancel request in between the Bind and + * Execute messages, resulting in the cancel request being ignored. So + * instead we build the query string client side and send it using + * PQsendQuery so there is only a single Query message. + */ + query = psprintf("SELECT pg_sleep(%d)", atoi(env_wait)); + + if (PQsendQuery(conn, query) != 1) pg_fatal_impl(line, "failed to send query: %s", PQerrorMessage(conn)); + pfree(query); + /* * 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. base-commit: cc6e64afda530576d83e331365d36c758495a7cd -- 2.34.1