codekingpro/portable-devtools
114k
1/*-------------------------------------------------------------------------2 *3 * plannodes.h4 * definitions for query plan nodes5 *6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 * Portions Copyright (c) 1994, Regents of the University of California9 *10 * src/include/nodes/plannodes.h11 *12 *-------------------------------------------------------------------------13 */14#ifndef PLANNODES_H15#define PLANNODES_H16 17#include "access/sdir.h"18#include "access/stratnum.h"19#include "common/relpath.h"20#include "lib/stringinfo.h"21#include "nodes/bitmapset.h"22#include "nodes/lockoptions.h"23#include "nodes/parsenodes.h"24#include "nodes/primnodes.h"25 26 27/* ----------------------------------------------------------------28 * node definitions29 * ----------------------------------------------------------------30 */31 32/* ----------------33 * PlannedStmt node34 *35 * The output of the planner is a Plan tree headed by a PlannedStmt node.36 * PlannedStmt holds the "one time" information needed by the executor.37 *38 * For simplicity in APIs, we also wrap utility statements in PlannedStmt39 * nodes; in such cases, commandType == CMD_UTILITY, the statement itself40 * is in the utilityStmt field, and the rest of the struct is mostly dummy.41 * (We do use canSetTag, stmt_location, stmt_len, and possibly queryId.)42 *43 * PlannedStmt, as well as all varieties of Plan, do not support equal(),44 * not because it's not sensible but because we currently have no need.45 * ----------------46 */47typedef struct PlannedStmt48{49 pg_node_attr(no_equal, no_query_jumble)50 51 NodeTag type;52 53 CmdType commandType; /* select|insert|update|delete|merge|utility */54 55 uint64 queryId; /* query identifier (copied from Query) */56 57 bool hasReturning; /* is it insert|update|delete RETURNING? */58 59 bool hasModifyingCTE; /* has insert|update|delete in WITH? */60 61 bool canSetTag; /* do I set the command result tag? */62 63 bool transientPlan; /* redo plan when TransactionXmin changes? */64 65 bool dependsOnRole; /* is plan specific to current role? */66 67 bool parallelModeNeeded; /* parallel mode required to execute? */68 69 int jitFlags; /* which forms of JIT should be performed */70 71 struct Plan *planTree; /* tree of Plan nodes */72 73 List *rtable; /* list of RangeTblEntry nodes */74 75 List *permInfos; /* list of RTEPermissionInfo nodes for rtable76 * entries needing one */77 78 /* rtable indexes of target relations for INSERT/UPDATE/DELETE/MERGE */79 List *resultRelations; /* integer list of RT indexes, or NIL */80 81 List *appendRelations; /* list of AppendRelInfo nodes */82 83 List *subplans; /* Plan trees for SubPlan expressions; note84 * that some could be NULL */85 86 Bitmapset *rewindPlanIDs; /* indices of subplans that require REWIND */87 88 List *rowMarks; /* a list of PlanRowMark's */89 90 List *relationOids; /* OIDs of relations the plan depends on */91 92 List *invalItems; /* other dependencies, as PlanInvalItems */93 94 List *paramExecTypes; /* type OIDs for PARAM_EXEC Params */95 96 Node *utilityStmt; /* non-null if this is utility stmt */97 98 /* statement location in source string (copied from Query) */99 int stmt_location; /* start location, or -1 if unknown */100 int stmt_len; /* length in bytes; 0 means "rest of string" */101} PlannedStmt;102 103/* macro for fetching the Plan associated with a SubPlan node */104#define exec_subplan_get_plan(plannedstmt, subplan) \105 ((Plan *) list_nth((plannedstmt)->subplans, (subplan)->plan_id - 1))106 107 108/* ----------------109 * Plan node110 *111 * All plan nodes "derive" from the Plan structure by having the112 * Plan structure as the first field. This ensures that everything works113 * when nodes are cast to Plan's. (node pointers are frequently cast to Plan*114 * when passed around generically in the executor)115 *116 * We never actually instantiate any Plan nodes; this is just the common117 * abstract superclass for all Plan-type nodes.118 * ----------------119 */120typedef struct Plan121{122 pg_node_attr(abstract, no_equal, no_query_jumble)123 124 NodeTag type;125 126 /*127 * estimated execution costs for plan (see costsize.c for more info)128 */129 Cost startup_cost; /* cost expended before fetching any tuples */130 Cost total_cost; /* total cost (assuming all tuples fetched) */131 132 /*133 * planner's estimate of result size of this plan step134 */135 Cardinality plan_rows; /* number of rows plan is expected to emit */136 int plan_width; /* average row width in bytes */137 138 /*139 * information needed for parallel query140 */141 bool parallel_aware; /* engage parallel-aware logic? */142 bool parallel_safe; /* OK to use as part of parallel plan? */143 144 /*145 * information needed for asynchronous execution146 */147 bool async_capable; /* engage asynchronous-capable logic? */148 149 /*150 * Common structural data for all Plan types.151 */152 int plan_node_id; /* unique across entire final plan tree */153 List *targetlist; /* target list to be computed at this node */154 List *qual; /* implicitly-ANDed qual conditions */155 struct Plan *lefttree; /* input plan tree(s) */156 struct Plan *righttree;157 List *initPlan; /* Init Plan nodes (un-correlated expr158 * subselects) */159 160 /*161 * Information for management of parameter-change-driven rescanning162 *163 * extParam includes the paramIDs of all external PARAM_EXEC params164 * affecting this plan node or its children. setParam params from the165 * node's initPlans are not included, but their extParams are.166 *167 * allParam includes all the extParam paramIDs, plus the IDs of local168 * params that affect the node (i.e., the setParams of its initplans).169 * These are _all_ the PARAM_EXEC params that affect this node.170 */171 Bitmapset *extParam;172 Bitmapset *allParam;173} Plan;174 175/* ----------------176 * these are defined to avoid confusion problems with "left"177 * and "right" and "inner" and "outer". The convention is that178 * the "left" plan is the "outer" plan and the "right" plan is179 * the inner plan, but these make the code more readable.180 * ----------------181 */182#define innerPlan(node) (((Plan *)(node))->righttree)183#define outerPlan(node) (((Plan *)(node))->lefttree)184 185 186/* ----------------187 * Result node -188 * If no outer plan, evaluate a variable-free targetlist.189 * If outer plan, return tuples from outer plan (after a level of190 * projection as shown by targetlist).191 *192 * If resconstantqual isn't NULL, it represents a one-time qualification193 * test (i.e., one that doesn't depend on any variables from the outer plan,194 * so needs to be evaluated only once).195 * ----------------196 */197typedef struct Result198{199 Plan plan;200 Node *resconstantqual;201} Result;202 203/* ----------------204 * ProjectSet node -205 * Apply a projection that includes set-returning functions to the206 * output tuples of the outer plan.207 * ----------------208 */209typedef struct ProjectSet210{211 Plan plan;212} ProjectSet;213 214/* ----------------215 * ModifyTable node -216 * Apply rows produced by outer plan to result table(s),217 * by inserting, updating, or deleting.218 *219 * If the originally named target table is a partitioned table or inheritance220 * tree, both nominalRelation and rootRelation contain the RT index of the221 * partition root or appendrel RTE, which is not otherwise mentioned in the222 * plan. Otherwise rootRelation is zero. However, nominalRelation will223 * always be set, as it's the rel that EXPLAIN should claim is the224 * INSERT/UPDATE/DELETE/MERGE target.225 *226 * Note that rowMarks and epqParam are presumed to be valid for all the227 * table(s); they can't contain any info that varies across tables.228 * ----------------229 */230typedef struct ModifyTable231{232 Plan plan;233 CmdType operation; /* INSERT, UPDATE, DELETE, or MERGE */234 bool canSetTag; /* do we set the command tag/es_processed? */235 Index nominalRelation; /* Parent RT index for use of EXPLAIN */236 Index rootRelation; /* Root RT index, if partitioned/inherited */237 bool partColsUpdated; /* some part key in hierarchy updated? */238 List *resultRelations; /* integer list of RT indexes */239 List *updateColnosLists; /* per-target-table update_colnos lists */240 List *withCheckOptionLists; /* per-target-table WCO lists */241 List *returningLists; /* per-target-table RETURNING tlists */242 List *fdwPrivLists; /* per-target-table FDW private data lists */243 Bitmapset *fdwDirectModifyPlans; /* indices of FDW DM plans */244 List *rowMarks; /* PlanRowMarks (non-locking only) */245 int epqParam; /* ID of Param for EvalPlanQual re-eval */246 OnConflictAction onConflictAction; /* ON CONFLICT action */247 List *arbiterIndexes; /* List of ON CONFLICT arbiter index OIDs */248 List *onConflictSet; /* INSERT ON CONFLICT DO UPDATE targetlist */249 List *onConflictCols; /* target column numbers for onConflictSet */250 Node *onConflictWhere; /* WHERE for ON CONFLICT UPDATE */251 Index exclRelRTI; /* RTI of the EXCLUDED pseudo relation */252 List *exclRelTlist; /* tlist of the EXCLUDED pseudo relation */253 List *mergeActionLists; /* per-target-table lists of actions for254 * MERGE */255} ModifyTable;256 257struct PartitionPruneInfo; /* forward reference to struct below */258 259/* ----------------260 * Append node -261 * Generate the concatenation of the results of sub-plans.262 * ----------------263 */264typedef struct Append265{266 Plan plan;267 Bitmapset *apprelids; /* RTIs of appendrel(s) formed by this node */268 List *appendplans;269 int nasyncplans; /* # of asynchronous plans */270 271 /*272 * All 'appendplans' preceding this index are non-partial plans. All273 * 'appendplans' from this index onwards are partial plans.274 */275 int first_partial_plan;276 277 /* Info for run-time subplan pruning; NULL if we're not doing that */278 struct PartitionPruneInfo *part_prune_info;279} Append;280 281/* ----------------282 * MergeAppend node -283 * Merge the results of pre-sorted sub-plans to preserve the ordering.284 * ----------------285 */286typedef struct MergeAppend287{288 Plan plan;289 290 /* RTIs of appendrel(s) formed by this node */291 Bitmapset *apprelids;292 293 List *mergeplans;294 295 /* these fields are just like the sort-key info in struct Sort: */296 297 /* number of sort-key columns */298 int numCols;299 300 /* their indexes in the target list */301 AttrNumber *sortColIdx pg_node_attr(array_size(numCols));302 303 /* OIDs of operators to sort them by */304 Oid *sortOperators pg_node_attr(array_size(numCols));305 306 /* OIDs of collations */307 Oid *collations pg_node_attr(array_size(numCols));308 309 /* NULLS FIRST/LAST directions */310 bool *nullsFirst pg_node_attr(array_size(numCols));311 312 /* Info for run-time subplan pruning; NULL if we're not doing that */313 struct PartitionPruneInfo *part_prune_info;314} MergeAppend;315 316/* ----------------317 * RecursiveUnion node -318 * Generate a recursive union of two subplans.319 *320 * The "outer" subplan is always the non-recursive term, and the "inner"321 * subplan is the recursive term.322 * ----------------323 */324typedef struct RecursiveUnion325{326 Plan plan;327 328 /* ID of Param representing work table */329 int wtParam;330 331 /* Remaining fields are zero/null in UNION ALL case */332 333 /* number of columns to check for duplicate-ness */334 int numCols;335 336 /* their indexes in the target list */337 AttrNumber *dupColIdx pg_node_attr(array_size(numCols));338 339 /* equality operators to compare with */340 Oid *dupOperators pg_node_attr(array_size(numCols));341 Oid *dupCollations pg_node_attr(array_size(numCols));342 343 /* estimated number of groups in input */344 long numGroups;345} RecursiveUnion;346 347/* ----------------348 * BitmapAnd node -349 * Generate the intersection of the results of sub-plans.350 *351 * The subplans must be of types that yield tuple bitmaps. The targetlist352 * and qual fields of the plan are unused and are always NIL.353 * ----------------354 */355typedef struct BitmapAnd356{357 Plan plan;358 List *bitmapplans;359} BitmapAnd;360 361/* ----------------362 * BitmapOr node -363 * Generate the union of the results of sub-plans.364 *365 * The subplans must be of types that yield tuple bitmaps. The targetlist366 * and qual fields of the plan are unused and are always NIL.367 * ----------------368 */369typedef struct BitmapOr370{371 Plan plan;372 bool isshared;373 List *bitmapplans;374} BitmapOr;375 376/*377 * ==========378 * Scan nodes379 *380 * Scan is an abstract type that all relation scan plan types inherit from.381 * ==========382 */383typedef struct Scan384{385 pg_node_attr(abstract)386 387 Plan plan;388 Index scanrelid; /* relid is index into the range table */389} Scan;390 391/* ----------------392 * sequential scan node393 * ----------------394 */395typedef struct SeqScan396{397 Scan scan;398} SeqScan;399 400/* ----------------401 * table sample scan node402 * ----------------403 */404typedef struct SampleScan405{406 Scan scan;407 /* use struct pointer to avoid including parsenodes.h here */408 struct TableSampleClause *tablesample;409} SampleScan;410 411/* ----------------412 * index scan node413 *414 * indexqualorig is an implicitly-ANDed list of index qual expressions, each415 * in the same form it appeared in the query WHERE condition. Each should416 * be of the form (indexkey OP comparisonval) or (comparisonval OP indexkey).417 * The indexkey is a Var or expression referencing column(s) of the index's418 * base table. The comparisonval might be any expression, but it won't use419 * any columns of the base table. The expressions are ordered by index420 * column position (but items referencing the same index column can appear421 * in any order). indexqualorig is used at runtime only if we have to recheck422 * a lossy indexqual.423 *424 * indexqual has the same form, but the expressions have been commuted if425 * necessary to put the indexkeys on the left, and the indexkeys are replaced426 * by Var nodes identifying the index columns (their varno is INDEX_VAR and427 * their varattno is the index column number).428 *429 * indexorderbyorig is similarly the original form of any ORDER BY expressions430 * that are being implemented by the index, while indexorderby is modified to431 * have index column Vars on the left-hand side. Here, multiple expressions432 * must appear in exactly the ORDER BY order, and this is not necessarily the433 * index column order. Only the expressions are provided, not the auxiliary434 * sort-order information from the ORDER BY SortGroupClauses; it's assumed435 * that the sort ordering is fully determinable from the top-level operators.436 * indexorderbyorig is used at runtime to recheck the ordering, if the index437 * cannot calculate an accurate ordering. It is also needed for EXPLAIN.438 *439 * indexorderbyops is a list of the OIDs of the operators used to sort the440 * ORDER BY expressions. This is used together with indexorderbyorig to441 * recheck ordering at run time. (Note that indexorderby, indexorderbyorig,442 * and indexorderbyops are used for amcanorderbyop cases, not amcanorder.)443 *444 * indexorderdir specifies the scan ordering, for indexscans on amcanorder445 * indexes (for other indexes it should be "don't care").446 * ----------------447 */448typedef struct IndexScan449{450 Scan scan;451 Oid indexid; /* OID of index to scan */452 List *indexqual; /* list of index quals (usually OpExprs) */453 List *indexqualorig; /* the same in original form */454 List *indexorderby; /* list of index ORDER BY exprs */455 List *indexorderbyorig; /* the same in original form */456 List *indexorderbyops; /* OIDs of sort ops for ORDER BY exprs */457 ScanDirection indexorderdir; /* forward or backward or don't care */458} IndexScan;459 460/* ----------------461 * index-only scan node462 *463 * IndexOnlyScan is very similar to IndexScan, but it specifies an464 * index-only scan, in which the data comes from the index not the heap.465 * Because of this, *all* Vars in the plan node's targetlist, qual, and466 * index expressions reference index columns and have varno = INDEX_VAR.467 *468 * We could almost use indexqual directly against the index's output tuple469 * when rechecking lossy index operators, but that won't work for quals on470 * index columns that are not retrievable. Hence, recheckqual is needed471 * for rechecks: it expresses the same condition as indexqual, but using472 * only index columns that are retrievable. (We will not generate an473 * index-only scan if this is not possible. An example is that if an474 * index has table column "x" in a retrievable index column "ind1", plus475 * an expression f(x) in a non-retrievable column "ind2", an indexable476 * query on f(x) will use "ind2" in indexqual and f(ind1) in recheckqual.477 * Without the "ind1" column, an index-only scan would be disallowed.)478 *479 * We don't currently need a recheckable equivalent of indexorderby,480 * because we don't support lossy operators in index ORDER BY.481 *482 * To help EXPLAIN interpret the index Vars for display, we provide483 * indextlist, which represents the contents of the index as a targetlist484 * with one TLE per index column. Vars appearing in this list reference485 * the base table, and this is the only field in the plan node that may486 * contain such Vars. Also, for the convenience of setrefs.c, TLEs in487 * indextlist are marked as resjunk if they correspond to columns that488 * the index AM cannot reconstruct.489 * ----------------490 */491typedef struct IndexOnlyScan492{493 Scan scan;494 Oid indexid; /* OID of index to scan */495 List *indexqual; /* list of index quals (usually OpExprs) */496 List *recheckqual; /* index quals in recheckable form */497 List *indexorderby; /* list of index ORDER BY exprs */498 List *indextlist; /* TargetEntry list describing index's cols */499 ScanDirection indexorderdir; /* forward or backward or don't care */500} IndexOnlyScan;501 502/* ----------------503 * bitmap index scan node504 *505 * BitmapIndexScan delivers a bitmap of potential tuple locations;506 * it does not access the heap itself. The bitmap is used by an507 * ancestor BitmapHeapScan node, possibly after passing through508 * intermediate BitmapAnd and/or BitmapOr nodes to combine it with509 * the results of other BitmapIndexScans.510 *511 * The fields have the same meanings as for IndexScan, except we don't512 * store a direction flag because direction is uninteresting.513 *514 * In a BitmapIndexScan plan node, the targetlist and qual fields are515 * not used and are always NIL. The indexqualorig field is unused at516 * run time too, but is saved for the benefit of EXPLAIN.517 * ----------------518 */519typedef struct BitmapIndexScan520{521 Scan scan;522 Oid indexid; /* OID of index to scan */523 bool isshared; /* Create shared bitmap if set */524 List *indexqual; /* list of index quals (OpExprs) */525 List *indexqualorig; /* the same in original form */526} BitmapIndexScan;527 528/* ----------------529 * bitmap sequential scan node530 *531 * This needs a copy of the qual conditions being used by the input index532 * scans because there are various cases where we need to recheck the quals;533 * for example, when the bitmap is lossy about the specific rows on a page534 * that meet the index condition.535 * ----------------536 */537typedef struct BitmapHeapScan538{539 Scan scan;540 List *bitmapqualorig; /* index quals, in standard expr form */541} BitmapHeapScan;542 543/* ----------------544 * tid scan node545 *546 * tidquals is an implicitly OR'ed list of qual expressions of the form547 * "CTID = pseudoconstant", or "CTID = ANY(pseudoconstant_array)",548 * or a CurrentOfExpr for the relation.549 * ----------------550 */551typedef struct TidScan552{553 Scan scan;554 List *tidquals; /* qual(s) involving CTID = something */555} TidScan;556 557/* ----------------558 * tid range scan node559 *560 * tidrangequals is an implicitly AND'ed list of qual expressions of the form561 * "CTID relop pseudoconstant", where relop is one of >,>=,<,<=.562 * ----------------563 */564typedef struct TidRangeScan565{566 Scan scan;567 List *tidrangequals; /* qual(s) involving CTID op something */568} TidRangeScan;569 570/* ----------------571 * subquery scan node572 *573 * SubqueryScan is for scanning the output of a sub-query in the range table.574 * We often need an extra plan node above the sub-query's plan to perform575 * expression evaluations (which we can't push into the sub-query without576 * risking changing its semantics). Although we are not scanning a physical577 * relation, we make this a descendant of Scan anyway for code-sharing578 * purposes.579 *580 * SubqueryScanStatus caches the trivial_subqueryscan property of the node.581 * SUBQUERY_SCAN_UNKNOWN means not yet determined. This is only used during582 * planning.583 *584 * Note: we store the sub-plan in the type-specific subplan field, not in585 * the generic lefttree field as you might expect. This is because we do586 * not want plan-tree-traversal routines to recurse into the subplan without587 * knowing that they are changing Query contexts.588 * ----------------589 */590typedef enum SubqueryScanStatus591{592 SUBQUERY_SCAN_UNKNOWN,593 SUBQUERY_SCAN_TRIVIAL,594 SUBQUERY_SCAN_NONTRIVIAL595} SubqueryScanStatus;596 597typedef struct SubqueryScan598{599 Scan scan;600 Plan *subplan;601 SubqueryScanStatus scanstatus;602} SubqueryScan;603 604/* ----------------605 * FunctionScan node606 * ----------------607 */608typedef struct FunctionScan609{610 Scan scan;611 List *functions; /* list of RangeTblFunction nodes */612 bool funcordinality; /* WITH ORDINALITY */613} FunctionScan;614 615/* ----------------616 * ValuesScan node617 * ----------------618 */619typedef struct ValuesScan620{621 Scan scan;622 List *values_lists; /* list of expression lists */623} ValuesScan;624 625/* ----------------626 * TableFunc scan node627 * ----------------628 */629typedef struct TableFuncScan630{631 Scan scan;632 TableFunc *tablefunc; /* table function node */633} TableFuncScan;634 635/* ----------------636 * CteScan node637 * ----------------638 */639typedef struct CteScan640{641 Scan scan;642 int ctePlanId; /* ID of init SubPlan for CTE */643 int cteParam; /* ID of Param representing CTE output */644} CteScan;645 646/* ----------------647 * NamedTuplestoreScan node648 * ----------------649 */650typedef struct NamedTuplestoreScan651{652 Scan scan;653 char *enrname; /* Name given to Ephemeral Named Relation */654} NamedTuplestoreScan;655 656/* ----------------657 * WorkTableScan node658 * ----------------659 */660typedef struct WorkTableScan661{662 Scan scan;663 int wtParam; /* ID of Param representing work table */664} WorkTableScan;665 666/* ----------------667 * ForeignScan node668 *669 * fdw_exprs and fdw_private are both under the control of the foreign-data670 * wrapper, but fdw_exprs is presumed to contain expression trees and will671 * be post-processed accordingly by the planner; fdw_private won't be.672 * Note that everything in both lists must be copiable by copyObject().673 * One way to store an arbitrary blob of bytes is to represent it as a bytea674 * Const. Usually, though, you'll be better off choosing a representation675 * that can be dumped usefully by nodeToString().676 *677 * fdw_scan_tlist is a targetlist describing the contents of the scan tuple678 * returned by the FDW; it can be NIL if the scan tuple matches the declared679 * rowtype of the foreign table, which is the normal case for a simple foreign680 * table scan. (If the plan node represents a foreign join, fdw_scan_tlist681 * is required since there is no rowtype available from the system catalogs.)682 * When fdw_scan_tlist is provided, Vars in the node's tlist and quals must683 * have varno INDEX_VAR, and their varattnos correspond to resnos in the684 * fdw_scan_tlist (which are also column numbers in the actual scan tuple).685 * fdw_scan_tlist is never actually executed; it just holds expression trees686 * describing what is in the scan tuple's columns.687 *688 * fdw_recheck_quals should contain any quals which the core system passed to689 * the FDW but which were not added to scan.plan.qual; that is, it should690 * contain the quals being checked remotely. This is needed for correct691 * behavior during EvalPlanQual rechecks.692 *693 * When the plan node represents a foreign join, scan.scanrelid is zero and694 * fs_relids must be consulted to identify the join relation. (fs_relids695 * is valid for simple scans as well, but will always match scan.scanrelid.)696 * fs_relids includes outer joins; fs_base_relids does not.697 *698 * If the FDW's PlanDirectModify() callback decides to repurpose a ForeignScan699 * node to perform the UPDATE or DELETE operation directly in the remote700 * server, it sets 'operation' and 'resultRelation' to identify the operation701 * type and target relation. Note that these fields are only set if the702 * modification is performed *fully* remotely; otherwise, the modification is703 * driven by a local ModifyTable node and 'operation' is left to CMD_SELECT.704 * ----------------705 */706typedef struct ForeignScan707{708 Scan scan;709 CmdType operation; /* SELECT/INSERT/UPDATE/DELETE */710 Index resultRelation; /* direct modification target's RT index */711 Oid checkAsUser; /* user to perform the scan as; 0 means to712 * check as current user */713 Oid fs_server; /* OID of foreign server */714 List *fdw_exprs; /* expressions that FDW may evaluate */715 List *fdw_private; /* private data for FDW */716 List *fdw_scan_tlist; /* optional tlist describing scan tuple */717 List *fdw_recheck_quals; /* original quals not in scan.plan.qual */718 Bitmapset *fs_relids; /* base+OJ RTIs generated by this scan */719 Bitmapset *fs_base_relids; /* base RTIs generated by this scan */720 bool fsSystemCol; /* true if any "system column" is needed */721} ForeignScan;722 723/* ----------------724 * CustomScan node725 *726 * The comments for ForeignScan's fdw_exprs, fdw_private, fdw_scan_tlist,727 * and fs_relids fields apply equally to CustomScan's custom_exprs,728 * custom_private, custom_scan_tlist, and custom_relids fields. The729 * convention of setting scan.scanrelid to zero for joins applies as well.730 *731 * Note that since Plan trees can be copied, custom scan providers *must*732 * fit all plan data they need into those fields; embedding CustomScan in733 * a larger struct will not work.734 * ----------------735 */736struct CustomScanMethods;737 738typedef struct CustomScan739{740 Scan scan;741 uint32 flags; /* mask of CUSTOMPATH_* flags, see742 * nodes/extensible.h */743 List *custom_plans; /* list of Plan nodes, if any */744 List *custom_exprs; /* expressions that custom code may evaluate */745 List *custom_private; /* private data for custom code */746 List *custom_scan_tlist; /* optional tlist describing scan tuple */747 Bitmapset *custom_relids; /* RTIs generated by this scan */748 749 /*750 * NOTE: The method field of CustomScan is required to be a pointer to a751 * static table of callback functions. So we don't copy the table itself,752 * just reference the original one.753 */754 const struct CustomScanMethods *methods;755} CustomScan;756 757/*758 * ==========759 * Join nodes760 * ==========761 */762 763/* ----------------764 * Join node765 *766 * jointype: rule for joining tuples from left and right subtrees767 * inner_unique each outer tuple can match to no more than one inner tuple768 * joinqual: qual conditions that came from JOIN/ON or JOIN/USING769 * (plan.qual contains conditions that came from WHERE)770 *771 * When jointype is INNER, joinqual and plan.qual are semantically772 * interchangeable. For OUTER jointypes, the two are *not* interchangeable;773 * only joinqual is used to determine whether a match has been found for774 * the purpose of deciding whether to generate null-extended tuples.775 * (But plan.qual is still applied before actually returning a tuple.)776 * For an outer join, only joinquals are allowed to be used as the merge777 * or hash condition of a merge or hash join.778 *779 * inner_unique is set if the joinquals are such that no more than one inner780 * tuple could match any given outer tuple. This allows the executor to781 * skip searching for additional matches. (This must be provable from just782 * the joinquals, ignoring plan.qual, due to where the executor tests it.)783 * ----------------784 */785typedef struct Join786{787 pg_node_attr(abstract)788 789 Plan plan;790 JoinType jointype;791 bool inner_unique;792 List *joinqual; /* JOIN quals (in addition to plan.qual) */793} Join;794 795/* ----------------796 * nest loop join node797 *798 * The nestParams list identifies any executor Params that must be passed799 * into execution of the inner subplan carrying values from the current row800 * of the outer subplan. Currently we restrict these values to be simple801 * Vars, but perhaps someday that'd be worth relaxing. (Note: during plan802 * creation, the paramval can actually be a PlaceHolderVar expression; but it803 * must be a Var with varno OUTER_VAR by the time it gets to the executor.)804 * ----------------805 */806typedef struct NestLoop807{808 Join join;809 List *nestParams; /* list of NestLoopParam nodes */810} NestLoop;811 812typedef struct NestLoopParam813{814 pg_node_attr(no_equal, no_query_jumble)815 816 NodeTag type;817 int paramno; /* number of the PARAM_EXEC Param to set */818 Var *paramval; /* outer-relation Var to assign to Param */819} NestLoopParam;820 821/* ----------------822 * merge join node823 *824 * The expected ordering of each mergeable column is described by a btree825 * opfamily OID, a collation OID, a direction (BTLessStrategyNumber or826 * BTGreaterStrategyNumber) and a nulls-first flag. Note that the two sides827 * of each mergeclause may be of different datatypes, but they are ordered the828 * same way according to the common opfamily and collation. The operator in829 * each mergeclause must be an equality operator of the indicated opfamily.830 * ----------------831 */832typedef struct MergeJoin833{834 Join join;835 836 /* Can we skip mark/restore calls? */837 bool skip_mark_restore;838 839 /* mergeclauses as expression trees */840 List *mergeclauses;841 842 /* these are arrays, but have the same length as the mergeclauses list: */843 844 /* per-clause OIDs of btree opfamilies */845 Oid *mergeFamilies pg_node_attr(array_size(mergeclauses));846 847 /* per-clause OIDs of collations */848 Oid *mergeCollations pg_node_attr(array_size(mergeclauses));849 850 /* per-clause ordering (ASC or DESC) */851 int *mergeStrategies pg_node_attr(array_size(mergeclauses));852 853 /* per-clause nulls ordering */854 bool *mergeNullsFirst pg_node_attr(array_size(mergeclauses));855} MergeJoin;856 857/* ----------------858 * hash join node859 * ----------------860 */861typedef struct HashJoin862{863 Join join;864 List *hashclauses;865 List *hashoperators;866 List *hashcollations;867 868 /*869 * List of expressions to be hashed for tuples from the outer plan, to870 * perform lookups in the hashtable over the inner plan.871 */872 List *hashkeys;873} HashJoin;874 875/* ----------------876 * materialization node877 * ----------------878 */879typedef struct Material880{881 Plan plan;882} Material;883 884/* ----------------885 * memoize node886 * ----------------887 */888typedef struct Memoize889{890 Plan plan;891 892 /* size of the two arrays below */893 int numKeys;894 895 /* hash operators for each key */896 Oid *hashOperators pg_node_attr(array_size(numKeys));897 898 /* collations for each key */899 Oid *collations pg_node_attr(array_size(numKeys));900 901 /* cache keys in the form of exprs containing parameters */902 List *param_exprs;903 904 /*905 * true if the cache entry should be marked as complete after we store the906 * first tuple in it.907 */908 bool singlerow;909 910 /*911 * true when cache key should be compared bit by bit, false when using912 * hash equality ops913 */914 bool binary_mode;915 916 /*917 * The maximum number of entries that the planner expects will fit in the918 * cache, or 0 if unknown919 */920 uint32 est_entries;921 922 /* paramids from param_exprs */923 Bitmapset *keyparamids;924} Memoize;925 926/* ----------------927 * sort node928 * ----------------929 */930typedef struct Sort931{932 Plan plan;933 934 /* number of sort-key columns */935 int numCols;936 937 /* their indexes in the target list */938 AttrNumber *sortColIdx pg_node_attr(array_size(numCols));939 940 /* OIDs of operators to sort them by */941 Oid *sortOperators pg_node_attr(array_size(numCols));942 943 /* OIDs of collations */944 Oid *collations pg_node_attr(array_size(numCols));945 946 /* NULLS FIRST/LAST directions */947 bool *nullsFirst pg_node_attr(array_size(numCols));948} Sort;949 950/* ----------------951 * incremental sort node952 * ----------------953 */954typedef struct IncrementalSort955{956 Sort sort;957 int nPresortedCols; /* number of presorted columns */958} IncrementalSort;959 960/* ---------------961 * group node -962 * Used for queries with GROUP BY (but no aggregates) specified.963 * The input must be presorted according to the grouping columns.964 * ---------------965 */966typedef struct Group967{968 Plan plan;969 970 /* number of grouping columns */971 int numCols;972 973 /* their indexes in the target list */974 AttrNumber *grpColIdx pg_node_attr(array_size(numCols));975 976 /* equality operators to compare with */977 Oid *grpOperators pg_node_attr(array_size(numCols));978 Oid *grpCollations pg_node_attr(array_size(numCols));979} Group;980 981/* ---------------982 * aggregate node983 *984 * An Agg node implements plain or grouped aggregation. For grouped985 * aggregation, we can work with presorted input or unsorted input;986 * the latter strategy uses an internal hashtable.987 *988 * Notice the lack of any direct info about the aggregate functions to be989 * computed. They are found by scanning the node's tlist and quals during990 * executor startup. (It is possible that there are no aggregate functions;991 * this could happen if they get optimized away by constant-folding, or if992 * we are using the Agg node to implement hash-based grouping.)993 * ---------------994 */995typedef struct Agg996{997 Plan plan;998 999 /* basic strategy, see nodes.h */1000 AggStrategy aggstrategy;1001 1002 /* agg-splitting mode, see nodes.h */1003 AggSplit aggsplit;1004 1005 /* number of grouping columns */1006 int numCols;1007 1008 /* their indexes in the target list */1009 AttrNumber *grpColIdx pg_node_attr(array_size(numCols));1010 1011 /* equality operators to compare with */1012 Oid *grpOperators pg_node_attr(array_size(numCols));1013 Oid *grpCollations pg_node_attr(array_size(numCols));1014 1015 /* estimated number of groups in input */1016 long numGroups;1017 1018 /* for pass-by-ref transition data */1019 uint64 transitionSpace;1020 1021 /* IDs of Params used in Aggref inputs */1022 Bitmapset *aggParams;1023 1024 /* Note: planner provides numGroups & aggParams only in HASHED/MIXED case */1025 1026 /* grouping sets to use */1027 List *groupingSets;1028 1029 /* chained Agg/Sort nodes */1030 List *chain;1031} Agg;1032 1033/* ----------------1034 * window aggregate node1035 * ----------------1036 */1037typedef struct WindowAgg1038{1039 Plan plan;1040 1041 /* ID referenced by window functions */1042 Index winref;1043 1044 /* number of columns in partition clause */1045 int partNumCols;1046 1047 /* their indexes in the target list */1048 AttrNumber *partColIdx pg_node_attr(array_size(partNumCols));1049 1050 /* equality operators for partition columns */1051 Oid *partOperators pg_node_attr(array_size(partNumCols));1052 1053 /* collations for partition columns */1054 Oid *partCollations pg_node_attr(array_size(partNumCols));1055 1056 /* number of columns in ordering clause */1057 int ordNumCols;1058 1059 /* their indexes in the target list */1060 AttrNumber *ordColIdx pg_node_attr(array_size(ordNumCols));1061 1062 /* equality operators for ordering columns */1063 Oid *ordOperators pg_node_attr(array_size(ordNumCols));1064 1065 /* collations for ordering columns */1066 Oid *ordCollations pg_node_attr(array_size(ordNumCols));1067 1068 /* frame_clause options, see WindowDef */1069 int frameOptions;1070 1071 /* expression for starting bound, if any */1072 Node *startOffset;1073 1074 /* expression for ending bound, if any */1075 Node *endOffset;1076 1077 /* qual to help short-circuit execution */1078 List *runCondition;1079 1080 /* runCondition for display in EXPLAIN */1081 List *runConditionOrig;1082 1083 /* these fields are used with RANGE offset PRECEDING/FOLLOWING: */1084 1085 /* in_range function for startOffset */1086 Oid startInRangeFunc;1087 1088 /* in_range function for endOffset */1089 Oid endInRangeFunc;1090 1091 /* collation for in_range tests */1092 Oid inRangeColl;1093 1094 /* use ASC sort order for in_range tests? */1095 bool inRangeAsc;1096 1097 /* nulls sort first for in_range tests? */1098 bool inRangeNullsFirst;1099 1100 /*1101 * false for all apart from the WindowAgg that's closest to the root of1102 * the plan1103 */1104 bool topWindow;1105} WindowAgg;1106 1107/* ----------------1108 * unique node1109 * ----------------1110 */1111typedef struct Unique1112{1113 Plan plan;1114 1115 /* number of columns to check for uniqueness */1116 int numCols;1117 1118 /* their indexes in the target list */1119 AttrNumber *uniqColIdx pg_node_attr(array_size(numCols));1120 1121 /* equality operators to compare with */1122 Oid *uniqOperators pg_node_attr(array_size(numCols));1123 1124 /* collations for equality comparisons */1125 Oid *uniqCollations pg_node_attr(array_size(numCols));1126} Unique;1127 1128/* ------------1129 * gather node1130 *1131 * Note: rescan_param is the ID of a PARAM_EXEC parameter slot. That slot1132 * will never actually contain a value, but the Gather node must flag it as1133 * having changed whenever it is rescanned. The child parallel-aware scan1134 * nodes are marked as depending on that parameter, so that the rescan1135 * machinery is aware that their output is likely to change across rescans.1136 * In some cases we don't need a rescan Param, so rescan_param is set to -1.1137 * ------------1138 */1139typedef struct Gather1140{1141 Plan plan;1142 int num_workers; /* planned number of worker processes */1143 int rescan_param; /* ID of Param that signals a rescan, or -1 */1144 bool single_copy; /* don't execute plan more than once */1145 bool invisible; /* suppress EXPLAIN display (for testing)? */1146 Bitmapset *initParam; /* param id's of initplans which are referred1147 * at gather or one of it's child node */1148} Gather;1149 1150/* ------------1151 * gather merge node1152 * ------------1153 */1154typedef struct GatherMerge1155{1156 Plan plan;1157 1158 /* planned number of worker processes */1159 int num_workers;1160 1161 /* ID of Param that signals a rescan, or -1 */1162 int rescan_param;1163 1164 /* remaining fields are just like the sort-key info in struct Sort */1165 1166 /* number of sort-key columns */1167 int numCols;1168 1169 /* their indexes in the target list */1170 AttrNumber *sortColIdx pg_node_attr(array_size(numCols));1171 1172 /* OIDs of operators to sort them by */1173 Oid *sortOperators pg_node_attr(array_size(numCols));1174 1175 /* OIDs of collations */1176 Oid *collations pg_node_attr(array_size(numCols));1177 1178 /* NULLS FIRST/LAST directions */1179 bool *nullsFirst pg_node_attr(array_size(numCols));1180 1181 /*1182 * param id's of initplans which are referred at gather merge or one of1183 * it's child node1184 */1185 Bitmapset *initParam;1186} GatherMerge;1187 1188/* ----------------1189 * hash build node1190 *1191 * If the executor is supposed to try to apply skew join optimization, then1192 * skewTable/skewColumn/skewInherit identify the outer relation's join key1193 * column, from which the relevant MCV statistics can be fetched.1194 * ----------------1195 */1196typedef struct Hash1197{1198 Plan plan;1199 1200 /*