| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| /*------------------------------------------------------------------------- |
| * |
| * plannodes.h |
| * definitions for query plan nodes |
| * |
| * |
| * Portions Copyright (c) 2005-2008, Greenplum inc |
| * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group |
| * Portions Copyright (c) 1994, Regents of the University of California |
| * |
| * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.85 2006/08/02 01:59:47 joe Exp $ |
| * |
| *------------------------------------------------------------------------- |
| */ |
| #ifndef PLANNODES_H |
| #define PLANNODES_H |
| |
| #include "access/sdir.h" |
| #include "nodes/bitmapset.h" |
| #include "nodes/primnodes.h" |
| #include "storage/itemptr.h" |
| |
| #include "cdb/cdbquerycontextdispatching.h" |
| |
| typedef struct DirectDispatchInfo |
| { |
| /** |
| * if true then this Slice requires an n-gang but the gang can be targeted to |
| * fewer segments than the entire cluster. |
| * |
| * When true, directDispatchContentId and directDispathCount will combine to indicate |
| * the content ids that need segments. |
| */ |
| bool isDirectDispatch; |
| List *contentIds; |
| } DirectDispatchInfo; |
| |
| typedef enum PlanGenerator |
| { |
| PLANGEN_PLANNER, /* plan produced by the planner*/ |
| PLANGEN_OPTIMIZER, /* plan produced by the optimizer*/ |
| } PlanGenerator; |
| |
| /* DML Actions */ |
| typedef enum DMLAction |
| { |
| DML_DELETE, |
| DML_INSERT |
| } DMLAction; |
| |
| /* ---------------------------------------------------------------- |
| * node definitions |
| * ---------------------------------------------------------------- |
| */ |
| |
| /* ---------------- |
| * PlannedStmt node |
| * |
| * The output of the planner is a Plan tree headed by a PlannedStmt node. |
| * PlannedStmt holds the "one time" information needed by the executor. |
| * ---------------- |
| */ |
| typedef struct PlannedStmt |
| { |
| NodeTag type; |
| |
| CmdType commandType; /* select|insert|update|delete */ |
| |
| PlanGenerator planGen; /* optimizer generation */ |
| |
| bool canSetTag; /* do I set the command result tag? */ |
| |
| bool transientPlan; /* redo plan when TransactionXmin changes? */ |
| |
| /* Field qdContext communicates memory context on the QD from portal to |
| * dispatch. |
| * |
| * TODO Remove the field once evaluation of stable (and sequence) functions |
| * moves out of dispatch and into the executor. |
| * |
| * Do not copy or serialize. |
| */ |
| MemoryContext qdContext; |
| |
| struct Plan *planTree; /* tree of Plan nodes */ |
| |
| List *rtable; /* list of RangeTblEntry nodes */ |
| |
| /* rtable indexes of target relations for INSERT/UPDATE/DELETE */ |
| List *resultRelations; /* integer list of RT indexes, or NIL */ |
| |
| Node *utilityStmt; /* non-null if this is DECLARE CURSOR */ |
| |
| IntoClause *intoClause; /* target for SELECT INTO / CREATE TABLE AS */ |
| |
| List *subplans; /* Plan trees for SubPlan expressions */ |
| |
| Bitmapset *rewindPlanIDs; /* indices of subplans that require REWIND */ |
| |
| /* |
| * If the query has a returningList then the planner will store a list of |
| * processed targetlists (one per result relation) here. We must have a |
| * separate RETURNING targetlist for each result rel because column |
| * numbers may vary within an inheritance tree. In the targetlists, Vars |
| * referencing the result relation will have their original varno and |
| * varattno, while Vars referencing other rels will be converted to have |
| * varno OUTER and varattno referencing a resjunk entry in the top plan |
| * node's targetlist. |
| */ |
| List *returningLists; /* list of lists of TargetEntry, or NIL */ |
| |
| /* |
| * If the resultRelation turns out to be the parent of an inheritance |
| * tree, the planner will add all the child tables to the rtable and store |
| * a list of the rtindexes of all the result relations here. This is done |
| * at plan time, not parse time, since we don't want to commit to the |
| * exact set of child tables at parse time. This field used to be in Query. |
| */ |
| struct PartitionNode *result_partitions; |
| |
| List *result_aosegnos; /* AO file 'seg' numbers for resultRels to use */ |
| |
| List *result_segfileinfos; /* AO 'seg' file information for resultRels to use */ |
| |
| List *scantable_splits; /* AO file splits assignment */ |
| |
| List *into_aosegnos; /* AO file 'seg' numbers for into relation to use */ |
| |
| /* |
| * Relation oids and partitioning metadata for all partitions |
| * that are involved in a query. |
| */ |
| List *queryPartOids; |
| List *queryPartsMetadata; |
| /* |
| * List containing the number of partition selectors for every scan id. |
| * Element #i in the list corresponds to scan id i |
| */ |
| List *numSelectorsPerScanId; |
| |
| List *rowMarks; /* a list of RowMarkClause's */ |
| |
| List *relationOids; /* OIDs of relations the plan depends on */ |
| |
| List *invalItems; /* other dependencies, as PlanInvalItems */ |
| |
| int nCrossLevelParams; /* number of PARAM_EXEC Params used */ |
| |
| int nMotionNodes; /* number of Motion nodes in plan */ |
| |
| int nInitPlans; /* number of initPlans in plan */ |
| |
| /* GPDB: Used only on QD. Don't serialize. Cloned from top Query node |
| * at the end of planning. Holds the result distribution policy |
| * for SELECT ... INTO and set operations. |
| */ |
| struct GpPolicy *intoPolicy; |
| |
| /* |
| * GPDB: This allows the slice table to accompany the plan as it |
| * moves around the executor. |
| * |
| * Currently, the slice table should not be installed on the QD. |
| * Rather is it shipped to QEs as a separate parameter to MPPEXEC. |
| * The implementation of MPPEXEC, which runs on the QEs, installs |
| * the slice table in the plan as required there. |
| */ |
| Node *sliceTable; |
| |
| /** |
| * Backoff weight; |
| */ |
| int backoff_weight; |
| |
| /* What is the memory reserved for this query's execution? */ |
| uint64 query_mem; |
| |
| QueryContextInfo * contextdisp; /* query context for dispatching */ |
| |
| struct QueryResource *resource; |
| int planner_segments; |
| |
| /* The overall memory consumption account (i.e., outside of an operator) */ |
| MemoryAccount *memoryAccount; |
| |
| StringInfo datalocalityInfo; |
| } PlannedStmt; |
| |
| |
| /* |
| * Fetch the Plan associated with a SubPlan node in a completed PlannedStmt. |
| */ |
| static inline struct Plan *exec_subplan_get_plan(struct PlannedStmt *plannedstmt, SubPlan *subplan) |
| { |
| return (struct Plan *) list_nth(plannedstmt->subplans, subplan->plan_id - 1); |
| } |
| |
| /* |
| * Rewrite the Plan associated with a SubPlan node in a completed PlannedStmt. |
| */ |
| static inline void exec_subplan_put_plan(struct PlannedStmt *plannedstmt, SubPlan *subplan, struct Plan *plan) |
| { |
| ListCell *cell = list_nth_cell(plannedstmt->subplans, subplan->plan_id-1); |
| cell->data.ptr_value = plan; |
| } |
| |
| |
| /* ---------------- |
| * Plan node |
| * |
| * All plan nodes "derive" from the Plan structure by having the |
| * Plan structure as the first field. This ensures that everything works |
| * when nodes are cast to Plan's. (node pointers are frequently cast to Plan* |
| * when passed around generically in the executor) |
| * |
| * We never actually instantiate any Plan nodes; this is just the common |
| * abstract superclass for all Plan-type nodes. |
| * ---------------- |
| */ |
| typedef struct Plan |
| { |
| NodeTag type; |
| |
| /* Plan node id and parent node id */ |
| int plan_node_id; |
| int plan_parent_node_id; |
| |
| /* |
| * estimated execution costs for plan (see costsize.c for more info) |
| */ |
| Cost startup_cost; /* cost expended before fetching any tuples */ |
| Cost total_cost; /* total cost (assuming all tuples fetched) */ |
| |
| /* |
| * planner's estimate of result size of this plan step |
| */ |
| double plan_rows; /* number of rows plan is expected to emit */ |
| int plan_width; /* average row width in bytes */ |
| |
| /* |
| * Common structural data for all Plan types. |
| */ |
| List *targetlist; /* target list to be computed at this node */ |
| List *qual; /* implicitly-ANDed qual conditions */ |
| |
| struct Plan *lefttree; /* input plan tree(s) */ |
| struct Plan *righttree; |
| List *initPlan; /* Init Plan nodes (un-correlated expr |
| * subselects) */ |
| |
| /* |
| * Information for management of parameter-change-driven rescanning |
| * |
| * extParam includes the paramIDs of all external PARAM_EXEC params |
| * affecting this plan node or its children. setParam params from the |
| * node's initPlans are not included, but their extParams are. |
| * |
| * allParam includes all the extParam paramIDs, plus the IDs of local |
| * params that affect the node (i.e., the setParams of its initplans). |
| * These are _all_ the PARAM_EXEC params that affect this node. |
| */ |
| Bitmapset *extParam; |
| Bitmapset *allParam; |
| |
| int nParamExec; /* Also in PlannedStmt */ |
| |
| /* |
| * MPP needs to keep track of the characteristics of flow of output |
| * tuple of Plan nodes. |
| */ |
| Flow *flow; /* Flow description. Initially NULL. |
| * Set during parallelization. |
| */ |
| |
| /* |
| * CDB: How should this plan tree be dispatched? Initially this is set |
| * to DISPATCH_UNDETERMINED and, in non-root nodes, may remain so. |
| * However, in Plan nodes at the root of any separately dispatchable plan |
| * fragment, it must be set to a specific dispatch type. |
| */ |
| DispatchMethod dispatch; |
| |
| /* |
| * CDB: if we're going to direct dispatch, point it at a particular id. |
| * |
| * For motion nodes, this direct dispatch data is for the slice rooted at the |
| * motion node (the sending side!) |
| * For other nodes, it is for the slice rooted at this plan so it must be a root |
| * plan for a query |
| * Note that for nodes that are internal to a slice then this data is not |
| * set. |
| */ |
| DirectDispatchInfo directDispatch; |
| |
| /* |
| * CDB: Now many motion nodes are there in the Plan. How many init plans? |
| * Additional plan tree global significant only in the root node. |
| */ |
| int nMotionNodes; |
| int nInitPlans; |
| |
| /* |
| * CDB: This allows the slice table to accompany the plan as it |
| * moves around the executor. This is anoter plan tree global that |
| * should be non-NULL only in the top node of a dispatchable tree. |
| * It could (and should) move to a TopPlan node if we ever do that. |
| * |
| * Currently, the slice table should not be installed on the QD. |
| * Rather is it shipped to QEs as a separate parameter to MPPEXEC. |
| * The implementation of MPPEXEC, which runs on the QEs, installs |
| * the slice table in the plan as required there. |
| */ |
| Node *sliceTable; |
| |
| /** |
| * How much memory (in KB) should be used to execute this plan node? |
| */ |
| uint64 operatorMemKB; |
| |
| /* MemoryAccount to use for recording the memory usage of different plan nodes. */ |
| MemoryAccount* memoryAccount; |
| } Plan; |
| |
| /* ---------------- |
| * these are 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 innerPlan(node) (((Plan *)(node))->righttree) |
| #define outerPlan(node) (((Plan *)(node))->lefttree) |
| |
| |
| /* ---------------- |
| * Result node - |
| * If no outer plan, evaluate a variable-free targetlist. |
| * If outer plan, return tuples from outer plan (after a level of |
| * projection as shown by targetlist). |
| * |
| * If resconstantqual isn't NULL, it represents a one-time qualification |
| * test (i.e., one that doesn't depend on any variables from the outer plan, |
| * so needs to be evaluated only once). |
| * ---------------- |
| */ |
| typedef struct Result |
| { |
| Plan plan; |
| Node *resconstantqual; |
| bool hashFilter; |
| List *hashList; |
| } Result; |
| |
| /* ---------------- |
| * Repeat node - |
| * Repeatly output the results of the subplan. |
| * |
| * The repetition for each result tuple from the subplan is determined |
| * by the value from a specified column. |
| * ---------------- |
| */ |
| typedef struct Repeat |
| { |
| Plan plan; |
| |
| /* |
| * An expression to represent the number of times an input tuple to |
| * be repeatly outputted by this node. |
| * |
| * Currently, this expression should result in an integer. |
| */ |
| Expr *repeatCountExpr; |
| |
| /* |
| * The GROUPING value. This is used for grouping extension |
| * distinct-qualified queries. The distinct-qualified plan generated |
| * through cdbgroup.c may have a Join Plan node on the top, which |
| * can not properly handle GROUPING values. We let the Repeat |
| * node to handle this case. |
| */ |
| uint64 grouping; |
| } Repeat; |
| |
| /* ---------------- |
| * Append node - |
| * Generate the concatenation of the results of sub-plans. |
| * |
| * Append nodes are sometimes used to switch between several result relations |
| * (when the target of an UPDATE or DELETE is an inheritance set). Such a |
| * node will have isTarget true. The Append executor is then responsible |
| * for updating the executor state to point at the correct target relation |
| * whenever it switches subplans. |
| * ---------------- |
| */ |
| typedef struct Append |
| { |
| Plan plan; |
| List *appendplans; |
| bool isTarget; |
| bool isZapped; |
| |
| /* |
| * Indicate whether the subnodes of this Append node contain |
| * cross-slice shared nodes, and one of these subnodes running |
| * on the same slice as this Append node. |
| */ |
| bool hasXslice; |
| } Append; |
| |
| /* |
| * Sequence node |
| * Execute a list of subplans in the order of left-to-right, and return |
| * the results of the last subplan. |
| */ |
| typedef struct Sequence |
| { |
| Plan plan; |
| List *subplans; |
| } Sequence; |
| |
| /* ---------------- |
| * BitmapAnd node - |
| * Generate the intersection of the results of sub-plans. |
| * |
| * The subplans must be of types that yield tuple bitmaps. The targetlist |
| * and qual fields of the plan are unused and are always NIL. |
| * ---------------- |
| */ |
| typedef struct BitmapAnd |
| { |
| Plan plan; |
| List *bitmapplans; |
| } BitmapAnd; |
| |
| /* ---------------- |
| * BitmapOr node - |
| * Generate the union of the results of sub-plans. |
| * |
| * The subplans must be of types that yield tuple bitmaps. The targetlist |
| * and qual fields of the plan are unused and are always NIL. |
| * ---------------- |
| */ |
| typedef struct BitmapOr |
| { |
| Plan plan; |
| List *bitmapplans; |
| } BitmapOr; |
| |
| /* |
| * ========== |
| * Scan nodes |
| * ========== |
| */ |
| typedef struct Scan |
| { |
| Plan plan; |
| Index scanrelid; /* relid is index into the range table */ |
| |
| /* |
| * The index to an internal array structure that |
| * contains oids of the parts that need to be scanned. |
| * |
| * This internal structure is maintained in EState. |
| * |
| * Note: if the scan is not "dynamic" (i.e., not using optimizer), |
| * we set it to INVALID_PART_INDEX. |
| */ |
| int32 partIndex; |
| int32 partIndexPrintable; |
| } Scan; |
| |
| /* ---------------- |
| * sequential scan node |
| * ---------------- |
| */ |
| typedef Scan SeqScan; |
| |
| /* |
| * TableScan |
| * Scan node that captures different table types. |
| */ |
| typedef Scan TableScan; |
| |
| /* ---------------- |
| * index type information |
| */ |
| typedef enum LogicalIndexType |
| { |
| INDTYPE_BTREE = 0, |
| INDTYPE_BITMAP = 1 |
| } LogicalIndexType; |
| |
| typedef struct LogicalIndexInfo |
| { |
| Oid logicalIndexOid; /* OID of the logical index */ |
| int nColumns; /* Number of columns in the index */ |
| AttrNumber *indexKeys; /* column numbers of index keys */ |
| List *indPred; /* predicate if partial index, or NIL */ |
| List *indExprs; /* index on expressions */ |
| bool indIsUnique; /* unique index */ |
| LogicalIndexType indType; /* index type: btree or bitmap */ |
| Node *partCons; /* concatenated list of check constraints |
| * of each partition on which this index is defined */ |
| List *defaultLevels; /* Used to identify a default partition */ |
| } LogicalIndexInfo; |
| |
| /* ---------------- |
| * index scan node |
| * |
| * indexqualorig is an implicitly-ANDed list of index qual expressions, each |
| * in the same form it appeared in the query WHERE condition. Each should |
| * be of the form (indexkey OP comparisonval) or (comparisonval OP indexkey). |
| * The indexkey is a Var or expression referencing column(s) of the index's |
| * base table. The comparisonval might be any expression, but it won't use |
| * any columns of the base table. |
| * |
| * indexqual has the same form, but the expressions have been commuted if |
| * necessary to put the indexkeys on the left, and the indexkeys are replaced |
| * by Var nodes identifying the index columns (varattno is the index column |
| * position, not the base table's column, even though varno is for the base |
| * table). This is a bit hokey ... would be cleaner to use a special-purpose |
| * node type that could not be mistaken for a regular Var. But it will do |
| * for now. |
| * |
| * indexstrategy and indexsubtype are lists corresponding one-to-one with |
| * indexqual; they give information about the indexable operators that appear |
| * at the top of each indexqual. |
| * ---------------- |
| */ |
| typedef struct IndexScan |
| { |
| Scan scan; |
| Oid indexid; /* OID of index to scan */ |
| List *indexqual; /* list of index quals (OpExprs) */ |
| List *indexqualorig; /* the same in original form */ |
| List *indexstrategy; /* integer list of strategy numbers */ |
| List *indexsubtype; /* OID list of strategy subtypes */ |
| ScanDirection indexorderdir; /* forward or backward or don't care */ |
| |
| /* logical index to use */ |
| LogicalIndexInfo *logicalIndexInfo; |
| } IndexScan; |
| |
| /* |
| * DynamicIndexScan |
| * Scan a list of indexes that will be determined at run time. |
| * The primary application of this operator is to be used |
| * for partition tables. |
| */ |
| typedef IndexScan DynamicIndexScan; |
| |
| /* ---------------- |
| * bitmap index scan node |
| * |
| * BitmapIndexScan delivers a bitmap of potential tuple locations; |
| * it does not access the heap itself. The bitmap is used by an |
| * ancestor BitmapHeapScan node, possibly after passing through |
| * intermediate BitmapAnd and/or BitmapOr nodes to combine it with |
| * the results of other BitmapIndexScans. |
| * |
| * The fields have the same meanings as for IndexScan, except we don't |
| * store a direction flag because direction is uninteresting. |
| * |
| * In a BitmapIndexScan plan node, the targetlist and qual fields are |
| * not used and are always NIL. The indexqualorig field is unused at |
| * run time too, but is saved for the benefit of EXPLAIN, as well |
| * as for the use of the planner when doing clause examination on plans |
| * (such as for targeted dispatch) |
| * ---------------- |
| */ |
| typedef IndexScan BitmapIndexScan; |
| |
| /* ---------------- |
| * bitmap sequential scan node |
| * |
| * This needs a copy of the qual conditions being used by the input index |
| * scans because there are various cases where we need to recheck the quals; |
| * for example, when the bitmap is lossy about the specific rows on a page |
| * that meet the index condition. |
| * ---------------- |
| */ |
| typedef struct BitmapHeapScan |
| { |
| Scan scan; |
| List *bitmapqualorig; /* index quals, in standard expr form */ |
| } BitmapHeapScan; |
| |
| /* ---------------- |
| * bitmap append-only row-store scan node |
| * |
| * NOTE: This is a copy of BitmapHeapScan. |
| * ---------------- |
| */ |
| typedef struct BitmapAppendOnlyScan |
| { |
| Scan scan; |
| List *bitmapqualorig; /* index quals, in standard expr form */ |
| bool isAORow; /* If this is for AO Row tables */ |
| } BitmapAppendOnlyScan; |
| |
| /* ---------------- |
| * bitmap table scan node |
| * |
| * This is a copy of BitmapHeapScan |
| * ---------------- |
| */ |
| typedef BitmapHeapScan BitmapTableScan; |
| |
| /* |
| * DynamicTableScan |
| * Scan a list of tables that will be determined at run time. |
| */ |
| typedef Scan DynamicTableScan; |
| |
| /* ---------------- |
| * tid scan node |
| * |
| * tidquals is an implicitly OR'ed list of qual expressions of the form |
| * "CTID = pseudoconstant" or "CTID = ANY(pseudoconstant_array)". |
| * ---------------- |
| */ |
| typedef struct TidScan |
| { |
| Scan scan; |
| List *tidquals; /* qual(s) involving CTID = something */ |
| } TidScan; |
| |
| /* ---------------- |
| * subquery scan node |
| * |
| * SubqueryScan is for scanning the output of a sub-query in the range table. |
| * We often need an extra plan node above the sub-query's plan to perform |
| * expression evaluations (which we can't push into the sub-query without |
| * risking changing its semantics). Although we are not scanning a physical |
| * relation, we make this a descendant of Scan anyway for code-sharing |
| * purposes. |
| * |
| * Note: we store the sub-plan in the type-specific subplan field, not in |
| * the generic lefttree field as you might expect. This is because we do |
| * not want plan-tree-traversal routines to recurse into the subplan without |
| * knowing that they are changing Query contexts. |
| * |
| * Note: subrtable is used just to carry the subquery rangetable from |
| * createplan.c to setrefs.c; it should always be NIL by the time the |
| * executor sees the plan. |
| * ---------------- |
| */ |
| typedef struct SubqueryScan |
| { |
| Scan scan; |
| Plan *subplan; |
| List *subrtable; /* temporary workspace for planner */ |
| } SubqueryScan; |
| |
| /* ---------------- |
| * FunctionScan node |
| * ---------------- |
| */ |
| typedef struct FunctionScan |
| { |
| Scan scan; |
| } FunctionScan; |
| |
| /* ---------------- |
| * TableFunctionScan node |
| * ---------------- |
| */ |
| typedef struct TableFunctionScan |
| { |
| Scan scan; |
| List *subrtable; /* temporary workspace for planner */ |
| } TableFunctionScan; |
| |
| /* ---------------- |
| * ValuesScan node |
| * ---------------- |
| */ |
| typedef struct ValuesScan |
| { |
| Scan scan; |
| /* no other fields needed at present */ |
| } ValuesScan; |
| |
| /* ---------------- |
| * External Scan node |
| * |
| * Field scan.scanrelid is the index of the external relation for |
| * this node. |
| * |
| * Field filenames is a list of N string node pointers (or NULL) |
| * where N is number of segments in the array. The pointer in |
| * position I is NULL or points to the string node containing the |
| * file name for segment I. |
| * ---------------- |
| */ |
| typedef struct ExternalScan |
| { |
| Scan scan; |
| List *uriList; /* data uri or null for each segment */ |
| List *fmtOpts; /* data format options */ |
| char fmtType; /* data format type */ |
| bool isMasterOnly; /* true for EXECUTE on master seg only */ |
| int rejLimit; /* reject limit (-1 for no sreh) */ |
| bool rejLimitInRows; /* true if ROWS false if PERCENT */ |
| Oid fmterrtbl; /* format error table, InvalidOid if none */ |
| List *errAosegnos; /* AO segno for error table */ |
| List *err_aosegfileinfos; /* AO segment file information for error table */ |
| int encoding; /* encoding of external table data */ |
| uint32 scancounter; /* counter incr per scan node created */ |
| |
| } ExternalScan; |
| |
| /* ---------------- |
| * AppendOnly Scan node |
| * |
| * Field scan.scanrelid is the index of the append only relation for |
| * this node. |
| * |
| * ---------------- |
| */ |
| typedef struct AppendOnlyScan |
| { |
| Scan scan; |
| /* nothing for now... */ |
| } AppendOnlyScan; |
| |
| typedef struct ParquetScan |
| { |
| Scan scan; |
| /* nothing for now... */ |
| } ParquetScan; |
| |
| /* |
| * ========== |
| * Join nodes |
| * ========== |
| */ |
| |
| /* ---------------- |
| * Join node |
| * |
| * jointype: rule for joining tuples from left and right subtrees |
| * joinqual: qual conditions that came from JOIN/ON or JOIN/USING |
| * (plan.qual contains conditions that came from WHERE) |
| * |
| * When jointype is INNER, joinqual and plan.qual are semantically |
| * interchangeable. For OUTER jointypes, the two are *not* interchangeable; |
| * only joinqual is used to determine whether a match has been found for |
| * the purpose of deciding whether to generate null-extended tuples. |
| * (But plan.qual is still applied before actually returning a tuple.) |
| * For an outer join, only joinquals are allowed to be used as the merge |
| * or hash condition of a merge or hash join. |
| * ---------------- |
| */ |
| typedef struct Join |
| { |
| Plan plan; |
| JoinType jointype; |
| List *joinqual; /* JOIN quals (in addition to plan.qual) */ |
| |
| bool prefetch_inner; /* to avoid deadlock in MPP */ |
| } Join; |
| |
| /* ---------------- |
| * nest loop join node |
| * ---------------- |
| */ |
| typedef struct NestLoop |
| { |
| Join join; |
| |
| bool outernotreferencedbyinner; /* true => inner has no OUTER Var */ |
| bool shared_outer; |
| bool singleton_outer; /*CDB-OLAP true => outer is plain Agg */ |
| } NestLoop; |
| |
| /* ---------------- |
| * merge join node |
| * ---------------- |
| */ |
| typedef struct MergeJoin |
| { |
| Join join; |
| List *mergeclauses; |
| bool unique_outer; /*CDB-OLAP true => outer is unique in merge key */ |
| } MergeJoin; |
| |
| /* ---------------- |
| * hash join (probe) node |
| * |
| * CDB: In order to support hash join on IS NOT DISTINCT FROM (as well as =), |
| * field hashqualclauses is added to hold the expression that tests for |
| * a match. This is normally identical to hashclauses (which holds the |
| * equality test), but differs in case of non-equijoin comparisons. |
| * Field hashclauses is retained for use in hash table operations. |
| * ---------------- |
| */ |
| typedef struct HashJoin |
| { |
| Join join; |
| List *hashclauses; |
| List *hashqualclauses; |
| } HashJoin; |
| |
| /* |
| * Share type of sharing a node. |
| */ |
| typedef enum ShareType |
| { |
| SHARE_NOTSHARED, |
| SHARE_MATERIAL, /* Sharing a material node */ |
| SHARE_MATERIAL_XSLICE, /* Sharing a material node, across slice */ |
| SHARE_SORT, /* Sharing a sort */ |
| SHARE_SORT_XSLICE /* Sharing a sort, across slice */ |
| /* Other types maybe added later, like sharing a hash */ |
| } ShareType; |
| |
| #define SHARE_ID_NOT_SHARED (-1) |
| #define SHARE_ID_NOT_ASSIGNED (-2) |
| |
| extern int get_plan_share_id(Plan *p); |
| extern void set_plan_share_id(Plan *p, int share_id); |
| extern ShareType get_plan_share_type (Plan *p); |
| extern void set_plan_share_type(Plan *p, ShareType st); |
| extern void set_plan_share_type_xslice(Plan *p); |
| extern int get_plan_driver_slice(Plan *p); |
| extern void set_plan_driver_slice(Plan *P, int slice); |
| extern void incr_plan_nsharer_xslice(Plan *p); |
| extern bool isDynamicScan(const Scan *scan); |
| |
| /* ---------------- |
| * shareinputscan node |
| * ---------------- |
| */ |
| typedef struct ShareInputScan |
| { |
| Plan plan; /* The ShareInput */ |
| |
| ShareType share_type; |
| int share_id; |
| int driver_slice; /* slice id that will execute the underlying material/sort */ |
| } ShareInputScan; |
| |
| /* ---------------- |
| * Material node |
| * ---------------- |
| */ |
| typedef struct Material |
| { |
| Plan plan; |
| bool cdb_strict; |
| |
| /* Material can be shared */ |
| ShareType share_type; |
| int share_id; |
| int driver_slice; /* slice id that will execute this material */ |
| int nsharer; /* number of sharer */ |
| int nsharer_xslice; /* number of sharer cross slice */ |
| } Material; |
| |
| |
| /* ---------------- |
| * sort node |
| * ---------------- |
| */ |
| typedef struct Sort |
| { |
| Plan plan; |
| int numCols; /* number of sort-key columns */ |
| AttrNumber *sortColIdx; /* their indexes in the target list */ |
| Oid *sortOperators; /* OIDs of operators to sort them by */ |
| bool *nullsFirst; /* NULLS FIRST/LAST directions */ |
| /* CDB */ /* add limit node, distinct */ |
| Node *limitOffset; /* OFFSET parameter, or NULL if none */ |
| Node *limitCount; /* COUNT parameter, or NULL if none */ |
| bool noduplicates; /* TRUE if sort should discard duplicates */ |
| |
| /* Sort node can be shared */ |
| ShareType share_type; |
| int share_id; |
| int driver_slice; /* slice id that will execute this sort */ |
| int nsharer; /* number of sharer */ |
| int nsharer_xslice; /* number of sharer cross slice */ |
| } Sort; |
| |
| /* --------------- |
| * aggregate node |
| * |
| * An Agg node implements plain or grouped aggregation. For grouped |
| * aggregation, we can work with presorted input or unsorted input; |
| * the latter strategy uses an internal hashtable. |
| * |
| * Notice the lack of any direct info about the aggregate functions to be |
| * computed. They are found by scanning the node's tlist and quals during |
| * executor startup. (It is possible that there are no aggregate functions; |
| * this could happen if they get optimized away by constant-folding, or if |
| * we are using the Agg node to implement hash-based grouping.) |
| * --------------- |
| */ |
| typedef enum AggStrategy |
| { |
| AGG_PLAIN, /* simple agg across all input rows */ |
| AGG_SORTED, /* grouped agg, input must be sorted */ |
| AGG_HASHED /* grouped agg, use internal hashtable */ |
| } AggStrategy; |
| |
| typedef struct Agg |
| { |
| Plan plan; |
| AggStrategy aggstrategy; |
| int numCols; /* number of grouping columns */ |
| AttrNumber *grpColIdx; /* their indexes in the target list */ |
| long numGroups; /* estimated number of groups in input */ |
| int transSpace; /* est storage per group for byRef transition values */ |
| |
| /* |
| * The following is used by ROLLUP. |
| */ |
| |
| /* |
| * The number of grouping columns for this node whose values should be null for |
| * this Agg node. |
| */ |
| int numNullCols; |
| |
| /* |
| * Indicate the GROUPING value of input tuples for this Agg node. |
| * For example of ROLLUP(a,b,c), there are four Agg nodes: |
| * |
| * Agg(a,b,c) ==> Agg(a,b) ==> Agg(a) ==> Agg() |
| * |
| * The GROUPING value of input tuples for Agg(a,b,c) is 0, and the values |
| * for Agg(a,b), Agg(a), Agg() are 1, 3, 7, respectively. |
| * |
| * We also use the value "-1" to indicate an Agg node is the final |
| * one that brings back all rollup results from different segments. This final |
| * Agg node is very similar to the non-rollup Agg node, except that we need |
| * a way to know this to properly set GROUPING value during execution. |
| * |
| * For a non-rollup Agg node, this value is 0. |
| */ |
| uint64 inputGrouping; |
| |
| /* The value of GROUPING for this rollup-aware node. */ |
| uint64 grouping; |
| |
| /* |
| * Indicate if input tuples contain values for GROUPING column. |
| * |
| * This is used to determine if the node that generates inputs |
| * for this Agg node is also an Agg node. That is, this Agg node |
| * is one of the list of Agg nodes for a ROLLUP. One exception is |
| * the first Agg node in the list, whose inputs do not have a |
| * GROUPING column. |
| */ |
| bool inputHasGrouping; |
| |
| /* |
| * How many times the aggregates in this rollup level will be output |
| * for a given query. Used only for ROLLUP queries. |
| */ |
| int rollupGSTimes; |
| |
| /* |
| * Indicate if this Agg node is the last one in a rollup. |
| */ |
| bool lastAgg; |
| |
| /* Should we stream this agg */ |
| bool streaming; |
| } Agg; |
| |
| /* --------------- |
| * window node |
| * |
| * A Window node implements window functions over zero or more |
| * ordering/framing specifications within a partition specification on |
| * appropriately ordered input. |
| * |
| * For example, if there are window functions |
| * |
| * over (partition by a,b orderby c) and |
| * over (partition by a,b order by c,d,e) |
| * |
| * then the input (outer plan) of the window node will be sorted by |
| * (a,b,c,d,e) -- the common partition key (a,b) and the partial |
| * ordering keys (c) and (d,e). |
| * |
| * A Window node contains no direct information about the window |
| * functions it computes. Those functions are found by scanning |
| * the node's targetlist for WindowRef nodes during executor startup. |
| * There need not be any, but there's no good reason for the planner |
| * to construct a Window node without at least one WindowRef. |
| * |
| * A WindowRef is related to its Window node by the fact that it is |
| * contained by it. It may also be related to a particular WindowKey |
| * node in the windowKeys list. The WindowRef field winlevel is the |
| * position (counting from 0) of its WindowKey. If winlevel equals |
| * the length of the windowKeys list, than it has not WindowKey an |
| * applied to the unordered partition as a whole. |
| * |
| * A WindowKey specifies a partial ordering key. It may optionally |
| * specify framing. The actual ordering key at a given level is the |
| * concatenation of the partial ordering keys prior to and including |
| * that level. |
| * |
| * For example, the ordering key for the WindowKey in position 2 of |
| * the windowKeys list is the concatenation of the partial keys found |
| * in positions 0 through 2. * |
| * --------------- |
| */ |
| typedef struct Window |
| { |
| Plan plan; |
| int numPartCols; /* number of partitioning columns */ |
| AttrNumber *partColIdx; /* their indexes in the target list |
| of the window's outer plan. */ |
| List *windowKeys; /* list of WindowKey nodes */ |
| } Window; |
| |
| |
| /* ---------------- |
| * unique node |
| * ---------------- |
| */ |
| typedef struct Unique |
| { |
| Plan plan; |
| int numCols; /* number of columns to check for uniqueness */ |
| AttrNumber *uniqColIdx; /* indexes into the target list */ |
| } Unique; |
| |
| /* ---------------- |
| * hash build node |
| * ---------------- |
| */ |
| typedef struct Hash |
| { |
| Plan plan; |
| bool rescannable; /* CDB: true => save rows for rescan */ |
| /* all other info is in the parent HashJoin node */ |
| } Hash; |
| |
| /* ---------------- |
| * setop node |
| * ---------------- |
| */ |
| typedef enum SetOpCmd |
| { |
| SETOPCMD_INTERSECT, |
| SETOPCMD_INTERSECT_ALL, |
| SETOPCMD_EXCEPT, |
| SETOPCMD_EXCEPT_ALL |
| } SetOpCmd; |
| |
| typedef struct SetOp |
| { |
| Plan plan; |
| SetOpCmd cmd; /* what to do */ |
| int numCols; /* number of columns to check for |
| * duplicate-ness */ |
| AttrNumber *dupColIdx; /* indexes into the target list */ |
| AttrNumber flagColIdx; |
| } SetOp; |
| |
| /* ---------------- |
| * limit node |
| * |
| * Note: as of Postgres 8.2, the offset and count expressions are expected |
| * to yield int8, rather than int4 as before. |
| * ---------------- |
| */ |
| typedef struct Limit |
| { |
| Plan plan; |
| Node *limitOffset; /* OFFSET parameter, or NULL if none */ |
| Node *limitCount; /* COUNT parameter, or NULL if none */ |
| } Limit; |
| |
| /* ------------------------- |
| * motion node structs |
| * ------------------------- |
| */ |
| typedef enum MotionType |
| { |
| MOTIONTYPE_HASH, /* Use hashing to select a segindex destination */ |
| MOTIONTYPE_FIXED, /* Send tuples to a fixed set of segindexes */ |
| MOTIONTYPE_EXPLICIT /* Send tuples to the segment explicitly specified in their segid column */ |
| } MotionType; |
| |
| /* |
| * Motion Node |
| * |
| */ |
| typedef struct Motion |
| { |
| Plan plan; |
| |
| MotionType motionType; |
| bool sendSorted; /* if true, output should be sorted */ |
| int motionID; /* required by AMS */ |
| |
| /* For Hash */ |
| List *hashExpr; /* list of hash expressions */ |
| List *hashDataTypes; /* list of hash expr data type oids */ |
| |
| /* Output segments */ |
| int numOutputSegs; /* number of seg indexes in outputSegIdx array, 0 for broadcast */ |
| int *outputSegIdx; /* array of output segindexes */ |
| |
| /* For Explicit */ |
| AttrNumber segidColIdx; /* index of the segid column in the target list */ |
| |
| /* The following field is only used when sendSorted == true */ |
| int numSortCols; /* number of sort key columns */ |
| AttrNumber *sortColIdx; /* their indexes in target list */ |
| Oid *sortOperators; /* OID of operators to sort them by */ |
| } Motion; |
| |
| /* |
| * DML Node |
| */ |
| typedef struct DML |
| { |
| |
| Plan plan; |
| Index scanrelid; /* index into the range table */ |
| AttrNumber oidColIdx; /* index of table oid into the target list */ |
| AttrNumber actionColIdx; /* index of action column into the target list */ |
| AttrNumber ctidColIdx; /* index of ctid column into the target list */ |
| AttrNumber tupleoidColIdx; /* index of tuple oid column into the target list */ |
| |
| } DML; |
| |
| /* |
| * SplitUpdate Node |
| * |
| */ |
| typedef struct SplitUpdate |
| { |
| |
| Plan plan; |
| AttrNumber actionColIdx; /* index of action column into the target list */ |
| AttrNumber ctidColIdx; /* index of ctid column into the target list */ |
| AttrNumber tupleoidColIdx; /* index of tuple oid column into the target list */ |
| List *insertColIdx; /* list of columns to INSERT into the target list */ |
| List *deleteColIdx; /* list of columns to DELETE into the target list */ |
| |
| } SplitUpdate; |
| |
| /* |
| * AssertOp Node |
| * |
| */ |
| typedef struct AssertOp |
| { |
| |
| Plan plan; |
| int errcode; /* SQL error code */ |
| List *errmessage; /* error message */ |
| |
| } AssertOp; |
| |
| /* |
| * RowTrigger Node |
| * |
| */ |
| typedef struct RowTrigger |
| { |
| |
| Plan plan; |
| Oid relid; /* OID of target relation */ |
| int eventFlags; /* TriggerEvent bit flags (see trigger.h).*/ |
| List *oldValuesColIdx; /* list of old columns */ |
| List *newValuesColIdx; /* list of new columns */ |
| |
| } RowTrigger; |
| |
| /* |
| * Plan invalidation info |
| * |
| * We track the objects on which a PlannedStmt depends in two ways: |
| * relations are recorded as a simple list of OIDs, and everything else |
| * is represented as a list of PlanInvalItems. A PlanInvalItem identifies |
| * a system catalog entry by cache ID and tuple TID. |
| */ |
| typedef struct PlanInvalItem |
| { |
| NodeTag type; |
| int cacheId; /* a syscache ID, see utils/syscache.h */ |
| ItemPointerData tupleId; /* TID of the object's catalog tuple */ |
| } PlanInvalItem; |
| |
| /* |
| * ---------------- |
| * PartitionSelector node |
| * |
| * PartitionSelector finds a set of leaf partition OIDs given the root table |
| * OID and optionally selection predicates. |
| * |
| * It hides the logic of partition selection and propagation instead of |
| * polluting the plan with it to make a plan look consistent and easy to |
| * understand. It will be easy to locate where partition selection happens |
| * in a plan. |
| * ---------------- |
| */ |
| typedef struct PartitionSelector |
| { |
| Plan plan; |
| Oid relid; /* OID of target relation */ |
| int nLevels; /* number of partition levels */ |
| int32 scanId; /* id of the corresponding dynamic scan */ |
| int32 selectorId; /* id of this partition selector */ |
| List *levelEqExpressions; /* equality expressions used for individual levels */ |
| List *levelExpressions; /* predicates used for individual levels */ |
| Node *residualPredicate; /* residual predicate (to be applied at the end) */ |
| Node *propagationExpression; /* propagation expression */ |
| Node *printablePredicate; /* printable predicate (for explain purposes) */ |
| bool staticSelection; /* static selection performed? */ |
| List *staticPartOids; /* list of statically selected parts */ |
| List *staticScanIds; /* scan ids used to propagate statically selected part oids */ |
| |
| } PartitionSelector; |
| |
| #endif /* PLANNODES_H */ |