Skip to content

Commit 1b812af

Browse files
committed
Fix multiple problems in postgres_fdw query cancellation logic.
First, even if we cancel a query, we still have to roll back the containing transaction; otherwise, the session will be left in a failed transaction state. Second, we need to support canceling queries whe aborting a subtransaction as well as when aborting a toplevel transaction. Etsuro Fujita, reviewed by Michael Paquier
1 parent b7a9347 commit 1b812af

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

contrib/postgres_fdw/connection.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,7 @@ pgfdw_xact_callback(XactEvent event, void *arg)
677677
* using an asynchronous execution function, the command
678678
* might not have yet completed. Check to see if a command
679679
* is still being processed by the remote server, and if so,
680-
* request cancellation of the command; if not, abort
681-
* gracefully.
680+
* request cancellation of the command.
682681
*/
683682
if (PQtransactionStatus(entry->conn) == PQTRANS_ACTIVE)
684683
{
@@ -694,7 +693,6 @@ pgfdw_xact_callback(XactEvent event, void *arg)
694693
errbuf)));
695694
PQfreeCancel(cancel);
696695
}
697-
break;
698696
}
699697

700698
/* If we're aborting, abort all remote transactions too */
@@ -798,6 +796,30 @@ pgfdw_subxact_callback(SubXactEvent event, SubTransactionId mySubid,
798796
{
799797
/* Assume we might have lost track of prepared statements */
800798
entry->have_error = true;
799+
800+
/*
801+
* If a command has been submitted to the remote server by using an
802+
* asynchronous execution function, the command might not have yet
803+
* completed. Check to see if a command is still being processed by
804+
* the remote server, and if so, request cancellation of the
805+
* command.
806+
*/
807+
if (PQtransactionStatus(entry->conn) == PQTRANS_ACTIVE)
808+
{
809+
PGcancel *cancel;
810+
char errbuf[256];
811+
812+
if ((cancel = PQgetCancel(entry->conn)))
813+
{
814+
if (!PQcancel(cancel, errbuf, sizeof(errbuf)))
815+
ereport(WARNING,
816+
(errcode(ERRCODE_CONNECTION_FAILURE),
817+
errmsg("could not send cancel request: %s",
818+
errbuf)));
819+
PQfreeCancel(cancel);
820+
}
821+
}
822+
801823
/* Rollback all remote subtransactions during abort */
802824
snprintf(sql, sizeof(sql),
803825
"ROLLBACK TO SAVEPOINT s%d; RELEASE SAVEPOINT s%d",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy