Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)