Commit b4093310 authored by Andres Freund's avatar Andres Freund

Perform slot validity checks in a separate pass over expression.

This reduces code duplication a bit, but the primary benefit that it
makes JITing expression evaluation easier. When doing so we can't, as
previously done in the interpreted case, really change opcode without
recompiling. Nor dow we just carry around unnecessary branches to
avoid re-checking over and over.

As a minor side-effect this makes ExecEvalStepOp() O(log(N)) rather
than O(N).

Author: Andres Freund
Discussion: https://postgr.es/m/20170901064131.tazjxwus3k2w3ybh@alap3.anarazel.de
parent 4717fdb1
......@@ -680,20 +680,19 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* regular user column */
scratch.d.var.attnum = variable->varattno - 1;
scratch.d.var.vartype = variable->vartype;
/* select EEOP_*_FIRST opcode to force one-time checks */
switch (variable->varno)
{
case INNER_VAR:
scratch.opcode = EEOP_INNER_VAR_FIRST;
scratch.opcode = EEOP_INNER_VAR;
break;
case OUTER_VAR:
scratch.opcode = EEOP_OUTER_VAR_FIRST;
scratch.opcode = EEOP_OUTER_VAR;
break;
/* INDEX_VAR is handled by default case */
default:
scratch.opcode = EEOP_SCAN_VAR_FIRST;
scratch.opcode = EEOP_SCAN_VAR;
break;
}
}
......
This diff is collapsed.
......@@ -51,12 +51,8 @@ typedef enum ExprEvalOp
EEOP_SCAN_FETCHSOME,
/* compute non-system Var value */
/* "FIRST" variants are used only the first time through */
EEOP_INNER_VAR_FIRST,
EEOP_INNER_VAR,
EEOP_OUTER_VAR_FIRST,
EEOP_OUTER_VAR,
EEOP_SCAN_VAR_FIRST,
EEOP_SCAN_VAR,
/* compute system Var value */
......@@ -67,8 +63,11 @@ typedef enum ExprEvalOp
/* compute wholerow Var */
EEOP_WHOLEROW,
/* compute non-system Var value, assign it into ExprState's resultslot */
/* (these are not used if _FIRST checks would be needed) */
/*
* Compute non-system Var value, assign it into ExprState's
* resultslot. These are not used if a CheckVarSlotCompatibility() check
* would be needed.
*/
EEOP_ASSIGN_INNER_VAR,
EEOP_ASSIGN_OUTER_VAR,
EEOP_ASSIGN_SCAN_VAR,
......@@ -621,6 +620,9 @@ extern void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s);
extern void ExecReadyInterpretedExpr(ExprState *state);
extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op);
extern Datum ExecInterpExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull);
extern void CheckExprStillValid(ExprState *state, ExprContext *econtext);
/*
* Non fast-path execution functions. These are externs instead of statics in
* execExprInterp.c, because that allows them to be used by other methods of
......
......@@ -87,6 +87,9 @@ typedef struct ExprState
/* original expression tree, for debugging only */
Expr *expr;
/* private state for an evalfunc */
void *evalfunc_private;
/*
* XXX: following fields only needed during "compilation" (ExecInitExpr);
* could be thrown away afterwards.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment