static void ExecInitInterpreter(void);
/* support functions */
-static void CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype);
static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
TupleDesc *cache_field, ExprContext *econtext);
static void ShutdownTupleDescRef(Datum arg);
ExprContext *econtext, bool checkisnull);
/* fast-path evaluation functions */
-static Datum ExecJustInnerVarFirst(ExprState *state, ExprContext *econtext, bool *isnull);
static Datum ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull);
-static Datum ExecJustOuterVarFirst(ExprState *state, ExprContext *econtext, bool *isnull);
static Datum ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull);
-static Datum ExecJustScanVarFirst(ExprState *state, ExprContext *econtext, bool *isnull);
static Datum ExecJustScanVar(ExprState *state, ExprContext *econtext, bool *isnull);
static Datum ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull);
static Datum ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull);
if (state->flags & EEO_FLAG_INTERPRETER_INITIALIZED)
return;
+ state->evalfunc = ExecInterpExprStillValid;
+
/* DIRECT_THREADED should not already be set */
Assert((state->flags & EEO_FLAG_DIRECT_THREADED) == 0);
ExprEvalOp step1 = state->steps[1].opcode;
if (step0 == EEOP_INNER_FETCHSOME &&
- step1 == EEOP_INNER_VAR_FIRST)
+ step1 == EEOP_INNER_VAR)
{
- state->evalfunc = ExecJustInnerVarFirst;
+ state->evalfunc_private = ExecJustInnerVar;
return;
}
else if (step0 == EEOP_OUTER_FETCHSOME &&
- step1 == EEOP_OUTER_VAR_FIRST)
+ step1 == EEOP_OUTER_VAR)
{
- state->evalfunc = ExecJustOuterVarFirst;
+ state->evalfunc_private = ExecJustOuterVar;
return;
}
else if (step0 == EEOP_SCAN_FETCHSOME &&
- step1 == EEOP_SCAN_VAR_FIRST)
+ step1 == EEOP_SCAN_VAR)
{
- state->evalfunc = ExecJustScanVarFirst;
+ state->evalfunc_private = ExecJustScanVar;
return;
}
else if (step0 == EEOP_INNER_FETCHSOME &&
step1 == EEOP_ASSIGN_INNER_VAR)
{
- state->evalfunc = ExecJustAssignInnerVar;
+ state->evalfunc_private = ExecJustAssignInnerVar;
return;
}
else if (step0 == EEOP_OUTER_FETCHSOME &&
step1 == EEOP_ASSIGN_OUTER_VAR)
{
- state->evalfunc = ExecJustAssignOuterVar;
+ state->evalfunc_private = ExecJustAssignOuterVar;
return;
}
else if (step0 == EEOP_SCAN_FETCHSOME &&
step1 == EEOP_ASSIGN_SCAN_VAR)
{
- state->evalfunc = ExecJustAssignScanVar;
+ state->evalfunc_private = ExecJustAssignScanVar;
return;
}
}
else if (state->steps_len == 2 &&
state->steps[0].opcode == EEOP_CONST)
{
- state->evalfunc = ExecJustConst;
+ state->evalfunc_private = ExecJustConst;
return;
}
}
#endif /* EEO_USE_COMPUTED_GOTO */
- state->evalfunc = ExecInterpExpr;
+ state->evalfunc_private = ExecInterpExpr;
}
&&CASE_EEOP_INNER_FETCHSOME,
&&CASE_EEOP_OUTER_FETCHSOME,
&&CASE_EEOP_SCAN_FETCHSOME,
- &&CASE_EEOP_INNER_VAR_FIRST,
&&CASE_EEOP_INNER_VAR,
- &&CASE_EEOP_OUTER_VAR_FIRST,
&&CASE_EEOP_OUTER_VAR,
- &&CASE_EEOP_SCAN_VAR_FIRST,
&&CASE_EEOP_SCAN_VAR,
&&CASE_EEOP_INNER_SYSVAR,
&&CASE_EEOP_OUTER_SYSVAR,
EEO_NEXT();
}
- EEO_CASE(EEOP_INNER_VAR_FIRST)
- {
- int attnum = op->d.var.attnum;
-
- /*
- * First time through, check whether attribute matches Var. Might
- * not be ok anymore, due to schema changes.
- */
- CheckVarSlotCompatibility(innerslot, attnum + 1, op->d.var.vartype);
-
- /* Skip that check on subsequent evaluations */
- op->opcode = EEO_OPCODE(EEOP_INNER_VAR);
-
- /* FALL THROUGH to EEOP_INNER_VAR */
- }
-
EEO_CASE(EEOP_INNER_VAR)
{
int attnum = op->d.var.attnum;
EEO_NEXT();
}
- EEO_CASE(EEOP_OUTER_VAR_FIRST)
- {
- int attnum = op->d.var.attnum;
-
- /* See EEOP_INNER_VAR_FIRST comments */
-
- CheckVarSlotCompatibility(outerslot, attnum + 1, op->d.var.vartype);
- op->opcode = EEO_OPCODE(EEOP_OUTER_VAR);
-
- /* FALL THROUGH to EEOP_OUTER_VAR */
- }
-
EEO_CASE(EEOP_OUTER_VAR)
{
int attnum = op->d.var.attnum;
EEO_NEXT();
}
- EEO_CASE(EEOP_SCAN_VAR_FIRST)
- {
- int attnum = op->d.var.attnum;
-
- /* See EEOP_INNER_VAR_FIRST comments */
-
- CheckVarSlotCompatibility(scanslot, attnum + 1, op->d.var.vartype);
- op->opcode = EEO_OPCODE(EEOP_SCAN_VAR);
-
- /* FALL THROUGH to EEOP_SCAN_VAR */
- }
-
EEO_CASE(EEOP_SCAN_VAR)
{
int attnum = op->d.var.attnum;
* expression. This should succeed unless there have been schema changes
* since the expression tree has been created.
*/
-static void
+void
CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype)
{
/*
}
}
+Datum
+ExecInterpExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull)
+{
+ CheckExprStillValid(state, econtext, isNull);
+
+ state->evalfunc = state->evalfunc_private;
+
+ return state->evalfunc(state, econtext, isNull);
+}
+
+void
+CheckExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull)
+{
+ int i = 0;
+ TupleTableSlot *innerslot;
+ TupleTableSlot *outerslot;
+ TupleTableSlot *scanslot;
+
+ innerslot = econtext->ecxt_innertuple;
+ outerslot = econtext->ecxt_outertuple;
+ scanslot = econtext->ecxt_scantuple;
+
+ for (i = 0; i < state->steps_len;i++)
+ {
+ ExprEvalStep *op = &state->steps[i];
+
+ switch (ExecEvalStepOp(state, op))
+ {
+ case EEOP_INNER_VAR:
+ {
+ int attnum = op->d.var.attnum;
+ CheckVarSlotCompatibility(innerslot, attnum + 1, op->d.var.vartype);
+ break;
+ }
+
+ case EEOP_OUTER_VAR:
+ {
+ int attnum = op->d.var.attnum;
+ CheckVarSlotCompatibility(outerslot, attnum + 1, op->d.var.vartype);
+ break;
+ }
+
+ case EEOP_SCAN_VAR:
+ {
+ int attnum = op->d.var.attnum;
+ CheckVarSlotCompatibility(scanslot, attnum + 1, op->d.var.vartype);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+
/*
* get_cached_rowtype: utility function to lookup a rowtype tupdesc
*
* Fast-path functions, for very simple expressions
*/
-/* Simple reference to inner Var, first time through */
+/* Simple reference to inner Var */
static Datum
-ExecJustInnerVarFirst(ExprState *state, ExprContext *econtext, bool *isnull)
+ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull)
{
ExprEvalStep *op = &state->steps[1];
int attnum = op->d.var.attnum + 1;
TupleTableSlot *slot = econtext->ecxt_innertuple;
- /* See ExecInterpExpr()'s comments for EEOP_INNER_VAR_FIRST */
-
- CheckVarSlotCompatibility(slot, attnum, op->d.var.vartype);
- op->opcode = EEOP_INNER_VAR; /* just for cleanliness */
- state->evalfunc = ExecJustInnerVar;
-
/*
* Since we use slot_getattr(), we don't need to implement the FETCHSOME
* step explicitly, and we also needn't Assert that the attnum is in range
return slot_getattr(slot, attnum, isnull);
}
-/* Simple reference to inner Var */
-static Datum
-ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull)
-{
- ExprEvalStep *op = &state->steps[1];
- int attnum = op->d.var.attnum + 1;
- TupleTableSlot *slot = econtext->ecxt_innertuple;
-
- /* See comments in ExecJustInnerVarFirst */
- return slot_getattr(slot, attnum, isnull);
-}
-
-/* Simple reference to outer Var, first time through */
-static Datum
-ExecJustOuterVarFirst(ExprState *state, ExprContext *econtext, bool *isnull)
-{
- ExprEvalStep *op = &state->steps[1];
- int attnum = op->d.var.attnum + 1;
- TupleTableSlot *slot = econtext->ecxt_outertuple;
-
- CheckVarSlotCompatibility(slot, attnum, op->d.var.vartype);
- op->opcode = EEOP_OUTER_VAR; /* just for cleanliness */
- state->evalfunc = ExecJustOuterVar;
-
- /* See comments in ExecJustInnerVarFirst */
- return slot_getattr(slot, attnum, isnull);
-}
-
/* Simple reference to outer Var */
static Datum
ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull)
int attnum = op->d.var.attnum + 1;
TupleTableSlot *slot = econtext->ecxt_outertuple;
- /* See comments in ExecJustInnerVarFirst */
- return slot_getattr(slot, attnum, isnull);
-}
-
-/* Simple reference to scan Var, first time through */
-static Datum
-ExecJustScanVarFirst(ExprState *state, ExprContext *econtext, bool *isnull)
-{
- ExprEvalStep *op = &state->steps[1];
- int attnum = op->d.var.attnum + 1;
- TupleTableSlot *slot = econtext->ecxt_scantuple;
-
- CheckVarSlotCompatibility(slot, attnum, op->d.var.vartype);
- op->opcode = EEOP_SCAN_VAR; /* just for cleanliness */
- state->evalfunc = ExecJustScanVar;
-
- /* See comments in ExecJustInnerVarFirst */
+ /* See comments in ExecJustInnerVar */
return slot_getattr(slot, attnum, isnull);
}
int attnum = op->d.var.attnum + 1;
TupleTableSlot *slot = econtext->ecxt_scantuple;
- /* See comments in ExecJustInnerVarFirst */
+ /* See comments in ExecJustInnerVar */
return slot_getattr(slot, attnum, isnull);
}