*
* execnodes.h
* definitions for executor state nodes
*
*
* Portions Copyright (c) 2021, openGauss Contributors
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/nodes/execnodes.h
*
* -------------------------------------------------------------------------
*/
#ifndef EXECNODES_H
#define EXECNODES_H
#include "access/genam.h"
#include "access/relscan.h"
#include "bulkload/dist_fdw.h"
#include "executor/instrument.h"
#include "nodes/params.h"
#include "nodes/plannodes.h"
#include "storage/pagecompress.h"
#include "utils/array.h"
#include "utils/bloom_filter.h"
#include "utils/reltrigger.h"
#include "utils/sortsupport.h"
#include "utils/tuplesort.h"
#include "utils/tuplestore.h"
#include "vecexecutor/vectorbatch.h"
#include "db4ai/matrix.h"
#ifdef ENABLE_MOT
namespace JitExec
{
struct MotJitContext;
}
#endif
#define ATTACH_RIGHT_REF_STATE(planstate) if ((planstate) && (planstate)->ps_ExprContext && (planstate)->plan) {\
(planstate)->ps_ExprContext->rightRefState = (planstate)->plan->rightRefState; \
}
typedef struct UtilityDesc {
double cost;
int query_mem[2];
int min_mem;
int assigned_mem;
} UtilityDesc;
* IndexInfo information
*
* this struct holds the information needed to construct new index
* entries for a particular index. Used for both index_build and
* retail creation of index entries.
*
* NumIndexAttrs total number of columns in this index
* NumIndexKeyAttrs number of key columns in index
* KeyAttrNumbers underlying-rel attribute numbers used as keys
* (zeroes indicate expressions). It also contains
* info about included columns.
* Expressions expr trees for expression entries, or NIL if none
* ExpressionsState exec state for expressions, or NIL if none
* Predicate partial-index predicate, or NIL if none
* PredicateState exec state for predicate, or NIL if none
* ExclusionOps Per-column exclusion operators, or NULL if none
* ExclusionProcs Underlying function OIDs for ExclusionOps
* ExclusionStrats Opclass strategy numbers for ExclusionOps
* UniqueOps Theses are like Exclusion*, but for unique indexes
* UniqueProcs
* UniqueStrats
* Unique is it a unique index?
* ReadyForInserts is it valid for inserts?
* Concurrent are we doing a concurrent index build?
* BrokenHotChain did we detect any broken HOT chains?
*
* ii_Concurrent and ii_BrokenHotChain are used only during index build;
* they're conventionally set to false otherwise.
* ----------------
*/
typedef struct IndexInfo {
NodeTag type;
int ii_NumIndexAttrs;
int ii_NumIndexKeyAttrs;
AttrNumber ii_KeyAttrNumbers[INDEX_MAX_KEYS];
List* ii_Expressions;
List* ii_ExpressionsState;
List* ii_Predicate;
List* ii_PredicateState;
Oid* ii_ExclusionOps;
Oid* ii_ExclusionProcs;
uint16* ii_ExclusionStrats;
Oid *ii_UniqueOps;
Oid *ii_UniqueProcs;
uint16 *ii_UniqueStrats;
bool ii_Unique;
bool ii_ReadyForInserts;
bool ii_Concurrent;
bool ii_BrokenHotChain;
int ii_ParallelWorkers;
short ii_PgClassAttrId;
UtilityDesc ii_desc;
} IndexInfo;
* ExprContext_CB
*
* List of callbacks to be called at ExprContext shutdown.
* ----------------
*/
typedef void (*ExprContextCallbackFunction)(Datum arg);
typedef struct ExprContext_CB {
struct ExprContext_CB* next;
ExprContextCallbackFunction function;
ResourceOwner resowner;
Datum arg;
} ExprContext_CB;
* ExprContext
*
* This class holds the "current context" information
* needed to evaluate expressions for doing tuple qualifications
* and tuple projections. For example, if an expression refers
* to an attribute in the current inner tuple then we need to know
* what the current inner tuple is and so we look at the expression
* context.
*
* There are two memory contexts associated with an ExprContext:
* * ecxt_per_query_memory is a query-lifespan context, typically the same
* context the ExprContext node itself is allocated in. This context
* can be used for purposes such as storing function call cache info.
* * ecxt_per_tuple_memory is a short-term context for expression results.
* As the name suggests, it will typically be reset once per tuple,
* before we begin to evaluate expressions for that tuple. Each
* ExprContext normally has its very own per-tuple memory context.
*
* CurrentMemoryContext should be set to ecxt_per_tuple_memory before
* calling ExecEvalExpr() --- see ExecEvalExprSwitchContext().
* ----------------
*/
struct PLpgSQL_execstate;
typedef struct ExprContext {
NodeTag type;
TupleTableSlot* ecxt_scantuple;
TupleTableSlot* ecxt_innertuple;
TupleTableSlot* ecxt_outertuple;
MemoryContext ecxt_per_query_memory;
MemoryContext ecxt_per_tuple_memory;
ParamExecData* ecxt_param_exec_vals;
ParamListInfo ecxt_param_list_info;
* Values to substitute for Aggref nodes in the expressions of an Agg
* node, or for WindowFunc nodes within a WindowAgg node.
*/
Datum* ecxt_aggvalues;
bool* ecxt_aggnulls;
Datum caseValue_datum;
bool caseValue_isNull;
ScalarVector* caseValue_vector;
Datum domainValue_datum;
bool domainValue_isNull;
struct EState* ecxt_estate;
ExprContext_CB* ecxt_callbacks;
VectorBatch* ecxt_scanbatch;
VectorBatch* ecxt_innerbatch;
VectorBatch* ecxt_outerbatch;
VectorBatch* ecxt_aggbatch;
* mark the real rows for expression cluster, all the results' m_rows generated by
* vec-expression are aligned by econtext->align_rows
*/
int align_rows;
bool m_fUseSelection;
ScalarVector* qual_results;
ScalarVector* boolVector;
bool is_cursor;
Cursor_Data cursor_data;
int dno;
PLpgSQL_execstate* plpgsql_estate;
bool hasSetResultStore;
* For vector set-result function.
*/
bool have_vec_set_fun;
bool* vec_fun_sel;
int current_row;
bool can_ignore;
RightRefState* rightRefState;
#ifdef USE_SPQ
OffsetNumber cached_root_offsets[MaxHeapTuplesPerPage];
BlockNumber cached_blkno;
#endif
} ExprContext;
* Set-result status used when evaluating functions potentially returning a
* set.
*/
typedef enum {
ExprSingleResult,
ExprMultipleResult,
ExprEndResult
} ExprDoneCond;
* Return modes for functions returning sets. Note values must be chosen
* as separate bits so that a bitmask can be formed to indicate supported
* modes. SFRM_Materialize_Random and SFRM_Materialize_Preferred are
* auxiliary flags about SFRM_Materialize mode, rather than separate modes.
*/
typedef enum {
SFRM_ValuePerCall = 0x01,
SFRM_Materialize = 0x02,
SFRM_Materialize_Random = 0x04,
SFRM_Materialize_Preferred = 0x08
} SetFunctionReturnMode;
* When calling a function that might return a set (multiple rows),
* a node of this type is passed as fcinfo->resultinfo to allow
* return status to be passed back. A function returning set should
* raise an error if no such resultinfo is provided.
*/
typedef struct ReturnSetInfo {
NodeTag type;
ExprContext* econtext;
TupleDesc expectedDesc;
int allowedModes;
SetFunctionReturnMode returnMode;
ExprDoneCond isDone;
Tuplestorestate* setResult;
TupleDesc setDesc;
} ReturnSetInfo;
* Function pointer which will be used by LLVM assemble. The created IR functions
* will be added to the actual machine code.
*/
typedef ScalarVector* (*vecqual_func)(ExprContext* econtext);
* JunkFilter
*
* This class is used to store information regarding junk attributes.
* A junk attribute is an attribute in a tuple that is needed only for
* storing intermediate information in the executor, and does not belong
* in emitted tuples. For example, when we do an UPDATE query,
* the planner adds a "junk" entry to the targetlist so that the tuples
* returned to ExecutePlan() contain an extra attribute: the ctid of
* the tuple to be updated. This is needed to do the update, but we
* don't want the ctid to be part of the stored new tuple! So, we
* apply a "junk filter" to remove the junk attributes and form the
* real output tuple. The junkfilter code also provides routines to
* extract the values of the junk attribute(s) from the input tuple.
*
* targetList: the original target list (including junk attributes).
* cleanTupType: the tuple descriptor for the "clean" tuple (with
* junk attributes removed).
* cleanMap: A map with the correspondence between the non-junk
* attribute numbers of the "original" tuple and the
* attribute numbers of the "clean" tuple.
* resultSlot: tuple slot used to hold cleaned tuple.
* junkAttNo: not used by junkfilter code. Can be used by caller
* to remember the attno of a specific junk attribute
* (nodeModifyTable.c keeps the "ctid" or "wholerow"
* attno here).
* ----------------
*/
typedef struct JunkFilter {
NodeTag type;
List* jf_targetList;
TupleDesc jf_cleanTupType;
AttrNumber* jf_cleanMap;
TupleTableSlot* jf_resultSlot;
AttrNumber jf_junkAttNo;
#ifdef PGXC
* Similar to jf_junkAttNo that is used for ctid, we also need xc_node_id
* and wholerow junk attribute numbers to be saved here. In XC, we need
* multiple junk attributes at the same time, so just jf_junkAttNo is not
* enough. In PG, jf_junkAttNo is used either for ctid or for wholerow,
* it does not need both of them at the same time; ctid is used for physical
* relations while wholerow is used for views.
*/
AttrNumber jf_xc_node_id;
AttrNumber jf_xc_wholerow;
AttrNumber jf_xc_part_id;
AttrNumber jf_xc_bucket_id;
List* jf_primary_keys;
#endif
} JunkFilter;
typedef struct MergeState {
List* matchedActionStates;
List* notMatchedActionStates;
} MergeState;
* Expression State Trees
*
* Each executable expression tree has a parallel ExprState tree.
*
* Unlike PlanState, there is not an exact one-for-one correspondence between
* ExprState node types and Expr node types. Many Expr node types have no
* need for node-type-specific run-time state, and so they can use plain
* ExprState or GenericExprState as their associated ExprState node type.
* ----------------------------------------------------------------
*/
* ExprState node
*
* ExprState is the common superclass for all ExprState-type nodes.
*
* It can also be instantiated directly for leaf Expr nodes that need no
* local run-time state (such as Var, Const, or Param).
*
* To save on dispatch overhead, each ExprState node contains a function
* pointer to the routine to execute to evaluate the node.
* ----------------
*/
struct ExprState;
typedef Datum (*ExprStateEvalFunc)(ExprState* expression, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);
typedef ScalarVector* (*VectorExprFun)(
ExprState* expression, ExprContext* econtext, bool* selVector, ScalarVector* inputVector, ExprDoneCond* isDone);
typedef void* (*exprFakeCodeGenSig)(void*);
#define EEO_FLAG_IS_QUAL (1 << 0)
struct ExprState {
NodeTag type;
uint8 flags;
* Storage for result value of a scalar expression, or for individual
* column results within expressions built by ExecBuildProjectionInfo().
*/
bool resnull;
Datum resvalue;
* If projecting a tuple result, this slot holds the result; else NULL.
*/
TupleTableSlot *resultslot;
* Instructions to compute expression's return value.
*/
struct ExprEvalStep *steps;
* Function that actually evaluates the expression. This can be set to
* different values depending on the complexity of the expression.
*/
ExprStateEvalFunc evalfunc;
Expr *expr;
void *evalfunc_private;
* XXX: following fields only needed during "compilation" (ExecInitExpr);
* could be thrown away afterwards.
*/
int steps_len;
int steps_alloc;
struct PlanState *parent;
Datum *innermost_caseval;
bool *innermost_casenull;
Datum *innermost_domainval;
bool *innermost_domainnull;
ListCell *current_targetentry;
VectorExprFun vecExprFun;
exprFakeCodeGenSig exprCodeGen;
bool is_flt_frame;
ScalarVector tmpVector;
Oid resultType;
};
* ProjectionInfo node information
*
* This is all the information needed to perform projections ---
* that is, form new tuples by evaluation of targetlist expressions.
* Nodes which need to do projections create one of these.
*
* ExecProject() evaluates the tlist, forms a tuple, and stores it
* in the given slot. Note that the result will be a "virtual" tuple
* unless ExecMaterializeSlot() is then called to force it to be
* converted to a physical tuple. The slot must have a tupledesc
* that matches the output of the tlist!
*
* The planner very often produces tlists that consist entirely of
* simple Var references (lower levels of a plan tree almost always
* look like that). And top-level tlists are often mostly Vars too.
* We therefore optimize execution of simple-Var tlist entries.
* The pi_targetlist list actually contains only the tlist entries that
* aren't simple Vars, while those that are Vars are processed using the
* varSlotOffsets/varNumbers/varOutputCols arrays.
*
* The lastXXXVar fields are used to optimize fetching of fields from
* input tuples: they let us do a slot_getsomeattrs() call to ensure
* that all needed attributes are extracted in one pass.
*
* targetlist target list for projection (non-Var expressions only)
* exprContext expression context in which to evaluate targetlist
* slot slot to place projection result in
* itemIsDone workspace array for ExecProject
* directMap true if varOutputCols[] is an identity map
* numSimpleVars number of simple Vars found in original tlist
* varSlotOffsets array indicating which slot each simple Var is from
* varNumbers array containing input attr numbers of simple Vars
* varOutputCols array containing output attr numbers of simple Vars
* lastInnerVar highest attnum from inner tuple slot (0 if none)
* lastOuterVar highest attnum from outer tuple slot (0 if none)
* lastScanVar highest attnum from scan tuple slot (0 if none)
* pi_maxOrmin column table optimize, indicate if get this column's max or min.
* ----------------
*/
typedef bool (*vectarget_func)(ExprContext* econtext, VectorBatch* pBatch);
typedef struct ProjectionInfo {
NodeTag type;
List* pi_targetlist;
ExprState pi_state;
ExprContext* pi_exprContext;
TupleTableSlot* pi_slot;
ExprDoneCond* pi_itemIsDone;
bool pi_directMap;
bool pi_topPlan;
int pi_numSimpleVars;
int* pi_varSlotOffsets;
int* pi_varNumbers;
int* pi_varOutputCols;
int pi_lastInnerVar;
int pi_lastOuterVar;
int pi_lastScanVar;
List* pi_projectVarNumbers;
List* pi_acessedVarNumbers;
List* pi_sysAttrList;
List* pi_lateAceessVarNumbers;
List* pi_maxOrmin;
List* pi_PackTCopyVars;
List* pi_PackLateAccessVarNumbers;
scan.*/
bool pi_const;
ExprDoneCond* pi_vec_itemIsDone;
VectorBatch* pi_batch;
vectarget_func jitted_vectarget;
VectorBatch* pi_setFuncBatch;
bool isUpsertHasRightRef;
} ProjectionInfo;
* ResultRelInfo information
*
* Whenever we update an existing relation, we have to
* update indices on the relation, and perhaps also fire triggers.
* The ResultRelInfo class is used to hold all the information needed
* about a result relation, including indices.. -cim 10/15/89
*
* RangeTableIndex result relation's range table index
* RelationDesc relation descriptor for result relation
* NumIndices # of indices existing on result relation
* ri_ContainGPI indices whether contain global parition index
* IndexRelationDescs array of relation descriptors for indices
* IndexRelationInfo array of key/attr info for indices
* TrigDesc triggers to be fired, if any
* TrigFunctions cached lookup info for trigger functions
* TrigWhenExprs array of trigger WHEN expr states
* TrigInstrument optional runtime measurements for triggers
* FdwRoutine FDW callback functions, if foreign table
* FdwState available to save private state of FDW
* ConstraintExprs array of constraint-checking expr states
* junkFilter for removing junk attributes from tuples
* projectReturning for computing a RETURNING list
* updateProj for computing a UPSERT update list
* WithCheckOptions list of WithCheckOption's for views
* WithCheckOptionExprs list of WithCheckOption expr states
* ----------------
*/
typedef struct ResultRelInfo {
NodeTag type;
Index ri_RangeTableIndex;
Relation ri_RelationDesc;
int ri_NumIndices;
bool ri_ContainGPI;
RelationPtr ri_IndexRelationDescs;
IndexInfo** ri_IndexRelationInfo;
TriggerDesc* ri_TrigDesc;
FmgrInfo* ri_TrigFunctions;
List** ri_TrigWhenExprs;
Instrumentation* ri_TrigInstrument;
struct FdwRoutine* ri_FdwRoutine;
void* ri_FdwState;
List** ri_ConstraintExprs;
JunkFilter* ri_junkFilter;
AttrNumber ri_partOidAttNum;
AttrNumber ri_bucketIdAttNum;
ProjectionInfo* ri_projectReturning;
MergeState* ri_mergeState;
* While executing MERGE, the target relation is processed twice; once
* as a target relation and once to run a join between the target and the
* source. We generate two different RTEs for these two purposes, one with
* rte->inh set to false and other with rte->inh set to true.
*
* Since the plan re-evaluated by EvalPlanQual uses the join RTE, we must
* install the updated tuple in the scan corresponding to that RTE. The
* following member tracks the index of the second RTE for EvalPlanQual
* purposes. ri_mergeTargetRTI is non-zero only when MERGE is in-progress.
* We use ri_mergeTargetRTI to run EvalPlanQual for MERGE and
* ri_RangeTableIndex elsewhere.
*/
Index ri_mergeTargetRTI;
ProjectionInfo* ri_updateProj;
ExprState **ri_GeneratedExprs;
ExprState **ri_UpdatedExprs;
int ri_NumGeneratedNeeded;
int ri_NumUpdatedNeeded;
List* ri_WithCheckOptions;
List* ri_WithCheckOptionExprs;
ProjectionInfo* ri_updateWhere;
#ifdef USE_SPQ
AttrNumber ri_actionAttno;
#endif
int ri_NumUnusableIndices;
RelationPtr ri_UnusableIndexRelationDescs;
IndexInfo** ri_UnusableIndexRelationInfo;
} ResultRelInfo;
typedef struct BloomFilterControl {
filter::BloomFilter** bfarray;
int array_size;
} BloomFilterControl;
#define InvalidBktId (-1)
* EState information
*
* Master working state for an Executor invocation
* ----------------
*/
typedef struct EState {
NodeTag type;
ScanDirection es_direction;
Snapshot es_snapshot;
Snapshot es_crosscheck_snapshot;
List* es_range_table;
PlannedStmt* es_plannedstmt;
JunkFilter* es_junkFilter;
CommandId es_output_cid;
bool es_is_flt_frame;
ResultRelInfo* es_result_relations;
int es_num_result_relations;
ResultRelInfo* es_result_relation_info;
Relation esCurrentPartition;
HTAB* esfRelations;
#ifdef PGXC
struct PlanState* es_result_remoterel;
struct PlanState* es_result_insert_remoterel;
struct PlanState* es_result_update_remoterel;
struct PlanState* es_result_delete_remoterel;
#endif
List* es_trig_target_relations;
TupleTableSlot* es_trig_tuple_slot;
TupleTableSlot* es_trig_oldtup_slot;
TupleTableSlot* es_trig_newtup_slot;
ParamListInfo es_param_list_info;
ParamExecData* es_param_exec_vals;
MemoryContext es_query_cxt;
MemoryContext es_const_query_cxt;
List* es_tupleTable;
List* es_rowMarks;
List *es_modifiedRowHash;
uint64 es_processed;
uint64 deleteLimitCount;
bool withLimitCount;
uint64 es_last_processed;
Oid es_lastoid;
int es_top_eflags;
int es_instrument;
bool es_finished;
List* es_exprcontexts;
List* es_subplanstates;
List* es_auxmodifytables;
List* es_remotequerystates;
* this ExprContext is for per-output-tuple operations, such as constraint
* checks and index-value computations. It will be reset for each output
* tuple. Note that it will be created only if needed.
*/
ExprContext* es_per_tuple_exprcontext;
* These fields are for re-evaluating plan quals when an updated tuple is
* substituted in READ COMMITTED mode. es_epqTuple[] contains tuples that
* scan plan nodes should return instead of whatever they'd normally
* return, or NULL if nothing to return; es_epqTupleSet[] is true if a
* particular array entry is valid; and es_epqScanDone[] is state to
* remember if the tuple has been returned already. Arrays are of size
* list_length(es_range_table) and are indexed by scan node scanrelid - 1.
*/
Tuple* es_epqTuple;
TupleTableSlot** es_epqTupleSlot;
bool* es_epqTupleSet;
bool* es_epqScanDone;
List* es_subplan_ids;
bool es_skip_early_free;
bool es_skip_early_deinit_consumer;
bool es_under_subplan;
List* es_material_of_subplan;
bool es_recursive_next_iteration;
* dataDestRelIndex is index into the range table. This variable
* will take effect on data redistribution state.
*/
Index dataDestRelIndex;
BloomFilterControl es_bloom_filter;
bool es_can_realtime_statistics;
bool es_can_history_statistics;
bool isRowTriggerShippable;
#ifdef ENABLE_MOT
JitExec::MotJitContext* mot_jit_context;
#endif
PruningResult* pruningResult;
bool have_current_xact_date;
int128 first_autoinc;
int result_rel_index;
int128 cur_insert_autoinc;
int128 next_autoinc;
#ifdef USE_SPQ
List *es_sharenode;
#endif
bool compileCodegen;
} EState;
* ExecRowMark -
* runtime representation of FOR UPDATE/SHARE clauses
*
* When doing UPDATE, DELETE, or SELECT FOR UPDATE/SHARE, we should have an
* ExecRowMark for each non-target relation in the query (except inheritance
* parent RTEs, which can be ignored at runtime). See PlanRowMark for details
* about most of the fields. In addition to fields directly derived from
* PlanRowMark, we store curCtid, which is used by the WHERE CURRENT OF code.
*
* EState->es_rowMarks is a list of these structs.
*/
typedef struct ExecRowMark {
Relation relation;
Index rti;
Index prti;
Index rowmarkId;
RowMarkType markType;
LockWaitPolicy waitPolicy;
int waitSec;
ItemPointerData curCtid;
int numAttrs;
} ExecRowMark;
#define PREV_HASH_LEN 36
* ExecModifiedRowHash -
* store previous hash of modified row.
*
*/
typedef struct ExecModifiedRowHash {
char hash[PREV_HASH_LEN];
} ExecModifiedRowHash;
* ExecAuxRowMark -
* additional runtime representation of FOR UPDATE/SHARE clauses
*
* Each LockRows and ModifyTable node keeps a list of the rowmarks it needs to
* deal with. In addition to a pointer to the related entry in es_rowMarks,
* this struct carries the column number(s) of the resjunk columns associated
* with the rowmark (see comments for PlanRowMark for more detail). In the
* case of ModifyTable, there has to be a separate ExecAuxRowMark list for
* each child plan, because the resjunk columns could be at different physical
* column positions in different subplans.
*/
typedef struct ExecAuxRowMark {
ExecRowMark* rowmark;
AttrNumber ctidAttNo;
AttrNumber toidAttNo;
AttrNumber tbidAttNo;
AttrNumber wholeAttNo;
} ExecAuxRowMark;
* Tuple Hash Tables
*
* All-in-memory tuple hash tables are used for a number of purposes.
*
* Note: tab_hash_funcs are for the key datatype(s) stored in the table,
* and tab_eq_funcs are non-cross-type equality operators for those types.
* Normally these are the only functions used, but FindTupleHashEntry()
* supports searching a hashtable using cross-data-type hashing. For that,
* the caller must supply hash functions for the LHS datatype as well as
* the cross-type equality operators to use. in_hash_funcs and cur_eq_funcs
* are set to point to the caller's function arrays while doing such a search.
* During LookupTupleHashEntry(), they point to tab_hash_funcs and
* tab_eq_funcs respectively.
* ----------------------------------------------------------------
*/
typedef struct TupleHashEntryData* TupleHashEntry;
typedef struct TupleHashTableData* TupleHashTable;
typedef struct TupleHashEntryData {
MinimalTuple firstTuple;
} TupleHashEntryData;
typedef struct TupleHashTableData {
HTAB* hashtab;
int numCols;
AttrNumber* keyColIdx;
FmgrInfo* tab_hash_funcs;
FmgrInfo* tab_eq_funcs;
MemoryContext tablecxt;
MemoryContext tempcxt;
Size entrysize;
TupleTableSlot* tableslot;
TupleTableSlot* inputslot;
FmgrInfo* in_hash_funcs;
FmgrInfo* cur_eq_funcs;
int64 width;
bool add_width;
bool causedBySysRes;
Oid *tab_collations;
} TupleHashTableData;
typedef HASH_SEQ_STATUS TupleHashIterator;
* Use InitTupleHashIterator/TermTupleHashIterator for a read/write scan.
* Use ResetTupleHashIterator if the table can be frozen (in this case no
* explicit scan termination is needed).
*/
#define InitTupleHashIterator(htable, iter) hash_seq_init(iter, (htable)->hashtab)
#define TermTupleHashIterator(iter) hash_seq_term(iter)
#define ResetTupleHashIterator(htable, iter) \
do { \
hash_freeze((htable)->hashtab); \
hash_seq_init(iter, (htable)->hashtab); \
} while (0)
#define ScanTupleHashTable(iter) ((TupleHashEntry)hash_seq_search(iter))
* GenericExprState node
*
* This is used for Expr node types that need no local run-time state,
* but have one child Expr node.
* ----------------
*/
typedef struct GenericExprState {
ExprState xprstate;
ExprState* arg;
} GenericExprState;
* WholeRowVarExprState node
* ----------------
*/
typedef struct WholeRowVarExprState {
ExprState xprstate;
struct PlanState* parent;
JunkFilter* wrv_junkFilter;
} WholeRowVarExprState;
* AggrefExprState node
* ----------------
*/
typedef struct AggrefExprState {
ExprState xprstate;
Aggref *aggref;
List* aggdirectargs;
List* args;
ExprState* aggfilter;
int aggno;
int m_htbOffset;
} AggrefExprState;
* WindowFuncExprState node
* ----------------
*/
typedef struct WindowFuncExprState {
ExprState xprstate;
WindowFunc *wfunc;
List* args;
int wfuncno;
ScalarVector* m_resultVector;
List *keep_args;
bool keep_first;
} WindowFuncExprState;
* ArrayRefExprState node
*
* Note: array types can be fixed-length (typlen > 0), but only when the
* element type is itself fixed-length. Otherwise they are varlena structures
* and have typlen = -1. In any case, an array type is never pass-by-value.
* ----------------
*/
typedef struct ArrayRefExprState {
ExprState xprstate;
List* refupperindexpr;
List* reflowerindexpr;
ExprState* refexpr;
ExprState* refassgnexpr;
int16 refattrlength;
int16 refelemlength;
bool refelembyval;
char refelemalign;
} ArrayRefExprState;
* FuncExprState node
*
* Although named for FuncExpr, this is also used for OpExpr, DistinctExpr,
* and NullIf nodes; be careful to check what xprstate.expr is actually
* pointing at!
* ----------------
*/
typedef struct FuncExprState {
ExprState xprstate;
List* args;
char* fmtstr;
char* nlsfmtstr;
char prokind;
* Function manager's lookup info for the target function. If func.fn_oid
* is InvalidOid, we haven't initialized it yet (nor any of the following
* fields, except funcReturnsSet).
*/
FmgrInfo func;
* For a set-returning function (SRF) that returns a tuplestore, we keep
* the tuplestore here and dole out the result rows one at a time. The
* slot holds the row currently being returned.
*/
Tuplestorestate* funcResultStore;
TupleTableSlot* funcResultSlot;
* In some cases we need to compute a tuple descriptor for the function's
* output. If so, it's stored here.
*/
TupleDesc funcResultDesc;
bool funcReturnsTuple;
* NULL */
* Remember whether the function is declared to return a set. This is set
* by ExecInitExpr, and is valid even before the FmgrInfo is set up.
*/
bool funcReturnsSet;
* setArgsValid is true when we are evaluating a set-returning function
* that uses value-per-call mode and we are in the middle of a call
* series; we want to pass the same argument values to the function again
* (and again, until it returns ExprEndResult). This indicates that
* fcinfo_data already contains valid argument data.
*/
bool setArgsValid;
bool setArgByVal;
bool setHasSetArg;
bool is_plpgsql_func_with_outparam;
bool has_refcursor;
* Flag to remember whether we have registered a shutdown callback for
* this FuncExprState. We do so only if funcResultStore or setArgsValid
* has been set at least once (since all the callback is for is to release
* the tuplestore or clear setArgsValid).
*/
bool shutdown_reg;
* Call parameter structure for the function. This has been initialized
* (by InitFunctionCallInfoData) if func.fn_oid is valid. It also saves
* argument values between calls, when setArgsValid is true.
*/
FunctionCallInfoData fcinfo_data;
ScalarVector* tmpVec;
bool vec_setHasSetArg;
} FuncExprState;
* ScalarArrayOpExprState node
*
* This is a FuncExprState plus some additional data.
* ----------------
*/
typedef struct ScalarArrayOpExprState {
FuncExprState fxprstate;
Oid element_type;
int16 typlen;
bool typbyval;
char typalign;
bool* pSel;
ScalarVector *tmpVecLeft;
ScalarVector *tmpVecRight;
ScalarVector* tmpVec;
} ScalarArrayOpExprState;
* BoolExprState node
* ----------------
*/
typedef struct BoolExprState {
ExprState xprstate;
List* args;
bool tmpSelection[BatchMaxSize];
} BoolExprState;
* SubPlanState node
* ----------------
*/
typedef struct SubPlanState {
ExprState xprstate;
struct PlanState* planstate;
ExprState* testexpr;
List* args;
ExprState* row_testexpr;
HeapTuple curTuple;
Datum curArray;
ProjectionInfo* projLeft;
ProjectionInfo* projRight;
TupleHashTable hashtable;
TupleHashTable hashnulls;
bool havehashrows;
bool havenullrows;
MemoryContext hashtablecxt;
MemoryContext hashtempcxt;
ExprContext* innerecontext;
AttrNumber* keyColIdx;
FmgrInfo* tab_hash_funcs;
FmgrInfo* tab_eq_funcs;
FmgrInfo* lhs_hash_funcs;
FmgrInfo* cur_eq_funcs;
int idx;
ScalarVector** pParamVectorArray;
ScalarVector** pParamVectorTmp;
bool* pSel;
VectorBatch* outExprBatch;
VectorBatch* innerExprBatch;
VectorBatch* scanExprBatch;
VectorBatch* aggExprBatch;
ScalarVector* tempvector;
MemoryContext ecxt_per_batch_memory;
Oid *tab_collations;
} SubPlanState;
* AlternativeSubPlanState node
* ----------------
*/
typedef struct AlternativeSubPlanState {
ExprState xprstate;
AlternativeSubPlan* subplan;
List* subplans;
int active;
} AlternativeSubPlanState;
* FieldSelectState node
* ----------------
*/
typedef struct FieldSelectState {
ExprState xprstate;
ExprState* arg;
TupleDesc argdesc;
} FieldSelectState;
* FieldStoreState node
* ----------------
*/
typedef struct FieldStoreState {
ExprState xprstate;
ExprState* arg;
List* newvals;
TupleDesc argdesc;
} FieldStoreState;
* CoerceViaIOState node
* ----------------
*/
typedef struct CoerceViaIOState {
ExprState xprstate;
ExprState* arg;
char* fmtstr;
char* nlsfmtstr;
FmgrInfo outfunc;
FmgrInfo infunc;
Oid intypioparam;
} CoerceViaIOState;
* ArrayCoerceExprState node
* ----------------
*/
typedef struct ArrayCoerceExprState {
ExprState xprstate;
ExprState* arg;
char* fmtstr;
char* nlsfmtstr;
Oid resultelemtype;
FmgrInfo elemfunc;
struct ArrayMapState* amstate;
} ArrayCoerceExprState;
* ConvertRowtypeExprState node
* ----------------
*/
typedef struct ConvertRowtypeExprState {
ExprState xprstate;
ExprState* arg;
TupleDesc indesc;
TupleDesc outdesc;
struct TupleConversionMap* map;
bool initialized;
} ConvertRowtypeExprState;
* CaseExprState node
* ----------------
*/
typedef struct CaseExprState {
ExprState xprstate;
ExprState* arg;
List* args;
ExprState* defresult;
bool* matchedResult;
bool* localSel;
ScalarVector* save_vector;
} CaseExprState;
* CaseWhenState node
* ----------------
*/
typedef struct CaseWhenState {
ExprState xprstate;
ExprState* expr;
ExprState* result;
} CaseWhenState;
* ArrayExprState node
*
* Note: ARRAY[] expressions always produce varlena arrays, never fixed-length
* arrays.
* ----------------
*/
typedef struct ArrayExprState {
ExprState xprstate;
List* elements;
int16 elemlength;
bool elembyval;
char elemalign;
} ArrayExprState;
* RowExprState node
* ----------------
*/
typedef struct RowExprState {
ExprState xprstate;
List* args;
TupleDesc tupdesc;
VectorBatch* rowBatch;
} RowExprState;
* RowCompareExprState node
* ----------------
*/
typedef struct RowCompareExprState {
ExprState xprstate;
List* largs;
List* rargs;
FmgrInfo* funcs;
Oid* collations;
FunctionCallInfoData* cinfo;
ScalarVector* left_argvec;
ScalarVector* right_argvec;
ScalarVector* cmpresult;
bool* pSel;
} RowCompareExprState;
* CoalesceExprState node
* ----------------
*/
typedef struct CoalesceExprState {
ExprState xprstate;
List* args;
bool* pSel;
} CoalesceExprState;
* MinMaxExprState node
* ----------------
*/
typedef struct MinMaxExprState {
ExprState xprstate;
List* args;
List* cmpargs;
FmgrInfo cfunc;
FunctionCallInfoData cinfo;
ScalarVector* argvec;
ScalarVector* cmpresult;
bool* pSel;
} MinMaxExprState;
* XmlExprState node
* ----------------
*/
typedef struct XmlExprState {
ExprState xprstate;
List* named_args;
List* args;
} XmlExprState;
* NullTestState node
* ----------------
*/
typedef struct NullTestState {
ExprState xprstate;
ExprState* arg;
TupleDesc argdesc;
} NullTestState;
* NanTestState node
* ----------------
*/
typedef struct NanTestState {
ExprState xprstate;
ExprState* arg;
} NanTestState;
* InfiniteTestState node
* ----------------
*/
typedef struct InfiniteTestState {
ExprState xprstate;
ExprState* arg;
} InfiniteTestState;
* HashFilterState node
* ----------------
*/
typedef struct HashFilterState {
ExprState xprstate;
List* arg;
uint2* nodelist;
uint2* bucketMap;
int bucketCnt;
} HashFilterState;
* CoerceToDomainState node
* ----------------
*/
typedef struct CoerceToDomainState {
ExprState xprstate;
ExprState* arg;
List* constraints;
} CoerceToDomainState;
* DomainConstraintState - one item to check during CoerceToDomain
*
* Note: this is just a Node, and not an ExprState, because it has no
* corresponding Expr to link to. Nonetheless it is part of an ExprState
* tree, so we give it a name following the xxxState convention.
*/
typedef enum DomainConstraintType { DOM_CONSTRAINT_NOTNULL, DOM_CONSTRAINT_CHECK } DomainConstraintType;
typedef struct DomainConstraintState {
NodeTag type;
DomainConstraintType constrainttype;
char* name;
Expr *check_node;
ExprState *check_expr;
} DomainConstraintState;
typedef struct HbktScanSlot {
int currSlot;
} HbktScanSlot;
* Executor State Trees
*
* An executing query has a PlanState tree paralleling the Plan tree
* that describes the plan.
* ----------------------------------------------------------------
*/
typedef enum {
PST_None = 0,
PST_Norm = 1,
PST_Scan = 2
} PlanStubType;
struct PlanState;
* ExecProcNodeMtd
*
* This is the method called by ExecProcNode to return the next tuple
* from an executor node. It returns NULL, or an empty TupleTableSlot,
* if no more tuples are available.
* ----------------
*/
typedef TupleTableSlot *(*ExecProcNodeMtd)(struct PlanState *pstate);
* PlanState node
*
* We never actually instantiate any PlanState nodes; this is just the common
* abstract superclass for all PlanState-type nodes.
* ----------------
*/
typedef struct PlanState {
NodeTag type;
Plan* plan;
EState* state;
* nodes point to one EState for the whole
* top-level plan */
ExecProcNodeMtd ExecProcNode;
ExecProcNodeMtd ExecProcNodeReal;
* wrapper */
Instrumentation* instrument;
MemoryContext nodeContext;
* Common structural data for all Plan types. These links to subsidiary
* state trees parallel links in the associated plan tree (except for the
* subPlan list, which does not exist in the plan tree).
*/
List* qual;
struct PlanState* lefttree;
struct PlanState* righttree;
List* initPlan;
List* subPlan;
* State for management of parameter-change-driven rescanning
*/
Bitmapset* chgParam;
* Other run-time state needed by most if not all node types.
*/
TupleTableSlot* ps_ResultTupleSlot;
ExprContext* ps_ExprContext;
ProjectionInfo* ps_ProjInfo;
int64 ps_rownum;
List* targetlist;
HbktScanSlot hbktScanSlot;
bool vectorized;
bool earlyFreed;
uint8 stubType;
bool recursive_reset;
bool qual_is_inited;
bool do_not_reset_rownum;
bool ps_vec_TupFromTlist;
vectarget_func jitted_vectarget;
* Describe issues found in curernt plan node, mainly used for issue de-duplication
* of data skew and inaccurate e-rows
*/
List* plan_issues;
} PlanState;
static inline bool planstate_need_stub(PlanState* ps)
{
return ps->stubType != PST_None;
}
* these are defined to avoid confusion problems with "left"
* and "right" and "inner" and "outer". The convention is that
* the "left" plan is the "outer" plan and the "right" plan is
* the inner plan, but these make the code more readable.
* ----------------
*/
#define innerPlanState(node) (((PlanState*)(node))->righttree)
#define outerPlanState(node) (((PlanState*)(node))->lefttree)
#define InstrCountFiltered1(node, delta) \
do { \
if (((PlanState*)(node))->instrument) \
((PlanState*)(node))->instrument->nfiltered1 += (delta); \
} while (0)
#define InstrCountFiltered2(node, delta) \
do { \
if (((PlanState*)(node))->instrument) \
((PlanState*)(node))->instrument->nfiltered2 += (delta); \
} while (0)
* EPQState is state for executing an EvalPlanQual recheck on a candidate
* tuple in ModifyTable or LockRows. The estate and planstate fields are
* NULL if inactive.
*/
typedef struct EPQState {
EState* estate;
PlanState* planstate;
TupleTableSlot* origslot;
Plan* plan;
List* arowMarks;
int epqParam;
* We need its memory context to palloc es_epqTupleSlot if needed
*/
EState *parentestate;
ProjectionInfo** projInfos;
} EPQState;
* ResultState information
* ----------------
*/
typedef struct ResultState {
PlanState ps;
ExprState* resconstantqual;
bool rs_done;
bool rs_checkqual;
} ResultState;
* MergeActionState information
* ----------------
*/
typedef struct MergeActionState {
NodeTag type;
bool matched;
ExprState* whenqual;
CmdType commandType;
ProjectionInfo* proj;
TupleDesc tupDesc;
JunkFilter* junkfilter;
VectorBatch* scanBatch;
} MergeActionState;
* UpsertState information
* ----------------
*/
typedef struct UpsertState
{
NodeTag type;
UpsertAction us_action;
TupleTableSlot *us_existing;
List *us_excludedtlist;
TupleTableSlot *us_updateproj;
List *us_updateWhere;
} UpsertState;
* ProjectSetState information
* ----------------
*/
typedef struct ProjectSetState {
PlanState ps;
Node **elems;
ExprDoneCond *elemdone;
int nelems;
bool pending_srf_tuples;
MemoryContext argcontext;
} ProjectSetState;
* ModifyTableState information
* ----------------
*/
typedef struct ModifyTableState {
PlanState ps;
CmdType operation;
bool canSetTag;
bool mt_done;
bool isReplace;
bool isConflict;
bool isinherit;
PlanState** mt_plans;
#ifdef PGXC
PlanState** mt_remoterels;
PlanState** mt_insert_remoterels;
PlanState** mt_update_remoterels;
PlanState** mt_delete_remoterels;
#endif
int mt_nplans;
int mt_whichplan;
ResultRelInfo* resultRelInfo;
List** mt_arowmarks;
EPQState mt_epqstate;
bool fireBSTriggers;
Relation delete_delta_rel;
Relation errorRel;
ErrorCacheEntry* cacheEnt;
TupleTableSlot* mt_scan_slot;
TupleTableSlot* mt_update_constr_slot;
TupleTableSlot* mt_insert_constr_slot;
TupleTableSlot* mt_mergeproj;
uint32 mt_merge_subcommands;
UpsertState* mt_upsert;
instr_time first_tuple_modified;
ExprContext* limitExprContext;
List* targetlists;
List* mt_ResultTupleSlots;
ProjectionInfo** mt_ProjInfos;
char** partExprKeyStrArray;
#ifdef USE_SPQ
bool* mt_isSplitUpdates;
#endif
} ModifyTableState;
typedef struct CopyFromManagerData* CopyFromManager;
typedef struct DistInsertSelectState {
ModifyTableState mt;
int rows;
MemoryContext insert_mcxt;
CopyFromManager mgr;
BulkInsertState bistate;
PageCompress* pcState;
} DistInsertSelectState;
* AppendState information
*
* nplans how many plans are in the array
* whichplan which plan is being executed (0 .. n-1)
* ----------------
*/
typedef struct AppendState {
PlanState ps;
PlanState** appendplans;
int as_nplans;
int as_whichplan;
} AppendState;
* MergeAppendState information
*
* nplans how many plans are in the array
* nkeys number of sort key columns
* sortkeys sort keys in SortSupport representation
* slots current output tuple of each subplan
* heap heap of active tuples (represented as array indexes)
* heap_size number of active heap entries
* initialized true if we have fetched first tuple from each subplan
* last_slot last subplan fetched from (which must be re-called)
* ----------------
*/
typedef struct MergeAppendState {
PlanState ps;
PlanState** mergeplans;
int ms_nplans;
int ms_nkeys;
SortSupport ms_sortkeys;
TupleTableSlot** ms_slots;
int* ms_heap;
int ms_heap_size;
bool ms_initialized;
int ms_last_slot;
} MergeAppendState;
* RecursiveUnionState information
*
* RecursiveUnionState is used for performing a recursive union.
*
* recursing T when we're done scanning the non-recursive term
* intermediate_empty T if intermediate_table is currently empty
* working_table working table (to be scanned by recursive term)
* intermediate_table current recursive output (next generation of WT)
* ----------------
*/
struct StartWithOpState;
struct RecursiveUnionController;
typedef struct RecursiveUnionState {
PlanState ps;
bool recursing;
bool intermediate_empty;
Tuplestorestate* working_table;
Tuplestorestate* intermediate_table;
int iteration;
FmgrInfo* eqfunctions;
FmgrInfo* hashfunctions;
MemoryContext tempContext;
TupleHashTable hashtable;
MemoryContext tableContext;
MemoryContext convertContext;
* MPP with-recursive support
*/
RecursiveUnionController* rucontroller;
uint64 step_tuple_produced;
* The share memory context pointer that is used in distributed recursive CTE
* processing where WorkTable is access via different stream threads, we need
* put it on higher level of memory context to persists the whole query runing
* stage.
*/
MemoryContext shareContext;
StartWithOpState *swstate;
* tuple's index of relative order position in current iteration level
* only useful once start with...connect by..siblings all exist.
*/
uint64 sw_tuple_idx;
} RecursiveUnionState;
typedef struct SWDfsOpState
{
List** prior_key_stack;
List** tuples_stack;
int stack_size;
int cur_level;
int cur_rownum;
TupleTableSlot* last_ru_slot;
} SWDfsOpState;
* StartWithOpState information
* ----------------
*/
#define PSEUDO_COLUMN_NUM 4
typedef struct StartWithOpState
{
PlanState ps;
int swop_status;
* An array of TargetEntry reference to store the entry for start-with pseudo
* return columns's TLE
* - entry[0] LEVEL
* - entry[1] CONNECT_BY_ISLEAF
* - entry[2] CONNECT_BY_ISCYCLE
* - entry[3] ROWNUM
*/
TargetEntry *sw_pseudoCols[PSEUDO_COLUMN_NUM];
IterationStats iterStats;
TupleTableSlot *sw_workingSlot;
conversion in side of StartWithOp node,
basically do not share use result tuple
to to avoid to tuple store,fetch,
conversion mess up */
Tuplestorestate *sw_workingTable;
one-by-on and store into resultTable */
Tuplestorestate *sw_backupTable;
Tuplestorestate *sw_resultTable;
AttrNumber sw_keyAttnum;
const char *sw_curKeyArrayStr;
Datum *sw_values;
bool *sw_isnull;
int sw_connect_by_level;
uint64 sw_rownum;
int sw_level;
int sw_numtuples;
MemoryContext sw_context;
List* sw_cycle_rowmarks;
List* sw_leaf_rowmarks;
List* connect_by_qual;
List* start_with_qual;
SWDfsOpState* dfs_state;
} StartWithOpState;
* BitmapAndState information
* ----------------
*/
typedef struct BitmapAndState {
PlanState ps;
PlanState** bitmapplans;
int nplans;
} BitmapAndState;
* BitmapOrState information
* ----------------
*/
typedef struct BitmapOrState {
PlanState ps;
PlanState** bitmapplans;
int nplans;
} BitmapOrState;
* Run time predicate information
* ----------------------------------------------------------------
*/
typedef struct RunTimeParamPredicateInfo {
ExprState* paraExecExpr;
Expr* opExpr;
AttrNumber varNoPos;
int32 typeMod;
Oid datumType;
Oid varTypeOid;
int32 paramPosition;
} RunTimeParamPredicateInfo;
* SampleScanInfo information
* ----------------
*/
typedef struct SampleScanParams {
List* args;
ExprState* repeatable;
TableSampleType sampleType;
void* tsm_state;
} SampleScanParams;
* Batch Scan Information
* ----------------------------------------------------------------
*/
struct ScanBatchResult {
int rows;
TupleTableSlot** scanTupleSlotInBatch;
};
struct ScanBatchColAttr {
int colId;
bool lateRead;
bool isProject;
};
struct ScanBatchState {
VectorBatch* pScanBatch;
int scanTupleSlotMaxNum;
int colNum;
int maxcolId;
ScanBatchColAttr* colAttr;
bool *nullflag;
bool scanfinished;
ScanBatchResult scanBatch;
};
* Scan State Information
* ----------------------------------------------------------------
*/
* ScanState information
*
* ScanState extends PlanState for node types that represent
* scans of an underlying relation. It can also be used for nodes
* that scan the output of an underlying plan node --- in that case,
* only ScanTupleSlot is actually useful, and it refers to the tuple
* retrieved from the subplan.
*
* currentRelation relation being scanned (NULL if none)
* currentScanDesc current scan descriptor for scan (NULL if none)
* ScanTupleSlot pointer to slot in tuple table holding scan tuple
* ----------------
*/
struct ScanState;
struct SeqScanAccessor;
* prototypes from functions in execScan.c
*/
typedef TupleTableSlot *(*ExecScanAccessMtd) (ScanState *node);
typedef bool(*ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot);
typedef void (*SeqScanGetNextMtd)(TableScanDesc scan, TupleTableSlot* slot, ScanDirection direction,
bool* has_cur_xact_write);
typedef struct ScanState {
PlanState ps;
Relation ss_currentRelation;
TableScanDesc ss_currentScanDesc;
TupleTableSlot* ss_ScanTupleSlot;
SeqScanGetNextMtd fillNextSlotFunc;
ExecScanAccessMtd ScanNextMtd;
bool scanBatchMode;
bool ss_ReScan;
bool isPartTbl;
bool isSampleScan;
bool runTimePredicatesReady;
bool is_scan_end;
bool isVersionScan;
int currentSlot;
int part_id;
int startPartitionId;
int endPartitionId;
LOCKMODE lockMode;
ScanDirection partScanDirection;
Relation ss_currentPartition;
List* partitions;
List* subpartitions;
List* runTimeParamPredicates;
SeqScanAccessor* ss_scanaccessor;
List* subPartLengthList;
RangeScanInRedis rangeScanInRedis;
SampleScanParams sampleScanInfo;
ScanBatchState* scanBatchState;
Snapshot timecapsuleSnapshot;
} ScanState;
* SeqScan uses a bare ScanState as its state node, since it needs
* no additional fields.
*/
typedef ScanState SeqScanState;
#ifdef USE_SPQ
* SpqSeqScanState
*/
typedef struct SpqSeqScanState {
SeqScanState ss;
void* pageManager;
void* blockManager;
} SpqSeqScanState;
typedef struct AssertOpState {
PlanState ps;
} AssertOpState;
* State of each scanner of the ShareInput node
* ----------------
*/
typedef struct ShareInputScanState {
ScanState ss;
Tuplestorestate *ts_state;
int ts_pos;
struct shareinput_local_state *local_state;
struct shareinput_Xslice_reference *ref;
bool isready;
} ShareInputScanState;
typedef struct SequenceState {
PlanState ps;
PlanState **subplans;
int numSubplans;
* True if no subplan has been executed.
*/
bool initState;
} SequenceState;
* ExecNode for Split.
* This operator contains a Plannode in PlanState.
* The Plannode contains indexes to the ctid, insert, delete, resjunk columns
* needed for adding the action (Insert/Delete).
* A MemoryContext and TupleTableSlot are maintained to keep the INSERT
* tuple until requested.
*/
typedef struct SplitUpdateState {
PlanState ps;
bool processInsert;
TupleTableSlot *insertTuple;
TupleTableSlot *deleteTuple;
} SplitUpdateState;
#endif
* These structs store information about index quals that don't have simple
* constant right-hand sides. See comments for ExecIndexBuildScanKeys()
* for discussion.
*/
typedef struct {
ScanKey scan_key;
ExprState* key_expr;
bool key_toastable;
} IndexRuntimeKeyInfo;
typedef struct {
ScanKey scan_key;
ExprState* array_expr;
int next_elem;
int num_elems;
Datum* elem_values;
bool* elem_nulls;
} IndexArrayKeyInfo;
* IndexScanState information
*
* indexqualorig execution state for indexqualorig expressions
* ScanKeys Skey structures for index quals
* NumScanKeys number of ScanKeys
* OrderByKeys Skey structures for index ordering operators
* NumOrderByKeys number of OrderByKeys
* RuntimeKeys info about Skeys that must be evaluated at runtime
* NumRuntimeKeys number of RuntimeKeys
* RuntimeKeysReady true if runtime Skeys have been computed
* RuntimeContext expr context for evaling runtime Skeys
* RelationDesc index relation descriptor
* ScanDesc index scan descriptor
* ----------------
*/
typedef struct IndexScanState {
ScanState ss;
List* indexqualorig;
ScanKey iss_ScanKeys;
int iss_NumScanKeys;
ScanKey iss_OrderByKeys;
int iss_NumOrderByKeys;
IndexRuntimeKeyInfo* iss_RuntimeKeys;
int iss_NumRuntimeKeys;
bool iss_RuntimeKeysReady;
ExprContext* iss_RuntimeContext;
Relation iss_RelationDesc;
IndexScanDesc iss_ScanDesc;
List* iss_IndexPartitionList;
LOCKMODE lockMode;
Relation iss_CurrentIndexPartition;
} IndexScanState;
* IndexOnlyScanState information
*
* indexqual execution state for indexqual expressions
* ScanKeys Skey structures for index quals
* NumScanKeys number of ScanKeys
* OrderByKeys Skey structures for index ordering operators
* NumOrderByKeys number of OrderByKeys
* RuntimeKeys info about Skeys that must be evaluated at runtime
* NumRuntimeKeys number of RuntimeKeys
* RuntimeKeysReady true if runtime Skeys have been computed
* RuntimeContext expr context for evaling runtime Skeys
* RelationDesc index relation descriptor
* ScanDesc index scan descriptor
* VMBuffer buffer in use for visibility map testing, if any
* HeapFetches number of tuples we were forced to fetch from heap
* ----------------
*/
typedef struct IndexOnlyScanState {
ScanState ss;
List* indexqual;
ScanKey ioss_ScanKeys;
int ioss_NumScanKeys;
ScanKey ioss_OrderByKeys;
int ioss_NumOrderByKeys;
IndexRuntimeKeyInfo* ioss_RuntimeKeys;
int ioss_NumRuntimeKeys;
bool ioss_RuntimeKeysReady;
ExprContext* ioss_RuntimeContext;
Relation ioss_RelationDesc;
IndexScanDesc ioss_ScanDesc;
Buffer ioss_VMBuffer;
long ioss_HeapFetches;
List* ioss_IndexPartitionList;
LOCKMODE lockMode;
Relation ioss_CurrentIndexPartition;
} IndexOnlyScanState;
* BitmapIndexScanState information
*
* result bitmap to return output into, or NULL
* ScanKeys Skey structures for index quals
* NumScanKeys number of ScanKeys
* RuntimeKeys info about Skeys that must be evaluated at runtime
* NumRuntimeKeys number of RuntimeKeys
* ArrayKeys info about Skeys that come from ScalarArrayOpExprs
* NumArrayKeys number of ArrayKeys
* RuntimeKeysReady true if runtime Skeys have been computed
* RuntimeContext expr context for evaling runtime Skeys
* RelationDesc index relation descriptor
* ScanDesc index scan descriptor
* ----------------
*/
typedef struct BitmapIndexScanState {
ScanState ss;
TIDBitmap* biss_result;
ScanKey biss_ScanKeys;
int biss_NumScanKeys;
IndexRuntimeKeyInfo* biss_RuntimeKeys;
int biss_NumRuntimeKeys;
IndexArrayKeyInfo* biss_ArrayKeys;
int biss_NumArrayKeys;
bool biss_RuntimeKeysReady;
ExprContext* biss_RuntimeContext;
Relation biss_RelationDesc;
IndexScanDesc biss_ScanDesc;
List* biss_IndexPartitionList;
LOCKMODE lockMode;
Relation biss_CurrentIndexPartition;
} BitmapIndexScanState;
* BitmapHeapScanState information
*
* bitmapqualorig execution state for bitmapqualorig expressions
* tbm bitmap obtained from child index scan(s)
* tbmiterator iterator for scanning current pages
* tbmres current-page data
* prefetch_iterator iterator for prefetching ahead of current page
* prefetch_pages # pages prefetch iterator is ahead of current
* prefetch_target target prefetch distance
* ----------------
*/
typedef struct BitmapHeapScanState {
ScanState ss;
List* bitmapqualorig;
TIDBitmap* tbm;
TBMIterator* tbmiterator;
TBMIterateResult* tbmres;
long exact_pages;
long lossy_pages;
TBMIterator* prefetch_iterator;
int prefetch_pages;
int prefetch_target;
GPIScanDesc gpi_scan;
CBIScanDesc cbi_scan;
} BitmapHeapScanState;
* AnnIndexScanState information
*
* indexqualorig execution state for indexqualorig expressions
* ScanKeys Skey structures for index quals
* NumScanKeys number of ScanKeys
* OrderByKeys Skey structures for index ordering operators
* NumOrderByKeys number of OrderByKeys
* RuntimeKeys info about Skeys that must be evaluated at runtime
* NumRuntimeKeys number of RuntimeKeys
* RuntimeKeysReady true if runtime Skeys have been computed
* RuntimeContext expr context for evaling runtime Skeys
* RelationDesc index relation descriptor
* ScanDesc index scan descriptor
* ----------------
*/
typedef struct AnnIndexScanState {
ScanState ss;
List* indexqualorig;
ScanKey iss_ScanKeys;
int iss_NumScanKeys;
ScanKey iss_OrderByKeys;
int iss_NumOrderByKeys;
IndexRuntimeKeyInfo* iss_RuntimeKeys;
int iss_NumRuntimeKeys;
bool iss_RuntimeKeysReady;
ExprContext* iss_RuntimeContext;
Relation iss_RelationDesc;
IndexScanDesc iss_ScanDesc;
List* iss_IndexPartitionList;
LOCKMODE lockMode;
Relation iss_CurrentIndexPartition;
double annCount;
} AnnIndexScanState;
* TidScanState information
*
* isCurrentOf scan has a CurrentOfExpr qual
* NumTids number of tids in this scan
* TidPtr index of currently fetched tid
* TidList evaluated item pointers (array of size NumTids)
* ----------------
*/
typedef struct TidScanState {
ScanState ss;
List* tss_tidexprs;
bool tss_isCurrentOf;
Relation tss_CurrentOf_CurrentPartition;
int tss_NumTids;
int tss_TidPtr;
int tss_MarkTidPtr;
ItemPointerData* tss_TidList;
union {
HeapTupleData tss_htup;
UHeapTupleData tss_uhtup;
};
*xs_ctbuf_hdr. t_bits which is varlength arr */
HeapTupleHeaderData tss_ctbuf_hdr;
} TidScanState;
#define SizeofTidScanState (offsetof(TidScanState, tss_ctbuf_hdr) + SizeofHeapTupleHeader)
* TidRangeScanState information
*
* trss_tidexprs list of TidOpExpr structs (see nodeTidrangescan.c)
* trss_mintid the lowest TID in the scan range
* trss_maxtid the highest TID in the scan range
* trss_inScan is a scan currently in progress?
* ----------------
*/
typedef struct TidRangeScanState
{
ScanState ss;
List *trss_tidexprs;
ItemPointerData trss_mintid;
ItemPointerData trss_maxtid;
bool trss_inScan;
} TidRangeScanState;
* SubqueryScanState information
*
* SubqueryScanState is used for scanning a sub-query in the range table.
* ScanTupleSlot references the current output tuple of the sub-query.
* ----------------
*/
typedef struct SubqueryScanState {
ScanState ss;
PlanState* subplan;
} SubqueryScanState;
* FunctionScanState information
*
* Function nodes are used to scan the results of a
* function appearing in FROM (typically a function returning set).
*
* eflags node's capability flags
* tupdesc expected return tuple description
* tuplestorestate private state of tuplestore.c
* funcexpr state for function expression being evaluated
* ----------------
*/
typedef struct FunctionScanState {
ScanState ss;
int eflags;
TupleDesc tupdesc;
Tuplestorestate* tuplestorestate;
ExprState* funcexpr;
bool atomic;
} FunctionScanState;
* ValuesScanState information
*
* ValuesScan nodes are used to scan the results of a VALUES list
*
* rowcontext per-expression-list context
* exprlists array of expression lists being evaluated
* exprstatelists array of expression state lists, for subplans only
* array_len size of above array
* curr_idx current array index (0-based)
* marked_idx marked position (for mark/restore)
*
* Note: ss.ps.ps_ExprContext is used to evaluate any qual or projection
* expressions attached to the node. We create a second ExprContext,
* rowcontext, in which to build the executor expression state for each
* Values sublist. Resetting this context lets us get rid of expression
* state for each row, avoiding major memory leakage over a long values list.
* However, that doesn't work for sublists containing SubPlans, because a
* SubPlan has to be connected up to the outer plan tree to work properly.
* Therefore, for only those sublists containing SubPlans, we do expression
* state construction at executor start, and store those pointers in
* exprstatelists[]. NULL entries in that array correspond to simple
* subexpressions that are handled as described above.
* ----------------
*/
typedef struct ValuesScanState {
ScanState ss;
ExprContext* rowcontext;
List** exprlists;
List** exprstatelists;
int array_len;
int curr_idx;
int marked_idx;
} ValuesScanState;
* CteScanState information
*
* CteScan nodes are used to scan a CommonTableExpr query.
*
* Multiple CteScan nodes can read out from the same CTE query. We use
* a tuplestore to hold rows that have been read from the CTE query but
* not yet consumed by all readers.
* ----------------
*/
typedef struct CteScanState {
ScanState ss;
int eflags;
int readptr;
PlanState* cteplanstate;
struct CteScanState* leader;
Tuplestorestate* cte_table;
bool eof_cte;
} CteScanState;
* WorkTableScanState information
*
* WorkTableScan nodes are used to scan the work table created by
* a RecursiveUnion node. We locate the RecursiveUnion node
* during executor startup.
* ----------------
*/
typedef struct WorkTableScanState {
ScanState ss;
RecursiveUnionState* rustate;
} WorkTableScanState;
* ForeignScanState information
*
* ForeignScan nodes are used to scan foreign-data tables.
* ----------------
*/
typedef struct ForeignScanState {
ScanState ss;
ExprState* fdw_recheck_quals;
struct FdwRoutine* fdwroutine;
void* fdw_state;
MemoryContext scanMcxt;
ForeignOptions* options;
} ForeignScanState;
* ExtensiblePlanState information
*
* ExtensiblePlan nodes are used to execute extensible code within executor.
*
* Core code must avoid assuming that the ExtensiblePlanState is only as large as
* the structure declared here; providers are allowed to make it the first
* element in a larger structure, and typically would need to do so. The
* struct is actually allocated by the CreateExtensiblePlanState method associated
* with the plan node. Any additional fields can be initialized there, or in
* the BeginExtensiblePlan method.
* ----------------
*/
struct ExplainState;
struct ExtensiblePlanState;
typedef struct ExtensibleExecMethods {
const char* ExtensibleName;
void (*BeginExtensiblePlan)(struct ExtensiblePlanState* node, EState* estate, int eflags);
TupleTableSlot* (*ExecExtensiblePlan)(struct ExtensiblePlanState* node);
void (*EndExtensiblePlan)(struct ExtensiblePlanState* node);
void (*ReScanExtensiblePlan)(struct ExtensiblePlanState* node);
void (*ExplainExtensiblePlan)(struct ExtensiblePlanState* node, List* ancestors, struct ExplainState* es);
} ExtensibleExecMethods;
typedef struct ExtensiblePlanState {
ScanState ss;
uint32 flags;
List* extensible_ps;
const ExtensibleExecMethods* methods;
} ExtensiblePlanState;
* Join State Information
* ----------------------------------------------------------------
*/
* JoinState information
*
* Superclass for state nodes of join plans.
* ----------------
*/
typedef struct JoinState {
PlanState ps;
JoinType jointype;
bool single_match;
List* joinqual;
List* nulleqqual;
} JoinState;
* NestLoopState information
*
* NeedNewOuter true if need new outer tuple on next call
* MatchedOuter true if found a join match for current outer tuple
* NullInnerTupleSlot prepared null tuple for left outer joins
* ----------------
*/
typedef struct NestLoopState {
JoinState js;
bool nl_NeedNewOuter;
bool nl_MatchedOuter;
bool nl_MaterialAll;
TupleTableSlot* nl_NullInnerTupleSlot;
#ifdef USE_SPQ
List *nl_InnerJoinKeys;
List *nl_OuterJoinKeys;
bool nl_innerSideScanned;
bool prefetch_inner;
#endif
} NestLoopState;
* MergeJoinState information
*
* NumClauses number of mergejoinable join clauses
* Clauses info for each mergejoinable clause
* JoinState current state of ExecMergeJoin state machine
* SkipMarkRestore true if we may skip Mark and Restore operations
* ExtraMarks true to issue extra Mark operations on inner scan
* ConstFalseJoin true if we have a constant-false joinqual
* FillOuter true if should emit unjoined outer tuples anyway
* FillInner true if should emit unjoined inner tuples anyway
* MatchedOuter true if found a join match for current outer tuple
* MatchedInner true if found a join match for current inner tuple
* OuterTupleSlot slot in tuple table for cur outer tuple
* InnerTupleSlot slot in tuple table for cur inner tuple
* MarkedTupleSlot slot in tuple table for marked tuple
* NullOuterTupleSlot prepared null tuple for right outer joins
* NullInnerTupleSlot prepared null tuple for left outer joins
* OuterEContext workspace for computing outer tuple's join values
* InnerEContext workspace for computing inner tuple's join values
* ----------------
*/
typedef struct MergeJoinClauseData* MergeJoinClause;
typedef struct MergeJoinState {
JoinState js;
int mj_NumClauses;
MergeJoinClause mj_Clauses;
int mj_JoinState;
bool mj_SkipMarkRestore;
bool mj_ExtraMarks;
bool mj_ConstFalseJoin;
bool mj_FillOuter;
bool mj_FillInner;
bool mj_MatchedOuter;
bool mj_MatchedInner;
TupleTableSlot* mj_OuterTupleSlot;
TupleTableSlot* mj_InnerTupleSlot;
TupleTableSlot* mj_MarkedTupleSlot;
TupleTableSlot* mj_NullOuterTupleSlot;
TupleTableSlot* mj_NullInnerTupleSlot;
ExprContext* mj_OuterEContext;
ExprContext* mj_InnerEContext;
} MergeJoinState;
struct MergeJoinShared {
JoinState js;
int mj_NumClauses;
int mj_JoinState;
bool mj_ExtraMarks;
bool mj_ConstFalseJoin;
bool mj_FillOuter;
bool mj_FillInner;
bool mj_MatchedOuter;
bool mj_MatchedInner;
};
typedef struct VecMergeJoinClauseData* VecMergeJoinClause;
struct MJBatchOffset {
uint16 m_offset;
bool m_fEmpty;
bool m_fMarked;
int m_batchSeq;
};
struct BatchAccessor {
PlanState* m_plan;
VectorBatch* m_curBatch;
int m_batchSeq;
int m_curOffset;
int m_maxOffset;
};
struct VecMergeJoinState : public MergeJoinShared {
VecMergeJoinClause mj_Clauses;
MJBatchOffset mj_OuterOffset;
MJBatchOffset mj_InnerOffset;
ExprContext* mj_OuterEContext;
ExprContext* mj_InnerEContext;
MJBatchOffset mj_MarkedOffset;
VectorBatch* mj_MarkedBatch;
BatchAccessor m_inputs[2];
MJBatchOffset m_prevInnerOffset;
bool m_prevInnerQualified;
MJBatchOffset m_prevOuterOffset;
bool m_prevOuterQualified;
bool m_fDone;
VectorBatch* m_pInnerMatch;
MJBatchOffset* m_pInnerOffset;
VectorBatch* m_pOuterMatch;
MJBatchOffset* m_pOuterOffset;
VectorBatch* m_pCurrentBatch;
VectorBatch* m_pReturnBatch;
vecqual_func jitted_joinqual;
};
* HashJoinState information
*
* hashclauses original form of the hashjoin condition
* hj_OuterHashKeys the outer hash keys in the hashjoin condition
* hj_InnerHashKeys the inner hash keys in the hashjoin condition
* hj_HashOperators the join operators in the hashjoin condition
* hj_HashTable hash table for the hashjoin
* (NULL if table not built yet)
* hj_CurHashValue hash value for current outer tuple
* hj_CurBucketNo regular bucket# for current outer tuple
* hj_CurSkewBucketNo skew bucket# for current outer tuple
* hj_CurTuple last inner tuple matched to current outer
* tuple, or NULL if starting search
* (hj_CurXXX variables are undefined if
* OuterTupleSlot is empty!)
* hj_OuterTupleSlot tuple slot for outer tuples
* hj_HashTupleSlot tuple slot for inner (hashed) tuples
* hj_NullOuterTupleSlot prepared null tuple for right/full outer joins
* hj_NullInnerTupleSlot prepared null tuple for left/full outer joins
* hj_FirstOuterTupleSlot first tuple retrieved from outer plan
* hj_JoinState current state of ExecHashJoin state machine
* hj_MatchedOuter true if found a join match for current outer
* hj_OuterNotEmpty true if outer relation known not empty
* ----------------
*/
typedef struct HashJoinTupleData* HashJoinTuple;
typedef struct HashJoinTableData* HashJoinTable;
typedef struct HashJoinState {
JoinState js;
List* hashclauses;
List* hj_OuterHashKeys;
List* hj_InnerHashKeys;
List* hj_HashOperators;
HashJoinTable hj_HashTable;
uint32 hj_CurHashValue;
int hj_CurBucketNo;
int hj_CurSkewBucketNo;
HashJoinTuple hj_CurTuple;
HashJoinTuple hj_PreTuple;
TupleTableSlot* hj_OuterTupleSlot;
TupleTableSlot* hj_HashTupleSlot;
TupleTableSlot* hj_NullOuterTupleSlot;
TupleTableSlot* hj_NullInnerTupleSlot;
TupleTableSlot* hj_FirstOuterTupleSlot;
int hj_JoinState;
bool hj_MatchedOuter;
bool hj_OuterNotEmpty;
bool hj_streamBothSides;
bool hj_rebuildHashtable;
List* hj_hashCollations;
#ifdef USE_SPQ
bool hj_nonequijoin;
bool hj_InnerEmpty;
bool prefetch_inner;
bool is_set_op_join;
#endif
} HashJoinState;
* Materialization State Information
* ----------------------------------------------------------------
*/
* MaterialState information
*
* materialize nodes are used to materialize the results
* of a subplan into a temporary file.
*
* ss.ss_ScanTupleSlot refers to output of underlying plan.
* ----------------
*/
typedef struct MaterialState {
ScanState ss;
int eflags;
bool eof_underlying;
bool materalAll;
Tuplestorestate* tuplestorestate;
} MaterialState;
* SortState information
* ----------------
*/
typedef struct SortState {
ScanState ss;
bool randomAccess;
bool bounded;
int64 bound;
bool sort_Done;
bool bounded_Done;
int64 bound_Done;
void* tuplesortstate;
int32 local_work_mem;
int sortMethodId;
int spaceTypeId;
long spaceUsed;
int64* space_size;
} SortState;
struct SortGroupStatePriv;
* SortGroupState information
* ----------------
*/
typedef struct SortGroupState {
ScanState ss;
int64 bound;
struct SortGroupStatePriv *state;
bool sort_Done;
bool *new_group_trigger;
const char *spaceType;
int64 spaceUsed;
} SortGroupState;
* GroupState information
* -------------------------
*/
typedef struct GroupState {
ScanState ss;
FmgrInfo* eqfunctions;
bool grp_done;
} GroupState;
* AggState information
*
* ss.ss_ScanTupleSlot refers to output of underlying plan.
*
* Note: ss.ps.ps_ExprContext contains ecxt_aggvalues and
* ecxt_aggnulls arrays, which hold the computed agg values for the current
* input group during evaluation of an Agg node's output tuple(s). We
* create a second ExprContext, tmpcontext, in which to evaluate input
* expressions and run the aggregate transition functions.
* -------------------------
*/
typedef struct AggStatePerAggData* AggStatePerAgg;
typedef struct AggStatePerAggForFlattenedExprData* AggStatePerAggForFlattenedExpr;
typedef struct AggStatePerTransData* AggStatePerTrans;
typedef struct AggStatePerGroupData* AggStatePerGroup;
typedef struct AggStatePerPhaseData* AggStatePerPhase;
typedef struct AggState {
ScanState ss;
List* aggs;
int numaggs;
AggStatePerPhase phase;
int numphases;
int current_phase;
FmgrInfo* hashfunctions;
AggStatePerAgg peragg;
MemoryContext* aggcontexts;
ExprContext* tmpcontext;
#ifdef USE_SPQ
AggSplit aggsplittype;
#endif
AggStatePerAgg curperagg;
bool input_done;
bool agg_done;
bool new_group_trigger;
int projected_set;
int current_set;
Bitmapset* grouped_cols;
List* all_grouped_cols;
int maxsets;
AggStatePerPhase phases;
Tuplesortstate* sort_in;
Tuplesortstate* sort_out;
TupleTableSlot* sort_slot;
AggStatePerGroup pergroup;
HeapTuple grp_firstTuple;
TupleHashTable hashtable;
TupleTableSlot* hashslot;
List* hash_needed;
bool table_filled;
TupleHashIterator hashiter;
#ifdef PGXC
bool is_final;
#endif
void* aggTempFileControl;
FmgrInfo* eqfunctions;
TupleTableSlot *evalslot;
ProjectionInfo *evalproj;
TupleDesc evaldesc;
int numtrans;
AggStrategy aggstrategy;
AggStatePerAggForFlattenedExpr peragg_flattened;
AggStatePerTrans pertrans;
MemoryContext curaggcontext;
AggStatePerTrans curpertrans;
int num_hashes;
AggStatePerGroup hash_pergroup;
AggStatePerGroup all_pergroups;
TupleTableSlot* ndp_slot;
} AggState;
* WindowAggState information
* ----------------
*/
typedef struct WindowStatePerFuncData* WindowStatePerFunc;
typedef struct WindowStatePerAggData* WindowStatePerAgg;
typedef struct WindowAggState {
ScanState ss;
List* funcs;
int numfuncs;
int numaggs;
WindowStatePerFunc perfunc;
WindowStatePerAgg peragg;
FmgrInfo* partEqfunctions;
FmgrInfo* ordEqfunctions;
Tuplestorestate* buffer;
int current_ptr;
int64 spooled_rows;
int64 currentpos;
int64 frameheadpos;
int64 frametailpos;
struct WindowObjectData* agg_winobj;
int64 aggregatedbase;
int64 aggregatedupto;
int frameOptions;
ExprState* startOffset;
ExprState* endOffset;
Datum startOffsetValue;
Datum endOffsetValue;
MemoryContext partcontext;
MemoryContext aggcontext;
ExprContext* tmpcontext;
bool all_first;
bool all_done;
bool partition_spooled;
bool more_partitions;
bool framehead_valid;
bool frametail_valid;
TupleTableSlot* first_part_slot;
TupleTableSlot* agg_row_slot;
TupleTableSlot* temp_slot_1;
TupleTableSlot* temp_slot_2;
} WindowAggState;
* OrderedSetAggState information
* ----------------
*/
typedef struct OrderedSetAggState {
AggState* aggstate;
Aggref* aggref;
Tuplesortstate* sortstate;
int64 number_of_rows;
TupleDesc tupdesc;
TupleTableSlot *tupslot;
Oid datumtype;
int16 typLen;
bool typByVal;
char typAlign;
Oid eq_operator;
char sign;
} OrderedSetAggState;
* UniqueState information
*
* Unique nodes are used "on top of" sort nodes to discard
* duplicate tuples returned from the sort phase. Basically
* all it does is compare the current tuple from the subplan
* with the previously fetched tuple (stored in its result slot).
* If the two are identical in all interesting fields, then
* we just fetch another tuple from the sort and try again.
* ----------------
*/
typedef struct UniqueState {
PlanState ps;
FmgrInfo* eqfunctions;
MemoryContext tempContext;
} UniqueState;
* HashState information
* ----------------
*/
typedef struct HashState {
PlanState ps;
HashJoinTable hashtable;
List* hashkeys;
int32 local_work_mem;
int64 spill_size;
#ifdef USE_SPQ
bool hs_keepnull;
bool hs_quit_if_hashkeys_null;
bool hs_hashkeys_null;
#endif
} HashState;
* SetOpState information
*
* Even in "sorted" mode, SetOp nodes are more complex than a simple
* Unique, since we have to count how many duplicates to return. But
* we also support hashing, so this is really more like a cut-down
* form of Agg.
* ----------------
*/
typedef struct SetOpStatePerGroupData* SetOpStatePerGroup;
typedef struct SetOpState {
PlanState ps;
FmgrInfo* eqfunctions;
FmgrInfo* hashfunctions;
bool setop_done;
long numOutput;
MemoryContext tempContext;
SetOpStatePerGroup pergroup;
HeapTuple grp_firstTuple;
TupleHashTable hashtable;
MemoryContext tableContext;
bool table_filled;
TupleHashIterator hashiter;
void* TempFileControl;
int64 spill_size;
} SetOpState;
* LockRowsState information
*
* LockRows nodes are used to enforce FOR [KEY] UPDATE/FOR SHARE locking.
* ----------------
*/
typedef struct LockRowsState {
PlanState ps;
List* lr_arowMarks;
EPQState lr_epqstate;
} LockRowsState;
* LimitState information
*
* Limit nodes are used to enforce LIMIT/OFFSET clauses.
* They just select the desired subrange of their subplan's output.
*
* offset is the number of initial tuples to skip (0 does nothing).
* count is the number of tuples to return after skipping the offset tuples.
* If no limit count was specified, count is undefined and noCount is true.
* When lstate == LIMIT_INITIAL, offset/count/noCount haven't been set yet.
* ----------------
*/
typedef enum {
LIMIT_INITIAL,
LIMIT_RESCAN,
LIMIT_EMPTY,
LIMIT_INWINDOW,
LIMIT_SUBPLANEOF,
LIMIT_WINDOWEND,
LIMIT_WINDOWSTART
} LimitStateCond;
typedef struct LimitState {
PlanState ps;
ExprState* limitOffset;
ExprState* limitCount;
bool isPercent;
bool withTies;
int numCols;
AttrNumber* sortColIdx;
Oid* collations;
FmgrInfo* eqfunctions;
MemoryContext tempContext;
int64 offset;
int64 count;
float8 fraction;
bool noCount;
TupleTableSlot* outputSlot;
Tuplestorestate* tuplestorestate;
LimitStateCond lstate;
int64 position;
TupleTableSlot* subSlot;
} LimitState;
* Target : data partition
* Brief : structure definition about partition iteration
*/
typedef struct PartIteratorState {
PlanState ps;
int currentItr;
int subPartCurrentItr;
} PartIteratorState;
struct VecLimitState : public LimitState {
VectorBatch* subBatch;
};
* RownumState node: used for computing the pseudo-column ROWNUM
*/
typedef struct RownumState {
ExprState xprstate;
PlanState* ps;
} RownumState;
typedef struct UserSetElemState {
ExprState xprstate;
UserSetElem* use;
ExprState* instate;
} UserSetElemState;
typedef struct PrefixKeyState {
ExprState xprstate;
ExprState* arg;
int encoding;
} PrefixKeyState;
* GroupingFuncExprState node
*
* The list of column numbers refers to the input tuples of the Agg node to
* which the GroupingFunc belongs, and may contain 0 for references to columns
* that are only present in grouping sets processed by different Agg nodes (and
* which are therefore always considered "grouping" here).
* ----------------
*/
typedef struct GroupingFuncExprState {
ExprState xprstate;
AggState* aggstate;
List* clauses;
} GroupingFuncExprState;
typedef struct GroupingIdExprState {
ExprState xprstate;
AggState* aggstate;
} GroupingIdExprState;
* used by CstoreInsert in nodeModifyTable.h and vecmodifytable.cpp
*/
#define FLUSH_DATA(obj, type) \
do { \
((type*)obj)->SetEndFlag(); \
((type*)obj)->BatchInsert((VectorBatch*)NULL, 0); \
((type*)obj)->EndBatchInsert(); \
((type*)obj)->Destroy(); \
delete (type*)obj; \
} while (0)
* used by TsStoreInsert in nodeModifyTable.h and vecmodifytable.cpp
*/
#define FLUSH_DATA_TSDB(obj, type) \
do{ \
((type*)obj)->BatchInsert((VectorBatch*)NULL, 0); \
((type*)obj)->end_batch_insert(); \
((type*)obj)->Destroy(); \
}while(0)
* record the first tuple time used by INSERT, UPDATE and DELETE in ExecModifyTable and ExecVecModifyTable
*/
#define record_first_time() \
do { \
if (unlikely(is_first_modified)) { \
INSTR_TIME_SET_CURRENT(node->first_tuple_modified); \
is_first_modified = false; \
} \
} while (0)
extern TupleTableSlot* ExecMakeTupleSlot(Tuple tuple, TableScanDesc tableScan, TupleTableSlot* slot, const TableAmRoutine* tam_ops);
* When the global partition index is used for bitmap scanning,
* checks whether the partition table needs to be
* switched each time an tbmres is obtained.
*/
inline bool BitmapNodeNeedSwitchPartRel(BitmapHeapScanState* node)
{
return tbm_is_global(node->tbm) && GPIScanCheckPartOid(node->gpi_scan, node->tbmres->partitionOid);
}
struct AlgorithmAPI;
struct TrainModelState;
typedef struct ModelTuple {
Datum *values;
bool *isnull;
Oid *typid;
bool *typbyval;
int16 *typlen;
int ncolumns;
} ModelTuple;
typedef bool (*callback_ml_fetch)(void *callback_data, ModelTuple *tuple);
typedef void (*callback_ml_rescan)(void *callback_data);
typedef struct TrainModelState {
ScanState ss;
const TrainModel *config;
AlgorithmAPI *algorithm;
int finished;
ModelTuple tuple;
bool row_allocated;
callback_ml_fetch fetch;
callback_ml_rescan rescan;
void *callback_data;
} TrainModelState;
typedef struct CursorExpressionState {
ExprState xprstate;
CursorExpression* cursor_expression;
List* param;
} CursorExpressionState;
#endif