mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 23:56:58 +03:00
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
This commit is contained in:
parent
b7a9347c11
commit
1b812afb0e
@ -677,8 +677,7 @@ pgfdw_xact_callback(XactEvent event, void *arg)
|
|||||||
* using an asynchronous execution function, the command
|
* using an asynchronous execution function, the command
|
||||||
* might not have yet completed. Check to see if a command
|
* might not have yet completed. Check to see if a command
|
||||||
* is still being processed by the remote server, and if so,
|
* is still being processed by the remote server, and if so,
|
||||||
* request cancellation of the command; if not, abort
|
* request cancellation of the command.
|
||||||
* gracefully.
|
|
||||||
*/
|
*/
|
||||||
if (PQtransactionStatus(entry->conn) == PQTRANS_ACTIVE)
|
if (PQtransactionStatus(entry->conn) == PQTRANS_ACTIVE)
|
||||||
{
|
{
|
||||||
@ -694,7 +693,6 @@ pgfdw_xact_callback(XactEvent event, void *arg)
|
|||||||
errbuf)));
|
errbuf)));
|
||||||
PQfreeCancel(cancel);
|
PQfreeCancel(cancel);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're aborting, abort all remote transactions too */
|
/* If we're aborting, abort all remote transactions too */
|
||||||
@ -798,6 +796,30 @@ pgfdw_subxact_callback(SubXactEvent event, SubTransactionId mySubid,
|
|||||||
{
|
{
|
||||||
/* Assume we might have lost track of prepared statements */
|
/* Assume we might have lost track of prepared statements */
|
||||||
entry->have_error = true;
|
entry->have_error = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a command has been submitted to the remote server by using an
|
||||||
|
* asynchronous execution function, the command might not have yet
|
||||||
|
* completed. Check to see if a command is still being processed by
|
||||||
|
* the remote server, and if so, request cancellation of the
|
||||||
|
* command.
|
||||||
|
*/
|
||||||
|
if (PQtransactionStatus(entry->conn) == PQTRANS_ACTIVE)
|
||||||
|
{
|
||||||
|
PGcancel *cancel;
|
||||||
|
char errbuf[256];
|
||||||
|
|
||||||
|
if ((cancel = PQgetCancel(entry->conn)))
|
||||||
|
{
|
||||||
|
if (!PQcancel(cancel, errbuf, sizeof(errbuf)))
|
||||||
|
ereport(WARNING,
|
||||||
|
(errcode(ERRCODE_CONNECTION_FAILURE),
|
||||||
|
errmsg("could not send cancel request: %s",
|
||||||
|
errbuf)));
|
||||||
|
PQfreeCancel(cancel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Rollback all remote subtransactions during abort */
|
/* Rollback all remote subtransactions during abort */
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"ROLLBACK TO SAVEPOINT s%d; RELEASE SAVEPOINT s%d",
|
"ROLLBACK TO SAVEPOINT s%d; RELEASE SAVEPOINT s%d",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user