codekingpro/portable-devtools
115k
1/*-------------------------------------------------------------------------2 *3 * pathnodes.h4 * Definitions for planner's internal data structures, especially Paths.5 *6 * We don't support copying RelOptInfo, IndexOptInfo, or Path nodes.7 * There are some subsidiary structs that are useful to copy, though.8 *9 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group10 * Portions Copyright (c) 1994, Regents of the University of California11 *12 * src/include/nodes/pathnodes.h13 *14 *-------------------------------------------------------------------------15 */16#ifndef PATHNODES_H17#define PATHNODES_H18 19#include "access/sdir.h"20#include "lib/stringinfo.h"21#include "nodes/params.h"22#include "nodes/parsenodes.h"23#include "storage/block.h"24 25 26/*27 * Relids28 * Set of relation identifiers (indexes into the rangetable).29 */30typedef Bitmapset *Relids;31 32/*33 * When looking for a "cheapest path", this enum specifies whether we want34 * cheapest startup cost or cheapest total cost.35 */36typedef enum CostSelector37{38 STARTUP_COST, TOTAL_COST39} CostSelector;40 41/*42 * The cost estimate produced by cost_qual_eval() includes both a one-time43 * (startup) cost, and a per-tuple cost.44 */45typedef struct QualCost46{47 Cost startup; /* one-time cost */48 Cost per_tuple; /* per-evaluation cost */49} QualCost;50 51/*52 * Costing aggregate function execution requires these statistics about53 * the aggregates to be executed by a given Agg node. Note that the costs54 * include the execution costs of the aggregates' argument expressions as55 * well as the aggregate functions themselves. Also, the fields must be56 * defined so that initializing the struct to zeroes with memset is correct.57 */58typedef struct AggClauseCosts59{60 QualCost transCost; /* total per-input-row execution costs */61 QualCost finalCost; /* total per-aggregated-row costs */62 Size transitionSpace; /* space for pass-by-ref transition data */63} AggClauseCosts;64 65/*66 * This enum identifies the different types of "upper" (post-scan/join)67 * relations that we might deal with during planning.68 */69typedef enum UpperRelationKind70{71 UPPERREL_SETOP, /* result of UNION/INTERSECT/EXCEPT, if any */72 UPPERREL_PARTIAL_GROUP_AGG, /* result of partial grouping/aggregation, if73 * any */74 UPPERREL_GROUP_AGG, /* result of grouping/aggregation, if any */75 UPPERREL_WINDOW, /* result of window functions, if any */76 UPPERREL_PARTIAL_DISTINCT, /* result of partial "SELECT DISTINCT", if any */77 UPPERREL_DISTINCT, /* result of "SELECT DISTINCT", if any */78 UPPERREL_ORDERED, /* result of ORDER BY, if any */79 UPPERREL_FINAL /* result of any remaining top-level actions */80 /* NB: UPPERREL_FINAL must be last enum entry; it's used to size arrays */81} UpperRelationKind;82 83/*----------84 * PlannerGlobal85 * Global information for planning/optimization86 *87 * PlannerGlobal holds state for an entire planner invocation; this state88 * is shared across all levels of sub-Queries that exist in the command being89 * planned.90 *91 * Not all fields are printed. (In some cases, there is no print support for92 * the field type; in others, doing so would lead to infinite recursion.)93 *----------94 */95typedef struct PlannerGlobal96{97 pg_node_attr(no_copy_equal, no_read, no_query_jumble)98 99 NodeTag type;100 101 /* Param values provided to planner() */102 ParamListInfo boundParams pg_node_attr(read_write_ignore);103 104 /* Plans for SubPlan nodes */105 List *subplans;106 107 /* PlannerInfos for SubPlan nodes */108 List *subroots pg_node_attr(read_write_ignore);109 110 /* indices of subplans that require REWIND */111 Bitmapset *rewindPlanIDs;112 113 /* "flat" rangetable for executor */114 List *finalrtable;115 116 /* "flat" list of RTEPermissionInfos */117 List *finalrteperminfos;118 119 /* "flat" list of PlanRowMarks */120 List *finalrowmarks;121 122 /* "flat" list of integer RT indexes */123 List *resultRelations;124 125 /* "flat" list of AppendRelInfos */126 List *appendRelations;127 128 /* OIDs of relations the plan depends on */129 List *relationOids;130 131 /* other dependencies, as PlanInvalItems */132 List *invalItems;133 134 /* type OIDs for PARAM_EXEC Params */135 List *paramExecTypes;136 137 /* highest PlaceHolderVar ID assigned */138 Index lastPHId;139 140 /* highest PlanRowMark ID assigned */141 Index lastRowMarkId;142 143 /* highest plan node ID assigned */144 int lastPlanNodeId;145 146 /* redo plan when TransactionXmin changes? */147 bool transientPlan;148 149 /* is plan specific to current role? */150 bool dependsOnRole;151 152 /* parallel mode potentially OK? */153 bool parallelModeOK;154 155 /* parallel mode actually required? */156 bool parallelModeNeeded;157 158 /* worst PROPARALLEL hazard level */159 char maxParallelHazard;160 161 /* partition descriptors */162 PartitionDirectory partition_directory pg_node_attr(read_write_ignore);163} PlannerGlobal;164 165/* macro for fetching the Plan associated with a SubPlan node */166#define planner_subplan_get_plan(root, subplan) \167 ((Plan *) list_nth((root)->glob->subplans, (subplan)->plan_id - 1))168 169 170/*----------171 * PlannerInfo172 * Per-query information for planning/optimization173 *174 * This struct is conventionally called "root" in all the planner routines.175 * It holds links to all of the planner's working state, in addition to the176 * original Query. Note that at present the planner extensively modifies177 * the passed-in Query data structure; someday that should stop.178 *179 * For reasons explained in optimizer/optimizer.h, we define the typedef180 * either here or in that header, whichever is read first.181 *182 * Not all fields are printed. (In some cases, there is no print support for183 * the field type; in others, doing so would lead to infinite recursion or184 * bloat dump output more than seems useful.)185 *----------186 */187#ifndef HAVE_PLANNERINFO_TYPEDEF188typedef struct PlannerInfo PlannerInfo;189#define HAVE_PLANNERINFO_TYPEDEF 1190#endif191 192struct PlannerInfo193{194 pg_node_attr(no_copy_equal, no_read, no_query_jumble)195 196 NodeTag type;197 198 /* the Query being planned */199 Query *parse;200 201 /* global info for current planner run */202 PlannerGlobal *glob;203 204 /* 1 at the outermost Query */205 Index query_level;206 207 /* NULL at outermost Query */208 PlannerInfo *parent_root pg_node_attr(read_write_ignore);209 210 /*211 * plan_params contains the expressions that this query level needs to212 * make available to a lower query level that is currently being planned.213 * outer_params contains the paramIds of PARAM_EXEC Params that outer214 * query levels will make available to this query level.215 */216 /* list of PlannerParamItems, see below */217 List *plan_params;218 Bitmapset *outer_params;219 220 /*221 * simple_rel_array holds pointers to "base rels" and "other rels" (see222 * comments for RelOptInfo for more info). It is indexed by rangetable223 * index (so entry 0 is always wasted). Entries can be NULL when an RTE224 * does not correspond to a base relation, such as a join RTE or an225 * unreferenced view RTE; or if the RelOptInfo hasn't been made yet.226 */227 struct RelOptInfo **simple_rel_array pg_node_attr(array_size(simple_rel_array_size));228 /* allocated size of array */229 int simple_rel_array_size;230 231 /*232 * simple_rte_array is the same length as simple_rel_array and holds233 * pointers to the associated rangetable entries. Using this is a shade234 * faster than using rt_fetch(), mostly due to fewer indirections. (Not235 * printed because it'd be redundant with parse->rtable.)236 */237 RangeTblEntry **simple_rte_array pg_node_attr(read_write_ignore);238 239 /*240 * append_rel_array is the same length as the above arrays, and holds241 * pointers to the corresponding AppendRelInfo entry indexed by242 * child_relid, or NULL if the rel is not an appendrel child. The array243 * itself is not allocated if append_rel_list is empty. (Not printed244 * because it'd be redundant with append_rel_list.)245 */246 struct AppendRelInfo **append_rel_array pg_node_attr(read_write_ignore);247 248 /*249 * all_baserels is a Relids set of all base relids (but not joins or250 * "other" rels) in the query. This is computed in deconstruct_jointree.251 */252 Relids all_baserels;253 254 /*255 * outer_join_rels is a Relids set of all outer-join relids in the query.256 * This is computed in deconstruct_jointree.257 */258 Relids outer_join_rels;259 260 /*261 * all_query_rels is a Relids set of all base relids and outer join relids262 * (but not "other" relids) in the query. This is the Relids identifier263 * of the final join we need to form. This is computed in264 * deconstruct_jointree.265 */266 Relids all_query_rels;267 268 /*269 * join_rel_list is a list of all join-relation RelOptInfos we have270 * considered in this planning run. For small problems we just scan the271 * list to do lookups, but when there are many join relations we build a272 * hash table for faster lookups. The hash table is present and valid273 * when join_rel_hash is not NULL. Note that we still maintain the list274 * even when using the hash table for lookups; this simplifies life for275 * GEQO.276 */277 List *join_rel_list;278 struct HTAB *join_rel_hash pg_node_attr(read_write_ignore);279 280 /*281 * When doing a dynamic-programming-style join search, join_rel_level[k]282 * is a list of all join-relation RelOptInfos of level k, and283 * join_cur_level is the current level. New join-relation RelOptInfos are284 * automatically added to the join_rel_level[join_cur_level] list.285 * join_rel_level is NULL if not in use.286 *287 * Note: we've already printed all baserel and joinrel RelOptInfos above,288 * so we don't dump join_rel_level or other lists of RelOptInfos.289 */290 /* lists of join-relation RelOptInfos */291 List **join_rel_level pg_node_attr(read_write_ignore);292 /* index of list being extended */293 int join_cur_level;294 295 /* init SubPlans for query */296 List *init_plans;297 298 /*299 * per-CTE-item list of subplan IDs (or -1 if no subplan was made for that300 * CTE)301 */302 List *cte_plan_ids;303 304 /* List of Lists of Params for MULTIEXPR subquery outputs */305 List *multiexpr_params;306 307 /* list of JoinDomains used in the query (higher ones first) */308 List *join_domains;309 310 /* list of active EquivalenceClasses */311 List *eq_classes;312 313 /* set true once ECs are canonical */314 bool ec_merging_done;315 316 /* list of "canonical" PathKeys */317 List *canon_pathkeys;318 319 /*320 * list of OuterJoinClauseInfos for mergejoinable outer join clauses321 * w/nonnullable var on left322 */323 List *left_join_clauses;324 325 /*326 * list of OuterJoinClauseInfos for mergejoinable outer join clauses327 * w/nonnullable var on right328 */329 List *right_join_clauses;330 331 /*332 * list of OuterJoinClauseInfos for mergejoinable full join clauses333 */334 List *full_join_clauses;335 336 /* list of SpecialJoinInfos */337 List *join_info_list;338 339 /* counter for assigning RestrictInfo serial numbers */340 int last_rinfo_serial;341 342 /*343 * all_result_relids is empty for SELECT, otherwise it contains at least344 * parse->resultRelation. For UPDATE/DELETE/MERGE across an inheritance345 * or partitioning tree, the result rel's child relids are added. When346 * using multi-level partitioning, intermediate partitioned rels are347 * included. leaf_result_relids is similar except that only actual result348 * tables, not partitioned tables, are included in it.349 */350 /* set of all result relids */351 Relids all_result_relids;352 /* set of all leaf relids */353 Relids leaf_result_relids;354 355 /*356 * list of AppendRelInfos357 *358 * Note: for AppendRelInfos describing partitions of a partitioned table,359 * we guarantee that partitions that come earlier in the partitioned360 * table's PartitionDesc will appear earlier in append_rel_list.361 */362 List *append_rel_list;363 364 /* list of RowIdentityVarInfos */365 List *row_identity_vars;366 367 /* list of PlanRowMarks */368 List *rowMarks;369 370 /* list of PlaceHolderInfos */371 List *placeholder_list;372 373 /* array of PlaceHolderInfos indexed by phid */374 struct PlaceHolderInfo **placeholder_array pg_node_attr(read_write_ignore, array_size(placeholder_array_size));375 /* allocated size of array */376 int placeholder_array_size pg_node_attr(read_write_ignore);377 378 /* list of ForeignKeyOptInfos */379 List *fkey_list;380 381 /* desired pathkeys for query_planner() */382 List *query_pathkeys;383 384 /* groupClause pathkeys, if any */385 List *group_pathkeys;386 387 /*388 * The number of elements in the group_pathkeys list which belong to the389 * GROUP BY clause. Additional ones belong to ORDER BY / DISTINCT390 * aggregates.391 */392 int num_groupby_pathkeys;393 394 /* pathkeys of bottom window, if any */395 List *window_pathkeys;396 /* distinctClause pathkeys, if any */397 List *distinct_pathkeys;398 /* sortClause pathkeys, if any */399 List *sort_pathkeys;400 401 /* Canonicalised partition schemes used in the query. */402 List *part_schemes pg_node_attr(read_write_ignore);403 404 /* RelOptInfos we are now trying to join */405 List *initial_rels pg_node_attr(read_write_ignore);406 407 /*408 * Upper-rel RelOptInfos. Use fetch_upper_rel() to get any particular409 * upper rel.410 */411 List *upper_rels[UPPERREL_FINAL + 1] pg_node_attr(read_write_ignore);412 413 /* Result tlists chosen by grouping_planner for upper-stage processing */414 struct PathTarget *upper_targets[UPPERREL_FINAL + 1] pg_node_attr(read_write_ignore);415 416 /*417 * The fully-processed groupClause is kept here. It differs from418 * parse->groupClause in that we remove any items that we can prove419 * redundant, so that only the columns named here actually need to be420 * compared to determine grouping. Note that it's possible for *all* the421 * items to be proven redundant, implying that there is only one group422 * containing all the query's rows. Hence, if you want to check whether423 * GROUP BY was specified, test for nonempty parse->groupClause, not for424 * nonempty processed_groupClause.425 *426 * Currently, when grouping sets are specified we do not attempt to427 * optimize the groupClause, so that processed_groupClause will be428 * identical to parse->groupClause.429 */430 List *processed_groupClause;431 432 /*433 * The fully-processed distinctClause is kept here. It differs from434 * parse->distinctClause in that we remove any items that we can prove435 * redundant, so that only the columns named here actually need to be436 * compared to determine uniqueness. Note that it's possible for *all*437 * the items to be proven redundant, implying that there should be only438 * one output row. Hence, if you want to check whether DISTINCT was439 * specified, test for nonempty parse->distinctClause, not for nonempty440 * processed_distinctClause.441 */442 List *processed_distinctClause;443 444 /*445 * The fully-processed targetlist is kept here. It differs from446 * parse->targetList in that (for INSERT) it's been reordered to match the447 * target table, and defaults have been filled in. Also, additional448 * resjunk targets may be present. preprocess_targetlist() does most of449 * that work, but note that more resjunk targets can get added during450 * appendrel expansion. (Hence, upper_targets mustn't get set up till451 * after that.)452 */453 List *processed_tlist;454 455 /*456 * For UPDATE, this list contains the target table's attribute numbers to457 * which the first N entries of processed_tlist are to be assigned. (Any458 * additional entries in processed_tlist must be resjunk.) DO NOT use the459 * resnos in processed_tlist to identify the UPDATE target columns.460 */461 List *update_colnos;462 463 /*464 * Fields filled during create_plan() for use in setrefs.c465 */466 /* for GroupingFunc fixup (can't print: array length not known here) */467 AttrNumber *grouping_map pg_node_attr(read_write_ignore);468 /* List of MinMaxAggInfos */469 List *minmax_aggs;470 471 /* context holding PlannerInfo */472 MemoryContext planner_cxt pg_node_attr(read_write_ignore);473 474 /* # of pages in all non-dummy tables of query */475 Cardinality total_table_pages;476 477 /* tuple_fraction passed to query_planner */478 Selectivity tuple_fraction;479 /* limit_tuples passed to query_planner */480 Cardinality limit_tuples;481 482 /*483 * Minimum security_level for quals. Note: qual_security_level is zero if484 * there are no securityQuals.485 */486 Index qual_security_level;487 488 /* true if any RTEs are RTE_JOIN kind */489 bool hasJoinRTEs;490 /* true if any RTEs are marked LATERAL */491 bool hasLateralRTEs;492 /* true if havingQual was non-null */493 bool hasHavingQual;494 /* true if any RestrictInfo has pseudoconstant = true */495 bool hasPseudoConstantQuals;496 /* true if we've made any of those */497 bool hasAlternativeSubPlans;498 /* true once we're no longer allowed to add PlaceHolderInfos */499 bool placeholdersFrozen;500 /* true if planning a recursive WITH item */501 bool hasRecursion;502 503 /*504 * Information about aggregates. Filled by preprocess_aggrefs().505 */506 /* AggInfo structs */507 List *agginfos;508 /* AggTransInfo structs */509 List *aggtransinfos;510 /* number of aggs with DISTINCT/ORDER BY/WITHIN GROUP */511 int numOrderedAggs;512 /* does any agg not support partial mode? */513 bool hasNonPartialAggs;514 /* is any partial agg non-serializable? */515 bool hasNonSerialAggs;516 517 /*518 * These fields are used only when hasRecursion is true:519 */520 /* PARAM_EXEC ID for the work table */521 int wt_param_id;522 /* a path for non-recursive term */523 struct Path *non_recursive_path;524 525 /*526 * These fields are workspace for createplan.c527 */528 /* outer rels above current node */529 Relids curOuterRels;530 /* not-yet-assigned NestLoopParams */531 List *curOuterParams;532 533 /*534 * These fields are workspace for setrefs.c. Each is an array535 * corresponding to glob->subplans. (We could probably teach536 * gen_node_support.pl how to determine the array length, but it doesn't537 * seem worth the trouble, so just mark them read_write_ignore.)538 */539 bool *isAltSubplan pg_node_attr(read_write_ignore);540 bool *isUsedSubplan pg_node_attr(read_write_ignore);541 542 /* optional private data for join_search_hook, e.g., GEQO */543 void *join_search_private pg_node_attr(read_write_ignore);544 545 /* Does this query modify any partition key columns? */546 bool partColsUpdated;547};548 549 550/*551 * In places where it's known that simple_rte_array[] must have been prepared552 * already, we just index into it to fetch RTEs. In code that might be553 * executed before or after entering query_planner(), use this macro.554 */555#define planner_rt_fetch(rti, root) \556 ((root)->simple_rte_array ? (root)->simple_rte_array[rti] : \557 rt_fetch(rti, (root)->parse->rtable))558 559/*560 * If multiple relations are partitioned the same way, all such partitions561 * will have a pointer to the same PartitionScheme. A list of PartitionScheme562 * objects is attached to the PlannerInfo. By design, the partition scheme563 * incorporates only the general properties of the partition method (LIST vs.564 * RANGE, number of partitioning columns and the type information for each)565 * and not the specific bounds.566 *567 * We store the opclass-declared input data types instead of the partition key568 * datatypes since the former rather than the latter are used to compare569 * partition bounds. Since partition key data types and the opclass declared570 * input data types are expected to be binary compatible (per ResolveOpClass),571 * both of those should have same byval and length properties.572 */573typedef struct PartitionSchemeData574{575 char strategy; /* partition strategy */576 int16 partnatts; /* number of partition attributes */577 Oid *partopfamily; /* OIDs of operator families */578 Oid *partopcintype; /* OIDs of opclass declared input data types */579 Oid *partcollation; /* OIDs of partitioning collations */580 581 /* Cached information about partition key data types. */582 int16 *parttyplen;583 bool *parttypbyval;584 585 /* Cached information about partition comparison functions. */586 struct FmgrInfo *partsupfunc;587} PartitionSchemeData;588 589typedef struct PartitionSchemeData *PartitionScheme;590 591/*----------592 * RelOptInfo593 * Per-relation information for planning/optimization594 *595 * For planning purposes, a "base rel" is either a plain relation (a table)596 * or the output of a sub-SELECT or function that appears in the range table.597 * In either case it is uniquely identified by an RT index. A "joinrel"598 * is the joining of two or more base rels. A joinrel is identified by599 * the set of RT indexes for its component baserels, along with RT indexes600 * for any outer joins it has computed. We create RelOptInfo nodes for each601 * baserel and joinrel, and store them in the PlannerInfo's simple_rel_array602 * and join_rel_list respectively.603 *604 * Note that there is only one joinrel for any given set of component605 * baserels, no matter what order we assemble them in; so an unordered606 * set is the right datatype to identify it with.607 *608 * We also have "other rels", which are like base rels in that they refer to609 * single RT indexes; but they are not part of the join tree, and are given610 * a different RelOptKind to identify them.611 * Currently the only kind of otherrels are those made for member relations612 * of an "append relation", that is an inheritance set or UNION ALL subquery.613 * An append relation has a parent RTE that is a base rel, which represents614 * the entire append relation. The member RTEs are otherrels. The parent615 * is present in the query join tree but the members are not. The member616 * RTEs and otherrels are used to plan the scans of the individual tables or617 * subqueries of the append set; then the parent baserel is given Append618 * and/or MergeAppend paths comprising the best paths for the individual619 * member rels. (See comments for AppendRelInfo for more information.)620 *621 * At one time we also made otherrels to represent join RTEs, for use in622 * handling join alias Vars. Currently this is not needed because all join623 * alias Vars are expanded to non-aliased form during preprocess_expression.624 *625 * We also have relations representing joins between child relations of626 * different partitioned tables. These relations are not added to627 * join_rel_level lists as they are not joined directly by the dynamic628 * programming algorithm.629 *630 * There is also a RelOptKind for "upper" relations, which are RelOptInfos631 * that describe post-scan/join processing steps, such as aggregation.632 * Many of the fields in these RelOptInfos are meaningless, but their Path633 * fields always hold Paths showing ways to do that processing step.634 *635 * Parts of this data structure are specific to various scan and join636 * mechanisms. It didn't seem worth creating new node types for them.637 *638 * relids - Set of relation identifiers (RT indexes). This is a base639 * relation if there is just one, a join relation if more;640 * in the join case, RT indexes of any outer joins formed641 * at or below this join are included along with baserels642 * rows - estimated number of tuples in the relation after restriction643 * clauses have been applied (ie, output rows of a plan for it)644 * consider_startup - true if there is any value in keeping plain paths for645 * this rel on the basis of having cheap startup cost646 * consider_param_startup - the same for parameterized paths647 * reltarget - Default Path output tlist for this rel; normally contains648 * Var and PlaceHolderVar nodes for the values we need to649 * output from this relation.650 * List is in no particular order, but all rels of an651 * appendrel set must use corresponding orders.652 * NOTE: in an appendrel child relation, may contain653 * arbitrary expressions pulled up from a subquery!654 * pathlist - List of Path nodes, one for each potentially useful655 * method of generating the relation656 * ppilist - ParamPathInfo nodes for parameterized Paths, if any657 * cheapest_startup_path - the pathlist member with lowest startup cost658 * (regardless of ordering) among the unparameterized paths;659 * or NULL if there is no unparameterized path660 * cheapest_total_path - the pathlist member with lowest total cost661 * (regardless of ordering) among the unparameterized paths;662 * or if there is no unparameterized path, the path with lowest663 * total cost among the paths with minimum parameterization664 * cheapest_unique_path - for caching cheapest path to produce unique665 * (no duplicates) output from relation; NULL if not yet requested666 * cheapest_parameterized_paths - best paths for their parameterizations;667 * always includes cheapest_total_path, even if that's unparameterized668 * direct_lateral_relids - rels this rel has direct LATERAL references to669 * lateral_relids - required outer rels for LATERAL, as a Relids set670 * (includes both direct and indirect lateral references)671 *672 * If the relation is a base relation it will have these fields set:673 *674 * relid - RTE index (this is redundant with the relids field, but675 * is provided for convenience of access)676 * rtekind - copy of RTE's rtekind field677 * min_attr, max_attr - range of valid AttrNumbers for rel678 * attr_needed - array of bitmapsets indicating the highest joinrel679 * in which each attribute is needed; if bit 0 is set then680 * the attribute is needed as part of final targetlist681 * attr_widths - cache space for per-attribute width estimates;682 * zero means not computed yet683 * nulling_relids - relids of outer joins that can null this rel684 * lateral_vars - lateral cross-references of rel, if any (list of685 * Vars and PlaceHolderVars)686 * lateral_referencers - relids of rels that reference this one laterally687 * (includes both direct and indirect lateral references)688 * indexlist - list of IndexOptInfo nodes for relation's indexes689 * (always NIL if it's not a table or partitioned table)690 * pages - number of disk pages in relation (zero if not a table)691 * tuples - number of tuples in relation (not considering restrictions)692 * allvisfrac - fraction of disk pages that are marked all-visible693 * eclass_indexes - EquivalenceClasses that mention this rel (filled694 * only after EC merging is complete)695 * subroot - PlannerInfo for subquery (NULL if it's not a subquery)696 * subplan_params - list of PlannerParamItems to be passed to subquery697 *698 * Note: for a subquery, tuples and subroot are not set immediately699 * upon creation of the RelOptInfo object; they are filled in when700 * set_subquery_pathlist processes the object.701 *702 * For otherrels that are appendrel members, these fields are filled703 * in just as for a baserel, except we don't bother with lateral_vars.704 *705 * If the relation is either a foreign table or a join of foreign tables that706 * all belong to the same foreign server and are assigned to the same user to707 * check access permissions as (cf checkAsUser), these fields will be set:708 *709 * serverid - OID of foreign server, if foreign table (else InvalidOid)710 * userid - OID of user to check access as (InvalidOid means current user)711 * useridiscurrent - we've assumed that userid equals current user712 * fdwroutine - function hooks for FDW, if foreign table (else NULL)713 * fdw_private - private state for FDW, if foreign table (else NULL)714 *715 * Two fields are used to cache knowledge acquired during the join search716 * about whether this rel is provably unique when being joined to given other717 * relation(s), ie, it can have at most one row matching any given row from718 * that join relation. Currently we only attempt such proofs, and thus only719 * populate these fields, for base rels; but someday they might be used for720 * join rels too:721 *722 * unique_for_rels - list of Relid sets, each one being a set of other723 * rels for which this one has been proven unique724 * non_unique_for_rels - list of Relid sets, each one being a set of725 * other rels for which we have tried and failed to prove726 * this one unique727 *728 * The presence of the following fields depends on the restrictions729 * and joins that the relation participates in:730 *731 * baserestrictinfo - List of RestrictInfo nodes, containing info about732 * each non-join qualification clause in which this relation733 * participates (only used for base rels)734 * baserestrictcost - Estimated cost of evaluating the baserestrictinfo735 * clauses at a single tuple (only used for base rels)736 * baserestrict_min_security - Smallest security_level found among737 * clauses in baserestrictinfo738 * joininfo - List of RestrictInfo nodes, containing info about each739 * join clause in which this relation participates (but740 * note this excludes clauses that might be derivable from741 * EquivalenceClasses)742 * has_eclass_joins - flag that EquivalenceClass joins are possible743 *744 * Note: Keeping a restrictinfo list in the RelOptInfo is useful only for745 * base rels, because for a join rel the set of clauses that are treated as746 * restrict clauses varies depending on which sub-relations we choose to join.747 * (For example, in a 3-base-rel join, a clause relating rels 1 and 2 must be748 * treated as a restrictclause if we join {1} and {2 3} to make {1 2 3}; but749 * if we join {1 2} and {3} then that clause will be a restrictclause in {1 2}750 * and should not be processed again at the level of {1 2 3}.) Therefore,751 * the restrictinfo list in the join case appears in individual JoinPaths752 * (field joinrestrictinfo), not in the parent relation. But it's OK for753 * the RelOptInfo to store the joininfo list, because that is the same754 * for a given rel no matter how we form it.755 *756 * We store baserestrictcost in the RelOptInfo (for base relations) because757 * we know we will need it at least once (to price the sequential scan)758 * and may need it multiple times to price index scans.759 *760 * A join relation is considered to be partitioned if it is formed from a761 * join of two relations that are partitioned, have matching partitioning762 * schemes, and are joined on an equijoin of the partitioning columns.763 * Under those conditions we can consider the join relation to be partitioned764 * by either relation's partitioning keys, though some care is needed if765 * either relation can be forced to null by outer-joining. For example, an766 * outer join like (A LEFT JOIN B ON A.a = B.b) may produce rows with B.b767 * NULL. These rows may not fit the partitioning conditions imposed on B.768 * Hence, strictly speaking, the join is not partitioned by B.b and thus769 * partition keys of an outer join should include partition key expressions770 * from the non-nullable side only. However, if a subsequent join uses771 * strict comparison operators (and all commonly-used equijoin operators are772 * strict), the presence of nulls doesn't cause a problem: such rows couldn't773 * match anything on the other side and thus they don't create a need to do774 * any cross-partition sub-joins. Hence we can treat such values as still775 * partitioning the join output for the purpose of additional partitionwise776 * joining, so long as a strict join operator is used by the next join.777 *778 * If the relation is partitioned, these fields will be set:779 *780 * part_scheme - Partitioning scheme of the relation781 * nparts - Number of partitions782 * boundinfo - Partition bounds783 * partbounds_merged - true if partition bounds are merged ones784 * partition_qual - Partition constraint if not the root785 * part_rels - RelOptInfos for each partition786 * all_partrels - Relids set of all partition relids787 * partexprs, nullable_partexprs - Partition key expressions788 *789 * The partexprs and nullable_partexprs arrays each contain790 * part_scheme->partnatts elements. Each of the elements is a list of791 * partition key expressions. For partitioned base relations, there is one792 * expression in each partexprs element, and nullable_partexprs is empty.793 * For partitioned join relations, each base relation within the join794 * contributes one partition key expression per partitioning column;795 * that expression goes in the partexprs[i] list if the base relation796 * is not nullable by this join or any lower outer join, or in the797 * nullable_partexprs[i] list if the base relation is nullable.798 * Furthermore, FULL JOINs add extra nullable_partexprs expressions799 * corresponding to COALESCE expressions of the left and right join columns,800 * to simplify matching join clauses to those lists.801 *802 * Not all fields are printed. (In some cases, there is no print support for803 * the field type.)804 *----------805 */806 807/* Bitmask of flags supported by table AMs */808#define AMFLAG_HAS_TID_RANGE (1 << 0)809 810typedef enum RelOptKind811{812 RELOPT_BASEREL,813 RELOPT_JOINREL,814 RELOPT_OTHER_MEMBER_REL,815 RELOPT_OTHER_JOINREL,816 RELOPT_UPPER_REL,817 RELOPT_OTHER_UPPER_REL818} RelOptKind;819 820/*821 * Is the given relation a simple relation i.e a base or "other" member822 * relation?823 */824#define IS_SIMPLE_REL(rel) \825 ((rel)->reloptkind == RELOPT_BASEREL || \826 (rel)->reloptkind == RELOPT_OTHER_MEMBER_REL)827 828/* Is the given relation a join relation? */829#define IS_JOIN_REL(rel) \830 ((rel)->reloptkind == RELOPT_JOINREL || \831 (rel)->reloptkind == RELOPT_OTHER_JOINREL)832 833/* Is the given relation an upper relation? */834#define IS_UPPER_REL(rel) \835 ((rel)->reloptkind == RELOPT_UPPER_REL || \836 (rel)->reloptkind == RELOPT_OTHER_UPPER_REL)837 838/* Is the given relation an "other" relation? */839#define IS_OTHER_REL(rel) \840 ((rel)->reloptkind == RELOPT_OTHER_MEMBER_REL || \841 (rel)->reloptkind == RELOPT_OTHER_JOINREL || \842 (rel)->reloptkind == RELOPT_OTHER_UPPER_REL)843 844typedef struct RelOptInfo845{846 pg_node_attr(no_copy_equal, no_read, no_query_jumble)847 848 NodeTag type;849 850 RelOptKind reloptkind;851 852 /*853 * all relations included in this RelOptInfo; set of base + OJ relids854 * (rangetable indexes)855 */856 Relids relids;857 858 /*859 * size estimates generated by planner860 */861 /* estimated number of result tuples */862 Cardinality rows;863 864 /*865 * per-relation planner control flags866 */867 /* keep cheap-startup-cost paths? */868 bool consider_startup;869 /* ditto, for parameterized paths? */870 bool consider_param_startup;871 /* consider parallel paths? */872 bool consider_parallel;873 874 /*875 * default result targetlist for Paths scanning this relation; list of876 * Vars/Exprs, cost, width877 */878 struct PathTarget *reltarget;879 880 /*881 * materialization information882 */883 List *pathlist; /* Path structures */884 List *ppilist; /* ParamPathInfos used in pathlist */885 List *partial_pathlist; /* partial Paths */886 struct Path *cheapest_startup_path;887 struct Path *cheapest_total_path;888 struct Path *cheapest_unique_path;889 List *cheapest_parameterized_paths;890 891 /*892 * parameterization information needed for both base rels and join rels893 * (see also lateral_vars and lateral_referencers)894 */895 /* rels directly laterally referenced */896 Relids direct_lateral_relids;897 /* minimum parameterization of rel */898 Relids lateral_relids;899 900 /*901 * information about a base rel (not set for join rels!)902 */903 Index relid;904 /* containing tablespace */905 Oid reltablespace;906 /* RELATION, SUBQUERY, FUNCTION, etc */907 RTEKind rtekind;908 /* smallest attrno of rel (often <0) */909 AttrNumber min_attr;910 /* largest attrno of rel */911 AttrNumber max_attr;912 /* array indexed [min_attr .. max_attr] */913 Relids *attr_needed pg_node_attr(read_write_ignore);914 /* array indexed [min_attr .. max_attr] */915 int32 *attr_widths pg_node_attr(read_write_ignore);916 /* relids of outer joins that can null this baserel */917 Relids nulling_relids;918 /* LATERAL Vars and PHVs referenced by rel */919 List *lateral_vars;920 /* rels that reference this baserel laterally */921 Relids lateral_referencers;922 /* list of IndexOptInfo */923 List *indexlist;924 /* list of StatisticExtInfo */925 List *statlist;926 /* size estimates derived from pg_class */927 BlockNumber pages;928 Cardinality tuples;929 double allvisfrac;930 /* indexes in PlannerInfo's eq_classes list of ECs that mention this rel */931 Bitmapset *eclass_indexes;932 PlannerInfo *subroot; /* if subquery */933 List *subplan_params; /* if subquery */934 /* wanted number of parallel workers */935 int rel_parallel_workers;936 /* Bitmask of optional features supported by the table AM */937 uint32 amflags;938 939 /*940 * Information about foreign tables and foreign joins941 */942 /* identifies server for the table or join */943 Oid serverid;944 /* identifies user to check access as; 0 means to check as current user */945 Oid userid;946 /* join is only valid for current user */947 bool useridiscurrent;948 /* use "struct FdwRoutine" to avoid including fdwapi.h here */949 struct FdwRoutine *fdwroutine pg_node_attr(read_write_ignore);950 void *fdw_private pg_node_attr(read_write_ignore);951 952 /*953 * cache space for remembering if we have proven this relation unique954 */955 /* known unique for these other relid set(s) */956 List *unique_for_rels;957 /* known not unique for these set(s) */958 List *non_unique_for_rels;959 960 /*961 * used by various scans and joins:962 */963 /* RestrictInfo structures (if base rel) */964 List *baserestrictinfo;965 /* cost of evaluating the above */966 QualCost baserestrictcost;967 /* min security_level found in baserestrictinfo */968 Index baserestrict_min_security;969 /* RestrictInfo structures for join clauses involving this rel */970 List *joininfo;971 /* T means joininfo is incomplete */972 bool has_eclass_joins;973 974 /*975 * used by partitionwise joins:976 */977 /* consider partitionwise join paths? (if partitioned rel) */978 bool consider_partitionwise_join;979 980 /*981 * inheritance links, if this is an otherrel (otherwise NULL):982 */983 /* Immediate parent relation (dumping it would be too verbose) */984 struct RelOptInfo *parent pg_node_attr(read_write_ignore);985 /* Topmost parent relation (dumping it would be too verbose) */986 struct RelOptInfo *top_parent pg_node_attr(read_write_ignore);987 /* Relids of topmost parent (redundant, but handy) */988 Relids top_parent_relids;989 990 /*991 * used for partitioned relations:992 */993 /* Partitioning scheme */994 PartitionScheme part_scheme pg_node_attr(read_write_ignore);995 996 /*997 * Number of partitions; -1 if not yet set; in case of a join relation 0998 * means it's considered unpartitioned999 */1000 int nparts;1001 /* Partition bounds */1002 struct PartitionBoundInfoData *boundinfo pg_node_attr(read_write_ignore);1003 /* True if partition bounds were created by partition_bounds_merge() */1004 bool partbounds_merged;1005 /* Partition constraint, if not the root */1006 List *partition_qual;1007 1008 /*1009 * Array of RelOptInfos of partitions, stored in the same order as bounds1010 * (don't print, too bulky and duplicative)1011 */1012 struct RelOptInfo **part_rels pg_node_attr(read_write_ignore);1013 1014 /*1015 * Bitmap with members acting as indexes into the part_rels[] array to1016 * indicate which partitions survived partition pruning.1017 */1018 Bitmapset *live_parts;1019 /* Relids set of all partition relids */1020 Relids all_partrels;1021 1022 /*1023 * These arrays are of length partkey->partnatts, which we don't have at1024 * hand, so don't try to print1025 */1026 1027 /* Non-nullable partition key expressions */1028 List **partexprs pg_node_attr(read_write_ignore);1029 /* Nullable partition key expressions */1030 List **nullable_partexprs pg_node_attr(read_write_ignore);1031} RelOptInfo;1032 1033/*1034 * Is given relation partitioned?1035 *1036 * It's not enough to test whether rel->part_scheme is set, because it might1037 * be that the basic partitioning properties of the input relations matched1038 * but the partition bounds did not. Also, if we are able to prove a rel1039 * dummy (empty), we should henceforth treat it as unpartitioned.1040 */1041#define IS_PARTITIONED_REL(rel) \1042 ((rel)->part_scheme && (rel)->boundinfo && (rel)->nparts > 0 && \1043 (rel)->part_rels && !IS_DUMMY_REL(rel))1044 1045/*1046 * Convenience macro to make sure that a partitioned relation has all the1047 * required members set.1048 */1049#define REL_HAS_ALL_PART_PROPS(rel) \1050 ((rel)->part_scheme && (rel)->boundinfo && (rel)->nparts > 0 && \1051 (rel)->part_rels && (rel)->partexprs && (rel)->nullable_partexprs)1052 1053/*1054 * IndexOptInfo1055 * Per-index information for planning/optimization1056 *1057 * indexkeys[], indexcollations[] each have ncolumns entries.1058 * opfamily[], and opcintype[] each have nkeycolumns entries. They do1059 * not contain any information about included attributes.1060 *1061 * sortopfamily[], reverse_sort[], and nulls_first[] have1062 * nkeycolumns entries, if the index is ordered; but if it is unordered,1063 * those pointers are NULL.1064 *1065 * Zeroes in the indexkeys[] array indicate index columns that are1066 * expressions; there is one element in indexprs for each such column.1067 *1068 * For an ordered index, reverse_sort[] and nulls_first[] describe the1069 * sort ordering of a forward indexscan; we can also consider a backward1070 * indexscan, which will generate the reverse ordering.1071 *1072 * The indexprs and indpred expressions have been run through1073 * prepqual.c and eval_const_expressions() for ease of matching to1074 * WHERE clauses. indpred is in implicit-AND form.1075 *1076 * indextlist is a TargetEntry list representing the index columns.1077 * It provides an equivalent base-relation Var for each simple column,1078 * and links to the matching indexprs element for each expression column.1079 *1080 * While most of these fields are filled when the IndexOptInfo is created1081 * (by plancat.c), indrestrictinfo and predOK are set later, in1082 * check_index_predicates().1083 */1084#ifndef HAVE_INDEXOPTINFO_TYPEDEF1085typedef struct IndexOptInfo IndexOptInfo;1086#define HAVE_INDEXOPTINFO_TYPEDEF 11087#endif1088 1089struct IndexOptInfo1090{1091 pg_node_attr(no_copy_equal, no_read, no_query_jumble)1092 1093 NodeTag type;1094 1095 /* OID of the index relation */1096 Oid indexoid;1097 /* tablespace of index (not table) */1098 Oid reltablespace;1099 /* back-link to index's table; don't print, else infinite recursion */1100 RelOptInfo *rel pg_node_attr(read_write_ignore);1101 1102 /*1103 * index-size statistics (from pg_class and elsewhere)1104 */1105 /* number of disk pages in index */1106 BlockNumber pages;1107 /* number of index tuples in index */1108 Cardinality tuples;1109 /* index tree height, or -1 if unknown */1110 int tree_height;1111 1112 /*1113 * index descriptor information1114 */1115 /* number of columns in index */1116 int ncolumns;1117 /* number of key columns in index */1118 int nkeycolumns;1119 1120 /*1121 * table column numbers of index's columns (both key and included1122 * columns), or 0 for expression columns1123 */1124 int *indexkeys pg_node_attr(array_size(ncolumns));1125 /* OIDs of collations of index columns */1126 Oid *indexcollations pg_node_attr(array_size(nkeycolumns));1127 /* OIDs of operator families for columns */1128 Oid *opfamily pg_node_attr(array_size(nkeycolumns));1129 /* OIDs of opclass declared input data types */1130 Oid *opcintype pg_node_attr(array_size(nkeycolumns));1131 /* OIDs of btree opfamilies, if orderable. NULL if partitioned index */1132 Oid *sortopfamily pg_node_attr(array_size(nkeycolumns));1133 /* is sort order descending? or NULL if partitioned index */1134 bool *reverse_sort pg_node_attr(array_size(nkeycolumns));1135 /* do NULLs come first in the sort order? or NULL if partitioned index */1136 bool *nulls_first pg_node_attr(array_size(nkeycolumns));1137 /* opclass-specific options for columns */1138 bytea **opclassoptions pg_node_attr(read_write_ignore);1139 /* which index cols can be returned in an index-only scan? */1140 bool *canreturn pg_node_attr(array_size(ncolumns));1141 /* OID of the access method (in pg_am) */1142 Oid relam;1143 1144 /*1145 * expressions for non-simple index columns; redundant to print since we1146 * print indextlist1147 */1148 List *indexprs pg_node_attr(read_write_ignore);1149 /* predicate if a partial index, else NIL */1150 List *indpred;1151 1152 /* targetlist representing index columns */1153 List *indextlist;1154 1155 /*1156 * parent relation's baserestrictinfo list, less any conditions implied by1157 * the index's predicate (unless it's a target rel, see comments in1158 * check_index_predicates())1159 */1160 List *indrestrictinfo;1161 1162 /* true if index predicate matches query */1163 bool predOK;1164 /* true if a unique index */1165 bool unique;1166 /* is uniqueness enforced immediately? */1167 bool immediate;1168 /* true if index doesn't really exist */1169 bool hypothetical;1170 1171 /*1172 * Remaining fields are copied from the index AM's API struct1173 * (IndexAmRoutine). These fields are not set for partitioned indexes.1174 */1175 bool amcanorderbyop;1176 bool amoptionalkey;1177 bool amsearcharray;1178 bool amsearchnulls;1179 /* does AM have amgettuple interface? */1180 bool amhasgettuple;1181 /* does AM have amgetbitmap interface? */1182 bool amhasgetbitmap;1183 bool amcanparallel;1184 /* does AM have ammarkpos interface? */1185 bool amcanmarkpos;1186 /* AM's cost estimator */1187 /* Rather than include amapi.h here, we declare amcostestimate like this */1188 void (*amcostestimate) () pg_node_attr(read_write_ignore);1189};1190 1191/*1192 * ForeignKeyOptInfo1193 * Per-foreign-key information for planning/optimization1194 *1195 * The per-FK-column arrays can be fixed-size because we allow at most1196 * INDEX_MAX_KEYS columns in a foreign key constraint. Each array has1197 * nkeys valid entries.1198 */1199typedef struct ForeignKeyOptInfo1200{