mirror of https://github.com/citusdata/citus.git
make sure to correctly decrement ExecutorLevel (#3311)
DESCRIPTION: Fix counter that keeps track of internal depth in executor While reviewing #3302 I ran into the `ExecutorLevel` variable which used a variable to keep the original value to restore on successful exit. I haven't explored the full space and if it is possible to get into an inconsistent state. However using `PG_TRY`/`PG_CATCH` seems generally more correct. Given very bad things will happen if this level is not reset, I kept the failsafe of setting the variiable back to 0 on the `XactCallback` but I did add an assert to treat it as a developer bug.release-9.1
parent
9f8e34f874
commit
b4facca9c3
|
@ -122,9 +122,11 @@ CitusExecutorRun(QueryDesc *queryDesc,
|
|||
ScanDirection direction, uint64 count, bool execute_once)
|
||||
{
|
||||
DestReceiver *dest = queryDesc->dest;
|
||||
int originalLevel = ExecutorLevel;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
ExecutorLevel++;
|
||||
|
||||
if (CitusHasBeenLoaded())
|
||||
{
|
||||
if (IsLocalReferenceTableJoinPlan(queryDesc->plannedstmt) &&
|
||||
|
@ -175,11 +177,15 @@ CitusExecutorRun(QueryDesc *queryDesc,
|
|||
standard_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the original value. It is not sufficient to decrease the value
|
||||
* because exceptions might cause us to go back a few levels at once.
|
||||
*/
|
||||
ExecutorLevel = originalLevel;
|
||||
ExecutorLevel--;
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
ExecutorLevel--;
|
||||
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -302,6 +302,13 @@ CoordinatedTransactionCallback(XactEvent event, void *arg)
|
|||
dlist_init(&InProgressTransactions);
|
||||
activeSetStmts = NULL;
|
||||
CoordinatedTransactionUses2PC = false;
|
||||
|
||||
/*
|
||||
* Getting here without ExecutorLevel 0 is a bug, however it is such a big
|
||||
* problem that will persist between reuse of the backend we still assign 0 in
|
||||
* production deploys, but during development and tests we want to crash.
|
||||
*/
|
||||
Assert(ExecutorLevel == 0);
|
||||
ExecutorLevel = 0;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue