/* Bits in ExprState->flags (see also execnodes.h for public flag bits): */ /* expression's interpreter has been initialized */ #define EEO_FLAG_INTERPRETER_INITIALIZED (1 << 5) /* jump-threading is in use */ #define EEO_FLAG_DIRECT_THREADED (1 << 6)
/* Typical API for out-of-line evaluation subroutines */ typedefvoid (*ExecEvalSubroutine) (ExprState *state, struct ExprEvalStep *op,
ExprContext *econtext);
/* API for out-of-line evaluation subroutines returning bool */ typedefbool (*ExecEvalBoolSubroutine) (ExprState *state, struct ExprEvalStep *op,
ExprContext *econtext);
/* ExprEvalSteps that cache a composite type's tupdesc need one of these */ /* (it fits in-line in some step types, otherwise allocate out-of-line) */ typedefstruct ExprEvalRowtypeCache
{ /* *cacheptrpointstocompositetype'sTypeCacheEntryiftupdesc_idisnot *0;orforananonymousRECORDtype,itpointsdirectlyatthecached *tupdescforthetype,andtupdesc_idis0.(We'duseseparatefields *ifspacewerenotatapremium.)Initialstateiscacheptr==NULL.
*/ void *cacheptr;
uint64 tupdesc_id; /* last-seen tupdesc identifier, or 0 */
} ExprEvalRowtypeCache;
/* *DiscriminatorforExprEvalSteps. * *Identifiestheoperationtobeexecutedandwhichmemberinthe *ExprEvalStep->dunionisvalid. * *Theorderofentriesneedstobekeptinsyncwiththedispatch_table[] *arrayinexecExprInterp.c:ExecInterpExpr().
*/ typedefenum ExprEvalOp
{ /* entire expression has been evaluated, return value */
EEOP_DONE_RETURN,
/* entire expression has been evaluated, no return value */
EEOP_DONE_NO_RETURN,
/* assign ExprState's resvalue/resnull to a column of its resultslot */
EEOP_ASSIGN_TMP, /* ditto, applying MakeExpandedObjectReadOnly() */
EEOP_ASSIGN_TMP_MAKE_RO,
/* where to store the result of this step */
Datum *resvalue; bool *resnull;
/* *Inlinedatafortheoperation.Inlinedataisfastertoaccess,but *alsobloatsthesizeofallinstructions.Theunionshouldbekeptto *nomorethan40byteson64-bitsystems(sothattheentirestructis *nomorethan64bytes,asinglecachelineoncommonsystems).
*/ union
{ /* for EEOP_INNER/OUTER/SCAN/OLD/NEW_FETCHSOME */ struct
{ /* attribute number up to which to fetch (inclusive) */ int last_var; /* will the type of slot be the same for every invocation */ bool fixed; /* tuple descriptor, if known */
TupleDesc known_desc; /* type of slot, can only be relied upon if fixed is set */ const TupleTableSlotOps *kind;
} fetch;
/* for EEOP_INNER/OUTER/SCAN/OLD/NEW_[SYS]VAR */ 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 */
VarReturningType varreturningtype; /* return old/new/default */
} 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_RETURNINGEXPR */ struct
{
uint8 nullflag; /* flag to test if OLD/NEW row is NULL */ int jumpdone; /* jump here if OLD/NEW row is NULL */
} returningexpr;
/* 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 */ bool make_ro; /* make arg0 R/O (used only for NULLIF) */
} 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 descriptor for composite type - filled at runtime */
ExprEvalRowtypeCache rowcache;
} nulltest_row;
/* for EEOP_PARAM_EXEC/EXTERN and EEOP_PARAM_SET */ struct
{ int paramid; /* numeric ID for parameter */
Oid paramtype; /* OID of parameter's datatype */
} param;
/* for EEOP_PARAM_CALLBACK */ struct
{
ExecEvalSubroutine paramfunc; /* add-on evaluation subroutine */ void *paramarg; /* private data for same */ void *paramarg2; /* more private data for same */ int paramid; /* numeric ID for parameter */
Oid paramtype; /* OID of parameter's datatype */
} cparam;
/* 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_NEXTVALUEEXPR */ struct
{
Oid seqid;
Oid seqtypid;
} nextvalueexpr;
/* 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
{
ExprState *elemexprstate; /* null if no per-element work */
Oid resultelemtype; /* element type of result array */ 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
{
CompareType cmptype;
} 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 descriptor for composite type - filled at runtime */
ExprEvalRowtypeCache rowcache;
} fieldselect;
/* for EEOP_FIELDSTORE_DEFORM / FIELDSTORE_FORM */ struct
{ /* original expression node */
FieldStore *fstore;
/* cached descriptor for composite type - filled at runtime */ /* note that a DEFORM and FORM pair share the same cache */
ExprEvalRowtypeCache *rowcache;
/* workspace for column values */
Datum *values; bool *nulls; int ncolumns;
} fieldstore;
/* for EEOP_SBSREF_SUBSCRIPTS */ struct
{
ExecEvalBoolSubroutine subscriptfunc; /* evaluation subroutine */ /* too big to have inline */ struct SubscriptingRefState *state; int jumpdone; /* jump here on null */
} sbsref_subscript;
/* for EEOP_SBSREF_OLD / ASSIGN / FETCH */ struct
{
ExecEvalSubroutine subscriptfunc; /* evaluation subroutine */ /* too big to have inline */ struct SubscriptingRefState *state;
} sbsref;
/* 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;
ErrorSaveContext *escontext;
} domaincheck;
/* for EEOP_HASH_SET_INITVAL */ struct
{
Datum init_value;
} hashdatum_initvalue;
/* for EEOP_HASHDATUM_(FIRST|NEXT32)[_STRICT] */ 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 jumpdone; /* jump here on null */
NullableDatum *iresult; /* intermediate hash result */
} hashdatum;
/* for EEOP_CONVERT_ROWTYPE */ struct
{
Oid inputtype; /* input composite type */
Oid outputtype; /* output composite type */ /* these three fields are filled at runtime: */
ExprEvalRowtypeCache *incache; /* cache for input type */
ExprEvalRowtypeCache *outcache; /* cache for output type */
TupleConversionMap *map; /* column mapping */
} 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_HASHED_SCALARARRAYOP */ struct
{ bool has_nulls; bool inclause; /* true for IN and false for NOT IN */ bool null_lhs_result; /* for non-strict lookups, we *cachewhatlookingupNULL
* returns. */ bool null_lhs_isnull; struct ScalarArrayOpExprHashTable *elements_tab;
FmgrInfo *finfo; /* function's lookup data */
FunctionCallInfo fcinfo_data; /* arguments etc */
ScalarArrayOpExpr *saop;
} hashedscalararrayop;
/* 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
{ int aggno;
} aggref;
/* for EEOP_GROUPING_FUNC */ struct
{
List *clauses; /* integer list of column numbers */
} grouping_func;
/* for EEOP_WINDOW_FUNC */ struct
{ /* out-of-line state, modified by nodeWindowAgg.c */
WindowFuncExprState *wfstate;
} window_func;
/* for EEOP_SUBPLAN */ struct
{ /* out-of-line state, created by nodeSubplan.c */
SubPlanState *sstate;
} subplan;
/* for EEOP_AGG_*DESERIALIZE */ struct
{
FunctionCallInfo fcinfo_data; int jumpnull;
} agg_deserialize;
/* for EEOP_AGG_STRICT_INPUT_CHECK_NULLS / STRICT_INPUT_CHECK_ARGS */ struct
{ /* *ForEEOP_AGG_STRICT_INPUT_CHECK_ARGSargscontainspointersto *theNullableDatumsthatneedtobecheckedforNULLs. * *ForEEOP_AGG_STRICT_INPUT_CHECK_NULLSnullscontainspointers *tobooleansthatneedtobecheckedforNULLs. * *Bothcasescurrentlyneedtoexistbecausesometimesthe *to-be-checkednullsareinTupleTableSlot.isnullarray,and *sometimesinFunctionCallInfoBaseData.args[i].isnull.
*/
NullableDatum *args; bool *nulls; int nargs; int jumpnull;
} agg_strict_input_check;
/* for EEOP_AGG_PLAIN_PERGROUP_NULLCHECK */ struct
{ int setoff; int jumpnull;
} agg_plain_pergroup_nullcheck;
/* for EEOP_AGG_PRESORTED_DISTINCT_{SINGLE,MULTI} */ struct
{
AggStatePerTrans pertrans;
ExprContext *aggcontext; int jumpdistinct;
} agg_presorted_distinctcheck;
/* for EEOP_AGG_PLAIN_TRANS_[INIT_][STRICT_]{BYVAL,BYREF} */ /* for EEOP_AGG_ORDERED_TRANS_{DATUM,TUPLE} */ struct
{
AggStatePerTrans pertrans;
ExprContext *aggcontext; int setno; int transno; int setoff;
} agg_trans;
/* for EEOP_IS_JSON */ struct
{
JsonIsPredicate *pred; /* original expression node */
} is_json;
/* for EEOP_JSONEXPR_COERCION */ struct
{
Oid targettype;
int32 targettypmod; bool omit_quotes; /* exists_* fields only relevant for JSON_EXISTS_OP. */ bool exists_coerce; bool exists_cast_to_int; bool exists_check_domain; void *json_coercion_cache;
ErrorSaveContext *escontext;
} jsonexpr_coercion;
} d;
} ExprEvalStep;
/* Enforce the size rule given in the comment above */
StaticAssertDecl(sizeof(ExprEvalStep) <= 64, "size of ExprEvalStep exceeds 64 bytes");
/* Non-inline data for container operations */ typedefstruct SubscriptingRefState
{ bool isassignment; /* is it assignment, or just fetch? */
/* workspace for type-specific subscripting code */ void *workspace;
/* numupper and upperprovided[] are filled at expression compile time */ /* at runtime, subscripts are computed in upperindex[]/upperindexnull[] */ int numupper; bool *upperprovided; /* indicates if this position is supplied */
Datum *upperindex; bool *upperindexnull;
/* similarly for lower indexes, if any */ int numlower; bool *lowerprovided;
Datum *lowerindex; bool *lowerindexnull;
/* for assignment, new value to assign is evaluated into here */
Datum replacevalue; bool replacenull;
/* if we have a nested assignment, sbs_fetch_old puts old value here */
Datum prevvalue; bool prevnull;
} SubscriptingRefState;
/* Execution step methods used for SubscriptingRef */ typedefstruct SubscriptExecSteps
{ /* See nodes/subscripting.h for more detail about these */
ExecEvalBoolSubroutine sbs_check_subscripts; /* process subscripts */
ExecEvalSubroutine sbs_fetch; /* fetch an element */
ExecEvalSubroutine sbs_assign; /* assign to an element */
ExecEvalSubroutine sbs_fetch_old; /* fetch old value for assignment */
} SubscriptExecSteps;
/* EEOP_JSON_CONSTRUCTOR state, too big to inline */ typedefstruct JsonConstructorExprState
{
JsonConstructorExpr *constructor;
Datum *arg_values; bool *arg_nulls;
Oid *arg_types; struct
{ int category;
Oid outfuncid;
} *arg_type_cache; /* cache for datum_to_json[b]() */ int nargs;
} JsonConstructorExprState;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.