*
* execExpr.h
* Low level infrastructure related to expression evaluation
*
*
* Portions Copyright (c) 1996-2018, 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 "executor/node/nodeAgg.h"
#include "nodes/execnodes.h"
struct ArrayRefState;
#define EEO_FLAG_INTERPRETER_INITIALIZED (1 << 1)
#define EEO_FLAG_DIRECT_THREADED (1 << 2)
#define FUNC_EXPR_FLAG_HAS_REFCURSOR uint32(1 << 0)
#define FUNC_EXPR_FLAG_HAS_CURSOR_RETURN uint32(1 << 1)
#define FUNC_EXPR_FLAG_STRICT uint32(1 << 2)
#define FUNC_EXPR_FLAG_FUSAGE uint32(1 << 3)
#define FUNC_EXPR_FLAG_STRICT_FUSAGE (FUNC_EXPR_FLAG_STRICT | FUNC_EXPR_FLAG_FUSAGE)
#define FUNC_EXPR_FLAG_IS_PLPGSQL uint32(1 << 4)
#define FUNC_EXPR_FLAG_ORACLE_COMPATIBILITY uint32(1 << 5)
* 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
{
EEOP_DONE,
EEOP_INNER_FETCHSOME,
EEOP_OUTER_FETCHSOME,
EEOP_SCAN_FETCHSOME,
EEOP_INNER_VAR,
EEOP_OUTER_VAR,
EEOP_SCAN_VAR,
EEOP_INNER_SYSVAR,
EEOP_OUTER_SYSVAR,
EEOP_SCAN_SYSVAR,
EEOP_WHOLEROW,
* 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,
EEOP_ASSIGN_TMP,
EEOP_ASSIGN_TMP_MAKE_RO,
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,
EEOP_FUNCEXPR_MAKE_FUNCTION_RESULT,
* 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,
EEOP_BOOL_OR_STEP_FIRST,
EEOP_BOOL_OR_STEP,
EEOP_BOOL_OR_STEP_LAST,
EEOP_BOOL_NOT_STEP,
EEOP_QUAL,
EEOP_JUMP,
EEOP_JUMP_IF_NULL,
EEOP_JUMP_IF_NOT_NULL,
EEOP_JUMP_IF_NOT_TRUE,
EEOP_NULLTEST_ISNULL,
EEOP_NULLTEST_ISNOTNULL,
EEOP_NULLTEST_ROWISNULL,
EEOP_NULLTEST_ROWISNOTNULL,
EEOP_BOOLTEST_IS_TRUE,
EEOP_BOOLTEST_IS_NOT_TRUE,
EEOP_BOOLTEST_IS_FALSE,
EEOP_BOOLTEST_IS_NOT_FALSE,
EEOP_PARAM_EXEC,
EEOP_PARAM_EXTERN,
EEOP_CASE_TESTVAL,
EEOP_MAKE_READONLY,
EEOP_IOCOERCE,
EEOP_DISTINCT,
EEOP_NULLIF,
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,
EEOP_ROWCOMPARE_FINAL,
EEOP_MINMAX,
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,
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,
EEOP_ARRAYREF_ASSIGN,
EEOP_ARRAYREF_FETCH,
EEOP_DOMAIN_TESTVAL,
EEOP_DOMAIN_NOTNULL,
EEOP_DOMAIN_CHECK,
EEOP_CONVERT_ROWTYPE,
EEOP_SCALARARRAYOP,
EEOP_HASHED_SCALARARRAYOP,
EEOP_XMLEXPR,
EEOP_AGGREF,
EEOP_GROUPING_FUNC,
EEOP_WINDOW_FUNC,
EEOP_SUBPLAN,
EEOP_ALTERNATIVE_SUBPLAN,
EEOP_ROWNUM,
EEOP_GROUPING_ID,
EEOP_HASH_FILTER,
EEOP_USERVAR_OR_SETVARIABLE,
EEOP_USERSET_ELEM,
EEOP_PREFIX_BTYEA,
EEOP_PREFIX_TEXT,
EEOP_AGG_STRICT_DESERIALIZE,
EEOP_AGG_DESERIALIZE,
EEOP_AGG_STRICT_INPUT_CHECK,
EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL,
EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYVAL,
EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL,
EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYVAL,
EEOP_AGG_PLAIN_TRANS_BYVAL,
EEOP_AGG_COLLECT_PLAIN_TRANS_BYVAL,
EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF,
EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYREF,
EEOP_AGG_PLAIN_TRANS_STRICT_BYREF,
EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYREF,
EEOP_AGG_PLAIN_TRANS_BYREF,
EEOP_AGG_COLLECT_PLAIN_TRANS_BYREF,
EEOP_AGG_ORDERED_TRANS_DATUM,
EEOP_AGG_ORDERED_TRANS_TUPLE,
EEOP_NANTEST_ISNAN,
EEOP_NANTEST_ISNOTNAN,
EEOP_INFINITETEST_ISINFINITE,
EEOP_INFINITETEST_ISNOTINFINITE,
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;
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
{
struct
{
int last_var;
} fetch;
struct
{
int attnum;
Oid vartype;
} var;
struct
{
Var *var;
bool first;
bool slow;
TupleDesc tupdesc;
JunkFilter *junkFilter;
} wholerow;
struct
{
int resultnum;
int attnum;
} assign_var;
struct
{
int resultnum;
} assign_tmp;
struct
{
Datum value;
bool isnull;
bool is_cursor;
Const* con;
} constval;
struct
{
char prokind;
bool needResetErrMsg;
uint32 flag;
FmgrInfo *finfo;
FunctionCallInfo fcinfo_data;
PGFunction fn_addr;
int nargs;
List* args;
int* var_dno;
bool is_plpgsql_func_with_outparam;
} func;
struct
{
bool *anynull;
int jumpdone;
} boolexpr;
struct
{
int jumpdone;
} qualexpr;
struct
{
int jumpdone;
} jump;
struct
{
TupleDesc argdesc;
} nulltest_row;
struct
{
Datum *value;
bool *isnull;
Expr *expr;
} decspecexpr;
struct
{
int paramid;
Oid paramtype;
bool is_cursor;
} param;
struct
{
Datum *value;
bool *isnull;
} casetest;
struct
{
Datum *value;
bool *isnull;
} make_readonly;
struct
{
FmgrInfo *finfo_out;
FunctionCallInfo fcinfo_data_out;
FmgrInfo *finfo_in;
FunctionCallInfo fcinfo_data_in;
} iocoerce;
struct
{
Datum *elemvalues;
bool *elemnulls;
int nelems;
Oid elemtype;
int16 elemlength;
bool elembyval;
char elemalign;
bool multidims;
} arrayexpr;
struct
{
ArrayCoerceExpr *coerceexpr;
Oid resultelemtype;
FmgrInfo *elemfunc;
* function */
struct ArrayMapState *amstate;
} arraycoerce;
struct
{
TupleDesc tupdesc;
Datum *elemvalues;
bool *elemnulls;
} row;
struct
{
FmgrInfo *finfo;
FunctionCallInfo fcinfo_data;
PGFunction fn_addr;
int jumpnull;
int jumpdone;
} rowcompare_step;
struct
{
RowCompareType rctype;
} rowcompare_final;
struct
{
Datum *values;
bool *nulls;
int nelems;
MinMaxOp op;
FmgrInfo *finfo;
FunctionCallInfo fcinfo_data;
} minmax;
struct
{
AttrNumber fieldnum;
Oid resulttype;
TupleDesc argdesc;
} fieldselect;
struct
{
FieldStore *fstore;
TupleDesc *argdesc;
Datum *values;
bool *nulls;
int ncolumns;
} fieldstore;
struct
{
struct ArrayRefState *state;
int off;
bool isupper;
int jumpdone;
} arrayref_subscript;
struct
{
struct ArrayRefState *state;
} arrayref;
struct
{
char *constraintname;
Datum *checkvalue;
bool *checknull;
Oid resulttype;
} domaincheck;
struct
{
ConvertRowtypeExpr *convert;
TupleDesc indesc;
TupleDesc outdesc;
TupleConversionMap *map;
bool initialized;
} convert_rowtype;
struct
{
Oid element_type;
bool useOr;
int16 typlen;
bool typbyval;
char typalign;
FmgrInfo *finfo;
FunctionCallInfo fcinfo_data;
PGFunction fn_addr;
} scalararrayop;
struct {
bool has_nulls;
bool inclause;
struct ScalarArrayOpExprHashTable *elements_tab;
FmgrInfo *finfo;
FunctionCallInfo fcinfo_data;
ScalarArrayOpExpr *saop;
} hashedscalararrayop;
struct
{
XmlExpr *xexpr;
Datum *named_argvalue;
bool *named_argnull;
Datum *argvalue;
bool *argnull;
} xmlexpr;
struct
{
AggrefExprState *astate;
} aggref;
struct
{
AggState *parent;
List *clauses;
} grouping_func;
struct
{
WindowFuncExprState *wfstate;
} window_func;
struct
{
SubPlanState *sstate;
} subplan;
struct
{
AlternativeSubPlanState *asstate;
} alternative_subplan;
struct
{
bool typeCompat;
PlanState* RownumState;
} rownum;
struct
{
Const* con;
} uservar;
struct
{
UserSetElem* useexpr;
} userset;
struct
{
PrefixKey* pkey;
int encoding;
} prefix_key;
struct
{
AggState* GroupingIdState;
} grouping_id;
struct
{
List* arg;
uint2* nodelist;
uint2* bucketMap;
int bucketCnt;
Datum* argvalue;
bool* argnull;
List* typeOids;
} hash_filter;
struct {
AggState *aggstate;
FunctionCallInfo fcinfo_data;
int jumpnull;
} agg_deserialize;
struct {
bool *nulls;
int nargs;
int jumpnull;
} agg_strict_input_check;
struct {
AggStatePerTrans pertrans;
MemoryContext aggcontext;
int setno;
int transno;
int setoff;
} agg_trans;
} d;
} ExprEvalStep;
typedef struct ArrayRefState
{
bool isassignment;
Oid refelemtype;
int16 refattrlength;
int16 refelemlength;
bool refelembyval;
char refelemalign;
int numupper;
bool upperprovided[MAXDIM];
int upperindex[MAXDIM];
int numlower;
bool lowerprovided[MAXDIM];
int lowerindex[MAXDIM];
Datum subscriptvalue;
bool subscriptnull;
Datum replacevalue;
bool replacenull;
Datum prevvalue;
bool prevnull;
Expr *refexpr;
int refupperindexpr_count;
int plpgsql_index;
Oid typOid;
} ArrayRefState;
extern void ExecReadyInterpretedExpr(ExprState *state);
extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op);
extern Datum ExecInterpExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull, ExprDoneCond* isDone);
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
* expression evaluation, reducing code duplication.
*/
extern void ExecEvalFuncExprFusage(ExprEvalStep *op, ExprContext *econtext);
extern void ExecEvalFuncExprStrictFusage(ExprEvalStep *op, ExprContext *econtext);
extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
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 ExecEvalNan(ExprState *state, ExprEvalStep *op, ExprContext *econtext);
extern void ExecEvalNotNan(ExprState *state, ExprEvalStep *op, ExprContext *econtext);
extern void ExecEvalInfinite(ExprState *state, ExprEvalStep *op, ExprContext *econtext);
extern void ExecEvalNotInfinite(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, ExprContext *econtext);
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 ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
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 ExecEvalHashFilter(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern bool IsTableOfFunc(Oid funcOid);
extern Datum ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans, Datum newValue, bool newValueIsNull,
Datum oldValue, bool oldValueIsNull);
extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup,
MemoryContext aggcontext);
extern void ExecAggInitCollectGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup,
MemoryContext aggcontext);
extern void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op, ExprContext *econtext);
extern void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op, ExprContext *econtext);
#endif