This commit is contained in:
blue-lemon0104
2026-04-07 13:35:22 +08:00
commit 0120fa9ce3
1530 changed files with 424864 additions and 0 deletions

25
db_include/executor/execAsync.h Executable file
View File

@@ -0,0 +1,25 @@
/*-------------------------------------------------------------------------
* execAsync.h
* Support functions for asynchronous execution
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/include/executor/execAsync.h
*-------------------------------------------------------------------------
*/
#ifndef EXECASYNC_H
#define EXECASYNC_H
#include "nodes/execnodes.h"
extern void ExecAsyncRequest(AsyncRequest *areq);
extern void ExecAsyncConfigureWait(AsyncRequest *areq);
extern void ExecAsyncNotify(AsyncRequest *areq);
extern void ExecAsyncResponse(AsyncRequest *areq);
extern void ExecAsyncRequestDone(AsyncRequest *areq, TupleTableSlot *result);
extern void ExecAsyncRequestPending(AsyncRequest *areq);
#endif /* EXECASYNC_H */

782
db_include/executor/execExpr.h Executable file
View File

@@ -0,0 +1,782 @@
/*-------------------------------------------------------------------------
*
* execExpr.h
* Low level infrastructure related to expression evaluation
*
*
* Portions Copyright (c) 1996-2021, 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/nodeAgg.h"
#include "nodes/execnodes.h"
/* forward references to avoid circularity */
struct ExprEvalStep;
struct SubscriptingRefState;
struct ScalarArrayOpExprHashTable;
/* 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)
/* Typical API for out-of-line evaluation subroutines */
typedef void (*ExecEvalSubroutine) (ExprState *state,
struct ExprEvalStep *op,
ExprContext *econtext);
/* API for out-of-line evaluation subroutines returning bool */
typedef bool (*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) */
typedef struct ExprEvalRowtypeCache
{
/*
* cacheptr points to composite type's TypeCacheEntry if tupdesc_id is not
* 0; or for an anonymous RECORD type, it points directly at the cached
* tupdesc for the type, and tupdesc_id is 0. (We'd use separate fields
* if space were not at a premium.) Initial state is cacheptr == NULL.
*/
void *cacheptr;
uint64 tupdesc_id; /* last-seen tupdesc identifier, or 0 */
} ExprEvalRowtypeCache;
/*
* 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 */
EEOP_INNER_VAR,
EEOP_OUTER_VAR,
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 a CheckVarSlotCompatibility() check 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,
EEOP_PARAM_CALLBACK,
/* 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_NOT_DISTINCT,
EEOP_NULLIF,
EEOP_SQLVALUEFUNCTION,
EEOP_CURRENTOFEXPR,
EEOP_NEXTVALUEEXPR,
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 container subscripts; possibly short-circuit result to NULL */
EEOP_SBSREF_SUBSCRIPTS,
/*
* Compute old container element/slice when a SubscriptingRef assignment
* expression contains SubscriptingRef/FieldStore subexpressions. Value is
* accessed using the CaseTest mechanism.
*/
EEOP_SBSREF_OLD,
/* compute new value for SubscriptingRef assignment expression */
EEOP_SBSREF_ASSIGN,
/* compute element/slice for SubscriptingRef fetch expression */
EEOP_SBSREF_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_HASHED_SCALARARRAYOP,
EEOP_XMLEXPR,
EEOP_AGGREF,
EEOP_GROUPING_FUNC,
EEOP_WINDOW_FUNC,
EEOP_SUBPLAN,
/* aggregation related nodes */
EEOP_AGG_STRICT_DESERIALIZE,
EEOP_AGG_DESERIALIZE,
EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
EEOP_AGG_STRICT_INPUT_CHECK_NULLS,
EEOP_AGG_PLAIN_PERGROUP_NULLCHECK,
EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL,
EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL,
EEOP_AGG_PLAIN_TRANS_BYVAL,
EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF,
EEOP_AGG_PLAIN_TRANS_STRICT_BYREF,
EEOP_AGG_PLAIN_TRANS_BYREF,
EEOP_AGG_ORDERED_TRANS_DATUM,
EEOP_AGG_ORDERED_TRANS_TUPLE,
/* 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;
/* 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_[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 descriptor for composite type - filled at runtime */
ExprEvalRowtypeCache rowcache;
} nulltest_row;
/* for EEOP_PARAM_EXEC/EXTERN */
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 */
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
{
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 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;
} domaincheck;
/* 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;
struct ScalarArrayOpExprHashTable *elements_tab;
FmgrInfo *finfo; /* function's lookup data */
FunctionCallInfo fcinfo_data; /* arguments etc */
/* faster to access without additional indirection: */
PGFunction fn_addr; /* actual call address */
FmgrInfo *hash_finfo; /* function's lookup data */
FunctionCallInfo hash_fcinfo_data; /* arguments etc */
/* faster to access without additional indirection: */
PGFunction hash_fn_addr; /* actual call address */
} 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
{
/*
* For EEOP_AGG_STRICT_INPUT_CHECK_ARGS args contains pointers to
* the NullableDatums that need to be checked for NULLs.
*
* For EEOP_AGG_STRICT_INPUT_CHECK_NULLS nulls contains pointers
* to booleans that need to be checked for NULLs.
*
* Both cases currently need to exist because sometimes the
* to-be-checked nulls are in TupleTableSlot.isnull array, and
* sometimes in FunctionCallInfoBaseData.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_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;
} d;
} ExprEvalStep;
/* Non-inline data for container operations */
typedef struct 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 */
typedef struct 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;
/* functions in execExpr.c */
extern void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s);
/* functions in execExprInterp.c */
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
* expression evaluation, reducing code duplication.
*/
extern void ExecEvalFuncExprFusage(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern void ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
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 ExecEvalNextValueExpr(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,
ExprContext *econtext);
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 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 ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op,
ExprContext *econtext, TupleTableSlot *slot);
extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup,
ExprContext *aggcontext);
extern Datum ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans,
Datum newValue, bool newValueIsNull,
Datum oldValue, bool oldValueIsNull);
extern void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
#endif /* EXEC_EXPR_H */

View File

@@ -0,0 +1,51 @@
/*--------------------------------------------------------------------
* execParallel.h
* POSTGRES parallel execution interface
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/include/executor/execParallel.h
*--------------------------------------------------------------------
*/
#ifndef EXECPARALLEL_H
#define EXECPARALLEL_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/plannodes.h"
#include "utils/dsa.h"
typedef struct SharedExecutorInstrumentation SharedExecutorInstrumentation;
typedef struct ParallelExecutorInfo
{
PlanState *planstate; /* plan subtree we're running in parallel */
ParallelContext *pcxt; /* parallel context we're using */
BufferUsage *buffer_usage; /* points to bufusage area in DSM */
WalUsage *wal_usage; /* walusage area in DSM */
SharedExecutorInstrumentation *instrumentation; /* optional */
struct SharedJitInstrumentation *jit_instrumentation; /* optional */
dsa_area *area; /* points to DSA area in DSM */
dsa_pointer param_exec; /* serialized PARAM_EXEC parameters */
bool finished; /* set true by ExecParallelFinish */
/* These two arrays have pcxt->nworkers_launched entries: */
shm_mq_handle **tqueue; /* tuple queues for worker output */
struct TupleQueueReader **reader; /* tuple reader/writer support */
} ParallelExecutorInfo;
extern ParallelExecutorInfo *ExecInitParallelPlan(PlanState *planstate,
EState *estate, Bitmapset *sendParam, int nworkers,
int64 tuples_needed);
extern void ExecParallelCreateReaders(ParallelExecutorInfo *pei);
extern void ExecParallelFinish(ParallelExecutorInfo *pei);
extern void ExecParallelCleanup(ParallelExecutorInfo *pei);
extern void ExecParallelReinitialize(PlanState *planstate,
ParallelExecutorInfo *pei, Bitmapset *sendParam);
extern void ParallelQueryMain(dsm_segment *seg, shm_toc *toc);
#endif /* EXECPARALLEL_H */

View File

@@ -0,0 +1,128 @@
/*--------------------------------------------------------------------
* execPartition.h
* POSTGRES partitioning executor interface
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/include/executor/execPartition.h
*--------------------------------------------------------------------
*/
#ifndef EXECPARTITION_H
#define EXECPARTITION_H
#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/plannodes.h"
#include "partitioning/partprune.h"
/* See execPartition.c for the definitions. */
typedef struct PartitionDispatchData *PartitionDispatch;
typedef struct PartitionTupleRouting PartitionTupleRouting;
/*
* PartitionedRelPruningData - Per-partitioned-table data for run-time pruning
* of partitions. For a multilevel partitioned table, we have one of these
* for the topmost partition plus one for each non-leaf child partition.
*
* subplan_map[] and subpart_map[] have the same definitions as in
* PartitionedRelPruneInfo (see plannodes.h); though note that here,
* subpart_map contains indexes into PartitionPruningData.partrelprunedata[].
*
* nparts Length of subplan_map[] and subpart_map[].
* subplan_map Subplan index by partition index, or -1.
* subpart_map Subpart index by partition index, or -1.
* present_parts A Bitmapset of the partition indexes that we
* have subplans or subparts for.
* initial_pruning_steps List of PartitionPruneSteps used to
* perform executor startup pruning.
* exec_pruning_steps List of PartitionPruneSteps used to
* perform per-scan pruning.
* initial_context If initial_pruning_steps isn't NIL, contains
* the details needed to execute those steps.
* exec_context If exec_pruning_steps isn't NIL, contains
* the details needed to execute those steps.
*/
typedef struct PartitionedRelPruningData
{
int nparts;
int *subplan_map;
int *subpart_map;
Bitmapset *present_parts;
List *initial_pruning_steps;
List *exec_pruning_steps;
PartitionPruneContext initial_context;
PartitionPruneContext exec_context;
} PartitionedRelPruningData;
/*
* PartitionPruningData - Holds all the run-time pruning information for
* a single partitioning hierarchy containing one or more partitions.
* partrelprunedata[] is an array ordered such that parents appear before
* their children; in particular, the first entry is the topmost partition,
* which was actually named in the SQL query.
*/
typedef struct PartitionPruningData
{
int num_partrelprunedata; /* number of array entries */
PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER];
} PartitionPruningData;
/*
* PartitionPruneState - State object required for plan nodes to perform
* run-time partition pruning.
*
* This struct can be attached to plan types which support arbitrary Lists of
* subplans containing partitions, to allow subplans to be eliminated due to
* the clauses being unable to match to any tuple that the subplan could
* possibly produce.
*
* execparamids Contains paramids of PARAM_EXEC Params found within
* any of the partprunedata structs. Pruning must be
* done again each time the value of one of these
* parameters changes.
* other_subplans Contains indexes of subplans that don't belong to any
* "partprunedata", e.g UNION ALL children that are not
* partitioned tables, or a partitioned table that the
* planner deemed run-time pruning to be useless for.
* These must not be pruned.
* prune_context A short-lived memory context in which to execute the
* partition pruning functions.
* do_initial_prune true if pruning should be performed during executor
* startup (at any hierarchy level).
* do_exec_prune true if pruning should be performed during
* executor run (at any hierarchy level).
* num_partprunedata Number of items in "partprunedata" array.
* partprunedata Array of PartitionPruningData pointers for the plan's
* partitioned relation(s), one for each partitioning
* hierarchy that requires run-time pruning.
*/
typedef struct PartitionPruneState
{
Bitmapset *execparamids;
Bitmapset *other_subplans;
MemoryContext prune_context;
bool do_initial_prune;
bool do_exec_prune;
int num_partprunedata;
PartitionPruningData *partprunedata[FLEXIBLE_ARRAY_MEMBER];
} PartitionPruneState;
extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(EState *estate,
Relation rel);
extern ResultRelInfo *ExecFindPartition(ModifyTableState *mtstate,
ResultRelInfo *rootResultRelInfo,
PartitionTupleRouting *proute,
TupleTableSlot *slot,
EState *estate);
extern void ExecCleanupTupleRouting(ModifyTableState *mtstate,
PartitionTupleRouting *proute);
extern PartitionPruneState *ExecCreatePartitionPruneState(PlanState *planstate,
PartitionPruneInfo *partitionpruneinfo);
extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate);
extern Bitmapset *ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate,
int nsubplans);
#endif /* EXECPARTITION_H */

130
db_include/executor/execdebug.h Executable file
View File

@@ -0,0 +1,130 @@
/*-------------------------------------------------------------------------
*
* execdebug.h
* #defines governing debugging behaviour in the executor
*
* XXX this is all pretty old and crufty. Newer code tends to use elog()
* for debug printouts, because that's more flexible than printf().
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/execdebug.h
*
*-------------------------------------------------------------------------
*/
#ifndef EXECDEBUG_H
#define EXECDEBUG_H
#include "executor/executor.h"
#include "nodes/print.h"
/* ----------------------------------------------------------------
* debugging defines.
*
* If you want certain debugging behaviour, then #define
* the variable to 1. No need to explicitly #undef by default,
* since we can use -D compiler options to enable features.
* - thomas 1999-02-20
* ----------------------------------------------------------------
*/
/* ----------------
* EXEC_NESTLOOPDEBUG is a flag which turns on debugging of the
* nest loop node by NL_printf() and ENL_printf() in nodeNestloop.c
* ----------------
#undef EXEC_NESTLOOPDEBUG
*/
/* ----------------
* EXEC_SORTDEBUG is a flag which turns on debugging of
* the ExecSort() stuff by SO_printf() in nodeSort.c
* ----------------
#undef EXEC_SORTDEBUG
*/
/* ----------------
* EXEC_MERGEJOINDEBUG is a flag which turns on debugging of
* the ExecMergeJoin() stuff by MJ_printf() in nodeMergejoin.c
* ----------------
#undef EXEC_MERGEJOINDEBUG
*/
/* ----------------------------------------------------------------
* #defines controlled by above definitions
*
* Note: most of these are "incomplete" because I didn't
* need the ones not defined. More should be added
* only as necessary -cim 10/26/89
* ----------------------------------------------------------------
*/
#define T_OR_F(b) ((b) ? "true" : "false")
#define NULL_OR_TUPLE(slot) (TupIsNull(slot) ? "null" : "a tuple")
/* ----------------
* nest loop debugging defines
* ----------------
*/
#ifdef EXEC_NESTLOOPDEBUG
#define NL_nodeDisplay(l) nodeDisplay(l)
#define NL_printf(s) printf(s)
#define NL1_printf(s, a) printf(s, a)
#define ENL1_printf(message) printf("ExecNestLoop: %s\n", message)
#else
#define NL_nodeDisplay(l)
#define NL_printf(s)
#define NL1_printf(s, a)
#define ENL1_printf(message)
#endif /* EXEC_NESTLOOPDEBUG */
/* ----------------
* sort node debugging defines
* ----------------
*/
#ifdef EXEC_SORTDEBUG
#define SO_nodeDisplay(l) nodeDisplay(l)
#define SO_printf(s) printf(s)
#define SO1_printf(s, p) printf(s, p)
#define SO2_printf(s, p1, p2) printf(s, p1, p2)
#else
#define SO_nodeDisplay(l)
#define SO_printf(s)
#define SO1_printf(s, p)
#define SO2_printf(s, p1, p2)
#endif /* EXEC_SORTDEBUG */
/* ----------------
* merge join debugging defines
* ----------------
*/
#ifdef EXEC_MERGEJOINDEBUG
#define MJ_nodeDisplay(l) nodeDisplay(l)
#define MJ_printf(s) printf(s)
#define MJ1_printf(s, p) printf(s, p)
#define MJ2_printf(s, p1, p2) printf(s, p1, p2)
#define MJ_debugtup(slot) debugtup(slot, NULL)
#define MJ_dump(state) ExecMergeTupleDump(state)
#define MJ_DEBUG_COMPARE(res) \
MJ1_printf(" MJCompare() returns %d\n", (res))
#define MJ_DEBUG_QUAL(clause, res) \
MJ2_printf(" ExecQual(%s, econtext) returns %s\n", \
CppAsString(clause), T_OR_F(res))
#define MJ_DEBUG_PROC_NODE(slot) \
MJ2_printf(" %s = ExecProcNode(...) returns %s\n", \
CppAsString(slot), NULL_OR_TUPLE(slot))
#else
#define MJ_nodeDisplay(l)
#define MJ_printf(s)
#define MJ1_printf(s, p)
#define MJ2_printf(s, p1, p2)
#define MJ_debugtup(slot)
#define MJ_dump(state)
#define MJ_DEBUG_COMPARE(res)
#define MJ_DEBUG_QUAL(clause, res)
#define MJ_DEBUG_PROC_NODE(slot)
#endif /* EXEC_MERGEJOINDEBUG */
#endif /* EXECDEBUG_H */

70
db_include/executor/execdesc.h Executable file
View File

@@ -0,0 +1,70 @@
/*-------------------------------------------------------------------------
*
* execdesc.h
* plan and query descriptor accessor macros used by the executor
* and related modules.
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/execdesc.h
*
*-------------------------------------------------------------------------
*/
#ifndef EXECDESC_H
#define EXECDESC_H
#include "nodes/execnodes.h"
#include "tcop/dest.h"
/* ----------------
* query descriptor:
*
* a QueryDesc encapsulates everything that the executor
* needs to execute the query.
*
* For the convenience of SQL-language functions, we also support QueryDescs
* containing utility statements; these must not be passed to the executor
* however.
* ---------------------
*/
typedef struct QueryDesc
{
/* These fields are provided by CreateQueryDesc */
CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */
PlannedStmt *plannedstmt; /* planner's output (could be utility, too) */
const char *sourceText; /* source text of the query */
Snapshot snapshot; /* snapshot to use for query */
Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */
DestReceiver *dest; /* the destination for tuple output */
ParamListInfo params; /* param values being passed in */
QueryEnvironment *queryEnv; /* query environment passed in */
int instrument_options; /* OR of InstrumentOption flags */
/* These fields are set by ExecutorStart */
TupleDesc tupDesc; /* descriptor for result tuples */
EState *estate; /* executor's query-wide state */
PlanState *planstate; /* tree of per-plan-node state */
/* This field is set by ExecutorRun */
bool already_executed; /* true if previously executed */
/* This is always set NULL by the core system, but plugins can change it */
struct Instrumentation *totaltime; /* total time spent in ExecutorRun */
} QueryDesc;
/* in pquery.c */
extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt,
const char *sourceText,
Snapshot snapshot,
Snapshot crosscheck_snapshot,
DestReceiver *dest,
ParamListInfo params,
QueryEnvironment *queryEnv,
int instrument_options);
extern void FreeQueryDesc(QueryDesc *qdesc);
#endif /* EXECDESC_H */

661
db_include/executor/executor.h Executable file
View File

@@ -0,0 +1,661 @@
/*-------------------------------------------------------------------------
*
* executor.h
* support for the POSTGRES executor module
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/executor.h
*
*-------------------------------------------------------------------------
*/
#ifndef EXECUTOR_H
#define EXECUTOR_H
#include "executor/execdesc.h"
#include "fmgr.h"
#include "nodes/lockoptions.h"
#include "nodes/parsenodes.h"
#include "utils/memutils.h"
/*
* The "eflags" argument to ExecutorStart and the various ExecInitNode
* routines is a bitwise OR of the following flag bits, which tell the
* called plan node what to expect. Note that the flags will get modified
* as they are passed down the plan tree, since an upper node may require
* functionality in its subnode not demanded of the plan as a whole
* (example: MergeJoin requires mark/restore capability in its inner input),
* or an upper node may shield its input from some functionality requirement
* (example: Materialize shields its input from needing to do backward scan).
*
* EXPLAIN_ONLY indicates that the plan tree is being initialized just so
* EXPLAIN can print it out; it will not be run. Hence, no side-effects
* of startup should occur. However, error checks (such as permission checks)
* should be performed.
*
* REWIND indicates that the plan node should try to efficiently support
* rescans without parameter changes. (Nodes must support ExecReScan calls
* in any case, but if this flag was not given, they are at liberty to do it
* through complete recalculation. Note that a parameter change forces a
* full recalculation in any case.)
*
* BACKWARD indicates that the plan node must respect the es_direction flag.
* When this is not passed, the plan node will only be run forwards.
*
* MARK indicates that the plan node must support Mark/Restore calls.
* When this is not passed, no Mark/Restore will occur.
*
* SKIP_TRIGGERS tells ExecutorStart/ExecutorFinish to skip calling
* AfterTriggerBeginQuery/AfterTriggerEndQuery. This does not necessarily
* mean that the plan can't queue any AFTER triggers; just that the caller
* is responsible for there being a trigger context for them to be queued in.
*/
#define EXEC_FLAG_EXPLAIN_ONLY 0x0001 /* EXPLAIN, no ANALYZE */
#define EXEC_FLAG_REWIND 0x0002 /* need efficient rescan */
#define EXEC_FLAG_BACKWARD 0x0004 /* need backward scan */
#define EXEC_FLAG_MARK 0x0008 /* need mark/restore */
#define EXEC_FLAG_SKIP_TRIGGERS 0x0010 /* skip AfterTrigger calls */
#define EXEC_FLAG_WITH_NO_DATA 0x0020 /* rel scannability doesn't matter */
/* Hook for plugins to get control in ExecutorStart() */
typedef void (*ExecutorStart_hook_type) (QueryDesc *queryDesc, int eflags);
extern PGDLLIMPORT ExecutorStart_hook_type ExecutorStart_hook;
/* Hook for plugins to get control in ExecutorRun() */
typedef void (*ExecutorRun_hook_type) (QueryDesc *queryDesc,
ScanDirection direction,
uint64 count,
bool execute_once);
extern PGDLLIMPORT ExecutorRun_hook_type ExecutorRun_hook;
/* Hook for plugins to get control in ExecutorFinish() */
typedef void (*ExecutorFinish_hook_type) (QueryDesc *queryDesc);
extern PGDLLIMPORT ExecutorFinish_hook_type ExecutorFinish_hook;
/* Hook for plugins to get control in ExecutorEnd() */
typedef void (*ExecutorEnd_hook_type) (QueryDesc *queryDesc);
extern PGDLLIMPORT ExecutorEnd_hook_type ExecutorEnd_hook;
/* Hook for plugins to get control in ExecCheckRTPerms() */
typedef bool (*ExecutorCheckPerms_hook_type) (List *, bool);
extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook;
/*
* prototypes from functions in execAmi.c
*/
struct Path; /* avoid including pathnodes.h here */
extern void ExecReScan(PlanState *node);
extern void ExecMarkPos(PlanState *node);
extern void ExecRestrPos(PlanState *node);
extern bool ExecSupportsMarkRestore(struct Path *pathnode);
extern bool ExecSupportsBackwardScan(Plan *node);
extern bool ExecMaterializesOutput(NodeTag plantype);
/*
* prototypes from functions in execCurrent.c
*/
extern bool execCurrentOf(CurrentOfExpr *cexpr,
ExprContext *econtext,
Oid table_oid,
ItemPointer current_tid);
/*
* prototypes from functions in execGrouping.c
*/
extern ExprState *execTuplesMatchPrepare(TupleDesc desc,
int numCols,
const AttrNumber *keyColIdx,
const Oid *eqOperators,
const Oid *collations,
PlanState *parent);
extern void execTuplesHashPrepare(int numCols,
const Oid *eqOperators,
Oid **eqFuncOids,
FmgrInfo **hashFunctions);
extern TupleHashTable BuildTupleHashTable(PlanState *parent,
TupleDesc inputDesc,
int numCols, AttrNumber *keyColIdx,
const Oid *eqfuncoids,
FmgrInfo *hashfunctions,
Oid *collations,
long nbuckets, Size additionalsize,
MemoryContext tablecxt,
MemoryContext tempcxt, bool use_variable_hash_iv);
extern TupleHashTable BuildTupleHashTableExt(PlanState *parent,
TupleDesc inputDesc,
int numCols, AttrNumber *keyColIdx,
const Oid *eqfuncoids,
FmgrInfo *hashfunctions,
Oid *collations,
long nbuckets, Size additionalsize,
MemoryContext metacxt,
MemoryContext tablecxt,
MemoryContext tempcxt, bool use_variable_hash_iv);
extern TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable,
TupleTableSlot *slot,
bool *isnew, uint32 *hash);
extern uint32 TupleHashTableHash(TupleHashTable hashtable,
TupleTableSlot *slot);
extern TupleHashEntry LookupTupleHashEntryHash(TupleHashTable hashtable,
TupleTableSlot *slot,
bool *isnew, uint32 hash);
extern TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable,
TupleTableSlot *slot,
ExprState *eqcomp,
FmgrInfo *hashfunctions);
extern void ResetTupleHashTable(TupleHashTable hashtable);
/*
* prototypes from functions in execJunk.c
*/
extern JunkFilter *ExecInitJunkFilter(List *targetList,
TupleTableSlot *slot);
extern JunkFilter *ExecInitJunkFilterConversion(List *targetList,
TupleDesc cleanTupType,
TupleTableSlot *slot);
extern AttrNumber ExecFindJunkAttribute(JunkFilter *junkfilter,
const char *attrName);
extern AttrNumber ExecFindJunkAttributeInTlist(List *targetlist,
const char *attrName);
extern TupleTableSlot *ExecFilterJunk(JunkFilter *junkfilter,
TupleTableSlot *slot);
/*
* ExecGetJunkAttribute
*
* Given a junk filter's input tuple (slot) and a junk attribute's number
* previously found by ExecFindJunkAttribute, extract & return the value and
* isNull flag of the attribute.
*/
#ifndef FRONTEND
static inline Datum
ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
{
Assert(attno > 0);
return slot_getattr(slot, attno, isNull);
}
#endif
/*
* prototypes from functions in execMain.c
*/
extern void ExecutorStart(QueryDesc *queryDesc, int eflags);
extern void standard_ExecutorStart(QueryDesc *queryDesc, int eflags);
extern void ExecutorRun(QueryDesc *queryDesc,
ScanDirection direction, uint64 count, bool execute_once);
extern void standard_ExecutorRun(QueryDesc *queryDesc,
ScanDirection direction, uint64 count, bool execute_once);
extern void ExecutorFinish(QueryDesc *queryDesc);
extern void standard_ExecutorFinish(QueryDesc *queryDesc);
extern void ExecutorEnd(QueryDesc *queryDesc);
extern void standard_ExecutorEnd(QueryDesc *queryDesc);
extern void ExecutorRewind(QueryDesc *queryDesc);
extern bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation);
extern void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation);
extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
Relation resultRelationDesc,
Index resultRelationIndex,
ResultRelInfo *partition_root_rri,
int instrument_options);
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate);
extern bool ExecPartitionCheck(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate, bool emitError);
extern void ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate);
extern void ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate);
extern LockTupleMode ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo);
extern ExecRowMark *ExecFindRowMark(EState *estate, Index rti, bool missing_ok);
extern ExecAuxRowMark *ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist);
extern TupleTableSlot *EvalPlanQual(EPQState *epqstate, Relation relation,
Index rti, TupleTableSlot *testslot);
extern void EvalPlanQualInit(EPQState *epqstate, EState *parentestate,
Plan *subplan, List *auxrowmarks, int epqParam);
extern void EvalPlanQualSetPlan(EPQState *epqstate,
Plan *subplan, List *auxrowmarks);
extern TupleTableSlot *EvalPlanQualSlot(EPQState *epqstate,
Relation relation, Index rti);
#define EvalPlanQualSetSlot(epqstate, slot) ((epqstate)->origslot = (slot))
extern bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot);
extern TupleTableSlot *EvalPlanQualNext(EPQState *epqstate);
extern void EvalPlanQualBegin(EPQState *epqstate);
extern void EvalPlanQualEnd(EPQState *epqstate);
/*
* functions in execProcnode.c
*/
extern PlanState *ExecInitNode(Plan *node, EState *estate, int eflags);
extern void ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function);
extern Node *MultiExecProcNode(PlanState *node);
extern void ExecEndNode(PlanState *node);
extern bool ExecShutdownNode(PlanState *node);
extern void ExecSetTupleBound(int64 tuples_needed, PlanState *child_node);
/* ----------------------------------------------------------------
* ExecProcNode
*
* Execute the given node to return a(nother) tuple.
* ----------------------------------------------------------------
*/
#ifndef FRONTEND
static inline TupleTableSlot *
ExecProcNode(PlanState *node)
{
if (node->chgParam != NULL) /* something changed? */
ExecReScan(node); /* let ReScan handle this */
return node->ExecProcNode(node);
}
#endif
/*
* prototypes from functions in execExpr.c
*/
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
extern ExprState *ExecInitExprWithParams(Expr *node, ParamListInfo ext_params);
extern ExprState *ExecInitQual(List *qual, PlanState *parent);
extern ExprState *ExecInitCheck(List *qual, PlanState *parent);
extern List *ExecInitExprList(List *nodes, PlanState *parent);
extern ExprState *ExecBuildAggTrans(AggState *aggstate, struct AggStatePerPhaseData *phase,
bool doSort, bool doHash, bool nullcheck);
extern ExprState *ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
const TupleTableSlotOps *lops, const TupleTableSlotOps *rops,
int numCols,
const AttrNumber *keyColIdx,
const Oid *eqfunctions,
const Oid *collations,
PlanState *parent);
extern ExprState *ExecBuildParamSetEqual(TupleDesc desc,
const TupleTableSlotOps *lops,
const TupleTableSlotOps *rops,
const Oid *eqfunctions,
const Oid *collations,
const List *param_exprs,
PlanState *parent);
extern ProjectionInfo *ExecBuildProjectionInfo(List *targetList,
ExprContext *econtext,
TupleTableSlot *slot,
PlanState *parent,
TupleDesc inputDesc);
extern ProjectionInfo *ExecBuildUpdateProjection(List *targetList,
bool evalTargetList,
List *targetColnos,
TupleDesc relDesc,
ExprContext *econtext,
TupleTableSlot *slot,
PlanState *parent);
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 ExecBuildProjectionInfo().
*
* 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_flags &= ~TTS_FLAG_EMPTY;
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
/*
* ExecQualAndReset() - evaluate qual with ExecQual() and reset expression
* context.
*/
#ifndef FRONTEND
static inline bool
ExecQualAndReset(ExprState *state, ExprContext *econtext)
{
bool ret = ExecQual(state, econtext);
/* inline ResetExprContext, to avoid ordering issue in this file */
MemoryContextReset(econtext->ecxt_per_tuple_memory);
return 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 SetExprState *ExecInitFunctionResultSet(Expr *expr,
ExprContext *econtext, PlanState *parent);
extern Datum ExecMakeFunctionResultSet(SetExprState *fcache,
ExprContext *econtext,
MemoryContext argContext,
bool *isNull,
ExprDoneCond *isDone);
/*
* prototypes from functions in execScan.c
*/
typedef TupleTableSlot *(*ExecScanAccessMtd) (ScanState *node);
typedef bool (*ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot);
extern TupleTableSlot *ExecScan(ScanState *node, ExecScanAccessMtd accessMtd,
ExecScanRecheckMtd recheckMtd);
extern void ExecAssignScanProjectionInfo(ScanState *node);
extern void ExecAssignScanProjectionInfoWithVarno(ScanState *node, Index varno);
extern void ExecScanReScan(ScanState *node);
/*
* prototypes from functions in execTuples.c
*/
extern void ExecInitResultTypeTL(PlanState *planstate);
extern void ExecInitResultSlot(PlanState *planstate,
const TupleTableSlotOps *tts_ops);
extern void ExecInitResultTupleSlotTL(PlanState *planstate,
const TupleTableSlotOps *tts_ops);
extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate,
TupleDesc tupleDesc,
const TupleTableSlotOps *tts_ops);
extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate,
TupleDesc tupledesc,
const TupleTableSlotOps *tts_ops);
extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate, TupleDesc tupType,
const TupleTableSlotOps *tts_ops);
extern TupleDesc ExecTypeFromTL(List *targetList);
extern TupleDesc ExecCleanTypeFromTL(List *targetList);
extern TupleDesc ExecTypeFromExprList(List *exprList);
extern void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList);
extern void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg);
typedef struct TupOutputState
{
TupleTableSlot *slot;
DestReceiver *dest;
} TupOutputState;
extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest,
TupleDesc tupdesc,
const TupleTableSlotOps *tts_ops);
extern void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull);
extern void do_text_output_multiline(TupOutputState *tstate, const char *txt);
extern void end_tup_output(TupOutputState *tstate);
/*
* Write a single line of text given as a C string.
*
* Should only be used with a single-TEXT-attribute tupdesc.
*/
#define do_text_output_oneline(tstate, str_to_emit) \
do { \
Datum values_[1]; \
bool isnull_[1]; \
values_[0] = PointerGetDatum(cstring_to_text(str_to_emit)); \
isnull_[0] = false; \
do_tup_output(tstate, values_, isnull_); \
pfree(DatumGetPointer(values_[0])); \
} while (0)
/*
* prototypes from functions in execUtils.c
*/
extern EState *CreateExecutorState(void);
extern void FreeExecutorState(EState *estate);
extern ExprContext *CreateExprContext(EState *estate);
extern ExprContext *CreateWorkExprContext(EState *estate);
extern ExprContext *CreateStandaloneExprContext(void);
extern void FreeExprContext(ExprContext *econtext, bool isCommit);
extern void ReScanExprContext(ExprContext *econtext);
#define ResetExprContext(econtext) \
MemoryContextReset((econtext)->ecxt_per_tuple_memory)
extern ExprContext *MakePerTupleExprContext(EState *estate);
/* Get an EState's per-output-tuple exprcontext, making it if first use */
#define GetPerTupleExprContext(estate) \
((estate)->es_per_tuple_exprcontext ? \
(estate)->es_per_tuple_exprcontext : \
MakePerTupleExprContext(estate))
#define GetPerTupleMemoryContext(estate) \
(GetPerTupleExprContext(estate)->ecxt_per_tuple_memory)
/* Reset an EState's per-output-tuple exprcontext, if one's been created */
#define ResetPerTupleExprContext(estate) \
do { \
if ((estate)->es_per_tuple_exprcontext) \
ResetExprContext((estate)->es_per_tuple_exprcontext); \
} while (0)
extern void ExecAssignExprContext(EState *estate, PlanState *planstate);
extern TupleDesc ExecGetResultType(PlanState *planstate);
extern const TupleTableSlotOps *ExecGetResultSlotOps(PlanState *planstate,
bool *isfixed);
extern void ExecAssignProjectionInfo(PlanState *planstate,
TupleDesc inputDesc);
extern void ExecConditionalAssignProjectionInfo(PlanState *planstate,
TupleDesc inputDesc, Index varno);
extern void ExecFreeExprContext(PlanState *planstate);
extern void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc);
extern void ExecCreateScanSlotFromOuterPlan(EState *estate,
ScanState *scanstate,
const TupleTableSlotOps *tts_ops);
extern bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid);
extern Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags);
extern void ExecInitRangeTable(EState *estate, List *rangeTable);
extern void ExecCloseRangeTableRelations(EState *estate);
extern void ExecCloseResultRelations(EState *estate);
static inline RangeTblEntry *
exec_rt_fetch(Index rti, EState *estate)
{
return (RangeTblEntry *) list_nth(estate->es_range_table, rti - 1);
}
extern Relation ExecGetRangeTableRelation(EState *estate, Index rti);
extern void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo,
Index rti);
extern int executor_errposition(EState *estate, int location);
extern void RegisterExprContextCallback(ExprContext *econtext,
ExprContextCallbackFunction function,
Datum arg);
extern void UnregisterExprContextCallback(ExprContext *econtext,
ExprContextCallbackFunction function,
Datum arg);
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);
extern TupleTableSlot *ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo);
extern TupleTableSlot *ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo);
extern TupleTableSlot *ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo);
extern TupleConversionMap *ExecGetChildToRootMap(ResultRelInfo *resultRelInfo);
extern Bitmapset *ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate);
extern Bitmapset *ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate);
extern Bitmapset *ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate);
extern Bitmapset *ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate);
/*
* prototypes from functions in execIndexing.c
*/
extern void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative);
extern void ExecCloseIndices(ResultRelInfo *resultRelInfo);
extern List *ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate,
bool update,
bool noDupErr,
bool *specConflict, List *arbiterIndexes);
extern bool ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot,
EState *estate, ItemPointer conflictTid,
List *arbiterIndexes);
extern void check_exclusion_constraint(Relation heap, Relation index,
IndexInfo *indexInfo,
ItemPointer tupleid,
Datum *values, bool *isnull,
EState *estate, bool newIndex);
/*
* prototypes from functions in execReplication.c
*/
extern bool RelationFindReplTupleByIndex(Relation rel, Oid idxoid,
LockTupleMode lockmode,
TupleTableSlot *searchslot,
TupleTableSlot *outslot);
extern bool RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode,
TupleTableSlot *searchslot, TupleTableSlot *outslot);
extern void ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo,
EState *estate, TupleTableSlot *slot);
extern void ExecSimpleRelationUpdate(ResultRelInfo *resultRelInfo,
EState *estate, EPQState *epqstate,
TupleTableSlot *searchslot, TupleTableSlot *slot);
extern void ExecSimpleRelationDelete(ResultRelInfo *resultRelInfo,
EState *estate, EPQState *epqstate,
TupleTableSlot *searchslot);
extern void CheckCmdReplicaIdentity(Relation rel, CmdType cmd);
extern void CheckSubscriptionRelkind(char relkind, const char *nspname,
const char *relname);
/*
* prototypes from functions in nodeModifyTable.c
*/
extern TupleTableSlot *ExecGetUpdateNewTuple(ResultRelInfo *relinfo,
TupleTableSlot *planSlot,
TupleTableSlot *oldSlot);
extern ResultRelInfo *ExecLookupResultRelByOid(ModifyTableState *node,
Oid resultoid,
bool missing_ok,
bool update_cache);
#endif /* EXECUTOR_H */

55
db_include/executor/functions.h Executable file
View File

@@ -0,0 +1,55 @@
/*-------------------------------------------------------------------------
*
* functions.h
* Declarations for execution of SQL-language functions.
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/functions.h
*
*-------------------------------------------------------------------------
*/
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#include "nodes/execnodes.h"
#include "tcop/dest.h"
/*
* Data structure needed by the parser callback hooks to resolve parameter
* references during parsing of a SQL function's body. This is separate from
* SQLFunctionCache since we sometimes do parsing separately from execution.
*/
typedef struct SQLFunctionParseInfo
{
char *fname; /* function's name */
int nargs; /* number of input arguments */
Oid *argtypes; /* resolved types of input arguments */
char **argnames; /* names of input arguments; NULL if none */
/* Note that argnames[i] can be NULL, if some args are unnamed */
Oid collation; /* function's input collation, if known */
} SQLFunctionParseInfo;
typedef SQLFunctionParseInfo *SQLFunctionParseInfoPtr;
extern Datum fmgr_sql(PG_FUNCTION_ARGS);
extern SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple,
Node *call_expr,
Oid inputCollation);
extern void sql_fn_parser_setup(struct ParseState *pstate,
SQLFunctionParseInfoPtr pinfo);
extern void check_sql_fn_statements(List *queryTreeLists);
extern bool check_sql_fn_retval(List *queryTreeLists,
Oid rettype, TupleDesc rettupdesc,
bool insertDroppedCols,
List **resultTargetList);
extern DestReceiver *CreateSQLFunctionDestReceiver(void);
#endif /* FUNCTIONS_H */

362
db_include/executor/hashjoin.h Executable file
View File

@@ -0,0 +1,362 @@
/*-------------------------------------------------------------------------
*
* hashjoin.h
* internal structures for hash joins
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/hashjoin.h
*
*-------------------------------------------------------------------------
*/
#ifndef HASHJOIN_H
#define HASHJOIN_H
#include "nodes/execnodes.h"
#include "port/atomics.h"
#include "storage/barrier.h"
#include "storage/buffile.h"
#include "storage/lwlock.h"
/* ----------------------------------------------------------------
* hash-join hash table structures
*
* Each active hashjoin has a HashJoinTable control block, which is
* palloc'd in the executor's per-query context. All other storage needed
* for the hashjoin is kept in private memory contexts, two for each hashjoin.
* This makes it easy and fast to release the storage when we don't need it
* anymore. (Exception: data associated with the temp files lives in the
* per-query context too, since we always call buffile.c in that context.)
*
* The hashtable contexts are made children of the per-query context, ensuring
* that they will be discarded at end of statement even if the join is
* aborted early by an error. (Likewise, any temporary files we make will
* be cleaned up by the virtual file manager in event of an error.)
*
* Storage that should live through the entire join is allocated from the
* "hashCxt", while storage that is only wanted for the current batch is
* allocated in the "batchCxt". By resetting the batchCxt at the end of
* each batch, we free all the per-batch storage reliably and without tedium.
*
* During first scan of inner relation, we get its tuples from executor.
* If nbatch > 1 then tuples that don't belong in first batch get saved
* into inner-batch temp files. The same statements apply for the
* first scan of the outer relation, except we write tuples to outer-batch
* temp files. After finishing the first scan, we do the following for
* each remaining batch:
* 1. Read tuples from inner batch file, load into hash buckets.
* 2. Read tuples from outer batch file, match to hash buckets and output.
*
* It is possible to increase nbatch on the fly if the in-memory hash table
* gets too big. The hash-value-to-batch computation is arranged so that this
* can only cause a tuple to go into a later batch than previously thought,
* never into an earlier batch. When we increase nbatch, we rescan the hash
* table and dump out any tuples that are now of a later batch to the correct
* inner batch file. Subsequently, while reading either inner or outer batch
* files, we might find tuples that no longer belong to the current batch;
* if so, we just dump them out to the correct batch file.
* ----------------------------------------------------------------
*/
/* these are in nodes/execnodes.h: */
/* typedef struct HashJoinTupleData *HashJoinTuple; */
/* typedef struct HashJoinTableData *HashJoinTable; */
typedef struct HashJoinTupleData
{
/* link to next tuple in same bucket */
union
{
struct HashJoinTupleData *unshared;
dsa_pointer shared;
} next;
uint32 hashvalue; /* tuple's hash code */
/* Tuple data, in MinimalTuple format, follows on a MAXALIGN boundary */
} HashJoinTupleData;
#define HJTUPLE_OVERHEAD MAXALIGN(sizeof(HashJoinTupleData))
#define HJTUPLE_MINTUPLE(hjtup) \
((MinimalTuple) ((char *) (hjtup) + HJTUPLE_OVERHEAD))
/*
* If the outer relation's distribution is sufficiently nonuniform, we attempt
* to optimize the join by treating the hash values corresponding to the outer
* relation's MCVs specially. Inner relation tuples matching these hash
* values go into the "skew" hashtable instead of the main hashtable, and
* outer relation tuples with these hash values are matched against that
* table instead of the main one. Thus, tuples with these hash values are
* effectively handled as part of the first batch and will never go to disk.
* The skew hashtable is limited to SKEW_HASH_MEM_PERCENT of the total memory
* allowed for the join; while building the hashtables, we decrease the number
* of MCVs being specially treated if needed to stay under this limit.
*
* Note: you might wonder why we look at the outer relation stats for this,
* rather than the inner. One reason is that the outer relation is typically
* bigger, so we get more I/O savings by optimizing for its most common values.
* Also, for similarly-sized relations, the planner prefers to put the more
* uniformly distributed relation on the inside, so we're more likely to find
* interesting skew in the outer relation.
*/
typedef struct HashSkewBucket
{
uint32 hashvalue; /* common hash value */
HashJoinTuple tuples; /* linked list of inner-relation tuples */
} HashSkewBucket;
#define SKEW_BUCKET_OVERHEAD MAXALIGN(sizeof(HashSkewBucket))
#define INVALID_SKEW_BUCKET_NO (-1)
#define SKEW_HASH_MEM_PERCENT 2
#define SKEW_MIN_OUTER_FRACTION 0.01
/*
* To reduce palloc overhead, the HashJoinTuples for the current batch are
* packed in 32kB buffers instead of pallocing each tuple individually.
*/
typedef struct HashMemoryChunkData
{
int ntuples; /* number of tuples stored in this chunk */
size_t maxlen; /* size of the chunk's tuple buffer */
size_t used; /* number of buffer bytes already used */
/* pointer to the next chunk (linked list) */
union
{
struct HashMemoryChunkData *unshared;
dsa_pointer shared;
} next;
/*
* The chunk's tuple buffer starts after the HashMemoryChunkData struct,
* at offset HASH_CHUNK_HEADER_SIZE (which must be maxaligned). Note that
* that offset is not included in "maxlen" or "used".
*/
} HashMemoryChunkData;
typedef struct HashMemoryChunkData *HashMemoryChunk;
#define HASH_CHUNK_SIZE (32 * 1024L)
#define HASH_CHUNK_HEADER_SIZE MAXALIGN(sizeof(HashMemoryChunkData))
#define HASH_CHUNK_DATA(hc) (((char *) (hc)) + HASH_CHUNK_HEADER_SIZE)
/* tuples exceeding HASH_CHUNK_THRESHOLD bytes are put in their own chunk */
#define HASH_CHUNK_THRESHOLD (HASH_CHUNK_SIZE / 4)
/*
* For each batch of a Parallel Hash Join, we have a ParallelHashJoinBatch
* object in shared memory to coordinate access to it. Since they are
* followed by variable-sized objects, they are arranged in contiguous memory
* but not accessed directly as an array.
*/
typedef struct ParallelHashJoinBatch
{
dsa_pointer buckets; /* array of hash table buckets */
Barrier batch_barrier; /* synchronization for joining this batch */
dsa_pointer chunks; /* chunks of tuples loaded */
size_t size; /* size of buckets + chunks in memory */
size_t estimated_size; /* size of buckets + chunks while writing */
size_t ntuples; /* number of tuples loaded */
size_t old_ntuples; /* number of tuples before repartitioning */
bool space_exhausted;
/*
* Variable-sized SharedTuplestore objects follow this struct in memory.
* See the accessor macros below.
*/
} ParallelHashJoinBatch;
/* Accessor for inner batch tuplestore following a ParallelHashJoinBatch. */
#define ParallelHashJoinBatchInner(batch) \
((SharedTuplestore *) \
((char *) (batch) + MAXALIGN(sizeof(ParallelHashJoinBatch))))
/* Accessor for outer batch tuplestore following a ParallelHashJoinBatch. */
#define ParallelHashJoinBatchOuter(batch, nparticipants) \
((SharedTuplestore *) \
((char *) ParallelHashJoinBatchInner(batch) + \
MAXALIGN(sts_estimate(nparticipants))))
/* Total size of a ParallelHashJoinBatch and tuplestores. */
#define EstimateParallelHashJoinBatch(hashtable) \
(MAXALIGN(sizeof(ParallelHashJoinBatch)) + \
MAXALIGN(sts_estimate((hashtable)->parallel_state->nparticipants)) * 2)
/* Accessor for the nth ParallelHashJoinBatch given the base. */
#define NthParallelHashJoinBatch(base, n) \
((ParallelHashJoinBatch *) \
((char *) (base) + \
EstimateParallelHashJoinBatch(hashtable) * (n)))
/*
* Each backend requires a small amount of per-batch state to interact with
* each ParallelHashJoinBatch.
*/
typedef struct ParallelHashJoinBatchAccessor
{
ParallelHashJoinBatch *shared; /* pointer to shared state */
/* Per-backend partial counters to reduce contention. */
size_t preallocated; /* pre-allocated space for this backend */
size_t ntuples; /* number of tuples */
size_t size; /* size of partition in memory */
size_t estimated_size; /* size of partition on disk */
size_t old_ntuples; /* how many tuples before repartitioning? */
bool at_least_one_chunk; /* has this backend allocated a chunk? */
bool done; /* flag to remember that a batch is done */
SharedTuplestoreAccessor *inner_tuples;
SharedTuplestoreAccessor *outer_tuples;
} ParallelHashJoinBatchAccessor;
/*
* While hashing the inner relation, any participant might determine that it's
* time to increase the number of buckets to reduce the load factor or batches
* to reduce the memory size. This is indicated by setting the growth flag to
* these values.
*/
typedef enum ParallelHashGrowth
{
/* The current dimensions are sufficient. */
PHJ_GROWTH_OK,
/* The load factor is too high, so we need to add buckets. */
PHJ_GROWTH_NEED_MORE_BUCKETS,
/* The memory budget would be exhausted, so we need to repartition. */
PHJ_GROWTH_NEED_MORE_BATCHES,
/* Repartitioning didn't help last time, so don't try to do that again. */
PHJ_GROWTH_DISABLED
} ParallelHashGrowth;
/*
* The shared state used to coordinate a Parallel Hash Join. This is stored
* in the DSM segment.
*/
typedef struct ParallelHashJoinState
{
dsa_pointer batches; /* array of ParallelHashJoinBatch */
dsa_pointer old_batches; /* previous generation during repartition */
int nbatch; /* number of batches now */
int old_nbatch; /* previous number of batches */
int nbuckets; /* number of buckets */
ParallelHashGrowth growth; /* control batch/bucket growth */
dsa_pointer chunk_work_queue; /* chunk work queue */
int nparticipants;
size_t space_allowed;
size_t total_tuples; /* total number of inner tuples */
LWLock lock; /* lock protecting the above */
Barrier build_barrier; /* synchronization for the build phases */
Barrier grow_batches_barrier;
Barrier grow_buckets_barrier;
pg_atomic_uint32 distributor; /* counter for load balancing */
SharedFileSet fileset; /* space for shared temporary files */
} ParallelHashJoinState;
/* The phases for building batches, used by build_barrier. */
#define PHJ_BUILD_ELECTING 0
#define PHJ_BUILD_ALLOCATING 1
#define PHJ_BUILD_HASHING_INNER 2
#define PHJ_BUILD_HASHING_OUTER 3
#define PHJ_BUILD_DONE 4
/* The phases for probing each batch, used by for batch_barrier. */
#define PHJ_BATCH_ELECTING 0
#define PHJ_BATCH_ALLOCATING 1
#define PHJ_BATCH_LOADING 2
#define PHJ_BATCH_PROBING 3
#define PHJ_BATCH_DONE 4
/* The phases of batch growth while hashing, for grow_batches_barrier. */
#define PHJ_GROW_BATCHES_ELECTING 0
#define PHJ_GROW_BATCHES_ALLOCATING 1
#define PHJ_GROW_BATCHES_REPARTITIONING 2
#define PHJ_GROW_BATCHES_DECIDING 3
#define PHJ_GROW_BATCHES_FINISHING 4
#define PHJ_GROW_BATCHES_PHASE(n) ((n) % 5) /* circular phases */
/* The phases of bucket growth while hashing, for grow_buckets_barrier. */
#define PHJ_GROW_BUCKETS_ELECTING 0
#define PHJ_GROW_BUCKETS_ALLOCATING 1
#define PHJ_GROW_BUCKETS_REINSERTING 2
#define PHJ_GROW_BUCKETS_PHASE(n) ((n) % 3) /* circular phases */
typedef struct HashJoinTableData
{
int nbuckets; /* # buckets in the in-memory hash table */
int log2_nbuckets; /* its log2 (nbuckets must be a power of 2) */
int nbuckets_original; /* # buckets when starting the first hash */
int nbuckets_optimal; /* optimal # buckets (per batch) */
int log2_nbuckets_optimal; /* log2(nbuckets_optimal) */
/* buckets[i] is head of list of tuples in i'th in-memory bucket */
union
{
/* unshared array is per-batch storage, as are all the tuples */
struct HashJoinTupleData **unshared;
/* shared array is per-query DSA area, as are all the tuples */
dsa_pointer_atomic *shared;
} buckets;
bool keepNulls; /* true to store unmatchable NULL tuples */
bool skewEnabled; /* are we using skew optimization? */
HashSkewBucket **skewBucket; /* hashtable of skew buckets */
int skewBucketLen; /* size of skewBucket array (a power of 2!) */
int nSkewBuckets; /* number of active skew buckets */
int *skewBucketNums; /* array indexes of active skew buckets */
int nbatch; /* number of batches */
int curbatch; /* current batch #; 0 during 1st pass */
int nbatch_original; /* nbatch when we started inner scan */
int nbatch_outstart; /* nbatch when we started outer scan */
bool growEnabled; /* flag to shut off nbatch increases */
double totalTuples; /* # tuples obtained from inner plan */
double partialTuples; /* # tuples obtained from inner plan by me */
double skewTuples; /* # tuples inserted into skew tuples */
/*
* These arrays are allocated for the life of the hash join, but only if
* nbatch > 1. A file is opened only when we first write a tuple into it
* (otherwise its pointer remains NULL). Note that the zero'th array
* elements never get used, since we will process rather than dump out any
* tuples of batch zero.
*/
BufFile **innerBatchFile; /* buffered virtual temp file per batch */
BufFile **outerBatchFile; /* buffered virtual temp file per batch */
/*
* Info about the datatype-specific hash functions for the datatypes being
* hashed. These are arrays of the same length as the number of hash join
* clauses (hash keys).
*/
FmgrInfo *outer_hashfunctions; /* lookup data for hash functions */
FmgrInfo *inner_hashfunctions; /* lookup data for hash functions */
bool *hashStrict; /* is each hash join operator strict? */
Oid *collations;
Size spaceUsed; /* memory space currently used by tuples */
Size spaceAllowed; /* upper limit for space used */
Size spacePeak; /* peak space used */
Size spaceUsedSkew; /* skew hash table's current space usage */
Size spaceAllowedSkew; /* upper limit for skew hashtable */
MemoryContext hashCxt; /* context for whole-hash-join storage */
MemoryContext batchCxt; /* context for this-batch-only storage */
/* used for dense allocation of tuples (into linked chunks) */
HashMemoryChunk chunks; /* one list for the whole batch */
/* Shared and private state for Parallel Hash. */
HashMemoryChunk current_chunk; /* this backend's current chunk */
dsa_area *area; /* DSA area to allocate memory from */
ParallelHashJoinState *parallel_state;
ParallelHashJoinBatchAccessor *batches;
dsa_pointer current_chunk_shared;
} HashJoinTableData;
#endif /* HASHJOIN_H */

116
db_include/executor/instrument.h Executable file
View File

@@ -0,0 +1,116 @@
/*-------------------------------------------------------------------------
*
* instrument.h
* definitions for run-time statistics collection
*
*
* Copyright (c) 2001-2021, PostgreSQL Global Development Group
*
* src/include/executor/instrument.h
*
*-------------------------------------------------------------------------
*/
#ifndef INSTRUMENT_H
#define INSTRUMENT_H
#include "portability/instr_time.h"
/*
* BufferUsage and WalUsage counters keep being incremented infinitely,
* i.e., must never be reset to zero, so that we can calculate how much
* the counters are incremented in an arbitrary period.
*/
typedef struct BufferUsage
{
int64 shared_blks_hit; /* # of shared buffer hits */
int64 shared_blks_read; /* # of shared disk blocks read */
int64 shared_blks_dirtied; /* # of shared blocks dirtied */
int64 shared_blks_written; /* # of shared disk blocks written */
int64 local_blks_hit; /* # of local buffer hits */
int64 local_blks_read; /* # of local disk blocks read */
int64 local_blks_dirtied; /* # of local blocks dirtied */
int64 local_blks_written; /* # of local disk blocks written */
int64 temp_blks_read; /* # of temp blocks read */
int64 temp_blks_written; /* # of temp blocks written */
instr_time blk_read_time; /* time spent reading */
instr_time blk_write_time; /* time spent writing */
} BufferUsage;
/*
* WalUsage tracks only WAL activity like WAL records generation that
* can be measured per query and is displayed by EXPLAIN command,
* pg_stat_statements extension, etc. It does not track other WAL activity
* like WAL writes that it's not worth measuring per query. That's tracked
* by WAL global statistics counters in WalStats, instead.
*/
typedef struct WalUsage
{
int64 wal_records; /* # of WAL records produced */
int64 wal_fpi; /* # of WAL full page images produced */
uint64 wal_bytes; /* size of WAL records produced */
} WalUsage;
/* Flag bits included in InstrAlloc's instrument_options bitmask */
typedef enum InstrumentOption
{
INSTRUMENT_TIMER = 1 << 0, /* needs timer (and row counts) */
INSTRUMENT_BUFFERS = 1 << 1, /* needs buffer usage */
INSTRUMENT_ROWS = 1 << 2, /* needs row count */
INSTRUMENT_WAL = 1 << 3, /* needs WAL usage */
INSTRUMENT_ALL = PG_INT32_MAX
} InstrumentOption;
typedef struct Instrumentation
{
/* Parameters set at node creation: */
bool need_timer; /* true if we need timer data */
bool need_bufusage; /* true if we need buffer usage data */
bool need_walusage; /* true if we need WAL usage data */
bool async_mode; /* true if node is in async mode */
/* Info about current plan cycle: */
bool running; /* true if we've completed first tuple */
instr_time starttime; /* start time of current iteration of node */
instr_time counter; /* accumulated runtime for this node */
double firsttuple; /* time for first tuple of this cycle */
double tuplecount; /* # of tuples emitted so far this cycle */
BufferUsage bufusage_start; /* buffer usage at start */
WalUsage walusage_start; /* WAL usage at start */
/* Accumulated statistics across all completed cycles: */
double startup; /* total startup time (in seconds) */
double total; /* total time (in seconds) */
double ntuples; /* total tuples produced */
double ntuples2; /* secondary node-specific tuple counter */
double nloops; /* # of run cycles for this node */
double nfiltered1; /* # of tuples removed by scanqual or joinqual */
double nfiltered2; /* # of tuples removed by "other" quals */
BufferUsage bufusage; /* total buffer usage */
WalUsage walusage; /* total WAL usage */
} Instrumentation;
typedef struct WorkerInstrumentation
{
int num_workers; /* # of structures that follow */
Instrumentation instrument[FLEXIBLE_ARRAY_MEMBER];
} WorkerInstrumentation;
extern PGDLLIMPORT BufferUsage pgBufferUsage;
extern PGDLLIMPORT WalUsage pgWalUsage;
extern Instrumentation *InstrAlloc(int n, int instrument_options,
bool async_mode);
extern void InstrInit(Instrumentation *instr, int instrument_options);
extern void InstrStartNode(Instrumentation *instr);
extern void InstrStopNode(Instrumentation *instr, double nTuples);
extern void InstrUpdateTupleCount(Instrumentation *instr, double nTuples);
extern void InstrEndLoop(Instrumentation *instr);
extern void InstrAggNode(Instrumentation *dst, Instrumentation *add);
extern void InstrStartParallelQuery(void);
extern void InstrEndParallelQuery(BufferUsage *bufusage, WalUsage *walusage);
extern void InstrAccumParallelQuery(BufferUsage *bufusage, WalUsage *walusage);
extern void BufferUsageAccumDiff(BufferUsage *dst,
const BufferUsage *add, const BufferUsage *sub);
extern void WalUsageAccumDiff(WalUsage *dst, const WalUsage *add,
const WalUsage *sub);
#endif /* INSTRUMENT_H */

333
db_include/executor/nodeAgg.h Executable file
View File

@@ -0,0 +1,333 @@
/*-------------------------------------------------------------------------
*
* nodeAgg.h
* prototypes for nodeAgg.c
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeAgg.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEAGG_H
#define NODEAGG_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
/*
* AggStatePerTransData - per aggregate state value information
*
* Working state for updating the aggregate's state value, by calling the
* transition function with an input row. This struct does not store the
* information needed to produce the final aggregate result from the transition
* state, that's stored in AggStatePerAggData instead. This separation allows
* multiple aggregate results to be produced from a single state value.
*/
typedef struct AggStatePerTransData
{
/*
* These values are set up during ExecInitAgg() and do not change
* thereafter:
*/
/*
* Link to an Aggref expr this state value is for.
*
* There can be multiple Aggref's sharing the same state value, so long as
* the inputs and transition functions are identical and the final
* functions are not read-write. This points to the first one of them.
*/
Aggref *aggref;
/*
* Is this state value actually being shared by more than one Aggref?
*/
bool aggshared;
/*
* Number of aggregated input columns. This includes ORDER BY expressions
* in both the plain-agg and ordered-set cases. Ordered-set direct args
* are not counted, though.
*/
int numInputs;
/*
* Number of aggregated input columns to pass to the transfn. This
* includes the ORDER BY columns for ordered-set aggs, but not for plain
* aggs. (This doesn't count the transition state value!)
*/
int numTransInputs;
/* Oid of the state transition or combine function */
Oid transfn_oid;
/* Oid of the serialization function or InvalidOid */
Oid serialfn_oid;
/* Oid of the deserialization function or InvalidOid */
Oid deserialfn_oid;
/* Oid of state value's datatype */
Oid aggtranstype;
/*
* fmgr lookup data for transition function or combine function. Note in
* particular that the fn_strict flag is kept here.
*/
FmgrInfo transfn;
/* fmgr lookup data for serialization function */
FmgrInfo serialfn;
/* fmgr lookup data for deserialization function */
FmgrInfo deserialfn;
/* Input collation derived for aggregate */
Oid aggCollation;
/* number of sorting columns */
int numSortCols;
/* number of sorting columns to consider in DISTINCT comparisons */
/* (this is either zero or the same as numSortCols) */
int numDistinctCols;
/* deconstructed sorting information (arrays of length numSortCols) */
AttrNumber *sortColIdx;
Oid *sortOperators;
Oid *sortCollations;
bool *sortNullsFirst;
/*
* Comparators for input columns --- only set/used when aggregate has
* DISTINCT flag. equalfnOne version is used for single-column
* comparisons, equalfnMulti for the case of multiple columns.
*/
FmgrInfo equalfnOne;
ExprState *equalfnMulti;
/*
* initial value from pg_aggregate entry
*/
Datum initValue;
bool initValueIsNull;
/*
* We need the len and byval info for the agg's input and transition data
* types in order to know how to copy/delete values.
*
* Note that the info for the input type is used only when handling
* DISTINCT aggs with just one argument, so there is only one input type.
*/
int16 inputtypeLen,
transtypeLen;
bool inputtypeByVal,
transtypeByVal;
/*
* Slots for holding the evaluated input arguments. These are set up
* during ExecInitAgg() and then used for each input row requiring either
* FILTER or ORDER BY/DISTINCT processing.
*/
TupleTableSlot *sortslot; /* current input tuple */
TupleTableSlot *uniqslot; /* used for multi-column DISTINCT */
TupleDesc sortdesc; /* descriptor of input tuples */
/*
* These values are working state that is initialized at the start of an
* input tuple group and updated for each input tuple.
*
* For a simple (non DISTINCT/ORDER BY) aggregate, we just feed the input
* values straight to the transition function. If it's DISTINCT or
* requires ORDER BY, we pass the input values into a Tuplesort object;
* then at completion of the input tuple group, we scan the sorted values,
* eliminate duplicates if needed, and run the transition function on the
* rest.
*
* We need a separate tuplesort for each grouping set.
*/
Tuplesortstate **sortstates; /* sort objects, if DISTINCT or ORDER BY */
/*
* This field is a pre-initialized FunctionCallInfo struct used for
* calling this aggregate's transfn. We save a few cycles per row by not
* re-initializing the unchanging fields; which isn't much, but it seems
* worth the extra space consumption.
*/
FunctionCallInfo transfn_fcinfo;
/* Likewise for serialization and deserialization functions */
FunctionCallInfo serialfn_fcinfo;
FunctionCallInfo deserialfn_fcinfo;
} AggStatePerTransData;
/*
* AggStatePerAggData - per-aggregate information
*
* This contains the information needed to call the final function, to produce
* a final aggregate result from the state value. If there are multiple
* identical Aggrefs in the query, they can all share the same per-agg data.
*
* These values are set up during ExecInitAgg() and do not change thereafter.
*/
typedef struct AggStatePerAggData
{
/*
* Link to an Aggref expr this state value is for.
*
* There can be multiple identical Aggref's sharing the same per-agg. This
* points to the first one of them.
*/
Aggref *aggref;
/* index to the state value which this agg should use */
int transno;
/* Optional Oid of final function (may be InvalidOid) */
Oid finalfn_oid;
/*
* fmgr lookup data for final function --- only valid when finalfn_oid is
* not InvalidOid.
*/
FmgrInfo finalfn;
/*
* Number of arguments to pass to the finalfn. This is always at least 1
* (the transition state value) plus any ordered-set direct args. If the
* finalfn wants extra args then we pass nulls corresponding to the
* aggregated input columns.
*/
int numFinalArgs;
/* ExprStates for any direct-argument expressions */
List *aggdirectargs;
/*
* We need the len and byval info for the agg's result data type in order
* to know how to copy/delete values.
*/
int16 resulttypeLen;
bool resulttypeByVal;
/*
* "shareable" is false if this agg cannot share state values with other
* aggregates because the final function is read-write.
*/
bool shareable;
} AggStatePerAggData;
/*
* AggStatePerGroupData - per-aggregate-per-group working state
*
* These values are working state that is initialized at the start of
* an input tuple group and updated for each input tuple.
*
* In AGG_PLAIN and AGG_SORTED modes, we have a single array of these
* structs (pointed to by aggstate->pergroup); we re-use the array for
* each input group, if it's AGG_SORTED mode. In AGG_HASHED mode, the
* hash table contains an array of these structs for each tuple group.
*
* Logically, the sortstate field belongs in this struct, but we do not
* keep it here for space reasons: we don't support DISTINCT aggregates
* in AGG_HASHED mode, so there's no reason to use up a pointer field
* in every entry of the hashtable.
*/
typedef struct AggStatePerGroupData
{
#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE 0
Datum transValue; /* current transition value */
#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL 1
bool transValueIsNull;
#define FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE 2
bool noTransValue; /* true if transValue not set yet */
/*
* Note: noTransValue initially has the same value as transValueIsNull,
* and if true both are cleared to false at the same time. They are not
* the same though: if transfn later returns a NULL, we want to keep that
* NULL and not auto-replace it with a later input value. Only the first
* non-NULL input will be auto-substituted.
*/
} AggStatePerGroupData;
/*
* AggStatePerPhaseData - per-grouping-set-phase state
*
* Grouping sets are divided into "phases", where a single phase can be
* processed in one pass over the input. If there is more than one phase, then
* at the end of input from the current phase, state is reset and another pass
* taken over the data which has been re-sorted in the mean time.
*
* Accordingly, each phase specifies a list of grouping sets and group clause
* information, plus each phase after the first also has a sort order.
*/
typedef struct AggStatePerPhaseData
{
AggStrategy aggstrategy; /* strategy for this phase */
int numsets; /* number of grouping sets (or 0) */
int *gset_lengths; /* lengths of grouping sets */
Bitmapset **grouped_cols; /* column groupings for rollup */
ExprState **eqfunctions; /* expression returning equality, indexed by
* nr of cols to compare */
Agg *aggnode; /* Agg node for phase data */
Sort *sortnode; /* Sort node for input ordering for phase */
ExprState *evaltrans; /* evaluation of transition functions */
/*----------
* Cached variants of the compiled expression.
* first subscript: 0: outerops; 1: TTSOpsMinimalTuple
* second subscript: 0: no NULL check; 1: with NULL check
*----------
*/
ExprState *evaltrans_cache[2][2];
} AggStatePerPhaseData;
/*
* AggStatePerHashData - per-hashtable state
*
* When doing grouping sets with hashing, we have one of these for each
* grouping set. (When doing hashing without grouping sets, we have just one of
* them.)
*/
typedef struct AggStatePerHashData
{
TupleHashTable hashtable; /* hash table with one entry per group */
TupleHashIterator hashiter; /* for iterating through hash table */
TupleTableSlot *hashslot; /* slot for loading hash table */
FmgrInfo *hashfunctions; /* per-grouping-field hash fns */
Oid *eqfuncoids; /* per-grouping-field equality fns */
int numCols; /* number of hash key columns */
int numhashGrpCols; /* number of columns in hash table */
int largestGrpColIdx; /* largest col required for hashing */
AttrNumber *hashGrpColIdxInput; /* hash col indices in input slot */
AttrNumber *hashGrpColIdxHash; /* indices in hash table tuples */
Agg *aggnode; /* original Agg node, for numGroups etc. */
} AggStatePerHashData;
extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags);
extern void ExecEndAgg(AggState *node);
extern void ExecReScanAgg(AggState *node);
extern Size hash_agg_entry_size(int numTrans, Size tupleWidth,
Size transitionSpace);
extern void hash_agg_set_limits(double hashentrysize, double input_groups,
int used_bits, Size *mem_limit,
uint64 *ngroups_limit, int *num_partitions);
/* parallel instrumentation support */
extern void ExecAggEstimate(AggState *node, ParallelContext *pcxt);
extern void ExecAggInitializeDSM(AggState *node, ParallelContext *pcxt);
extern void ExecAggInitializeWorker(AggState *node, ParallelWorkerContext *pwcxt);
extern void ExecAggRetrieveInstrumentation(AggState *node);
#endif /* NODEAGG_H */

View File

@@ -0,0 +1,30 @@
/*-------------------------------------------------------------------------
*
* nodeAppend.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeAppend.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEAPPEND_H
#define NODEAPPEND_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern AppendState *ExecInitAppend(Append *node, EState *estate, int eflags);
extern void ExecEndAppend(AppendState *node);
extern void ExecReScanAppend(AppendState *node);
extern void ExecAppendEstimate(AppendState *node, ParallelContext *pcxt);
extern void ExecAppendInitializeDSM(AppendState *node, ParallelContext *pcxt);
extern void ExecAppendReInitializeDSM(AppendState *node, ParallelContext *pcxt);
extern void ExecAppendInitializeWorker(AppendState *node, ParallelWorkerContext *pwcxt);
extern void ExecAsyncAppendResponse(AsyncRequest *areq);
#endif /* NODEAPPEND_H */

View File

@@ -0,0 +1,24 @@
/*-------------------------------------------------------------------------
*
* nodeBitmapAnd.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeBitmapAnd.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEBITMAPAND_H
#define NODEBITMAPAND_H
#include "nodes/execnodes.h"
extern BitmapAndState *ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags);
extern Node *MultiExecBitmapAnd(BitmapAndState *node);
extern void ExecEndBitmapAnd(BitmapAndState *node);
extern void ExecReScanBitmapAnd(BitmapAndState *node);
#endif /* NODEBITMAPAND_H */

View File

@@ -0,0 +1,32 @@
/*-------------------------------------------------------------------------
*
* nodeBitmapHeapscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeBitmapHeapscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEBITMAPHEAPSCAN_H
#define NODEBITMAPHEAPSCAN_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern BitmapHeapScanState *ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags);
extern void ExecEndBitmapHeapScan(BitmapHeapScanState *node);
extern void ExecReScanBitmapHeapScan(BitmapHeapScanState *node);
extern void ExecBitmapHeapEstimate(BitmapHeapScanState *node,
ParallelContext *pcxt);
extern void ExecBitmapHeapInitializeDSM(BitmapHeapScanState *node,
ParallelContext *pcxt);
extern void ExecBitmapHeapReInitializeDSM(BitmapHeapScanState *node,
ParallelContext *pcxt);
extern void ExecBitmapHeapInitializeWorker(BitmapHeapScanState *node,
ParallelWorkerContext *pwcxt);
#endif /* NODEBITMAPHEAPSCAN_H */

View File

@@ -0,0 +1,24 @@
/*-------------------------------------------------------------------------
*
* nodeBitmapIndexscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeBitmapIndexscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEBITMAPINDEXSCAN_H
#define NODEBITMAPINDEXSCAN_H
#include "nodes/execnodes.h"
extern BitmapIndexScanState *ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags);
extern Node *MultiExecBitmapIndexScan(BitmapIndexScanState *node);
extern void ExecEndBitmapIndexScan(BitmapIndexScanState *node);
extern void ExecReScanBitmapIndexScan(BitmapIndexScanState *node);
#endif /* NODEBITMAPINDEXSCAN_H */

View File

@@ -0,0 +1,24 @@
/*-------------------------------------------------------------------------
*
* nodeBitmapOr.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeBitmapOr.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEBITMAPOR_H
#define NODEBITMAPOR_H
#include "nodes/execnodes.h"
extern BitmapOrState *ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags);
extern Node *MultiExecBitmapOr(BitmapOrState *node);
extern void ExecEndBitmapOr(BitmapOrState *node);
extern void ExecReScanBitmapOr(BitmapOrState *node);
#endif /* NODEBITMAPOR_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeCtescan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeCtescan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODECTESCAN_H
#define NODECTESCAN_H
#include "nodes/execnodes.h"
extern CteScanState *ExecInitCteScan(CteScan *node, EState *estate, int eflags);
extern void ExecEndCteScan(CteScanState *node);
extern void ExecReScanCteScan(CteScanState *node);
#endif /* NODECTESCAN_H */

View File

@@ -0,0 +1,42 @@
/* ------------------------------------------------------------------------
*
* nodeCustom.h
*
* prototypes for CustomScan nodes
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* ------------------------------------------------------------------------
*/
#ifndef NODECUSTOM_H
#define NODECUSTOM_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
/*
* General executor code
*/
extern CustomScanState *ExecInitCustomScan(CustomScan *cscan,
EState *estate, int eflags);
extern void ExecEndCustomScan(CustomScanState *node);
extern void ExecReScanCustomScan(CustomScanState *node);
extern void ExecCustomMarkPos(CustomScanState *node);
extern void ExecCustomRestrPos(CustomScanState *node);
/*
* Parallel execution support
*/
extern void ExecCustomScanEstimate(CustomScanState *node,
ParallelContext *pcxt);
extern void ExecCustomScanInitializeDSM(CustomScanState *node,
ParallelContext *pcxt);
extern void ExecCustomScanReInitializeDSM(CustomScanState *node,
ParallelContext *pcxt);
extern void ExecCustomScanInitializeWorker(CustomScanState *node,
ParallelWorkerContext *pwcxt);
extern void ExecShutdownCustomScan(CustomScanState *node);
#endif /* NODECUSTOM_H */

View File

@@ -0,0 +1,38 @@
/*-------------------------------------------------------------------------
*
* nodeForeignscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeForeignscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEFOREIGNSCAN_H
#define NODEFOREIGNSCAN_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern ForeignScanState *ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags);
extern void ExecEndForeignScan(ForeignScanState *node);
extern void ExecReScanForeignScan(ForeignScanState *node);
extern void ExecForeignScanEstimate(ForeignScanState *node,
ParallelContext *pcxt);
extern void ExecForeignScanInitializeDSM(ForeignScanState *node,
ParallelContext *pcxt);
extern void ExecForeignScanReInitializeDSM(ForeignScanState *node,
ParallelContext *pcxt);
extern void ExecForeignScanInitializeWorker(ForeignScanState *node,
ParallelWorkerContext *pwcxt);
extern void ExecShutdownForeignScan(ForeignScanState *node);
extern void ExecAsyncForeignScanRequest(AsyncRequest *areq);
extern void ExecAsyncForeignScanConfigureWait(AsyncRequest *areq);
extern void ExecAsyncForeignScanNotify(AsyncRequest *areq);
#endif /* NODEFOREIGNSCAN_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeFunctionscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeFunctionscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEFUNCTIONSCAN_H
#define NODEFUNCTIONSCAN_H
#include "nodes/execnodes.h"
extern FunctionScanState *ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags);
extern void ExecEndFunctionScan(FunctionScanState *node);
extern void ExecReScanFunctionScan(FunctionScanState *node);
#endif /* NODEFUNCTIONSCAN_H */

View File

@@ -0,0 +1,24 @@
/*-------------------------------------------------------------------------
*
* nodeGather.h
* prototypes for nodeGather.c
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeGather.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEGATHER_H
#define NODEGATHER_H
#include "nodes/execnodes.h"
extern GatherState *ExecInitGather(Gather *node, EState *estate, int eflags);
extern void ExecEndGather(GatherState *node);
extern void ExecShutdownGather(GatherState *node);
extern void ExecReScanGather(GatherState *node);
#endif /* NODEGATHER_H */

View File

@@ -0,0 +1,26 @@
/*-------------------------------------------------------------------------
*
* nodeGatherMerge.h
* prototypes for nodeGatherMerge.c
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeGatherMerge.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEGATHERMERGE_H
#define NODEGATHERMERGE_H
#include "nodes/execnodes.h"
extern GatherMergeState *ExecInitGatherMerge(GatherMerge *node,
EState *estate,
int eflags);
extern void ExecEndGatherMerge(GatherMergeState *node);
extern void ExecReScanGatherMerge(GatherMergeState *node);
extern void ExecShutdownGatherMerge(GatherMergeState *node);
#endif /* NODEGATHERMERGE_H */

23
db_include/executor/nodeGroup.h Executable file
View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeGroup.h
* prototypes for nodeGroup.c
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeGroup.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEGROUP_H
#define NODEGROUP_H
#include "nodes/execnodes.h"
extern GroupState *ExecInitGroup(Group *node, EState *estate, int eflags);
extern void ExecEndGroup(GroupState *node);
extern void ExecReScanGroup(GroupState *node);
#endif /* NODEGROUP_H */

79
db_include/executor/nodeHash.h Executable file
View File

@@ -0,0 +1,79 @@
/*-------------------------------------------------------------------------
*
* nodeHash.h
* prototypes for nodeHash.c
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeHash.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEHASH_H
#define NODEHASH_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
struct SharedHashJoinBatch;
extern HashState *ExecInitHash(Hash *node, EState *estate, int eflags);
extern Node *MultiExecHash(HashState *node);
extern void ExecEndHash(HashState *node);
extern void ExecReScanHash(HashState *node);
extern HashJoinTable ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
bool keepNulls);
extern void ExecParallelHashTableAlloc(HashJoinTable hashtable,
int batchno);
extern void ExecHashTableDestroy(HashJoinTable hashtable);
extern void ExecHashTableDetach(HashJoinTable hashtable);
extern void ExecHashTableDetachBatch(HashJoinTable hashtable);
extern void ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable,
int batchno);
extern void ExecHashTableInsert(HashJoinTable hashtable,
TupleTableSlot *slot,
uint32 hashvalue);
extern void ExecParallelHashTableInsert(HashJoinTable hashtable,
TupleTableSlot *slot,
uint32 hashvalue);
extern void ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable,
TupleTableSlot *slot,
uint32 hashvalue);
extern bool ExecHashGetHashValue(HashJoinTable hashtable,
ExprContext *econtext,
List *hashkeys,
bool outer_tuple,
bool keep_nulls,
uint32 *hashvalue);
extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
uint32 hashvalue,
int *bucketno,
int *batchno);
extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
ExprContext *econtext);
extern void ExecHashTableReset(HashJoinTable hashtable);
extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
bool try_combined_hash_mem,
int parallel_workers,
size_t *space_allowed,
int *numbuckets,
int *numbatches,
int *num_skew_mcvs);
extern int ExecHashGetSkewBucket(HashJoinTable hashtable, uint32 hashvalue);
extern void ExecHashEstimate(HashState *node, ParallelContext *pcxt);
extern void ExecHashInitializeDSM(HashState *node, ParallelContext *pcxt);
extern void ExecHashInitializeWorker(HashState *node, ParallelWorkerContext *pwcxt);
extern void ExecHashRetrieveInstrumentation(HashState *node);
extern void ExecShutdownHash(HashState *node);
extern void ExecHashAccumInstrumentation(HashInstrumentation *instrument,
HashJoinTable hashtable);
#endif /* NODEHASH_H */

View File

@@ -0,0 +1,34 @@
/*-------------------------------------------------------------------------
*
* nodeHashjoin.h
* prototypes for nodeHashjoin.c
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeHashjoin.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEHASHJOIN_H
#define NODEHASHJOIN_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
#include "storage/buffile.h"
extern HashJoinState *ExecInitHashJoin(HashJoin *node, EState *estate, int eflags);
extern void ExecEndHashJoin(HashJoinState *node);
extern void ExecReScanHashJoin(HashJoinState *node);
extern void ExecShutdownHashJoin(HashJoinState *node);
extern void ExecHashJoinEstimate(HashJoinState *state, ParallelContext *pcxt);
extern void ExecHashJoinInitializeDSM(HashJoinState *state, ParallelContext *pcxt);
extern void ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *pcxt);
extern void ExecHashJoinInitializeWorker(HashJoinState *state,
ParallelWorkerContext *pwcxt);
extern void ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue,
BufFile **fileptr);
#endif /* NODEHASHJOIN_H */

View File

@@ -0,0 +1,28 @@
/*-------------------------------------------------------------------------
*
* nodeIncrementalSort.h
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeIncrementalSort.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEINCREMENTALSORT_H
#define NODEINCREMENTALSORT_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern IncrementalSortState *ExecInitIncrementalSort(IncrementalSort *node, EState *estate, int eflags);
extern void ExecEndIncrementalSort(IncrementalSortState *node);
extern void ExecReScanIncrementalSort(IncrementalSortState *node);
/* parallel instrumentation support */
extern void ExecIncrementalSortEstimate(IncrementalSortState *node, ParallelContext *pcxt);
extern void ExecIncrementalSortInitializeDSM(IncrementalSortState *node, ParallelContext *pcxt);
extern void ExecIncrementalSortInitializeWorker(IncrementalSortState *node, ParallelWorkerContext *pcxt);
extern void ExecIncrementalSortRetrieveInstrumentation(IncrementalSortState *node);
#endif /* NODEINCREMENTALSORT_H */

View File

@@ -0,0 +1,36 @@
/*-------------------------------------------------------------------------
*
* nodeIndexonlyscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeIndexonlyscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEINDEXONLYSCAN_H
#define NODEINDEXONLYSCAN_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern IndexOnlyScanState *ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags);
extern void ExecEndIndexOnlyScan(IndexOnlyScanState *node);
extern void ExecIndexOnlyMarkPos(IndexOnlyScanState *node);
extern void ExecIndexOnlyRestrPos(IndexOnlyScanState *node);
extern void ExecReScanIndexOnlyScan(IndexOnlyScanState *node);
/* Support functions for parallel index-only scans */
extern void ExecIndexOnlyScanEstimate(IndexOnlyScanState *node,
ParallelContext *pcxt);
extern void ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState *node,
ParallelContext *pcxt);
extern void ExecIndexOnlyScanReInitializeDSM(IndexOnlyScanState *node,
ParallelContext *pcxt);
extern void ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState *node,
ParallelWorkerContext *pwcxt);
#endif /* NODEINDEXONLYSCAN_H */

View File

@@ -0,0 +1,47 @@
/*-------------------------------------------------------------------------
*
* nodeIndexscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeIndexscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEINDEXSCAN_H
#define NODEINDEXSCAN_H
#include "access/genam.h"
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern IndexScanState *ExecInitIndexScan(IndexScan *node, EState *estate, int eflags);
extern void ExecEndIndexScan(IndexScanState *node);
extern void ExecIndexMarkPos(IndexScanState *node);
extern void ExecIndexRestrPos(IndexScanState *node);
extern void ExecReScanIndexScan(IndexScanState *node);
extern void ExecIndexScanEstimate(IndexScanState *node, ParallelContext *pcxt);
extern void ExecIndexScanInitializeDSM(IndexScanState *node, ParallelContext *pcxt);
extern void ExecIndexScanReInitializeDSM(IndexScanState *node, ParallelContext *pcxt);
extern void ExecIndexScanInitializeWorker(IndexScanState *node,
ParallelWorkerContext *pwcxt);
/*
* These routines are exported to share code with nodeIndexonlyscan.c and
* nodeBitmapIndexscan.c
*/
extern void ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
List *quals, bool isorderby,
ScanKey *scanKeys, int *numScanKeys,
IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys,
IndexArrayKeyInfo **arrayKeys, int *numArrayKeys);
extern void ExecIndexEvalRuntimeKeys(ExprContext *econtext,
IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys);
extern bool ExecIndexEvalArrayKeys(ExprContext *econtext,
IndexArrayKeyInfo *arrayKeys, int numArrayKeys);
extern bool ExecIndexAdvanceArrayKeys(IndexArrayKeyInfo *arrayKeys, int numArrayKeys);
#endif /* NODEINDEXSCAN_H */

23
db_include/executor/nodeLimit.h Executable file
View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeLimit.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeLimit.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODELIMIT_H
#define NODELIMIT_H
#include "nodes/execnodes.h"
extern LimitState *ExecInitLimit(Limit *node, EState *estate, int eflags);
extern void ExecEndLimit(LimitState *node);
extern void ExecReScanLimit(LimitState *node);
#endif /* NODELIMIT_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeLockRows.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeLockRows.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODELOCKROWS_H
#define NODELOCKROWS_H
#include "nodes/execnodes.h"
extern LockRowsState *ExecInitLockRows(LockRows *node, EState *estate, int eflags);
extern void ExecEndLockRows(LockRowsState *node);
extern void ExecReScanLockRows(LockRowsState *node);
#endif /* NODELOCKROWS_H */

View File

@@ -0,0 +1,25 @@
/*-------------------------------------------------------------------------
*
* nodeMaterial.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeMaterial.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEMATERIAL_H
#define NODEMATERIAL_H
#include "nodes/execnodes.h"
extern MaterialState *ExecInitMaterial(Material *node, EState *estate, int eflags);
extern void ExecEndMaterial(MaterialState *node);
extern void ExecMaterialMarkPos(MaterialState *node);
extern void ExecMaterialRestrPos(MaterialState *node);
extern void ExecReScanMaterial(MaterialState *node);
#endif /* NODEMATERIAL_H */

View File

@@ -0,0 +1,32 @@
/*-------------------------------------------------------------------------
*
* nodeMemoize.h
*
*
*
* Portions Copyright (c) 2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeMemoize.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEMEMOIZE_H
#define NODEMEMOIZE_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern MemoizeState *ExecInitMemoize(Memoize *node, EState *estate, int eflags);
extern void ExecEndMemoize(MemoizeState *node);
extern void ExecReScanMemoize(MemoizeState *node);
extern double ExecEstimateCacheEntryOverheadBytes(double ntuples);
extern void ExecMemoizeEstimate(MemoizeState *node,
ParallelContext *pcxt);
extern void ExecMemoizeInitializeDSM(MemoizeState *node,
ParallelContext *pcxt);
extern void ExecMemoizeInitializeWorker(MemoizeState *node,
ParallelWorkerContext *pwcxt);
extern void ExecMemoizeRetrieveInstrumentation(MemoizeState *node);
#endif /* NODEMEMOIZE_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeMergeAppend.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeMergeAppend.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEMERGEAPPEND_H
#define NODEMERGEAPPEND_H
#include "nodes/execnodes.h"
extern MergeAppendState *ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags);
extern void ExecEndMergeAppend(MergeAppendState *node);
extern void ExecReScanMergeAppend(MergeAppendState *node);
#endif /* NODEMERGEAPPEND_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeMergejoin.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeMergejoin.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEMERGEJOIN_H
#define NODEMERGEJOIN_H
#include "nodes/execnodes.h"
extern MergeJoinState *ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags);
extern void ExecEndMergeJoin(MergeJoinState *node);
extern void ExecReScanMergeJoin(MergeJoinState *node);
#endif /* NODEMERGEJOIN_H */

View File

@@ -0,0 +1,26 @@
/*-------------------------------------------------------------------------
*
* nodeModifyTable.h
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeModifyTable.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEMODIFYTABLE_H
#define NODEMODIFYTABLE_H
#include "nodes/execnodes.h"
extern void ExecComputeStoredGenerated(ResultRelInfo *resultRelInfo,
EState *estate, TupleTableSlot *slot,
CmdType cmdtype);
extern ModifyTableState *ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags);
extern void ExecEndModifyTable(ModifyTableState *node);
extern void ExecReScanModifyTable(ModifyTableState *node);
#endif /* NODEMODIFYTABLE_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeNamedtuplestorescan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeNamedtuplestorescan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODENAMEDTUPLESTORESCAN_H
#define NODENAMEDTUPLESTORESCAN_H
#include "nodes/execnodes.h"
extern NamedTuplestoreScanState *ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags);
extern void ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node);
extern void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node);
#endif /* NODENAMEDTUPLESTORESCAN_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeNestloop.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeNestloop.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODENESTLOOP_H
#define NODENESTLOOP_H
#include "nodes/execnodes.h"
extern NestLoopState *ExecInitNestLoop(NestLoop *node, EState *estate, int eflags);
extern void ExecEndNestLoop(NestLoopState *node);
extern void ExecReScanNestLoop(NestLoopState *node);
#endif /* NODENESTLOOP_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeProjectSet.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeProjectSet.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEPROJECTSET_H
#define NODEPROJECTSET_H
#include "nodes/execnodes.h"
extern ProjectSetState *ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags);
extern void ExecEndProjectSet(ProjectSetState *node);
extern void ExecReScanProjectSet(ProjectSetState *node);
#endif /* NODEPROJECTSET_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeRecursiveunion.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeRecursiveunion.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODERECURSIVEUNION_H
#define NODERECURSIVEUNION_H
#include "nodes/execnodes.h"
extern RecursiveUnionState *ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags);
extern void ExecEndRecursiveUnion(RecursiveUnionState *node);
extern void ExecReScanRecursiveUnion(RecursiveUnionState *node);
#endif /* NODERECURSIVEUNION_H */

View File

@@ -0,0 +1,25 @@
/*-------------------------------------------------------------------------
*
* nodeResult.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeResult.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODERESULT_H
#define NODERESULT_H
#include "nodes/execnodes.h"
extern ResultState *ExecInitResult(Result *node, EState *estate, int eflags);
extern void ExecEndResult(ResultState *node);
extern void ExecResultMarkPos(ResultState *node);
extern void ExecResultRestrPos(ResultState *node);
extern void ExecReScanResult(ResultState *node);
#endif /* NODERESULT_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeSamplescan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeSamplescan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODESAMPLESCAN_H
#define NODESAMPLESCAN_H
#include "nodes/execnodes.h"
extern SampleScanState *ExecInitSampleScan(SampleScan *node, EState *estate, int eflags);
extern void ExecEndSampleScan(SampleScanState *node);
extern void ExecReScanSampleScan(SampleScanState *node);
#endif /* NODESAMPLESCAN_H */

View File

@@ -0,0 +1,31 @@
/*-------------------------------------------------------------------------
*
* nodeSeqscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeSeqscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODESEQSCAN_H
#define NODESEQSCAN_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern SeqScanState *ExecInitSeqScan(SeqScan *node, EState *estate, int eflags);
extern void ExecEndSeqScan(SeqScanState *node);
extern void ExecReScanSeqScan(SeqScanState *node);
/* parallel scan support */
extern void ExecSeqScanEstimate(SeqScanState *node, ParallelContext *pcxt);
extern void ExecSeqScanInitializeDSM(SeqScanState *node, ParallelContext *pcxt);
extern void ExecSeqScanReInitializeDSM(SeqScanState *node, ParallelContext *pcxt);
extern void ExecSeqScanInitializeWorker(SeqScanState *node,
ParallelWorkerContext *pwcxt);
#endif /* NODESEQSCAN_H */

23
db_include/executor/nodeSetOp.h Executable file
View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeSetOp.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeSetOp.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODESETOP_H
#define NODESETOP_H
#include "nodes/execnodes.h"
extern SetOpState *ExecInitSetOp(SetOp *node, EState *estate, int eflags);
extern void ExecEndSetOp(SetOpState *node);
extern void ExecReScanSetOp(SetOpState *node);
#endif /* NODESETOP_H */

32
db_include/executor/nodeSort.h Executable file
View File

@@ -0,0 +1,32 @@
/*-------------------------------------------------------------------------
*
* nodeSort.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeSort.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODESORT_H
#define NODESORT_H
#include "access/parallel.h"
#include "nodes/execnodes.h"
extern SortState *ExecInitSort(Sort *node, EState *estate, int eflags);
extern void ExecEndSort(SortState *node);
extern void ExecSortMarkPos(SortState *node);
extern void ExecSortRestrPos(SortState *node);
extern void ExecReScanSort(SortState *node);
/* parallel instrumentation support */
extern void ExecSortEstimate(SortState *node, ParallelContext *pcxt);
extern void ExecSortInitializeDSM(SortState *node, ParallelContext *pcxt);
extern void ExecSortInitializeWorker(SortState *node, ParallelWorkerContext *pwcxt);
extern void ExecSortRetrieveInstrumentation(SortState *node);
#endif /* NODESORT_H */

View File

@@ -0,0 +1,29 @@
/*-------------------------------------------------------------------------
*
* nodeSubplan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeSubplan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODESUBPLAN_H
#define NODESUBPLAN_H
#include "nodes/execnodes.h"
extern SubPlanState *ExecInitSubPlan(SubPlan *subplan, PlanState *parent);
extern Datum ExecSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull);
extern void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent);
extern void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext);
extern void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext);
#endif /* NODESUBPLAN_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeSubqueryscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeSubqueryscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODESUBQUERYSCAN_H
#define NODESUBQUERYSCAN_H
#include "nodes/execnodes.h"
extern SubqueryScanState *ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags);
extern void ExecEndSubqueryScan(SubqueryScanState *node);
extern void ExecReScanSubqueryScan(SubqueryScanState *node);
#endif /* NODESUBQUERYSCAN_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeTableFuncscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeTableFuncscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODETABLEFUNCSCAN_H
#define NODETABLEFUNCSCAN_H
#include "nodes/execnodes.h"
extern TableFuncScanState *ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags);
extern void ExecEndTableFuncScan(TableFuncScanState *node);
extern void ExecReScanTableFuncScan(TableFuncScanState *node);
#endif /* NODETABLEFUNCSCAN_H */

View File

@@ -0,0 +1,24 @@
/*-------------------------------------------------------------------------
*
* nodeTidrangescan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeTidrangescan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODETIDRANGESCAN_H
#define NODETIDRANGESCAN_H
#include "nodes/execnodes.h"
extern TidRangeScanState *ExecInitTidRangeScan(TidRangeScan *node,
EState *estate, int eflags);
extern void ExecEndTidRangeScan(TidRangeScanState *node);
extern void ExecReScanTidRangeScan(TidRangeScanState *node);
#endif /* NODETIDRANGESCAN_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeTidscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeTidscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODETIDSCAN_H
#define NODETIDSCAN_H
#include "nodes/execnodes.h"
extern TidScanState *ExecInitTidScan(TidScan *node, EState *estate, int eflags);
extern void ExecEndTidScan(TidScanState *node);
extern void ExecReScanTidScan(TidScanState *node);
#endif /* NODETIDSCAN_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeUnique.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeUnique.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEUNIQUE_H
#define NODEUNIQUE_H
#include "nodes/execnodes.h"
extern UniqueState *ExecInitUnique(Unique *node, EState *estate, int eflags);
extern void ExecEndUnique(UniqueState *node);
extern void ExecReScanUnique(UniqueState *node);
#endif /* NODEUNIQUE_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeValuesscan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeValuesscan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEVALUESSCAN_H
#define NODEVALUESSCAN_H
#include "nodes/execnodes.h"
extern ValuesScanState *ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags);
extern void ExecEndValuesScan(ValuesScanState *node);
extern void ExecReScanValuesScan(ValuesScanState *node);
#endif /* NODEVALUESSCAN_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeWindowAgg.h
* prototypes for nodeWindowAgg.c
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeWindowAgg.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEWINDOWAGG_H
#define NODEWINDOWAGG_H
#include "nodes/execnodes.h"
extern WindowAggState *ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags);
extern void ExecEndWindowAgg(WindowAggState *node);
extern void ExecReScanWindowAgg(WindowAggState *node);
#endif /* NODEWINDOWAGG_H */

View File

@@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeWorktablescan.h
*
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/nodeWorktablescan.h
*
*-------------------------------------------------------------------------
*/
#ifndef NODEWORKTABLESCAN_H
#define NODEWORKTABLESCAN_H
#include "nodes/execnodes.h"
extern WorkTableScanState *ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags);
extern void ExecEndWorkTableScan(WorkTableScanState *node);
extern void ExecReScanWorkTableScan(WorkTableScanState *node);
#endif /* NODEWORKTABLESCAN_H */

213
db_include/executor/spi.h Executable file
View File

@@ -0,0 +1,213 @@
/*-------------------------------------------------------------------------
*
* spi.h
* Server Programming Interface public declarations
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/spi.h
*
*-------------------------------------------------------------------------
*/
#ifndef SPI_H
#define SPI_H
#include "commands/trigger.h"
#include "lib/ilist.h"
#include "parser/parser.h"
#include "utils/portal.h"
typedef struct SPITupleTable
{
/* Public members */
TupleDesc tupdesc; /* tuple descriptor */
HeapTuple *vals; /* array of tuples */
uint64 numvals; /* number of valid tuples */
/* Private members, not intended for external callers */
uint64 alloced; /* allocated length of vals array */
MemoryContext tuptabcxt; /* memory context of result table */
slist_node next; /* link for internal bookkeeping */
SubTransactionId subid; /* subxact in which tuptable was created */
} SPITupleTable;
/* Optional arguments for SPI_prepare_extended */
typedef struct SPIPrepareOptions
{
ParserSetupHook parserSetup;
void *parserSetupArg;
RawParseMode parseMode;
int cursorOptions;
} SPIPrepareOptions;
/* Optional arguments for SPI_execute[_plan]_extended */
typedef struct SPIExecuteOptions
{
ParamListInfo params;
bool read_only;
bool allow_nonatomic;
bool must_return_tuples;
uint64 tcount;
DestReceiver *dest;
ResourceOwner owner;
} SPIExecuteOptions;
/* Optional arguments for SPI_cursor_parse_open */
typedef struct SPIParseOpenOptions
{
ParamListInfo params;
int cursorOptions;
bool read_only;
} SPIParseOpenOptions;
/* Plans are opaque structs for standard users of SPI */
typedef struct _SPI_plan *SPIPlanPtr;
#define SPI_ERROR_CONNECT (-1)
#define SPI_ERROR_COPY (-2)
#define SPI_ERROR_OPUNKNOWN (-3)
#define SPI_ERROR_UNCONNECTED (-4)
#define SPI_ERROR_CURSOR (-5) /* not used anymore */
#define SPI_ERROR_ARGUMENT (-6)
#define SPI_ERROR_PARAM (-7)
#define SPI_ERROR_TRANSACTION (-8)
#define SPI_ERROR_NOATTRIBUTE (-9)
#define SPI_ERROR_NOOUTFUNC (-10)
#define SPI_ERROR_TYPUNKNOWN (-11)
#define SPI_ERROR_REL_DUPLICATE (-12)
#define SPI_ERROR_REL_NOT_FOUND (-13)
#define SPI_OK_CONNECT 1
#define SPI_OK_FINISH 2
#define SPI_OK_FETCH 3
#define SPI_OK_UTILITY 4
#define SPI_OK_SELECT 5
#define SPI_OK_SELINTO 6
#define SPI_OK_INSERT 7
#define SPI_OK_DELETE 8
#define SPI_OK_UPDATE 9
#define SPI_OK_CURSOR 10
#define SPI_OK_INSERT_RETURNING 11
#define SPI_OK_DELETE_RETURNING 12
#define SPI_OK_UPDATE_RETURNING 13
#define SPI_OK_REWRITTEN 14
#define SPI_OK_REL_REGISTER 15
#define SPI_OK_REL_UNREGISTER 16
#define SPI_OK_TD_REGISTER 17
#define SPI_OPT_NONATOMIC (1 << 0)
/* These used to be functions, now just no-ops for backwards compatibility */
#define SPI_push() ((void) 0)
#define SPI_pop() ((void) 0)
#define SPI_push_conditional() false
#define SPI_pop_conditional(pushed) ((void) 0)
#define SPI_restore_connection() ((void) 0)
extern PGDLLIMPORT uint64 SPI_processed;
extern PGDLLIMPORT SPITupleTable *SPI_tuptable;
extern PGDLLIMPORT int SPI_result;
extern int SPI_connect(void);
extern int SPI_connect_ext(int options);
extern int SPI_finish(void);
extern int SPI_execute(const char *src, bool read_only, long tcount);
extern int SPI_execute_extended(const char *src,
const SPIExecuteOptions *options);
extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls,
bool read_only, long tcount);
extern int SPI_execute_plan_extended(SPIPlanPtr plan,
const SPIExecuteOptions *options);
extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan,
ParamListInfo params,
bool read_only, long tcount);
extern int SPI_exec(const char *src, long tcount);
extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls,
long tcount);
extern int SPI_execute_snapshot(SPIPlanPtr plan,
Datum *Values, const char *Nulls,
Snapshot snapshot,
Snapshot crosscheck_snapshot,
bool read_only, bool fire_triggers, long tcount);
extern int SPI_execute_with_args(const char *src,
int nargs, Oid *argtypes,
Datum *Values, const char *Nulls,
bool read_only, long tcount);
extern SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes);
extern SPIPlanPtr SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes,
int cursorOptions);
extern SPIPlanPtr SPI_prepare_extended(const char *src,
const SPIPrepareOptions *options);
extern SPIPlanPtr SPI_prepare_params(const char *src,
ParserSetupHook parserSetup,
void *parserSetupArg,
int cursorOptions);
extern int SPI_keepplan(SPIPlanPtr plan);
extern SPIPlanPtr SPI_saveplan(SPIPlanPtr plan);
extern int SPI_freeplan(SPIPlanPtr plan);
extern Oid SPI_getargtypeid(SPIPlanPtr plan, int argIndex);
extern int SPI_getargcount(SPIPlanPtr plan);
extern bool SPI_is_cursor_plan(SPIPlanPtr plan);
extern bool SPI_plan_is_valid(SPIPlanPtr plan);
extern const char *SPI_result_code_string(int code);
extern List *SPI_plan_get_plan_sources(SPIPlanPtr plan);
extern CachedPlan *SPI_plan_get_cached_plan(SPIPlanPtr plan);
extern HeapTuple SPI_copytuple(HeapTuple tuple);
extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc);
extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts,
int *attnum, Datum *Values, const char *Nulls);
extern int SPI_fnumber(TupleDesc tupdesc, const char *fname);
extern char *SPI_fname(TupleDesc tupdesc, int fnumber);
extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber);
extern Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull);
extern char *SPI_gettype(TupleDesc tupdesc, int fnumber);
extern Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber);
extern char *SPI_getrelname(Relation rel);
extern char *SPI_getnspname(Relation rel);
extern void *SPI_palloc(Size size);
extern void *SPI_repalloc(void *pointer, Size size);
extern void SPI_pfree(void *pointer);
extern Datum SPI_datumTransfer(Datum value, bool typByVal, int typLen);
extern void SPI_freetuple(HeapTuple pointer);
extern void SPI_freetuptable(SPITupleTable *tuptable);
extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan,
Datum *Values, const char *Nulls, bool read_only);
extern Portal SPI_cursor_open_with_args(const char *name,
const char *src,
int nargs, Oid *argtypes,
Datum *Values, const char *Nulls,
bool read_only, int cursorOptions);
extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan,
ParamListInfo params, bool read_only);
extern Portal SPI_cursor_parse_open(const char *name,
const char *src,
const SPIParseOpenOptions *options);
extern Portal SPI_cursor_find(const char *name);
extern void SPI_cursor_fetch(Portal portal, bool forward, long count);
extern void SPI_cursor_move(Portal portal, bool forward, long count);
extern void SPI_scroll_cursor_fetch(Portal, FetchDirection direction, long count);
extern void SPI_scroll_cursor_move(Portal, FetchDirection direction, long count);
extern void SPI_cursor_close(Portal portal);
extern int SPI_register_relation(EphemeralNamedRelation enr);
extern int SPI_unregister_relation(const char *name);
extern int SPI_register_trigger_data(TriggerData *tdata);
extern void SPI_start_transaction(void);
extern void SPI_commit(void);
extern void SPI_commit_and_chain(void);
extern void SPI_rollback(void);
extern void SPI_rollback_and_chain(void);
extern void SPICleanup(void);
extern void AtEOXact_SPI(bool isCommit);
extern void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid);
extern bool SPI_inside_nonatomic_context(void);
#endif /* SPI_H */

105
db_include/executor/spi_priv.h Executable file
View File

@@ -0,0 +1,105 @@
/*-------------------------------------------------------------------------
*
* spi_priv.h
* Server Programming Interface private declarations
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/spi_priv.h
*
*-------------------------------------------------------------------------
*/
#ifndef SPI_PRIV_H
#define SPI_PRIV_H
#include "executor/spi.h"
#include "utils/queryenvironment.h"
#define _SPI_PLAN_MAGIC 569278163
typedef struct
{
/* current results */
uint64 processed; /* by Executor */
SPITupleTable *tuptable; /* tuptable currently being built */
/* subtransaction in which current Executor call was started */
SubTransactionId execSubid;
/* resources of this execution context */
slist_head tuptables; /* list of all live SPITupleTables */
MemoryContext procCxt; /* procedure context */
MemoryContext execCxt; /* executor context */
MemoryContext savedcxt; /* context of SPI_connect's caller */
SubTransactionId connectSubid; /* ID of connecting subtransaction */
QueryEnvironment *queryEnv; /* query environment setup for SPI level */
/* transaction management support */
bool atomic; /* atomic execution context, does not allow
* transactions */
bool internal_xact; /* SPI-managed transaction boundary, skip
* cleanup */
/* saved values of API global variables for previous nesting level */
uint64 outer_processed;
SPITupleTable *outer_tuptable;
int outer_result;
} _SPI_connection;
/*
* SPI plans have three states: saved, unsaved, or temporary.
*
* Ordinarily, the _SPI_plan struct itself as well as the argtypes array
* are in a dedicated memory context identified by plancxt (which can be
* really small). All the other subsidiary state is in plancache entries
* identified by plancache_list (note: the list cells themselves are in
* plancxt).
*
* In an unsaved plan, the plancxt as well as the plancache entries' contexts
* are children of the SPI procedure context, so they'll all disappear at
* function exit. plancache.c also knows that the plancache entries are
* "unsaved", so it doesn't link them into its global list; hence they do
* not respond to inval events. This is OK since we are presumably holding
* adequate locks to prevent other backends from messing with the tables.
*
* For a saved plan, the plancxt is made a child of CacheMemoryContext
* since it should persist until explicitly destroyed. Likewise, the
* plancache entries will be under CacheMemoryContext since we tell
* plancache.c to save them. We rely on plancache.c to keep the cache
* entries up-to-date as needed in the face of invalidation events.
*
* There are also "temporary" SPI plans, in which the _SPI_plan struct is
* not even palloc'd but just exists in some function's local variable.
* The plancache entries are unsaved and exist under the SPI executor context,
* while additional data such as argtypes and list cells is loose in the SPI
* executor context. Such plans can be identified by having plancxt == NULL.
*
* We can also have "one-shot" SPI plans (which are typically temporary,
* as described above). These are meant to be executed once and discarded,
* and various optimizations are made on the assumption of single use.
* Note in particular that the CachedPlanSources within such an SPI plan
* are not "complete" until execution.
*
* Note: if the original query string contained only whitespace and comments,
* the plancache_list will be NIL and so there is no place to store the
* query string. We don't care about that, but we do care about the
* argument type array, which is why it's seemingly-redundantly stored.
*/
typedef struct _SPI_plan
{
int magic; /* should equal _SPI_PLAN_MAGIC */
bool saved; /* saved or unsaved plan? */
bool oneshot; /* one-shot plan? */
List *plancache_list; /* one CachedPlanSource per parsetree */
MemoryContext plancxt; /* Context containing _SPI_plan and data */
RawParseMode parse_mode; /* raw_parser() mode */
int cursor_options; /* Cursor options used for planning */
int nargs; /* number of plan arguments */
Oid *argtypes; /* Argument types (NULL if nargs is 0) */
ParserSetupHook parserSetup; /* alternative parameter spec method */
void *parserSetupArg;
} _SPI_plan;
#endif /* SPI_PRIV_H */

67
db_include/executor/tablefunc.h Executable file
View File

@@ -0,0 +1,67 @@
/*-------------------------------------------------------------------------
*
* tablefunc.h
* interface for TableFunc executor node
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/tablefunc.h
*
*-------------------------------------------------------------------------
*/
#ifndef _TABLEFUNC_H
#define _TABLEFUNC_H
/* Forward-declare this to avoid including execnodes.h here */
struct TableFuncScanState;
/*
* TableFuncRoutine holds function pointers used for generating content of
* table-producer functions, such as XMLTABLE.
*
* InitOpaque initializes table builder private objects. The output tuple
* descriptor, input functions for the columns, and typioparams are passed
* from executor state.
*
* SetDocument is called to define the input document. The table builder may
* apply additional transformations not exposed outside the table builder
* context.
*
* SetNamespace is called to pass namespace declarations from the table
* expression. This function may be NULL if namespaces are not supported by
* the table builder. Namespaces must be given before setting the row and
* column filters. If the name is given as NULL, the entry shall be for the
* default namespace.
*
* SetRowFilter is called do define the row-generating filter, which shall be
* used to extract each row from the input document.
*
* SetColumnFilter is called once for each column, to define the column-
* generating filter for the given column.
*
* FetchRow shall be called repeatedly until it returns that no more rows are
* found in the document. On each invocation it shall set state in the table
* builder context such that each subsequent GetValue call returns the values
* for the indicated column for the row being processed.
*
* DestroyOpaque shall release all resources associated with a table builder
* context. It may be called either because all rows have been consumed, or
* because an error occurred while processing the table expression.
*/
typedef struct TableFuncRoutine
{
void (*InitOpaque) (struct TableFuncScanState *state, int natts);
void (*SetDocument) (struct TableFuncScanState *state, Datum value);
void (*SetNamespace) (struct TableFuncScanState *state, const char *name,
const char *uri);
void (*SetRowFilter) (struct TableFuncScanState *state, const char *path);
void (*SetColumnFilter) (struct TableFuncScanState *state,
const char *path, int colnum);
bool (*FetchRow) (struct TableFuncScanState *state);
Datum (*GetValue) (struct TableFuncScanState *state, int colnum,
Oid typid, int32 typmod, bool *isnull);
void (*DestroyOpaque) (struct TableFuncScanState *state);
} TableFuncRoutine;
#endif /* _TABLEFUNC_H */

32
db_include/executor/tqueue.h Executable file
View File

@@ -0,0 +1,32 @@
/*-------------------------------------------------------------------------
*
* tqueue.h
* Use shm_mq to send & receive tuples between parallel backends
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/tqueue.h
*
*-------------------------------------------------------------------------
*/
#ifndef TQUEUE_H
#define TQUEUE_H
#include "storage/shm_mq.h"
#include "tcop/dest.h"
/* Opaque struct, only known inside tqueue.c. */
typedef struct TupleQueueReader TupleQueueReader;
/* Use this to send tuples to a shm_mq. */
extern DestReceiver *CreateTupleQueueDestReceiver(shm_mq_handle *handle);
/* Use these to receive tuples from a shm_mq. */
extern TupleQueueReader *CreateTupleQueueReader(shm_mq_handle *handle);
extern void DestroyTupleQueueReader(TupleQueueReader *reader);
extern MinimalTuple TupleQueueReaderNext(TupleQueueReader *reader,
bool nowait, bool *done);
#endif /* TQUEUE_H */

View File

@@ -0,0 +1,31 @@
/*-------------------------------------------------------------------------
*
* tstoreReceiver.h
* prototypes for tstoreReceiver.c
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/tstoreReceiver.h
*
*-------------------------------------------------------------------------
*/
#ifndef TSTORE_RECEIVER_H
#define TSTORE_RECEIVER_H
#include "tcop/dest.h"
#include "utils/tuplestore.h"
extern DestReceiver *CreateTuplestoreDestReceiver(void);
extern void SetTuplestoreDestReceiverParams(DestReceiver *self,
Tuplestorestate *tStore,
MemoryContext tContext,
bool detoast,
TupleDesc target_tupdesc,
const char *map_failure_msg);
#endif /* TSTORE_RECEIVER_H */

487
db_include/executor/tuptable.h Executable file
View File

@@ -0,0 +1,487 @@
/*-------------------------------------------------------------------------
*
* tuptable.h
* tuple table support stuff
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/executor/tuptable.h
*
*-------------------------------------------------------------------------
*/
#ifndef TUPTABLE_H
#define TUPTABLE_H
#include "access/htup.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "access/tupdesc.h"
#include "storage/buf.h"
/*----------
* The executor stores tuples in a "tuple table" which is a List of
* independent TupleTableSlots.
*
* There's various different types of tuple table slots, each being able to
* store different types of tuples. Additional types of slots can be added
* without modifying core code. The type of a slot is determined by the
* TupleTableSlotOps* passed to the slot creation routine. The builtin types
* of slots are
*
* 1. physical tuple in a disk buffer page (TTSOpsBufferHeapTuple)
* 2. physical tuple constructed in palloc'ed memory (TTSOpsHeapTuple)
* 3. "minimal" physical tuple constructed in palloc'ed memory
* (TTSOpsMinimalTuple)
* 4. "virtual" tuple consisting of Datum/isnull arrays (TTSOpsVirtual)
*
*
* The first two cases are similar in that they both deal with "materialized"
* tuples, but resource management is different. For a tuple in a disk page
* we need to hold a pin on the buffer until the TupleTableSlot's reference
* to the tuple is dropped; while for a palloc'd tuple we usually want the
* tuple pfree'd when the TupleTableSlot's reference is dropped.
*
* A "minimal" tuple is handled similarly to a palloc'd regular tuple.
* At present, minimal tuples never are stored in buffers, so there is no
* parallel to case 1. Note that a minimal tuple has no "system columns".
* (Actually, it could have an OID, but we have no need to access the OID.)
*
* A "virtual" tuple is an optimization used to minimize physical data copying
* in a nest of plan nodes. Until materialized pass-by-reference Datums in
* the slot point to storage that is not directly associated with the
* TupleTableSlot; generally they will point to part of a tuple stored in a
* lower plan node's output TupleTableSlot, or to a function result
* constructed in a plan node's per-tuple econtext. It is the responsibility
* of the generating plan node to be sure these resources are not released for
* as long as the virtual tuple needs to be valid or is materialized. Note
* also that a virtual tuple does not have any "system columns".
*
* The Datum/isnull arrays of a TupleTableSlot serve double duty. For virtual
* slots they are the authoritative data. For the other builtin slots,
* the arrays contain data extracted from the tuple. (In this state, any
* pass-by-reference Datums point into the physical tuple.) The extracted
* information is built "lazily", ie, only as needed. This serves to avoid
* repeated extraction of data from the physical tuple.
*
* A TupleTableSlot can also be "empty", indicated by flag TTS_FLAG_EMPTY set
* in tts_flags, holding no valid data. This is the only valid state for a
* freshly-created slot that has not yet had a tuple descriptor assigned to
* it. In this state, TTS_SHOULDFREE should not be set in tts_flags, tts_tuple
* must be NULL and tts_nvalid zero.
*
* The tupleDescriptor is simply referenced, not copied, by the TupleTableSlot
* code. The caller of ExecSetSlotDescriptor() is responsible for providing
* a descriptor that will live as long as the slot does. (Typically, both
* slots and descriptors are in per-query memory and are freed by memory
* context deallocation at query end; so it's not worth providing any extra
* mechanism to do more. However, the slot will increment the tupdesc
* reference count if a reference-counted tupdesc is supplied.)
*
* When TTS_SHOULDFREE is set in tts_flags, the physical tuple is "owned" by
* the slot and should be freed when the slot's reference to the tuple is
* dropped.
*
* tts_values/tts_isnull are allocated either when the slot is created (when
* the descriptor is provided), or when a descriptor is assigned to the slot;
* they are of length equal to the descriptor's natts.
*
* The TTS_FLAG_SLOW flag is saved state for
* slot_deform_heap_tuple, and should not be touched by any other code.
*----------
*/
/* true = slot is empty */
#define TTS_FLAG_EMPTY (1 << 1)
#define TTS_EMPTY(slot) (((slot)->tts_flags & TTS_FLAG_EMPTY) != 0)
/* should pfree tuple "owned" by the slot? */
#define TTS_FLAG_SHOULDFREE (1 << 2)
#define TTS_SHOULDFREE(slot) (((slot)->tts_flags & TTS_FLAG_SHOULDFREE) != 0)
/* saved state for slot_deform_heap_tuple */
#define TTS_FLAG_SLOW (1 << 3)
#define TTS_SLOW(slot) (((slot)->tts_flags & TTS_FLAG_SLOW) != 0)
/* fixed tuple descriptor */
#define TTS_FLAG_FIXED (1 << 4)
#define TTS_FIXED(slot) (((slot)->tts_flags & TTS_FLAG_FIXED) != 0)
struct TupleTableSlotOps;
typedef struct TupleTableSlotOps TupleTableSlotOps;
/* base tuple table slot type */
typedef struct TupleTableSlot
{
NodeTag type;
#define FIELDNO_TUPLETABLESLOT_FLAGS 1
uint16 tts_flags; /* Boolean states */
#define FIELDNO_TUPLETABLESLOT_NVALID 2
AttrNumber tts_nvalid; /* # of valid values in tts_values */
const TupleTableSlotOps *const tts_ops; /* implementation of slot */
#define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 4
TupleDesc tts_tupleDescriptor; /* slot's tuple descriptor */
#define FIELDNO_TUPLETABLESLOT_VALUES 5
Datum *tts_values; /* current per-attribute values */
#define FIELDNO_TUPLETABLESLOT_ISNULL 6
bool *tts_isnull; /* current per-attribute isnull flags */
MemoryContext tts_mcxt; /* slot itself is in this context */
ItemPointerData tts_tid; /* stored tuple's tid */
Oid tts_tableOid; /* table oid of tuple */
} TupleTableSlot;
/* routines for a TupleTableSlot implementation */
struct TupleTableSlotOps
{
/* Minimum size of the slot */
size_t base_slot_size;
/* Initialization. */
void (*init) (TupleTableSlot *slot);
/* Destruction. */
void (*release) (TupleTableSlot *slot);
/*
* Clear the contents of the slot. Only the contents are expected to be
* cleared and not the tuple descriptor. Typically an implementation of
* this callback should free the memory allocated for the tuple contained
* in the slot.
*/
void (*clear) (TupleTableSlot *slot);
/*
* Fill up first natts entries of tts_values and tts_isnull arrays with
* values from the tuple contained in the slot. The function may be called
* with natts more than the number of attributes available in the tuple,
* in which case it should set tts_nvalid to the number of returned
* columns.
*/
void (*getsomeattrs) (TupleTableSlot *slot, int natts);
/*
* Returns value of the given system attribute as a datum and sets isnull
* to false, if it's not NULL. Throws an error if the slot type does not
* support system attributes.
*/
Datum (*getsysattr) (TupleTableSlot *slot, int attnum, bool *isnull);
/*
* Make the contents of the slot solely depend on the slot, and not on
* underlying resources (like another memory context, buffers, etc).
*/
void (*materialize) (TupleTableSlot *slot);
/*
* Copy the contents of the source slot into the destination slot's own
* context. Invoked using callback of the destination slot.
*/
void (*copyslot) (TupleTableSlot *dstslot, TupleTableSlot *srcslot);
/*
* Return a heap tuple "owned" by the slot. It is slot's responsibility to
* free the memory consumed by the heap tuple. If the slot can not "own" a
* heap tuple, it should not implement this callback and should set it as
* NULL.
*/
HeapTuple (*get_heap_tuple) (TupleTableSlot *slot);
/*
* Return a minimal tuple "owned" by the slot. It is slot's responsibility
* to free the memory consumed by the minimal tuple. If the slot can not
* "own" a minimal tuple, it should not implement this callback and should
* set it as NULL.
*/
MinimalTuple (*get_minimal_tuple) (TupleTableSlot *slot);
/*
* Return a copy of heap tuple representing the contents of the slot. The
* copy needs to be palloc'd in the current memory context. The slot
* itself is expected to remain unaffected. It is *not* expected to have
* meaningful "system columns" in the copy. The copy is not be "owned" by
* the slot i.e. the caller has to take responsibility to free memory
* consumed by the slot.
*/
HeapTuple (*copy_heap_tuple) (TupleTableSlot *slot);
/*
* Return a copy of minimal tuple representing the contents of the slot.
* The copy needs to be palloc'd in the current memory context. The slot
* itself is expected to remain unaffected. It is *not* expected to have
* meaningful "system columns" in the copy. The copy is not be "owned" by
* the slot i.e. the caller has to take responsibility to free memory
* consumed by the slot.
*/
MinimalTuple (*copy_minimal_tuple) (TupleTableSlot *slot);
};
/*
* Predefined TupleTableSlotOps for various types of TupleTableSlotOps. The
* same are used to identify the type of a given slot.
*/
extern PGDLLIMPORT const TupleTableSlotOps TTSOpsVirtual;
extern PGDLLIMPORT const TupleTableSlotOps TTSOpsHeapTuple;
extern PGDLLIMPORT const TupleTableSlotOps TTSOpsMinimalTuple;
extern PGDLLIMPORT const TupleTableSlotOps TTSOpsBufferHeapTuple;
#define TTS_IS_VIRTUAL(slot) ((slot)->tts_ops == &TTSOpsVirtual)
#define TTS_IS_HEAPTUPLE(slot) ((slot)->tts_ops == &TTSOpsHeapTuple)
#define TTS_IS_MINIMALTUPLE(slot) ((slot)->tts_ops == &TTSOpsMinimalTuple)
#define TTS_IS_BUFFERTUPLE(slot) ((slot)->tts_ops == &TTSOpsBufferHeapTuple)
/*
* Tuple table slot implementations.
*/
typedef struct VirtualTupleTableSlot
{
TupleTableSlot base;
char *data; /* data for materialized slots */
} VirtualTupleTableSlot;
typedef struct HeapTupleTableSlot
{
TupleTableSlot base;
#define FIELDNO_HEAPTUPLETABLESLOT_TUPLE 1
HeapTuple tuple; /* physical tuple */
#define FIELDNO_HEAPTUPLETABLESLOT_OFF 2
uint32 off; /* saved state for slot_deform_heap_tuple */
HeapTupleData tupdata; /* optional workspace for storing tuple */
} HeapTupleTableSlot;
/* heap tuple residing in a buffer */
typedef struct BufferHeapTupleTableSlot
{
HeapTupleTableSlot base;
/*
* If buffer is not InvalidBuffer, then the slot is holding a pin on the
* indicated buffer page; drop the pin when we release the slot's
* reference to that buffer. (TTS_FLAG_SHOULDFREE should not be set in
* such a case, since presumably tts_tuple is pointing into the buffer.)
*/
Buffer buffer; /* tuple's buffer, or InvalidBuffer */
} BufferHeapTupleTableSlot;
typedef struct MinimalTupleTableSlot
{
TupleTableSlot base;
/*
* In a minimal slot tuple points at minhdr and the fields of that struct
* are set correctly for access to the minimal tuple; in particular,
* minhdr.t_data points MINIMAL_TUPLE_OFFSET bytes before mintuple. This
* allows column extraction to treat the case identically to regular
* physical tuples.
*/
#define FIELDNO_MINIMALTUPLETABLESLOT_TUPLE 1
HeapTuple tuple; /* tuple wrapper */
MinimalTuple mintuple; /* minimal tuple, or NULL if none */
HeapTupleData minhdr; /* workspace for minimal-tuple-only case */
#define FIELDNO_MINIMALTUPLETABLESLOT_OFF 4
uint32 off; /* saved state for slot_deform_heap_tuple */
} MinimalTupleTableSlot;
/*
* TupIsNull -- is a TupleTableSlot empty?
*/
#define TupIsNull(slot) \
((slot) == NULL || TTS_EMPTY(slot))
/* in executor/execTuples.c */
extern TupleTableSlot *MakeTupleTableSlot(TupleDesc tupleDesc,
const TupleTableSlotOps *tts_ops);
extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable, TupleDesc desc,
const TupleTableSlotOps *tts_ops);
extern void ExecResetTupleTable(List *tupleTable, bool shouldFree);
extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc,
const TupleTableSlotOps *tts_ops);
extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot);
extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc);
extern TupleTableSlot *ExecStoreHeapTuple(HeapTuple tuple,
TupleTableSlot *slot,
bool shouldFree);
extern void ExecForceStoreHeapTuple(HeapTuple tuple,
TupleTableSlot *slot,
bool shouldFree);
extern TupleTableSlot *ExecStoreBufferHeapTuple(HeapTuple tuple,
TupleTableSlot *slot,
Buffer buffer);
extern TupleTableSlot *ExecStorePinnedBufferHeapTuple(HeapTuple tuple,
TupleTableSlot *slot,
Buffer buffer);
extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup,
TupleTableSlot *slot,
bool shouldFree);
extern void ExecForceStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot,
bool shouldFree);
extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot);
extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot);
extern void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot);
extern HeapTuple ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree);
extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot,
bool *shouldFree);
extern Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot);
extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum,
int lastAttNum);
extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attnum);
#ifndef FRONTEND
/*
* This function forces the entries of the slot's Datum/isnull arrays to be
* valid at least up through the attnum'th entry.
*/
static inline void
slot_getsomeattrs(TupleTableSlot *slot, int attnum)
{
if (slot->tts_nvalid < attnum)
slot_getsomeattrs_int(slot, attnum);
}
/*
* slot_getallattrs
* This function forces all the entries of the slot's Datum/isnull
* arrays to be valid. The caller may then extract data directly
* from those arrays instead of using slot_getattr.
*/
static inline void
slot_getallattrs(TupleTableSlot *slot)
{
slot_getsomeattrs(slot, slot->tts_tupleDescriptor->natts);
}
/*
* slot_attisnull
*
* Detect whether an attribute of the slot is null, without actually fetching
* it.
*/
static inline bool
slot_attisnull(TupleTableSlot *slot, int attnum)
{
AssertArg(attnum > 0);
if (attnum > slot->tts_nvalid)
slot_getsomeattrs(slot, attnum);
return slot->tts_isnull[attnum - 1];
}
/*
* slot_getattr - fetch one attribute of the slot's contents.
*/
static inline Datum
slot_getattr(TupleTableSlot *slot, int attnum,
bool *isnull)
{
AssertArg(attnum > 0);
if (attnum > slot->tts_nvalid)
slot_getsomeattrs(slot, attnum);
*isnull = slot->tts_isnull[attnum - 1];
return slot->tts_values[attnum - 1];
}
/*
* slot_getsysattr - fetch a system attribute of the slot's current tuple.
*
* If the slot type does not contain system attributes, this will throw an
* error. Hence before calling this function, callers should make sure that
* the slot type is the one that supports system attributes.
*/
static inline Datum
slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
{
AssertArg(attnum < 0); /* caller error */
if (attnum == TableOidAttributeNumber)
{
*isnull = false;
return ObjectIdGetDatum(slot->tts_tableOid);
}
else if (attnum == SelfItemPointerAttributeNumber)
{
*isnull = false;
return PointerGetDatum(&slot->tts_tid);
}
/* Fetch the system attribute from the underlying tuple. */
return slot->tts_ops->getsysattr(slot, attnum, isnull);
}
/*
* ExecClearTuple - clear the slot's contents
*/
static inline TupleTableSlot *
ExecClearTuple(TupleTableSlot *slot)
{
slot->tts_ops->clear(slot);
return slot;
}
/* ExecMaterializeSlot - force a slot into the "materialized" state.
*
* This causes the slot's tuple to be a local copy not dependent on any
* external storage (i.e. pointing into a Buffer, or having allocations in
* another memory context).
*
* A typical use for this operation is to prepare a computed tuple for being
* stored on disk. The original data may or may not be virtual, but in any
* case we need a private copy for heap_insert to scribble on.
*/
static inline void
ExecMaterializeSlot(TupleTableSlot *slot)
{
slot->tts_ops->materialize(slot);
}
/*
* ExecCopySlotHeapTuple - return HeapTuple allocated in caller's context
*/
static inline HeapTuple
ExecCopySlotHeapTuple(TupleTableSlot *slot)
{
Assert(!TTS_EMPTY(slot));
return slot->tts_ops->copy_heap_tuple(slot);
}
/*
* ExecCopySlotMinimalTuple - return MinimalTuple allocated in caller's context
*/
static inline MinimalTuple
ExecCopySlotMinimalTuple(TupleTableSlot *slot)
{
return slot->tts_ops->copy_minimal_tuple(slot);
}
/*
* ExecCopySlot - copy one slot's contents into another.
*
* If a source's system attributes are supposed to be accessed in the target
* slot, the target slot and source slot types need to match.
*/
static inline TupleTableSlot *
ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
{
Assert(!TTS_EMPTY(srcslot));
AssertArg(srcslot != dstslot);
dstslot->tts_ops->copyslot(dstslot, srcslot);
return dstslot;
}
#endif /* FRONTEND */
#endif /* TUPTABLE_H */