summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/executor/execExpr.h642
-rw-r--r--src/include/executor/execdebug.h23
-rw-r--r--src/include/executor/executor.h178
-rw-r--r--src/include/executor/nodeSubplan.h4
-rw-r--r--src/include/fmgr.h8
-rw-r--r--src/include/nodes/execnodes.h504
-rw-r--r--src/include/nodes/nodes.h30
-rw-r--r--src/include/utils/typcache.h3
-rw-r--r--src/include/utils/xml.h4
9 files changed, 946 insertions, 450 deletions
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
new file mode 100644
index 00000000000..a6653882321
--- /dev/null
+++ b/src/include/executor/execExpr.h
@@ -0,0 +1,642 @@
+/*-------------------------------------------------------------------------
+ *
+ * execExpr.h
+ * Low level infrastructure related to expression evaluation
+ *
+ *
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/executor/execExpr.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef EXEC_EXPR_H
+#define EXEC_EXPR_H
+
+#include "nodes/execnodes.h"
+
+/* forward reference to avoid circularity */
+struct ArrayRefState;
+
+/* Bits in ExprState->flags (see also execnodes.h for public flag bits): */
+/* expression's interpreter has been initialized */
+#define EEO_FLAG_INTERPRETER_INITIALIZED (1 << 1)
+/* jump-threading is in use */
+#define EEO_FLAG_DIRECT_THREADED (1 << 2)
+
+/*
+ * Discriminator for ExprEvalSteps.
+ *
+ * Identifies the operation to be executed and which member in the
+ * ExprEvalStep->d union is valid.
+ *
+ * The order of entries needs to be kept in sync with the dispatch_table[]
+ * array in execExprInterp.c:ExecInterpExpr().
+ */
+typedef enum ExprEvalOp
+{
+ /* entire expression has been evaluated completely, return */
+ EEOP_DONE,
+
+ /* apply slot_getsomeattrs on corresponding tuple slot */
+ EEOP_INNER_FETCHSOME,
+ EEOP_OUTER_FETCHSOME,
+ 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 */
+ EEOP_INNER_SYSVAR,
+ EEOP_OUTER_SYSVAR,
+ EEOP_SCAN_SYSVAR,
+
+ /* 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) */
+ EEOP_ASSIGN_INNER_VAR,
+ EEOP_ASSIGN_OUTER_VAR,
+ EEOP_ASSIGN_SCAN_VAR,
+
+ /* assign ExprState's resvalue/resnull to a column of its resultslot */
+ EEOP_ASSIGN_TMP,
+ /* ditto, applying MakeExpandedObjectReadOnly() */
+ EEOP_ASSIGN_TMP_MAKE_RO,
+
+ /* evaluate Const value */
+ EEOP_CONST,
+
+ /*
+ * Evaluate function call (including OpExprs etc). For speed, we
+ * distinguish in the opcode whether the function is strict and/or
+ * requires usage stats tracking.
+ */
+ EEOP_FUNCEXPR,
+ EEOP_FUNCEXPR_STRICT,
+ EEOP_FUNCEXPR_FUSAGE,
+ EEOP_FUNCEXPR_STRICT_FUSAGE,
+
+ /*
+ * Evaluate boolean AND expression, one step per subexpression. FIRST/LAST
+ * subexpressions are special-cased for performance. Since AND always has
+ * at least two subexpressions, FIRST and LAST never apply to the same
+ * subexpression.
+ */
+ EEOP_BOOL_AND_STEP_FIRST,
+ EEOP_BOOL_AND_STEP,
+ EEOP_BOOL_AND_STEP_LAST,
+
+ /* similarly for boolean OR expression */
+ EEOP_BOOL_OR_STEP_FIRST,
+ EEOP_BOOL_OR_STEP,
+ EEOP_BOOL_OR_STEP_LAST,
+
+ /* evaluate boolean NOT expression */
+ EEOP_BOOL_NOT_STEP,
+
+ /* simplified version of BOOL_AND_STEP for use by ExecQual() */
+ EEOP_QUAL,
+
+ /* unconditional jump to another step */
+ EEOP_JUMP,
+
+ /* conditional jumps based on current result value */
+ EEOP_JUMP_IF_NULL,
+ EEOP_JUMP_IF_NOT_NULL,
+ EEOP_JUMP_IF_NOT_TRUE,
+
+ /* perform NULL tests for scalar values */
+ EEOP_NULLTEST_ISNULL,
+ EEOP_NULLTEST_ISNOTNULL,
+
+ /* perform NULL tests for row values */
+ EEOP_NULLTEST_ROWISNULL,
+ EEOP_NULLTEST_ROWISNOTNULL,
+
+ /* evaluate a BooleanTest expression */
+ EEOP_BOOLTEST_IS_TRUE,
+ EEOP_BOOLTEST_IS_NOT_TRUE,
+ EEOP_BOOLTEST_IS_FALSE,
+ EEOP_BOOLTEST_IS_NOT_FALSE,
+
+ /* evaluate PARAM_EXEC/EXTERN parameters */
+ EEOP_PARAM_EXEC,
+ EEOP_PARAM_EXTERN,
+
+ /* return CaseTestExpr value */
+ EEOP_CASE_TESTVAL,
+
+ /* apply MakeExpandedObjectReadOnly() to target value */
+ EEOP_MAKE_READONLY,
+
+ /* evaluate assorted special-purpose expression types */
+ EEOP_IOCOERCE,
+ EEOP_DISTINCT,
+ EEOP_NULLIF,
+ EEOP_SQLVALUEFUNCTION,
+ EEOP_CURRENTOFEXPR,
+ EEOP_ARRAYEXPR,
+ EEOP_ARRAYCOERCE,
+ EEOP_ROW,
+
+ /*
+ * Compare two individual elements of each of two compared ROW()
+ * expressions. Skip to ROWCOMPARE_FINAL if elements are not equal.
+ */
+ EEOP_ROWCOMPARE_STEP,
+
+ /* evaluate boolean value based on previous ROWCOMPARE_STEP operations */
+ EEOP_ROWCOMPARE_FINAL,
+
+ /* evaluate GREATEST() or LEAST() */
+ EEOP_MINMAX,
+
+ /* evaluate FieldSelect expression */
+ EEOP_FIELDSELECT,
+
+ /*
+ * Deform tuple before evaluating new values for individual fields in a
+ * FieldStore expression.
+ */
+ EEOP_FIELDSTORE_DEFORM,
+
+ /*
+ * Form the new tuple for a FieldStore expression. Individual fields will
+ * have been evaluated into columns of the tuple deformed by the preceding
+ * DEFORM step.
+ */
+ EEOP_FIELDSTORE_FORM,
+
+ /* Process an array subscript; short-circuit expression to NULL if NULL */
+ EEOP_ARRAYREF_SUBSCRIPT,
+
+ /*
+ * Compute old array element/slice when an ArrayRef assignment expression
+ * contains ArrayRef/FieldStore subexpressions. Value is accessed using
+ * the CaseTest mechanism.
+ */
+ EEOP_ARRAYREF_OLD,
+
+ /* compute new value for ArrayRef assignment expression */
+ EEOP_ARRAYREF_ASSIGN,
+
+ /* compute element/slice for ArrayRef fetch expression */
+ EEOP_ARRAYREF_FETCH,
+
+ /* evaluate value for CoerceToDomainValue */
+ EEOP_DOMAIN_TESTVAL,
+
+ /* evaluate a domain's NOT NULL constraint */
+ EEOP_DOMAIN_NOTNULL,
+
+ /* evaluate a single domain CHECK constraint */
+ EEOP_DOMAIN_CHECK,
+
+ /* evaluate assorted special-purpose expression types */
+ EEOP_CONVERT_ROWTYPE,
+ EEOP_SCALARARRAYOP,
+ EEOP_XMLEXPR,
+ EEOP_AGGREF,
+ EEOP_GROUPING_FUNC,
+ EEOP_WINDOW_FUNC,
+ EEOP_SUBPLAN,
+ EEOP_ALTERNATIVE_SUBPLAN,
+
+ /* non-existent operation, used e.g. to check array lengths */
+ EEOP_LAST
+} ExprEvalOp;
+
+
+typedef struct ExprEvalStep
+{
+ /*
+ * Instruction to be executed. During instruction preparation this is an
+ * enum ExprEvalOp, but later it can be changed to some other type, e.g. a
+ * pointer for computed goto (that's why it's an intptr_t).
+ */
+ intptr_t opcode;
+
+ /* where to store the result of this step */
+ Datum *resvalue;
+ bool *resnull;
+
+ /*
+ * Inline data for the operation. Inline data is faster to access, but
+ * also bloats the size of all instructions. The union should be kept to
+ * no more than 40 bytes on 64-bit systems (so that the entire struct is
+ * no more than 64 bytes, a single cacheline on common systems).
+ */
+ union
+ {
+ /* for EEOP_INNER/OUTER/SCAN_FETCHSOME */
+ struct
+ {
+ /* attribute number up to which to fetch (inclusive) */
+ int last_var;
+ } fetch;
+
+ /* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */
+ struct
+ {
+ /* attnum is attr number - 1 for regular VAR ... */
+ /* but it's just the normal (negative) attr number for SYSVAR */
+ int attnum;
+ Oid vartype; /* type OID of variable */
+ } var;
+
+ /* for EEOP_WHOLEROW */
+ struct
+ {
+ Var *var; /* original Var node in plan tree */
+ bool first; /* first time through, need to initialize? */
+ bool slow; /* need runtime check for nulls? */
+ TupleDesc tupdesc; /* descriptor for resulting tuples */
+ JunkFilter *junkFilter; /* JunkFilter to remove resjunk cols */
+ } wholerow;
+
+ /* for EEOP_ASSIGN_*_VAR */
+ struct
+ {
+ /* target index in ExprState->resultslot->tts_values/nulls */
+ int resultnum;
+ /* source attribute number - 1 */
+ int attnum;
+ } assign_var;
+
+ /* for EEOP_ASSIGN_TMP[_MAKE_RO] */
+ struct
+ {
+ /* target index in ExprState->resultslot->tts_values/nulls */
+ int resultnum;
+ } assign_tmp;
+
+ /* for EEOP_CONST */
+ struct
+ {
+ /* constant's value */
+ Datum value;
+ bool isnull;
+ } constval;
+
+ /* for EEOP_FUNCEXPR_* / NULLIF / DISTINCT */
+ struct
+ {
+ FmgrInfo *finfo; /* function's lookup data */
+ FunctionCallInfo fcinfo_data; /* arguments etc */
+ /* faster to access without additional indirection: */
+ PGFunction fn_addr; /* actual call address */
+ int nargs; /* number of arguments */
+ } func;
+
+ /* for EEOP_BOOL_*_STEP */
+ struct
+ {
+ bool *anynull; /* track if any input was NULL */
+ int jumpdone; /* jump here if result determined */
+ } boolexpr;
+
+ /* for EEOP_QUAL */
+ struct
+ {
+ int jumpdone; /* jump here on false or null */
+ } qualexpr;
+
+ /* for EEOP_JUMP[_CONDITION] */
+ struct
+ {
+ int jumpdone; /* target instruction's index */
+ } jump;
+
+ /* for EEOP_NULLTEST_ROWIS[NOT]NULL */
+ struct
+ {
+ /* cached tupdesc pointer - filled at runtime */
+ TupleDesc argdesc;
+ } nulltest_row;
+
+ /* for EEOP_PARAM_EXEC/EXTERN */
+ struct
+ {
+ int paramid; /* numeric ID for parameter */
+ Oid paramtype; /* OID of parameter's datatype */
+ } param;
+
+ /* for EEOP_CASE_TESTVAL/DOMAIN_TESTVAL */
+ struct
+ {
+ Datum *value; /* value to return */
+ bool *isnull;
+ } casetest;
+
+ /* for EEOP_MAKE_READONLY */
+ struct
+ {
+ Datum *value; /* value to coerce to read-only */
+ bool *isnull;
+ } make_readonly;
+
+ /* for EEOP_IOCOERCE */
+ struct
+ {
+ /* lookup and call info for source type's output function */
+ FmgrInfo *finfo_out;
+ FunctionCallInfo fcinfo_data_out;
+ /* lookup and call info for result type's input function */
+ FmgrInfo *finfo_in;
+ FunctionCallInfo fcinfo_data_in;
+ } iocoerce;
+
+ /* for EEOP_SQLVALUEFUNCTION */
+ struct
+ {
+ SQLValueFunction *svf;
+ } sqlvaluefunction;
+
+ /* for EEOP_ARRAYEXPR */
+ struct
+ {
+ Datum *elemvalues; /* element values get stored here */
+ bool *elemnulls;
+ int nelems; /* length of the above arrays */
+ Oid elemtype; /* array element type */
+ int16 elemlength; /* typlen of the array element type */
+ bool elembyval; /* is the element type pass-by-value? */
+ char elemalign; /* typalign of the element type */
+ bool multidims; /* is array expression multi-D? */
+ } arrayexpr;
+
+ /* for EEOP_ARRAYCOERCE */
+ struct
+ {
+ ArrayCoerceExpr *coerceexpr;
+ Oid resultelemtype; /* element type of result array */
+ FmgrInfo *elemfunc; /* lookup info for element coercion
+ * function */
+ struct ArrayMapState *amstate; /* workspace for array_map */
+ } arraycoerce;
+
+ /* for EEOP_ROW */
+ struct
+ {
+ TupleDesc tupdesc; /* descriptor for result tuples */
+ /* workspace for the values constituting the row: */
+ Datum *elemvalues;
+ bool *elemnulls;
+ } row;
+
+ /* for EEOP_ROWCOMPARE_STEP */
+ struct
+ {
+ /* lookup and call data for column comparison function */
+ FmgrInfo *finfo;
+ FunctionCallInfo fcinfo_data;
+ PGFunction fn_addr;
+ /* target for comparison resulting in NULL */
+ int jumpnull;
+ /* target for comparison yielding inequality */
+ int jumpdone;
+ } rowcompare_step;
+
+ /* for EEOP_ROWCOMPARE_FINAL */
+ struct
+ {
+ RowCompareType rctype;
+ } rowcompare_final;
+
+ /* for EEOP_MINMAX */
+ struct
+ {
+ /* workspace for argument values */
+ Datum *values;
+ bool *nulls;
+ int nelems;
+ /* is it GREATEST or LEAST? */
+ MinMaxOp op;
+ /* lookup and call data for comparison function */
+ FmgrInfo *finfo;
+ FunctionCallInfo fcinfo_data;
+ } minmax;
+
+ /* for EEOP_FIELDSELECT */
+ struct
+ {
+ AttrNumber fieldnum; /* field number to extract */
+ Oid resulttype; /* field's type */
+ /* cached tupdesc pointer - filled at runtime */
+ TupleDesc argdesc;
+ } fieldselect;
+
+ /* for EEOP_FIELDSTORE_DEFORM / FIELDSTORE_FORM */
+ struct
+ {
+ /* original expression node */
+ FieldStore *fstore;
+
+ /* cached tupdesc pointer - filled at runtime */
+ /* note that a DEFORM and FORM pair share the same tupdesc */
+ TupleDesc *argdesc;
+
+ /* workspace for column values */
+ Datum *values;
+ bool *nulls;
+ int ncolumns;
+ } fieldstore;
+
+ /* for EEOP_ARRAYREF_SUBSCRIPT */
+ struct
+ {
+ /* too big to have inline */
+ struct ArrayRefState *state;
+ int off; /* 0-based index of this subscript */
+ bool isupper; /* is it upper or lower subscript? */
+ int jumpdone; /* jump here on null */
+ } arrayref_subscript;
+
+ /* for EEOP_ARRAYREF_OLD / ASSIGN / FETCH */
+ struct
+ {
+ /* too big to have inline */
+ struct ArrayRefState *state;
+ } arrayref;
+
+ /* for EEOP_DOMAIN_NOTNULL / DOMAIN_CHECK */
+ struct
+ {
+ /* name of constraint */
+ char *constraintname;
+ /* where the result of a CHECK constraint will be stored */
+ Datum *checkvalue;
+ bool *checknull;
+ /* OID of domain type */
+ Oid resulttype;
+ } domaincheck;
+
+ /* for EEOP_CONVERT_ROWTYPE */
+ struct
+ {
+ ConvertRowtypeExpr *convert; /* original expression */
+ /* these three fields are filled at runtime: */
+ TupleDesc indesc; /* tupdesc for input type */
+ TupleDesc outdesc; /* tupdesc for output type */
+ TupleConversionMap *map; /* column mapping */
+ bool initialized; /* initialized for current types? */
+ } convert_rowtype;
+
+ /* for EEOP_SCALARARRAYOP */
+ struct
+ {
+ /* element_type/typlen/typbyval/typalign are filled at runtime */
+ Oid element_type; /* InvalidOid if not yet filled */
+ bool useOr; /* use OR or AND semantics? */
+ int16 typlen; /* array element type storage info */
+ bool typbyval;
+ char typalign;
+ FmgrInfo *finfo; /* function's lookup data */
+ FunctionCallInfo fcinfo_data; /* arguments etc */
+ /* faster to access without additional indirection: */
+ PGFunction fn_addr; /* actual call address */
+ } scalararrayop;
+
+ /* for EEOP_XMLEXPR */
+ struct
+ {
+ XmlExpr *xexpr; /* original expression node */
+ /* workspace for evaluating named args, if any */
+ Datum *named_argvalue;
+ bool *named_argnull;
+ /* workspace for evaluating unnamed args, if any */
+ Datum *argvalue;
+ bool *argnull;
+ } xmlexpr;
+
+ /* for EEOP_AGGREF */
+ struct
+ {
+ /* out-of-line state, modified by nodeAgg.c */
+ AggrefExprState *astate;
+ } aggref;
+
+ /* for EEOP_GROUPING_FUNC */
+ struct
+ {
+ AggState *parent; /* parent Agg */
+ List *clauses; /* integer list of column numbers */
+ } grouping_func;
+
+ /* for EEOP_WINDOW_FUNC */
+ struct
+ {
+ /* out-of-line state, modified by nodeWindowFunc.c */
+ WindowFuncExprState *wfstate;
+ } window_func;
+
+ /* for EEOP_SUBPLAN */
+ struct
+ {
+ /* out-of-line state, created by nodeSubplan.c */
+ SubPlanState *sstate;
+ } subplan;
+
+ /* for EEOP_ALTERNATIVE_SUBPLAN */
+ struct
+ {
+ /* out-of-line state, created by nodeSubplan.c */
+ AlternativeSubPlanState *asstate;
+ } alternative_subplan;
+ } d;
+} ExprEvalStep;
+
+
+/* Non-inline data for array operations */
+typedef struct ArrayRefState
+{
+ bool isassignment; /* is it assignment, or just fetch? */
+
+ Oid refelemtype; /* OID of the array element type */
+ int16 refattrlength; /* typlen of array type */
+ int16 refelemlength; /* typlen of the array element type */
+ bool refelembyval; /* is the element type pass-by-value? */
+ char refelemalign; /* typalign of the element type */
+
+ /* numupper and upperprovided[] are filled at compile time */
+ /* at runtime, extracted subscript datums get stored in upperindex[] */
+ int numupper;
+ bool upperprovided[MAXDIM];
+ int upperindex[MAXDIM];
+
+ /* similarly for lower indexes, if any */
+ int numlower;
+ bool lowerprovided[MAXDIM];
+ int lowerindex[MAXDIM];
+
+ /* subscript expressions get evaluated into here */
+ Datum subscriptvalue;
+ bool subscriptnull;
+
+ /* for assignment, new value to assign is evaluated into here */
+ Datum replacevalue;
+ bool replacenull;
+
+ /* if we have a nested assignment, ARRAYREF_OLD puts old value here */
+ Datum prevvalue;
+ bool prevnull;
+} ArrayRefState;
+
+
+extern void ExecReadyInterpretedExpr(ExprState *state);
+
+extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op);
+
+/*
+ * 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
+ * expression evaluation, reducing code duplication.
+ */
+extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalRow(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern bool ExecEvalArrayRefSubscript(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalArrayRefFetch(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalArrayRefOld(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalArrayRefAssign(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalSubPlan(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalAlternativeSubPlan(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+
+#endif /* EXEC_EXPR_H */
diff --git a/src/include/executor/execdebug.h b/src/include/executor/execdebug.h
index cf44c3edbbc..8b61520e189 100644
--- a/src/include/executor/execdebug.h
+++ b/src/include/executor/execdebug.h
@@ -38,13 +38,6 @@
*/
/* ----------------
- * EXEC_EVALDEBUG is a flag which turns on debugging of
- * ExecEval and ExecTargetList() stuff by EV_printf() in execQual.c
- * ----------------
-#undef EXEC_EVALDEBUG
- */
-
-/* ----------------
* EXEC_SORTDEBUG is a flag which turns on debugging of
* the ExecSort() stuff by SO_printf() in nodeSort.c
* ----------------
@@ -86,20 +79,6 @@
#endif /* EXEC_NESTLOOPDEBUG */
/* ----------------
- * exec eval / target list debugging defines
- * ----------------
- */
-#ifdef EXEC_EVALDEBUG
-#define EV_nodeDisplay(l) nodeDisplay(l)
-#define EV_printf(s) printf(s)
-#define EV1_printf(s, a) printf(s, a)
-#else
-#define EV_nodeDisplay(l)
-#define EV_printf(s)
-#define EV1_printf(s, a)
-#endif /* EXEC_EVALDEBUG */
-
-/* ----------------
* sort node debugging defines
* ----------------
*/
@@ -146,4 +125,4 @@
#define MJ_DEBUG_PROC_NODE(slot)
#endif /* EXEC_MERGEJOINDEBUG */
-#endif /* ExecDebugIncluded */
+#endif /* EXECDEBUG_H */
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index a5c75e771f0..d3849b93eb1 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -65,15 +65,6 @@
#define EXEC_FLAG_WITH_NO_DATA 0x0080 /* rel scannability doesn't matter */
-/*
- * ExecEvalExpr was formerly a function containing a switch statement;
- * now it's just a macro invoking the function pointed to by an ExprState
- * node. Beware of double evaluation of the ExprState argument!
- */
-#define ExecEvalExpr(expr, econtext, isNull) \
- ((*(expr)->evalfunc) (expr, econtext, isNull))
-
-
/* Hook for plugins to get control in ExecutorStart() */
typedef void (*ExecutorStart_hook_type) (QueryDesc *queryDesc, int eflags);
extern PGDLLIMPORT ExecutorStart_hook_type ExecutorStart_hook;
@@ -242,29 +233,155 @@ extern void ExecEndNode(PlanState *node);
extern bool ExecShutdownNode(PlanState *node);
/*
- * prototypes from functions in execQual.c
+ * prototypes from functions in execExpr.c
*/
-extern Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno,
- bool *isNull);
-extern Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname,
- bool *isNull);
-extern Tuplestorestate *ExecMakeTableFunctionResult(ExprState *funcexpr,
+extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
+extern ExprState *ExecInitQual(List *qual, PlanState *parent);
+extern ExprState *ExecInitCheck(List *qual, PlanState *parent);
+extern List *ExecInitExprList(List *nodes, PlanState *parent);
+extern ProjectionInfo *ExecBuildProjectionInfo(List *targetList,
+ ExprContext *econtext,
+ TupleTableSlot *slot,
+ PlanState *parent,
+ TupleDesc inputDesc);
+extern ExprState *ExecPrepareExpr(Expr *node, EState *estate);
+extern ExprState *ExecPrepareQual(List *qual, EState *estate);
+extern ExprState *ExecPrepareCheck(List *qual, EState *estate);
+extern List *ExecPrepareExprList(List *nodes, EState *estate);
+
+/*
+ * ExecEvalExpr
+ *
+ * Evaluate expression identified by "state" in the execution context
+ * given by "econtext". *isNull is set to the is-null flag for the result,
+ * and the Datum value is the function result.
+ *
+ * The caller should already have switched into the temporary memory
+ * context econtext->ecxt_per_tuple_memory. The convenience entry point
+ * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
+ * do the switch in an outer loop.
+ */
+#ifndef FRONTEND
+static inline Datum
+ExecEvalExpr(ExprState *state,
+ ExprContext *econtext,
+ bool *isNull)
+{
+ return (*state->evalfunc) (state, econtext, isNull);
+}
+#endif
+
+/*
+ * ExecEvalExprSwitchContext
+ *
+ * Same as ExecEvalExpr, but get into the right allocation context explicitly.
+ */
+#ifndef FRONTEND
+static inline Datum
+ExecEvalExprSwitchContext(ExprState *state,
+ ExprContext *econtext,
+ bool *isNull)
+{
+ Datum retDatum;
+ MemoryContext oldContext;
+
+ oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+ retDatum = (*state->evalfunc) (state, econtext, isNull);
+ MemoryContextSwitchTo(oldContext);
+ return retDatum;
+}
+#endif
+
+/*
+ * ExecProject
+ *
+ * Projects a tuple based on projection info and stores it in the slot passed
+ * to ExecBuildProjectInfo().
+ *
+ * Note: the result is always a virtual tuple; therefore it may reference
+ * the contents of the exprContext's scan tuples and/or temporary results
+ * constructed in the exprContext. If the caller wishes the result to be
+ * valid longer than that data will be valid, he must call ExecMaterializeSlot
+ * on the result slot.
+ */
+#ifndef FRONTEND
+static inline TupleTableSlot *
+ExecProject(ProjectionInfo *projInfo)
+{
+ ExprContext *econtext = projInfo->pi_exprContext;
+ ExprState *state = &projInfo->pi_state;
+ TupleTableSlot *slot = state->resultslot;
+ bool isnull;
+
+ /*
+ * Clear any former contents of the result slot. This makes it safe for
+ * us to use the slot's Datum/isnull arrays as workspace.
+ */
+ ExecClearTuple(slot);
+
+ /* Run the expression, discarding scalar result from the last column. */
+ (void) ExecEvalExprSwitchContext(state, econtext, &isnull);
+
+ /*
+ * Successfully formed a result row. Mark the result slot as containing a
+ * valid virtual tuple (inlined version of ExecStoreVirtualTuple()).
+ */
+ slot->tts_isempty = false;
+ slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
+
+ return slot;
+}
+#endif
+
+/*
+ * ExecQual - evaluate a qual prepared with ExecInitQual (possibly via
+ * ExecPrepareQual). Returns true if qual is satisfied, else false.
+ *
+ * Note: ExecQual used to have a third argument "resultForNull". The
+ * behavior of this function now corresponds to resultForNull == false.
+ * If you want the resultForNull == true behavior, see ExecCheck.
+ */
+#ifndef FRONTEND
+static inline bool
+ExecQual(ExprState *state, ExprContext *econtext)
+{
+ Datum ret;
+ bool isnull;
+
+ /* short-circuit (here and in ExecInitQual) for empty restriction list */
+ if (state == NULL)
+ return true;
+
+ /* verify that expression was compiled using ExecInitQual */
+ Assert(state->flags & EEO_FLAG_IS_QUAL);
+
+ ret = ExecEvalExprSwitchContext(state, econtext, &isnull);
+
+ /* EEOP_QUAL should never return NULL */
+ Assert(!isnull);
+
+ return DatumGetBool(ret);
+}
+#endif
+
+extern bool ExecCheck(ExprState *state, ExprContext *context);
+
+/*
+ * prototypes from functions in execSRF.c
+ */
+extern SetExprState *ExecInitTableFunctionResult(Expr *expr,
+ ExprContext *econtext, PlanState *parent);
+extern Tuplestorestate *ExecMakeTableFunctionResult(SetExprState *setexpr,
ExprContext *econtext,
MemoryContext argContext,
TupleDesc expectedDesc,
bool randomAccess);
-extern Datum ExecMakeFunctionResultSet(FuncExprState *fcache,
+extern SetExprState *ExecInitFunctionResultSet(Expr *expr,
+ ExprContext *econtext, PlanState *parent);
+extern Datum ExecMakeFunctionResultSet(SetExprState *fcache,
ExprContext *econtext,
bool *isNull,
ExprDoneCond *isDone);
-extern Datum ExecEvalExprSwitchContext(ExprState *expression, ExprContext *econtext,
- bool *isNull);
-extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
-extern ExprState *ExecPrepareExpr(Expr *node, EState *estate);
-extern bool ExecQual(List *qual, ExprContext *econtext, bool resultForNull);
-extern int ExecTargetListLength(List *targetlist);
-extern int ExecCleanTargetListLength(List *targetlist);
-extern TupleTableSlot *ExecProject(ProjectionInfo *projInfo);
/*
* prototypes from functions in execScan.c
@@ -355,10 +472,6 @@ extern void ExecAssignExprContext(EState *estate, PlanState *planstate);
extern void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc);
extern void ExecAssignResultTypeFromTL(PlanState *planstate);
extern TupleDesc ExecGetResultType(PlanState *planstate);
-extern ProjectionInfo *ExecBuildProjectionInfo(List *targetList,
- ExprContext *econtext,
- TupleTableSlot *slot,
- TupleDesc inputDesc);
extern void ExecAssignProjectionInfo(PlanState *planstate,
TupleDesc inputDesc);
extern void ExecFreeExprContext(PlanState *planstate);
@@ -376,8 +489,17 @@ extern void RegisterExprContextCallback(ExprContext *econtext,
extern void UnregisterExprContextCallback(ExprContext *econtext,
ExprContextCallbackFunction function,
Datum arg);
+
extern void ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate);
+extern Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname,
+ bool *isNull);
+extern Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno,
+ bool *isNull);
+
+extern int ExecTargetListLength(List *targetlist);
+extern int ExecCleanTargetListLength(List *targetlist);
+
/*
* prototypes from functions in execIndexing.c
*/
diff --git a/src/include/executor/nodeSubplan.h b/src/include/executor/nodeSubplan.h
index 0f821dc8f67..0d3f52118b2 100644
--- a/src/include/executor/nodeSubplan.h
+++ b/src/include/executor/nodeSubplan.h
@@ -20,6 +20,10 @@ extern SubPlanState *ExecInitSubPlan(SubPlan *subplan, PlanState *parent);
extern AlternativeSubPlanState *ExecInitAlternativeSubPlan(AlternativeSubPlan *asplan, PlanState *parent);
+extern Datum ExecSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull);
+
+extern Datum ExecAlternativeSubPlan(AlternativeSubPlanState *node, ExprContext *econtext, bool *isNull);
+
extern void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent);
extern void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext);
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 0a155acee62..6128752ab19 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -49,6 +49,9 @@ typedef Datum (*PGFunction) (FunctionCallInfo fcinfo);
* arguments, rather than about the function itself. But it's convenient
* to store it here rather than in FunctionCallInfoData, where it might more
* logically belong.
+ *
+ * fn_extra is available for use by the called function; all other fields
+ * should be treated as read-only after the struct is created.
*/
typedef struct FmgrInfo
{
@@ -65,6 +68,11 @@ typedef struct FmgrInfo
/*
* This struct is the data actually passed to an fmgr-called function.
+ *
+ * The called function is expected to set isnull, and possibly resultinfo or
+ * fields in whatever resultinfo points to. It should not change any other
+ * fields. (In particular, scribbling on the argument arrays is a bad idea,
+ * since some callers assume they can re-call with the same arguments.)
*/
typedef struct FunctionCallInfoData
{
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index f856f6036f6..ff428951186 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -31,6 +31,72 @@
/* ----------------
+ * ExprState node
+ *
+ * ExprState is the top-level node for expression evaluation.
+ * It contains instructions (in ->steps) to evaluate the expression.
+ * ----------------
+ */
+struct ExprState; /* forward references in this file */
+struct ExprContext;
+struct ExprEvalStep; /* avoid including execExpr.h everywhere */
+
+typedef Datum (*ExprStateEvalFunc) (struct ExprState *expression,
+ struct ExprContext *econtext,
+ bool *isNull);
+
+/* Bits in ExprState->flags (see also execExpr.h for private flag bits): */
+/* expression is for use with ExecQual() */
+#define EEO_FLAG_IS_QUAL (1 << 0)
+
+typedef struct ExprState
+{
+ Node tag;
+
+ uint8 flags; /* bitmask of EEO_FLAG_* bits, see above */
+
+ /*
+ * Storage for result value of a scalar expression, or for individual
+ * column results within expressions built by ExecBuildProjectionInfo().
+ */
+ bool resnull;
+ Datum resvalue;
+
+ /*
+ * If projecting a tuple result, this slot holds the result; else NULL.
+ */
+ TupleTableSlot *resultslot;
+
+ /*
+ * Instructions to compute expression's return value.
+ */
+ struct ExprEvalStep *steps;
+
+ /*
+ * Function that actually evaluates the expression. This can be set to
+ * different values depending on the complexity of the expression.
+ */
+ ExprStateEvalFunc evalfunc;
+
+ /* original expression tree, for debugging only */
+ Expr *expr;
+
+ /*
+ * XXX: following only needed during "compilation", could be thrown away.
+ */
+
+ int steps_len; /* number of steps currently */
+ int steps_alloc; /* allocated length of steps array */
+
+ Datum *innermost_caseval;
+ bool *innermost_casenull;
+
+ Datum *innermost_domainval;
+ bool *innermost_domainnull;
+} ExprState;
+
+
+/* ----------------
* IndexInfo information
*
* this struct holds the information needed to construct new index
@@ -69,7 +135,7 @@ typedef struct IndexInfo
List *ii_Expressions; /* list of Expr */
List *ii_ExpressionsState; /* list of ExprState */
List *ii_Predicate; /* list of Expr */
- List *ii_PredicateState; /* list of ExprState */
+ ExprState *ii_PredicateState;
Oid *ii_ExclusionOps; /* array with one entry per column */
Oid *ii_ExclusionProcs; /* array with one entry per column */
uint16 *ii_ExclusionStrats; /* array with one entry per column */
@@ -214,51 +280,21 @@ typedef struct ReturnSetInfo
* that is, form new tuples by evaluation of targetlist expressions.
* Nodes which need to do projections create one of these.
*
+ * The target tuple slot is kept in ProjectionInfo->pi_state.resultslot.
* ExecProject() evaluates the tlist, forms a tuple, and stores it
* in the given slot. Note that the result will be a "virtual" tuple
* unless ExecMaterializeSlot() is then called to force it to be
* converted to a physical tuple. The slot must have a tupledesc
* that matches the output of the tlist!
- *
- * The planner very often produces tlists that consist entirely of
- * simple Var references (lower levels of a plan tree almost always
- * look like that). And top-level tlists are often mostly Vars too.
- * We therefore optimize execution of simple-Var tlist entries.
- * The pi_targetlist list actually contains only the tlist entries that
- * aren't simple Vars, while those that are Vars are processed using the
- * varSlotOffsets/varNumbers/varOutputCols arrays.
- *
- * The lastXXXVar fields are used to optimize fetching of fields from
- * input tuples: they let us do a slot_getsomeattrs() call to ensure
- * that all needed attributes are extracted in one pass.
- *
- * targetlist target list for projection (non-Var expressions only)
- * exprContext expression context in which to evaluate targetlist
- * slot slot to place projection result in
- * directMap true if varOutputCols[] is an identity map
- * numSimpleVars number of simple Vars found in original tlist
- * varSlotOffsets array indicating which slot each simple Var is from
- * varNumbers array containing input attr numbers of simple Vars
- * varOutputCols array containing output attr numbers of simple Vars
- * lastInnerVar highest attnum from inner tuple slot (0 if none)
- * lastOuterVar highest attnum from outer tuple slot (0 if none)
- * lastScanVar highest attnum from scan tuple slot (0 if none)
* ----------------
*/
typedef struct ProjectionInfo
{
NodeTag type;
- List *pi_targetlist;
+ /* instructions to evaluate projection */
+ ExprState pi_state;
+ /* expression context in which to evaluate expression */
ExprContext *pi_exprContext;
- TupleTableSlot *pi_slot;
- bool pi_directMap;
- int pi_numSimpleVars;
- int *pi_varSlotOffsets;
- int *pi_varNumbers;
- int *pi_varOutputCols;
- int pi_lastInnerVar;
- int pi_lastOuterVar;
- int pi_lastScanVar;
} ProjectionInfo;
/* ----------------
@@ -340,20 +376,20 @@ typedef struct ResultRelInfo
IndexInfo **ri_IndexRelationInfo;
TriggerDesc *ri_TrigDesc;
FmgrInfo *ri_TrigFunctions;
- List **ri_TrigWhenExprs;
+ ExprState **ri_TrigWhenExprs;
Instrumentation *ri_TrigInstrument;
struct FdwRoutine *ri_FdwRoutine;
void *ri_FdwState;
bool ri_usesFdwDirectModify;
List *ri_WithCheckOptions;
List *ri_WithCheckOptionExprs;
- List **ri_ConstraintExprs;
+ ExprState **ri_ConstraintExprs;
JunkFilter *ri_junkFilter;
ProjectionInfo *ri_projectReturning;
ProjectionInfo *ri_onConflictSetProj;
- List *ri_onConflictSetWhere;
+ ExprState *ri_onConflictSetWhere;
List *ri_PartitionCheck;
- List *ri_PartitionCheckExpr;
+ ExprState *ri_PartitionCheckExpr;
Relation ri_PartitionRoot;
} ResultRelInfo;
@@ -564,139 +600,63 @@ typedef tuplehash_iterator TupleHashIterator;
/* ----------------------------------------------------------------
- * Expression State Trees
- *
- * Each executable expression tree has a parallel ExprState tree.
- *
- * Unlike PlanState, there is not an exact one-for-one correspondence between
- * ExprState node types and Expr node types. Many Expr node types have no
- * need for node-type-specific run-time state, and so they can use plain
- * ExprState or GenericExprState as their associated ExprState node type.
+ * Expression State Nodes
+ *
+ * Formerly, there was a separate executor expression state node corresponding
+ * to each node in a planned expression tree. That's no longer the case; for
+ * common expression node types, all the execution info is embedded into
+ * step(s) in a single ExprState node. But we still have a few executor state
+ * node types for selected expression node types, mostly those in which info
+ * has to be shared with other parts of the execution state tree.
* ----------------------------------------------------------------
*/
/* ----------------
- * ExprState node
- *
- * ExprState is the common superclass for all ExprState-type nodes.
- *
- * It can also be instantiated directly for leaf Expr nodes that need no
- * local run-time state (such as Var, Const, or Param).
- *
- * To save on dispatch overhead, each ExprState node contains a function
- * pointer to the routine to execute to evaluate the node.
- * ----------------
- */
-
-typedef struct ExprState ExprState;
-
-typedef Datum (*ExprStateEvalFunc) (ExprState *expression,
- ExprContext *econtext,
- bool *isNull);
-
-struct ExprState
-{
- NodeTag type;
- Expr *expr; /* associated Expr node */
- ExprStateEvalFunc evalfunc; /* routine to run to execute node */
-};
-
-/* ----------------
- * GenericExprState node
- *
- * This is used for Expr node types that need no local run-time state,
- * but have one child Expr node.
- * ----------------
- */
-typedef struct GenericExprState
-{
- ExprState xprstate;
- ExprState *arg; /* state of my child node */
-} GenericExprState;
-
-/* ----------------
- * WholeRowVarExprState node
- * ----------------
- */
-typedef struct WholeRowVarExprState
-{
- ExprState xprstate;
- struct PlanState *parent; /* parent PlanState, or NULL if none */
- TupleDesc wrv_tupdesc; /* descriptor for resulting tuples */
- JunkFilter *wrv_junkFilter; /* JunkFilter to remove resjunk cols */
-} WholeRowVarExprState;
-
-/* ----------------
* AggrefExprState node
* ----------------
*/
typedef struct AggrefExprState
{
- ExprState xprstate;
+ NodeTag type;
+ Aggref *aggref; /* expression plan node */
int aggno; /* ID number for agg within its plan node */
} AggrefExprState;
/* ----------------
- * GroupingFuncExprState node
- *
- * The list of column numbers refers to the input tuples of the Agg node to
- * which the GroupingFunc belongs, and may contain 0 for references to columns
- * that are only present in grouping sets processed by different Agg nodes (and
- * which are therefore always considered "grouping" here).
- * ----------------
- */
-typedef struct GroupingFuncExprState
-{
- ExprState xprstate;
- struct AggState *aggstate;
- List *clauses; /* integer list of column numbers */
-} GroupingFuncExprState;
-
-/* ----------------
* WindowFuncExprState node
* ----------------
*/
typedef struct WindowFuncExprState
{
- ExprState xprstate;
- List *args; /* states of argument expressions */
+ NodeTag type;
+ WindowFunc *wfunc; /* expression plan node */
+ List *args; /* ExprStates for argument expressions */
ExprState *aggfilter; /* FILTER expression */
int wfuncno; /* ID number for wfunc within its plan node */
} WindowFuncExprState;
-/* ----------------
- * ArrayRefExprState node
- *
- * Note: array types can be fixed-length (typlen > 0), but only when the
- * element type is itself fixed-length. Otherwise they are varlena structures
- * and have typlen = -1. In any case, an array type is never pass-by-value.
- * ----------------
- */
-typedef struct ArrayRefExprState
-{
- ExprState xprstate;
- List *refupperindexpr; /* states for child nodes */
- List *reflowerindexpr;
- ExprState *refexpr;
- ExprState *refassgnexpr;
- int16 refattrlength; /* typlen of array type */
- int16 refelemlength; /* typlen of the array element type */
- bool refelembyval; /* is the element type pass-by-value? */
- char refelemalign; /* typalign of the element type */
-} ArrayRefExprState;
/* ----------------
- * FuncExprState node
+ * SetExprState node
*
- * Although named for FuncExpr, this is also used for OpExpr, DistinctExpr,
- * and NullIf nodes; be careful to check what xprstate.expr is actually
- * pointing at!
+ * State for evaluating a potentially set-returning expression (like FuncExpr
+ * or OpExpr). In some cases, like some of the expressions in ROWS FROM(...)
+ * the expression might not be a SRF, but nonetheless it uses the same
+ * machinery as SRFs; it will be treated as a SRF returning a single row.
* ----------------
*/
-typedef struct FuncExprState
+typedef struct SetExprState
{
- ExprState xprstate;
- List *args; /* states of argument expressions */
+ NodeTag type;
+ Expr *expr; /* expression plan node */
+ List *args; /* ExprStates for argument expressions */
+
+ /*
+ * In ROWS FROM, functions can be inlined, removing the FuncExpr normally
+ * inside. In such a case this is the compiled expression (which cannot
+ * return a set), which'll be evaluated using regular ExecEvalExpr().
+ */
+ ExprState *elidedFuncState;
/*
* Function manager's lookup info for the target function. If func.fn_oid
@@ -738,7 +698,7 @@ typedef struct FuncExprState
/*
* Flag to remember whether we have registered a shutdown callback for
- * this FuncExprState. We do so only if funcResultStore or setArgsValid
+ * this SetExprState. We do so only if funcResultStore or setArgsValid
* has been set at least once (since all the callback is for is to release
* the tuplestore or clear setArgsValid).
*/
@@ -750,33 +710,7 @@ typedef struct FuncExprState
* argument values between calls, when setArgsValid is true.
*/
FunctionCallInfoData fcinfo_data;
-} FuncExprState;
-
-/* ----------------
- * ScalarArrayOpExprState node
- *
- * This is a FuncExprState plus some additional data.
- * ----------------
- */
-typedef struct ScalarArrayOpExprState
-{
- FuncExprState fxprstate;
- /* Cached info about array element type */
- Oid element_type;
- int16 typlen;
- bool typbyval;
- char typalign;
-} ScalarArrayOpExprState;
-
-/* ----------------
- * BoolExprState node
- * ----------------
- */
-typedef struct BoolExprState
-{
- ExprState xprstate;
- List *args; /* states of argument expression(s) */
-} BoolExprState;
+} SetExprState;
/* ----------------
* SubPlanState node
@@ -784,7 +718,8 @@ typedef struct BoolExprState
*/
typedef struct SubPlanState
{
- ExprState xprstate;
+ NodeTag type;
+ SubPlan *subplan; /* expression plan node */
struct PlanState *planstate; /* subselect plan's state tree */
struct PlanState *parent; /* parent plan node's state tree */
ExprState *testexpr; /* state of combining expression */
@@ -814,203 +749,18 @@ typedef struct SubPlanState
*/
typedef struct AlternativeSubPlanState
{
- ExprState xprstate;
- List *subplans; /* states of alternative subplans */
+ NodeTag type;
+ AlternativeSubPlan *subplan; /* expression plan node */
+ List *subplans; /* SubPlanStates of alternative subplans */
int active; /* list index of the one we're using */
} AlternativeSubPlanState;
-/* ----------------
- * FieldSelectState node
- * ----------------
- */
-typedef struct FieldSelectState
-{
- ExprState xprstate;
- ExprState *arg; /* input expression */
- TupleDesc argdesc; /* tupdesc for most recent input */
-} FieldSelectState;
-
-/* ----------------
- * FieldStoreState node
- * ----------------
- */
-typedef struct FieldStoreState
-{
- ExprState xprstate;
- ExprState *arg; /* input tuple value */
- List *newvals; /* new value(s) for field(s) */
- TupleDesc argdesc; /* tupdesc for most recent input */
-} FieldStoreState;
-
-/* ----------------
- * CoerceViaIOState node
- * ----------------
- */
-typedef struct CoerceViaIOState
-{
- ExprState xprstate;
- ExprState *arg; /* input expression */
- FmgrInfo outfunc; /* lookup info for source output function */
- FmgrInfo infunc; /* lookup info for result input function */
- Oid intypioparam; /* argument needed for input function */
-} CoerceViaIOState;
-
-/* ----------------
- * ArrayCoerceExprState node
- * ----------------
- */
-typedef struct ArrayCoerceExprState
-{
- ExprState xprstate;
- ExprState *arg; /* input array value */
- Oid resultelemtype; /* element type of result array */
- FmgrInfo elemfunc; /* lookup info for element coercion function */
- /* use struct pointer to avoid including array.h here */
- struct ArrayMapState *amstate; /* workspace for array_map */
-} ArrayCoerceExprState;
-
-/* ----------------
- * ConvertRowtypeExprState node
- * ----------------
- */
-typedef struct ConvertRowtypeExprState
-{
- ExprState xprstate;
- ExprState *arg; /* input tuple value */
- TupleDesc indesc; /* tupdesc for source rowtype */
- TupleDesc outdesc; /* tupdesc for result rowtype */
- /* use "struct" so we needn't include tupconvert.h here */
- struct TupleConversionMap *map;
- bool initialized;
-} ConvertRowtypeExprState;
-
-/* ----------------
- * CaseExprState node
- * ----------------
- */
-typedef struct CaseExprState
-{
- ExprState xprstate;
- ExprState *arg; /* implicit equality comparison argument */
- List *args; /* the arguments (list of WHEN clauses) */
- ExprState *defresult; /* the default result (ELSE clause) */
- int16 argtyplen; /* if arg is provided, its typlen */
-} CaseExprState;
-
-/* ----------------
- * CaseWhenState node
- * ----------------
- */
-typedef struct CaseWhenState
-{
- ExprState xprstate;
- ExprState *expr; /* condition expression */
- ExprState *result; /* substitution result */
-} CaseWhenState;
-
-/* ----------------
- * ArrayExprState node
- *
- * Note: ARRAY[] expressions always produce varlena arrays, never fixed-length
- * arrays.
- * ----------------
- */
-typedef struct ArrayExprState
-{
- ExprState xprstate;
- List *elements; /* states for child nodes */
- int16 elemlength; /* typlen of the array element type */
- bool elembyval; /* is the element type pass-by-value? */
- char elemalign; /* typalign of the element type */
-} ArrayExprState;
-
-/* ----------------
- * RowExprState node
- * ----------------
- */
-typedef struct RowExprState
-{
- ExprState xprstate;
- List *args; /* the arguments */
- TupleDesc tupdesc; /* descriptor for result tuples */
-} RowExprState;
-
-/* ----------------
- * RowCompareExprState node
- * ----------------
- */
-typedef struct RowCompareExprState
-{
- ExprState xprstate;
- List *largs; /* the left-hand input arguments */
- List *rargs; /* the right-hand input arguments */
- FmgrInfo *funcs; /* array of comparison function info */
- Oid *collations; /* array of collations to use */
-} RowCompareExprState;
-
-/* ----------------
- * CoalesceExprState node
- * ----------------
- */
-typedef struct CoalesceExprState
-{
- ExprState xprstate;
- List *args; /* the arguments */
-} CoalesceExprState;
-
-/* ----------------
- * MinMaxExprState node
- * ----------------
- */
-typedef struct MinMaxExprState
-{
- ExprState xprstate;
- List *args; /* the arguments */
- FmgrInfo cfunc; /* lookup info for comparison func */
-} MinMaxExprState;
-
-/* ----------------
- * XmlExprState node
- * ----------------
- */
-typedef struct XmlExprState
-{
- ExprState xprstate;
- List *named_args; /* ExprStates for named arguments */
- List *args; /* ExprStates for other arguments */
-} XmlExprState;
-
-/* ----------------
- * NullTestState node
- * ----------------
- */
-typedef struct NullTestState
-{
- ExprState xprstate;
- ExprState *arg; /* input expression */
- /* used only if input is of composite type: */
- TupleDesc argdesc; /* tupdesc for most recent input */
-} NullTestState;
-
-/* ----------------
- * CoerceToDomainState node
- * ----------------
- */
-typedef struct CoerceToDomainState
-{
- ExprState xprstate;
- ExprState *arg; /* input expression */
- /* Cached set of constraints that need to be checked */
- /* use struct pointer to avoid including typcache.h here */
- struct DomainConstraintRef *constraint_ref;
-} CoerceToDomainState;
-
/*
* DomainConstraintState - one item to check during CoerceToDomain
*
- * Note: this is just a Node, and not an ExprState, because it has no
- * corresponding Expr to link to. Nonetheless it is part of an ExprState
- * tree, so we give it a name following the xxxState convention.
+ * Note: we consider this to be part of an ExprState tree, so we give it
+ * a name following the xxxState convention. But there's no directly
+ * associated plan-tree node.
*/
typedef enum DomainConstraintType
{
@@ -1023,7 +773,8 @@ typedef struct DomainConstraintState
NodeTag type;
DomainConstraintType constrainttype; /* constraint type */
char *name; /* name of constraint (for error msgs) */
- ExprState *check_expr; /* for CHECK, a boolean expression */
+ Expr *check_expr; /* for CHECK, a boolean expression */
+ ExprState *check_exprstate; /* check_expr's eval state, or NULL */
} DomainConstraintState;
@@ -1060,8 +811,7 @@ typedef struct PlanState
* state trees parallel links in the associated plan tree (except for the
* subPlan list, which does not exist in the plan tree).
*/
- List *targetlist; /* target list to be computed at this node */
- List *qual; /* implicitly-ANDed qual conditions */
+ ExprState *qual; /* boolean qual condition */
struct PlanState *lefttree; /* input plan tree(s) */
struct PlanState *righttree;
List *initPlan; /* Init SubPlanState nodes (un-correlated expr
@@ -1133,11 +883,15 @@ typedef struct ResultState
/* ----------------
* ProjectSetState information
+ *
+ * Note: at least one of the "elems" will be a SetExprState; the rest are
+ * regular ExprStates.
* ----------------
*/
typedef struct ProjectSetState
{
PlanState ps; /* its first field is NodeTag */
+ Node **elems; /* array of expression states */
ExprDoneCond *elemdone; /* array of per-SRF is-done states */
int nelems; /* length of elemdone[] array */
bool pending_srf_tuples; /* still evaluating srfs in tlist? */
@@ -1372,7 +1126,7 @@ typedef struct
typedef struct IndexScanState
{
ScanState ss; /* its first field is NodeTag */
- List *indexqualorig;
+ ExprState *indexqualorig;
List *indexorderbyorig;
ScanKey iss_ScanKeys;
int iss_NumScanKeys;
@@ -1418,7 +1172,7 @@ typedef struct IndexScanState
typedef struct IndexOnlyScanState
{
ScanState ss; /* its first field is NodeTag */
- List *indexqual;
+ ExprState *indexqual;
ScanKey ioss_ScanKeys;
int ioss_NumScanKeys;
ScanKey ioss_OrderByKeys;
@@ -1534,7 +1288,7 @@ typedef struct ParallelBitmapHeapState
typedef struct BitmapHeapScanState
{
ScanState ss; /* its first field is NodeTag */
- List *bitmapqualorig;
+ ExprState *bitmapqualorig;
TIDBitmap *tbm;
TBMIterator *tbmiterator;
TBMIterateResult *tbmres;
@@ -1554,16 +1308,18 @@ typedef struct BitmapHeapScanState
/* ----------------
* TidScanState information
*
+ * tidexprs list of TidExpr structs (see nodeTidscan.c)
* isCurrentOf scan has a CurrentOfExpr qual
* NumTids number of tids in this scan
* TidPtr index of currently fetched tid
* TidList evaluated item pointers (array of size NumTids)
+ * htup currently-fetched tuple, if any
* ----------------
*/
typedef struct TidScanState
{
ScanState ss; /* its first field is NodeTag */
- List *tss_tidquals; /* list of ExprState nodes */
+ List *tss_tidexprs;
bool tss_isCurrentOf;
int tss_NumTids;
int tss_TidPtr;
@@ -1712,7 +1468,7 @@ typedef struct WorkTableScanState
typedef struct ForeignScanState
{
ScanState ss; /* its first field is NodeTag */
- List *fdw_recheck_quals; /* original quals not in ss.ps.qual */
+ ExprState *fdw_recheck_quals; /* original quals not in ss.ps.qual */
Size pscan_len; /* size of parallel coordination information */
/* use struct pointer to avoid including fdwapi.h here */
struct FdwRoutine *fdwroutine;
@@ -1759,7 +1515,7 @@ typedef struct JoinState
{
PlanState ps;
JoinType jointype;
- List *joinqual; /* JOIN quals (in addition to ps.qual) */
+ ExprState *joinqual; /* JOIN quals (in addition to ps.qual) */
} JoinState;
/* ----------------
@@ -1857,7 +1613,7 @@ typedef struct HashJoinTableData *HashJoinTable;
typedef struct HashJoinState
{
JoinState js; /* its first field is NodeTag */
- List *hashclauses; /* list of ExprState nodes */
+ ExprState *hashclauses;
List *hj_OuterHashKeys; /* list of ExprState nodes */
List *hj_InnerHashKeys; /* list of ExprState nodes */
List *hj_HashOperators; /* list of operator OIDs */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index fc883a6f3ec..c83216943c1 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -192,36 +192,18 @@ typedef enum NodeTag
/*
* TAGS FOR EXPRESSION STATE NODES (execnodes.h)
*
- * These correspond (not always one-for-one) to primitive nodes derived
- * from Expr.
+ * ExprState represents the evaluation state for a whole expression tree.
+ * Most Expr-based plan nodes do not have a corresponding expression state
+ * node, they're fully handled within execExpr* - but sometimes the state
+ * needs to be shared with other parts of the executor, as for example
+ * with AggrefExprState, which nodeAgg.c has to modify.
*/
T_ExprState,
- T_GenericExprState,
- T_WholeRowVarExprState,
T_AggrefExprState,
- T_GroupingFuncExprState,
T_WindowFuncExprState,
- T_ArrayRefExprState,
- T_FuncExprState,
- T_ScalarArrayOpExprState,
- T_BoolExprState,
+ T_SetExprState,
T_SubPlanState,
T_AlternativeSubPlanState,
- T_FieldSelectState,
- T_FieldStoreState,
- T_CoerceViaIOState,
- T_ArrayCoerceExprState,
- T_ConvertRowtypeExprState,
- T_CaseExprState,
- T_CaseWhenState,
- T_ArrayExprState,
- T_RowExprState,
- T_RowCompareExprState,
- T_CoalesceExprState,
- T_MinMaxExprState,
- T_XmlExprState,
- T_NullTestState,
- T_CoerceToDomainState,
T_DomainConstraintState,
/*
diff --git a/src/include/utils/typcache.h b/src/include/utils/typcache.h
index 90a1f6347a4..1bf94e2548d 100644
--- a/src/include/utils/typcache.h
+++ b/src/include/utils/typcache.h
@@ -132,6 +132,7 @@ typedef struct DomainConstraintRef
List *constraints; /* list of DomainConstraintState nodes */
MemoryContext refctx; /* context holding DomainConstraintRef */
TypeCacheEntry *tcache; /* typcache entry for domain type */
+ bool need_exprstate; /* does caller need check_exprstate? */
/* Management data --- treat these fields as private to typcache.c */
DomainConstraintCache *dcc; /* current constraints, or NULL if none */
@@ -142,7 +143,7 @@ typedef struct DomainConstraintRef
extern TypeCacheEntry *lookup_type_cache(Oid type_id, int flags);
extern void InitDomainConstraintRef(Oid type_id, DomainConstraintRef *ref,
- MemoryContext refctx);
+ MemoryContext refctx, bool need_exprstate);
extern void UpdateDomainConstraintRef(DomainConstraintRef *ref);
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index e570b71c04f..195b9b3a97a 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -61,7 +61,9 @@ extern void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode,
const char *msg);
extern xmltype *xmlconcat(List *args);
-extern xmltype *xmlelement(XmlExprState *xmlExpr, ExprContext *econtext);
+extern xmltype *xmlelement(XmlExpr *xexpr,
+ Datum *named_argvalue, bool *named_argnull,
+ Datum *argvalue, bool *argnull);
extern xmltype *xmlparse(text *data, XmlOptionType xmloption, bool preserve_whitespace);
extern xmltype *xmlpi(char *target, text *arg, bool arg_is_null, bool *result_is_null);
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);