init
This commit is contained in:
25
db_include/executor/execAsync.h
Executable file
25
db_include/executor/execAsync.h
Executable 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
782
db_include/executor/execExpr.h
Executable 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 */
|
||||
51
db_include/executor/execParallel.h
Executable file
51
db_include/executor/execParallel.h
Executable 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 */
|
||||
128
db_include/executor/execPartition.h
Executable file
128
db_include/executor/execPartition.h
Executable 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
130
db_include/executor/execdebug.h
Executable 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
70
db_include/executor/execdesc.h
Executable 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
661
db_include/executor/executor.h
Executable 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
55
db_include/executor/functions.h
Executable 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
362
db_include/executor/hashjoin.h
Executable 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
116
db_include/executor/instrument.h
Executable 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
333
db_include/executor/nodeAgg.h
Executable 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 */
|
||||
30
db_include/executor/nodeAppend.h
Executable file
30
db_include/executor/nodeAppend.h
Executable 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 */
|
||||
24
db_include/executor/nodeBitmapAnd.h
Executable file
24
db_include/executor/nodeBitmapAnd.h
Executable 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 */
|
||||
32
db_include/executor/nodeBitmapHeapscan.h
Executable file
32
db_include/executor/nodeBitmapHeapscan.h
Executable 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 */
|
||||
24
db_include/executor/nodeBitmapIndexscan.h
Executable file
24
db_include/executor/nodeBitmapIndexscan.h
Executable 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 */
|
||||
24
db_include/executor/nodeBitmapOr.h
Executable file
24
db_include/executor/nodeBitmapOr.h
Executable 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 */
|
||||
23
db_include/executor/nodeCtescan.h
Executable file
23
db_include/executor/nodeCtescan.h
Executable 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 */
|
||||
42
db_include/executor/nodeCustom.h
Executable file
42
db_include/executor/nodeCustom.h
Executable 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 */
|
||||
38
db_include/executor/nodeForeignscan.h
Executable file
38
db_include/executor/nodeForeignscan.h
Executable 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 */
|
||||
23
db_include/executor/nodeFunctionscan.h
Executable file
23
db_include/executor/nodeFunctionscan.h
Executable 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 */
|
||||
24
db_include/executor/nodeGather.h
Executable file
24
db_include/executor/nodeGather.h
Executable 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 */
|
||||
26
db_include/executor/nodeGatherMerge.h
Executable file
26
db_include/executor/nodeGatherMerge.h
Executable 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
23
db_include/executor/nodeGroup.h
Executable 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
79
db_include/executor/nodeHash.h
Executable 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 */
|
||||
34
db_include/executor/nodeHashjoin.h
Executable file
34
db_include/executor/nodeHashjoin.h
Executable 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 */
|
||||
28
db_include/executor/nodeIncrementalSort.h
Executable file
28
db_include/executor/nodeIncrementalSort.h
Executable 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 */
|
||||
36
db_include/executor/nodeIndexonlyscan.h
Executable file
36
db_include/executor/nodeIndexonlyscan.h
Executable 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 */
|
||||
47
db_include/executor/nodeIndexscan.h
Executable file
47
db_include/executor/nodeIndexscan.h
Executable 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
23
db_include/executor/nodeLimit.h
Executable 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 */
|
||||
23
db_include/executor/nodeLockRows.h
Executable file
23
db_include/executor/nodeLockRows.h
Executable 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 */
|
||||
25
db_include/executor/nodeMaterial.h
Executable file
25
db_include/executor/nodeMaterial.h
Executable 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 */
|
||||
32
db_include/executor/nodeMemoize.h
Executable file
32
db_include/executor/nodeMemoize.h
Executable 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 */
|
||||
23
db_include/executor/nodeMergeAppend.h
Executable file
23
db_include/executor/nodeMergeAppend.h
Executable 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 */
|
||||
23
db_include/executor/nodeMergejoin.h
Executable file
23
db_include/executor/nodeMergejoin.h
Executable 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 */
|
||||
26
db_include/executor/nodeModifyTable.h
Executable file
26
db_include/executor/nodeModifyTable.h
Executable 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 */
|
||||
23
db_include/executor/nodeNamedtuplestorescan.h
Executable file
23
db_include/executor/nodeNamedtuplestorescan.h
Executable 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 */
|
||||
23
db_include/executor/nodeNestloop.h
Executable file
23
db_include/executor/nodeNestloop.h
Executable 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 */
|
||||
23
db_include/executor/nodeProjectSet.h
Executable file
23
db_include/executor/nodeProjectSet.h
Executable 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 */
|
||||
23
db_include/executor/nodeRecursiveunion.h
Executable file
23
db_include/executor/nodeRecursiveunion.h
Executable 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 */
|
||||
25
db_include/executor/nodeResult.h
Executable file
25
db_include/executor/nodeResult.h
Executable 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 */
|
||||
23
db_include/executor/nodeSamplescan.h
Executable file
23
db_include/executor/nodeSamplescan.h
Executable 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 */
|
||||
31
db_include/executor/nodeSeqscan.h
Executable file
31
db_include/executor/nodeSeqscan.h
Executable 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
23
db_include/executor/nodeSetOp.h
Executable 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
32
db_include/executor/nodeSort.h
Executable 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 */
|
||||
29
db_include/executor/nodeSubplan.h
Executable file
29
db_include/executor/nodeSubplan.h
Executable 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 */
|
||||
23
db_include/executor/nodeSubqueryscan.h
Executable file
23
db_include/executor/nodeSubqueryscan.h
Executable 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 */
|
||||
23
db_include/executor/nodeTableFuncscan.h
Executable file
23
db_include/executor/nodeTableFuncscan.h
Executable 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 */
|
||||
24
db_include/executor/nodeTidrangescan.h
Executable file
24
db_include/executor/nodeTidrangescan.h
Executable 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 */
|
||||
23
db_include/executor/nodeTidscan.h
Executable file
23
db_include/executor/nodeTidscan.h
Executable 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 */
|
||||
23
db_include/executor/nodeUnique.h
Executable file
23
db_include/executor/nodeUnique.h
Executable 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 */
|
||||
23
db_include/executor/nodeValuesscan.h
Executable file
23
db_include/executor/nodeValuesscan.h
Executable 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 */
|
||||
23
db_include/executor/nodeWindowAgg.h
Executable file
23
db_include/executor/nodeWindowAgg.h
Executable 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 */
|
||||
23
db_include/executor/nodeWorktablescan.h
Executable file
23
db_include/executor/nodeWorktablescan.h
Executable 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
213
db_include/executor/spi.h
Executable 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
105
db_include/executor/spi_priv.h
Executable 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
67
db_include/executor/tablefunc.h
Executable 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
32
db_include/executor/tqueue.h
Executable 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 */
|
||||
31
db_include/executor/tstoreReceiver.h
Executable file
31
db_include/executor/tstoreReceiver.h
Executable 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
487
db_include/executor/tuptable.h
Executable 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 */
|
||||
Reference in New Issue
Block a user