From 463098e59989b258c68e703b396e5364f48d840c Mon Sep 17 00:00:00 2001
From: Lukas Fittl <lukas@fittl.com>
Date: Wed, 20 Sep 2017 19:56:03 -0700
Subject: [PATCH] Only skip query cancel itself when query cancel holdoff count
 is positive

Previously the logic would short-circuit all other interrupts that follow,
which is particularly a problem for idle_in_transaction_session_timeout
since that might want to cancel a connection thats not receiving any data
whilst being inside a block that has query cancellation holdoff active.
---
 src/backend/tcop/postgres.c | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index c807b00b0b..edea6f177b 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2941,26 +2941,24 @@ ProcessInterrupts(void)
 						 " database and repeat your command.")));
 	}
 
-	if (QueryCancelPending)
+	/*
+	 * Don't allow query cancel interrupts while reading input from the
+	 * client, because we might lose sync in the FE/BE protocol.  (Die
+	 * interrupts are OK, because we won't read any further messages from
+	 * the client in that case.)
+	 */
+	if (QueryCancelPending && QueryCancelHoldoffCount != 0)
 	{
-		bool		lock_timeout_occurred;
-		bool		stmt_timeout_occurred;
-
 		/*
-		 * Don't allow query cancel interrupts while reading input from the
-		 * client, because we might lose sync in the FE/BE protocol.  (Die
-		 * interrupts are OK, because we won't read any further messages from
-		 * the client in that case.)
+		 * Re-arm InterruptPending so that we process the cancel request
+		 * as soon as we're done reading the message.
 		 */
-		if (QueryCancelHoldoffCount != 0)
-		{
-			/*
-			 * Re-arm InterruptPending so that we process the cancel request
-			 * as soon as we're done reading the message.
-			 */
-			InterruptPending = true;
-			return;
-		}
+		InterruptPending = true;
+	}
+	else if (QueryCancelPending)
+	{
+		bool		lock_timeout_occurred;
+		bool		stmt_timeout_occurred;
 
 		QueryCancelPending = false;
 
-- 
2.11.0

