diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 34c13a1113..47c72def5b 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -105,6 +105,8 @@ int			PostAuthDelay = 0;
 /* Time between checks that the client is still connected. */
 int			client_connection_check_interval = 0;
 
+char 		*QueryCancelMessage = NULL;
+
 /* ----------------
  *		private typedefs etc
  * ----------------
@@ -3326,8 +3328,20 @@ ProcessInterrupts(void)
 			LockErrorCleanup();
 			ereport(ERROR,
 					(errcode(ERRCODE_QUERY_CANCELED),
+					 QueryCancelMessage ?
+					 errmsg("%s", QueryCancelMessage) :
 					 errmsg("canceling statement due to user request")));
 		}
+		else if (QueryCancelMessage != NULL)
+		{
+			/*
+			 * If we reach here someone wanted to cancel query but it was skepped
+			 * because connection status was idle. So re-arm Pending flags
+			 * for next iteration.
+			 */
+			InterruptPending = true;
+			QueryCancelPending = true;
+		}
 	}
 
 	if (IdleInTransactionSessionTimeoutPending)
@@ -4247,6 +4261,9 @@ PostgresMain(const char *dbname, const char *username)
 		/* Report the error to the client and/or server log */
 		EmitErrorReport();
 
+		/* Make sure QueryCancelMessage is reset. */
+		QueryCancelMessage = NULL;
+
 		/*
 		 * Make sure debug_query_string gets reset before we possibly clobber
 		 * the storage it points at.
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 15a11bc3ff..51f91be14b 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -30,6 +30,7 @@ extern PGDLLIMPORT const char *debug_query_string;
 extern int	max_stack_depth;
 extern int	PostAuthDelay;
 extern int	client_connection_check_interval;
+extern PGDLLIMPORT char* QueryCancelMessage;
 
 /* GUC-configurable parameters */
 
