Skip to content

Commit

Permalink
Merge pull request #336 from deathwish/FEATURE-support_query_cancella…
Browse files Browse the repository at this point in the history
…tion

Support query cancellation using FreeTDS's cancellation hooks.
  • Loading branch information
GeoffMontee authored Jul 14, 2023
2 parents 3c79ca7 + 9c5d1f7 commit 96f594d
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/tds_fdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "foreign/foreign.h"
#include "miscadmin.h"
#include "mb/pg_wchar.h"
#include "libpq/pqsignal.h"
#include "optimizer/cost.h"
#include "optimizer/paths.h"
#include "optimizer/prep.h"
Expand Down Expand Up @@ -102,6 +103,13 @@ static char* last_error_message = NULL;
static int tds_err_capture(DBPROCESS *dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
static char *tds_err_msg(int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);

/* signal handling */
static volatile bool interrupt_flag = false;
static void tds_signal_handler(int signum);
static void tds_clear_signals(void);
static int tds_chkintr_func(void* vdbproc);
static int tds_hndlintr_func(void* vdbproc);

/*
* Indexes of FDW-private information stored in fdw_private lists.
*
Expand Down Expand Up @@ -155,6 +163,8 @@ PGDLLEXPORT Datum tds_fdw_handler(PG_FUNCTION_ARGS)
fdwroutine->ImportForeignSchema = tdsImportForeignSchema;
#endif /* IMPORT_API */

pqsignal(SIGINT, tds_signal_handler);

#ifdef DEBUG
ereport(NOTICE,
(errmsg("----> finishing tds_fdw_handler")
Expand Down Expand Up @@ -596,6 +606,9 @@ int tdsSetupConnection(TdsFdwOptionSet* option_set, LOGINREC *login, DBPROCESS *
/* set the normal error handler again */
dberrhandle(tds_err_handler);

/* set a signal handler that cancels now that dbopen() is complete */
dbsetinterrupt(*dbproc, tds_chkintr_func, tds_hndlintr_func);

if (option_set->database && option_set->dbuse)
{
ereport(DEBUG3,
Expand Down Expand Up @@ -1262,6 +1275,8 @@ void tdsBeginForeignScan(ForeignScanState *node, int eflags)
));
#endif

tds_clear_signals();

tdsGetForeignTableOptionsFromCatalog(RelationGetRelid(node->ss.ss_currentRelation), &option_set);

ereport(DEBUG3,
Expand Down Expand Up @@ -1987,6 +2002,8 @@ void tdsEndForeignScan(ForeignScanState *node)

MemoryContextSwitchTo(old_cxt);
MemoryContextReset(festate->mem_cxt);

tds_clear_signals();
}

/*
Expand Down Expand Up @@ -2250,6 +2267,8 @@ void tdsGetForeignRelSize(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntab
));
#endif

tds_clear_signals();

/*
* We use PgFdwRelationInfo to pass various information to subsequent
* functions.
Expand Down Expand Up @@ -2981,6 +3000,8 @@ tdsImportSqlServerSchema(ImportForeignSchemaStmt *stmt, DBPROCESS *dbproc,
RETCODE erc;
int ret_code;

tds_clear_signals();

initStringInfo(&buf);

/* Check that the schema really exists */
Expand Down Expand Up @@ -4013,3 +4034,29 @@ int tds_blackhole_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int

return 0;
}

void tds_signal_handler(int signum)
{
interrupt_flag = true;
}

void tds_clear_signals()
{
interrupt_flag = false;
}

int tds_chkintr_func(void *vdbproc)
{
int status = FALSE;
if(interrupt_flag)
{
status = TRUE;
}
return status;
}

int tds_hndlintr_func(void *vdbproc)
{
tds_clear_signals();
return INT_CANCEL;
}

0 comments on commit 96f594d

Please sign in to comment.