|
|
|
@ -226,8 +226,8 @@ struct PlannerInfo |
|
|
|
|
* even when using the hash table for lookups; this simplifies life for |
|
|
|
|
* GEQO. |
|
|
|
|
*/ |
|
|
|
|
List *join_rel_list; /* list of join-relation RelOptInfos */ |
|
|
|
|
struct HTAB *join_rel_hash; /* optional hashtable for join relations */ |
|
|
|
|
List *join_rel_list; |
|
|
|
|
struct HTAB *join_rel_hash; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* When doing a dynamic-programming-style join search, join_rel_level[k] |
|
|
|
@ -329,11 +329,16 @@ struct PlannerInfo |
|
|
|
|
*/ |
|
|
|
|
List *update_colnos; |
|
|
|
|
|
|
|
|
|
/* Fields filled during create_plan() for use in setrefs.c */ |
|
|
|
|
AttrNumber *grouping_map; /* for GroupingFunc fixup */ |
|
|
|
|
List *minmax_aggs; /* List of MinMaxAggInfos */ |
|
|
|
|
/*
|
|
|
|
|
* Fields filled during create_plan() for use in setrefs.c |
|
|
|
|
*/ |
|
|
|
|
/* for GroupingFunc fixup */ |
|
|
|
|
AttrNumber *grouping_map; |
|
|
|
|
/* List of MinMaxAggInfos */ |
|
|
|
|
List *minmax_aggs; |
|
|
|
|
|
|
|
|
|
MemoryContext planner_cxt; /* context holding PlannerInfo */ |
|
|
|
|
/* context holding PlannerInfo */ |
|
|
|
|
MemoryContext planner_cxt; |
|
|
|
|
|
|
|
|
|
Cardinality total_table_pages; /* # of pages in all non-dummy tables of
|
|
|
|
|
* query */ |
|
|
|
@ -369,9 +374,12 @@ struct PlannerInfo |
|
|
|
|
Relids curOuterRels; /* outer rels above current node */ |
|
|
|
|
List *curOuterParams; /* not-yet-assigned NestLoopParams */ |
|
|
|
|
|
|
|
|
|
/* These fields are workspace for setrefs.c */ |
|
|
|
|
bool *isAltSubplan; /* array corresponding to glob->subplans */ |
|
|
|
|
bool *isUsedSubplan; /* array corresponding to glob->subplans */ |
|
|
|
|
/*
|
|
|
|
|
* These fields are workspace for setrefs.c. Each is an array |
|
|
|
|
* corresponding to glob->subplans. |
|
|
|
|
*/ |
|
|
|
|
bool *isAltSubplan; |
|
|
|
|
bool *isUsedSubplan; |
|
|
|
|
|
|
|
|
|
/* optional private data for join_search_hook, e.g., GEQO */ |
|
|
|
|
void *join_search_private; |
|
|
|
@ -678,21 +686,37 @@ typedef struct RelOptInfo |
|
|
|
|
|
|
|
|
|
RelOptKind reloptkind; |
|
|
|
|
|
|
|
|
|
/* all relations included in this RelOptInfo */ |
|
|
|
|
Relids relids; /* set of base relids (rangetable indexes) */ |
|
|
|
|
/*
|
|
|
|
|
* all relations included in this RelOptInfo; set of base relids |
|
|
|
|
* (rangetable indexes) |
|
|
|
|
*/ |
|
|
|
|
Relids relids; |
|
|
|
|
|
|
|
|
|
/* size estimates generated by planner */ |
|
|
|
|
Cardinality rows; /* estimated number of result tuples */ |
|
|
|
|
/*
|
|
|
|
|
* size estimates generated by planner |
|
|
|
|
*/ |
|
|
|
|
/* estimated number of result tuples */ |
|
|
|
|
Cardinality rows; |
|
|
|
|
|
|
|
|
|
/* per-relation planner control flags */ |
|
|
|
|
bool consider_startup; /* keep cheap-startup-cost paths? */ |
|
|
|
|
bool consider_param_startup; /* ditto, for parameterized paths? */ |
|
|
|
|
bool consider_parallel; /* consider parallel paths? */ |
|
|
|
|
/*
|
|
|
|
|
* per-relation planner control flags |
|
|
|
|
*/ |
|
|
|
|
/* keep cheap-startup-cost paths? */ |
|
|
|
|
bool consider_startup; |
|
|
|
|
/* ditto, for parameterized paths? */ |
|
|
|
|
bool consider_param_startup; |
|
|
|
|
/* consider parallel paths? */ |
|
|
|
|
bool consider_parallel; |
|
|
|
|
|
|
|
|
|
/* default result targetlist for Paths scanning this relation */ |
|
|
|
|
struct PathTarget *reltarget; /* list of Vars/Exprs, cost, width */ |
|
|
|
|
/*
|
|
|
|
|
* default result targetlist for Paths scanning this relation; list of |
|
|
|
|
* Vars/Exprs, cost, width |
|
|
|
|
*/ |
|
|
|
|
struct PathTarget *reltarget; |
|
|
|
|
|
|
|
|
|
/* materialization information */ |
|
|
|
|
/*
|
|
|
|
|
* materialization information |
|
|
|
|
*/ |
|
|
|
|
List *pathlist; /* Path structures */ |
|
|
|
|
List *ppilist; /* ParamPathInfos used in pathlist */ |
|
|
|
|
List *partial_pathlist; /* partial Paths */ |
|
|
|
@ -701,79 +725,132 @@ typedef struct RelOptInfo |
|
|
|
|
struct Path *cheapest_unique_path; |
|
|
|
|
List *cheapest_parameterized_paths; |
|
|
|
|
|
|
|
|
|
/* parameterization information needed for both base rels and join rels */ |
|
|
|
|
/* (see also lateral_vars and lateral_referencers) */ |
|
|
|
|
Relids direct_lateral_relids; /* rels directly laterally referenced */ |
|
|
|
|
Relids lateral_relids; /* minimum parameterization of rel */ |
|
|
|
|
/*
|
|
|
|
|
* parameterization information needed for both base rels and join rels |
|
|
|
|
* (see also lateral_vars and lateral_referencers) |
|
|
|
|
*/ |
|
|
|
|
/* rels directly laterally referenced */ |
|
|
|
|
Relids direct_lateral_relids; |
|
|
|
|
/* minimum parameterization of rel */ |
|
|
|
|
Relids lateral_relids; |
|
|
|
|
|
|
|
|
|
/* information about a base rel (not set for join rels!) */ |
|
|
|
|
/*
|
|
|
|
|
* information about a base rel (not set for join rels!) |
|
|
|
|
*/ |
|
|
|
|
Index relid; |
|
|
|
|
Oid reltablespace; /* containing tablespace */ |
|
|
|
|
RTEKind rtekind; /* RELATION, SUBQUERY, FUNCTION, etc */ |
|
|
|
|
AttrNumber min_attr; /* smallest attrno of rel (often <0) */ |
|
|
|
|
AttrNumber max_attr; /* largest attrno of rel */ |
|
|
|
|
Relids *attr_needed; /* array indexed [min_attr .. max_attr] */ |
|
|
|
|
int32 *attr_widths; /* array indexed [min_attr .. max_attr] */ |
|
|
|
|
List *lateral_vars; /* LATERAL Vars and PHVs referenced by rel */ |
|
|
|
|
Relids lateral_referencers; /* rels that reference me laterally */ |
|
|
|
|
List *indexlist; /* list of IndexOptInfo */ |
|
|
|
|
List *statlist; /* list of StatisticExtInfo */ |
|
|
|
|
BlockNumber pages; /* size estimates derived from pg_class */ |
|
|
|
|
/* containing tablespace */ |
|
|
|
|
Oid reltablespace; |
|
|
|
|
/* RELATION, SUBQUERY, FUNCTION, etc */ |
|
|
|
|
RTEKind rtekind; |
|
|
|
|
/* smallest attrno of rel (often <0) */ |
|
|
|
|
AttrNumber min_attr; |
|
|
|
|
/* largest attrno of rel */ |
|
|
|
|
AttrNumber max_attr; |
|
|
|
|
/* array indexed [min_attr .. max_attr] */ |
|
|
|
|
Relids *attr_needed; |
|
|
|
|
/* array indexed [min_attr .. max_attr] */ |
|
|
|
|
int32 *attr_widths; |
|
|
|
|
/* LATERAL Vars and PHVs referenced by rel */ |
|
|
|
|
List *lateral_vars; |
|
|
|
|
/* rels that reference me laterally */ |
|
|
|
|
Relids lateral_referencers; |
|
|
|
|
/* list of IndexOptInfo */ |
|
|
|
|
List *indexlist; |
|
|
|
|
/* list of StatisticExtInfo */ |
|
|
|
|
List *statlist; |
|
|
|
|
/* size estimates derived from pg_class */ |
|
|
|
|
BlockNumber pages; |
|
|
|
|
Cardinality tuples; |
|
|
|
|
double allvisfrac; |
|
|
|
|
Bitmapset *eclass_indexes; /* Indexes in PlannerInfo's eq_classes list of
|
|
|
|
|
* ECs that mention this rel */ |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Indexes in PlannerInfo's eq_classes list of ECs that mention this rel |
|
|
|
|
*/ |
|
|
|
|
Bitmapset *eclass_indexes; |
|
|
|
|
PlannerInfo *subroot; /* if subquery */ |
|
|
|
|
List *subplan_params; /* if subquery */ |
|
|
|
|
int rel_parallel_workers; /* wanted number of parallel workers */ |
|
|
|
|
uint32 amflags; /* Bitmask of optional features supported by
|
|
|
|
|
* the table AM */ |
|
|
|
|
|
|
|
|
|
/* Information about foreign tables and foreign joins */ |
|
|
|
|
Oid serverid; /* identifies server for the table or join */ |
|
|
|
|
Oid userid; /* identifies user to check access as */ |
|
|
|
|
bool useridiscurrent; /* join is only valid for current user */ |
|
|
|
|
/* wanted number of parallel workers */ |
|
|
|
|
int rel_parallel_workers; |
|
|
|
|
/* Bitmask of optional features supported by the table AM */ |
|
|
|
|
uint32 amflags; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Information about foreign tables and foreign joins |
|
|
|
|
*/ |
|
|
|
|
/* identifies server for the table or join */ |
|
|
|
|
Oid serverid; |
|
|
|
|
/* identifies user to check access as */ |
|
|
|
|
Oid userid; |
|
|
|
|
/* join is only valid for current user */ |
|
|
|
|
bool useridiscurrent; |
|
|
|
|
/* use "struct FdwRoutine" to avoid including fdwapi.h here */ |
|
|
|
|
struct FdwRoutine *fdwroutine; |
|
|
|
|
void *fdw_private; |
|
|
|
|
|
|
|
|
|
/* cache space for remembering if we have proven this relation unique */ |
|
|
|
|
List *unique_for_rels; /* known unique for these other relid
|
|
|
|
|
* set(s) */ |
|
|
|
|
List *non_unique_for_rels; /* known not unique for these set(s) */ |
|
|
|
|
|
|
|
|
|
/* used by various scans and joins: */ |
|
|
|
|
List *baserestrictinfo; /* RestrictInfo structures (if base rel) */ |
|
|
|
|
QualCost baserestrictcost; /* cost of evaluating the above */ |
|
|
|
|
Index baserestrict_min_security; /* min security_level found in
|
|
|
|
|
* baserestrictinfo */ |
|
|
|
|
List *joininfo; /* RestrictInfo structures for join clauses
|
|
|
|
|
* involving this rel */ |
|
|
|
|
bool has_eclass_joins; /* T means joininfo is incomplete */ |
|
|
|
|
|
|
|
|
|
/* used by partitionwise joins: */ |
|
|
|
|
bool consider_partitionwise_join; /* consider partitionwise join
|
|
|
|
|
* paths? (if partitioned rel) */ |
|
|
|
|
Relids top_parent_relids; /* Relids of topmost parents (if "other"
|
|
|
|
|
* rel) */ |
|
|
|
|
|
|
|
|
|
/* used for partitioned relations: */ |
|
|
|
|
PartitionScheme part_scheme; /* Partitioning scheme */ |
|
|
|
|
int nparts; /* Number of partitions; -1 if not yet set; in
|
|
|
|
|
* case of a join relation 0 means it's |
|
|
|
|
* considered unpartitioned */ |
|
|
|
|
struct PartitionBoundInfoData *boundinfo; /* Partition bounds */ |
|
|
|
|
bool partbounds_merged; /* True if partition bounds were created
|
|
|
|
|
* by partition_bounds_merge() */ |
|
|
|
|
List *partition_qual; /* Partition constraint, if not the root */ |
|
|
|
|
struct RelOptInfo **part_rels; /* Array of RelOptInfos of partitions,
|
|
|
|
|
* stored in the same order as bounds */ |
|
|
|
|
Bitmapset *live_parts; /* Bitmap with members acting as indexes into
|
|
|
|
|
* the part_rels[] array to indicate which |
|
|
|
|
* partitions survived partition pruning. */ |
|
|
|
|
Relids all_partrels; /* Relids set of all partition relids */ |
|
|
|
|
List **partexprs; /* Non-nullable partition key expressions */ |
|
|
|
|
List **nullable_partexprs; /* Nullable partition key expressions */ |
|
|
|
|
/*
|
|
|
|
|
* cache space for remembering if we have proven this relation unique |
|
|
|
|
*/ |
|
|
|
|
/* known unique for these other relid set(s) */ |
|
|
|
|
List *unique_for_rels; |
|
|
|
|
/* known not unique for these set(s) */ |
|
|
|
|
List *non_unique_for_rels; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* used by various scans and joins: |
|
|
|
|
*/ |
|
|
|
|
/* RestrictInfo structures (if base rel) */ |
|
|
|
|
List *baserestrictinfo; |
|
|
|
|
/* cost of evaluating the above */ |
|
|
|
|
QualCost baserestrictcost; |
|
|
|
|
/* min security_level found in baserestrictinfo */ |
|
|
|
|
Index baserestrict_min_security; |
|
|
|
|
/* RestrictInfo structures for join clauses involving this rel */ |
|
|
|
|
List *joininfo; |
|
|
|
|
/* T means joininfo is incomplete */ |
|
|
|
|
bool has_eclass_joins; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* used by partitionwise joins: |
|
|
|
|
*/ |
|
|
|
|
/* consider partitionwise join paths? (if partitioned rel) */ |
|
|
|
|
bool consider_partitionwise_join; |
|
|
|
|
/* Relids of topmost parents (if "other" rel) */ |
|
|
|
|
Relids top_parent_relids; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* used for partitioned relations: |
|
|
|
|
*/ |
|
|
|
|
/* Partitioning scheme */ |
|
|
|
|
PartitionScheme part_scheme; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Number of partitions; -1 if not yet set; in case of a join relation 0 |
|
|
|
|
* means it's considered unpartitioned |
|
|
|
|
*/ |
|
|
|
|
int nparts; |
|
|
|
|
/* Partition bounds */ |
|
|
|
|
struct PartitionBoundInfoData *boundinfo; |
|
|
|
|
/* True if partition bounds were created by partition_bounds_merge() */ |
|
|
|
|
bool partbounds_merged; |
|
|
|
|
/* Partition constraint, if not the root */ |
|
|
|
|
List *partition_qual; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Array of RelOptInfos of partitions, stored in the same order as bounds |
|
|
|
|
*/ |
|
|
|
|
struct RelOptInfo **part_rels; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Bitmap with members acting as indexes into the part_rels[] array to |
|
|
|
|
* indicate which partitions survived partition pruning. |
|
|
|
|
*/ |
|
|
|
|
Bitmapset *live_parts; |
|
|
|
|
/* Relids set of all partition relids */ |
|
|
|
|
Relids all_partrels; |
|
|
|
|
/* Non-nullable partition key expressions */ |
|
|
|
|
List **partexprs; |
|
|
|
|
/* Nullable partition key expressions */ |
|
|
|
|
List **nullable_partexprs; |
|
|
|
|
} RelOptInfo; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -836,56 +913,93 @@ struct IndexOptInfo |
|
|
|
|
{ |
|
|
|
|
NodeTag type; |
|
|
|
|
|
|
|
|
|
Oid indexoid; /* OID of the index relation */ |
|
|
|
|
Oid reltablespace; /* tablespace of index (not table) */ |
|
|
|
|
RelOptInfo *rel; /* back-link to index's table */ |
|
|
|
|
|
|
|
|
|
/* index-size statistics (from pg_class and elsewhere) */ |
|
|
|
|
BlockNumber pages; /* number of disk pages in index */ |
|
|
|
|
Cardinality tuples; /* number of index tuples in index */ |
|
|
|
|
int tree_height; /* index tree height, or -1 if unknown */ |
|
|
|
|
|
|
|
|
|
/* index descriptor information */ |
|
|
|
|
int ncolumns; /* number of columns in index */ |
|
|
|
|
int nkeycolumns; /* number of key columns in index */ |
|
|
|
|
int *indexkeys; /* column numbers of index's attributes both
|
|
|
|
|
* key and included columns, or 0 */ |
|
|
|
|
Oid *indexcollations; /* OIDs of collations of index columns */ |
|
|
|
|
Oid *opfamily; /* OIDs of operator families for columns */ |
|
|
|
|
Oid *opcintype; /* OIDs of opclass declared input data types */ |
|
|
|
|
Oid *sortopfamily; /* OIDs of btree opfamilies, if orderable */ |
|
|
|
|
bool *reverse_sort; /* is sort order descending? */ |
|
|
|
|
bool *nulls_first; /* do NULLs come first in the sort order? */ |
|
|
|
|
bytea **opclassoptions; /* opclass-specific options for columns */ |
|
|
|
|
bool *canreturn; /* which index cols can be returned in an
|
|
|
|
|
* index-only scan? */ |
|
|
|
|
Oid relam; /* OID of the access method (in pg_am) */ |
|
|
|
|
|
|
|
|
|
List *indexprs; /* expressions for non-simple index columns */ |
|
|
|
|
List *indpred; /* predicate if a partial index, else NIL */ |
|
|
|
|
|
|
|
|
|
List *indextlist; /* targetlist representing index columns */ |
|
|
|
|
|
|
|
|
|
List *indrestrictinfo; /* parent relation's baserestrictinfo
|
|
|
|
|
* list, less any conditions implied by |
|
|
|
|
* the index's predicate (unless it's a |
|
|
|
|
* target rel, see comments in |
|
|
|
|
* check_index_predicates()) */ |
|
|
|
|
|
|
|
|
|
bool predOK; /* true if index predicate matches query */ |
|
|
|
|
bool unique; /* true if a unique index */ |
|
|
|
|
bool immediate; /* is uniqueness enforced immediately? */ |
|
|
|
|
bool hypothetical; /* true if index doesn't really exist */ |
|
|
|
|
|
|
|
|
|
/* Remaining fields are copied from the index AM's API struct: */ |
|
|
|
|
bool amcanorderbyop; /* does AM support order by operator result? */ |
|
|
|
|
bool amoptionalkey; /* can query omit key for the first column? */ |
|
|
|
|
bool amsearcharray; /* can AM handle ScalarArrayOpExpr quals? */ |
|
|
|
|
bool amsearchnulls; /* can AM search for NULL/NOT NULL entries? */ |
|
|
|
|
bool amhasgettuple; /* does AM have amgettuple interface? */ |
|
|
|
|
bool amhasgetbitmap; /* does AM have amgetbitmap interface? */ |
|
|
|
|
bool amcanparallel; /* does AM support parallel scan? */ |
|
|
|
|
bool amcanmarkpos; /* does AM support mark/restore? */ |
|
|
|
|
/* OID of the index relation */ |
|
|
|
|
Oid indexoid; |
|
|
|
|
/* tablespace of index (not table) */ |
|
|
|
|
Oid reltablespace; |
|
|
|
|
/* back-link to index's table */ |
|
|
|
|
RelOptInfo *rel; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* index-size statistics (from pg_class and elsewhere) |
|
|
|
|
*/ |
|
|
|
|
/* number of disk pages in index */ |
|
|
|
|
BlockNumber pages; |
|
|
|
|
/* number of index tuples in index */ |
|
|
|
|
Cardinality tuples; |
|
|
|
|
/* index tree height, or -1 if unknown */ |
|
|
|
|
int tree_height; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* index descriptor information |
|
|
|
|
*/ |
|
|
|
|
/* number of columns in index */ |
|
|
|
|
int ncolumns; |
|
|
|
|
/* number of key columns in index */ |
|
|
|
|
int nkeycolumns; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* column numbers of index's attributes both key and included columns, or |
|
|
|
|
* 0 |
|
|
|
|
*/ |
|
|
|
|
int *indexkeys; |
|
|
|
|
/* OIDs of collations of index columns */ |
|
|
|
|
Oid *indexcollations; |
|
|
|
|
/* OIDs of operator families for columns */ |
|
|
|
|
Oid *opfamily; |
|
|
|
|
/* OIDs of opclass declared input data types */ |
|
|
|
|
Oid *opcintype; |
|
|
|
|
/* OIDs of btree opfamilies, if orderable */ |
|
|
|
|
Oid *sortopfamily; |
|
|
|
|
/* is sort order descending? */ |
|
|
|
|
bool *reverse_sort; |
|
|
|
|
/* do NULLs come first in the sort order? */ |
|
|
|
|
bool *nulls_first; |
|
|
|
|
/* opclass-specific options for columns */ |
|
|
|
|
bytea **opclassoptions; |
|
|
|
|
/* which index cols can be returned in an index-only scan? */ |
|
|
|
|
bool *canreturn; |
|
|
|
|
/* OID of the access method (in pg_am) */ |
|
|
|
|
Oid relam; |
|
|
|
|
/* expressions for non-simple index columns */ |
|
|
|
|
List *indexprs; |
|
|
|
|
/* predicate if a partial index, else NIL */ |
|
|
|
|
List *indpred; |
|
|
|
|
|
|
|
|
|
/* targetlist representing index columns */ |
|
|
|
|
List *indextlist; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* parent relation's baserestrictinfo list, less any conditions implied by |
|
|
|
|
* the index's predicate (unless it's a target rel, see comments in |
|
|
|
|
* check_index_predicates()) |
|
|
|
|
*/ |
|
|
|
|
List *indrestrictinfo; |
|
|
|
|
|
|
|
|
|
/* true if index predicate matches query */ |
|
|
|
|
bool predOK; |
|
|
|
|
/* true if a unique index */ |
|
|
|
|
bool unique; |
|
|
|
|
/* is uniqueness enforced immediately? */ |
|
|
|
|
bool immediate; |
|
|
|
|
/* true if index doesn't really exist */ |
|
|
|
|
bool hypothetical; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Remaining fields are copied from the index AM's API struct |
|
|
|
|
* (IndexAmRoutine) |
|
|
|
|
*/ |
|
|
|
|
bool amcanorderbyop; |
|
|
|
|
bool amoptionalkey; |
|
|
|
|
bool amsearcharray; |
|
|
|
|
bool amsearchnulls; |
|
|
|
|
/* does AM have amgettuple interface? */ |
|
|
|
|
bool amhasgettuple; |
|
|
|
|
/* does AM have amgetbitmap interface? */ |
|
|
|
|
bool amhasgetbitmap; |
|
|
|
|
bool amcanparallel; |
|
|
|
|
/* does AM have ammarkpos interface? */ |
|
|
|
|
bool amcanmarkpos; |
|
|
|
|
/* Rather than include amapi.h here, we declare amcostestimate like this */ |
|
|
|
|
void (*amcostestimate) (); /* AM's cost estimator */ |
|
|
|
|
}; |
|
|
|
@ -902,19 +1016,35 @@ typedef struct ForeignKeyOptInfo |
|
|
|
|
{ |
|
|
|
|
NodeTag type; |
|
|
|
|
|
|
|
|
|
/* Basic data about the foreign key (fetched from catalogs): */ |
|
|
|
|
Index con_relid; /* RT index of the referencing table */ |
|
|
|
|
Index ref_relid; /* RT index of the referenced table */ |
|
|
|
|
int nkeys; /* number of columns in the foreign key */ |
|
|
|
|
AttrNumber conkey[INDEX_MAX_KEYS]; /* cols in referencing table */ |
|
|
|
|
AttrNumber confkey[INDEX_MAX_KEYS]; /* cols in referenced table */ |
|
|
|
|
Oid conpfeqop[INDEX_MAX_KEYS]; /* PK = FK operator OIDs */ |
|
|
|
|
|
|
|
|
|
/* Derived info about whether FK's equality conditions match the query: */ |
|
|
|
|
int nmatched_ec; /* # of FK cols matched by ECs */ |
|
|
|
|
int nconst_ec; /* # of these ECs that are ec_has_const */ |
|
|
|
|
int nmatched_rcols; /* # of FK cols matched by non-EC rinfos */ |
|
|
|
|
int nmatched_ri; /* total # of non-EC rinfos matched to FK */ |
|
|
|
|
/*
|
|
|
|
|
* Basic data about the foreign key (fetched from catalogs): |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* RT index of the referencing table */ |
|
|
|
|
Index con_relid; |
|
|
|
|
/* RT index of the referenced table */ |
|
|
|
|
Index ref_relid; |
|
|
|
|
/* number of columns in the foreign key */ |
|
|
|
|
int nkeys; |
|
|
|
|
/* cols in referencing table */ |
|
|
|
|
AttrNumber conkey[INDEX_MAX_KEYS]; |
|
|
|
|
/* cols in referenced table */ |
|
|
|
|
AttrNumber confkey[INDEX_MAX_KEYS]; |
|
|
|
|
/* PK = FK operator OIDs */ |
|
|
|
|
Oid conpfeqop[INDEX_MAX_KEYS]; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Derived info about whether FK's equality conditions match the query: |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* # of FK cols matched by ECs */ |
|
|
|
|
int nmatched_ec; |
|
|
|
|
/* # of these ECs that are ec_has_const */ |
|
|
|
|
int nconst_ec; |
|
|
|
|
/* # of FK cols matched by non-EC rinfos */ |
|
|
|
|
int nmatched_rcols; |
|
|
|
|
/* total # of non-EC rinfos matched to FK */ |
|
|
|
|
int nmatched_ri; |
|
|
|
|
/* Pointer to eclass matching each column's condition, if there is one */ |
|
|
|
|
struct EquivalenceClass *eclass[INDEX_MAX_KEYS]; |
|
|
|
|
/* Pointer to eclass member for the referencing Var, if there is one */ |
|
|
|
@ -934,12 +1064,23 @@ typedef struct StatisticExtInfo |
|
|
|
|
{ |
|
|
|
|
NodeTag type; |
|
|
|
|
|
|
|
|
|
Oid statOid; /* OID of the statistics row */ |
|
|
|
|
bool inherit; /* includes child relations */ |
|
|
|
|
RelOptInfo *rel; /* back-link to statistic's table */ |
|
|
|
|
char kind; /* statistics kind of this entry */ |
|
|
|
|
Bitmapset *keys; /* attnums of the columns covered */ |
|
|
|
|
List *exprs; /* expressions */ |
|
|
|
|
/* OID of the statistics row */ |
|
|
|
|
Oid statOid; |
|
|
|
|
|
|
|
|
|
/* includes child relations */ |
|
|
|
|
bool inherit; |
|
|
|
|
|
|
|
|
|
/* back-link to statistic's table */ |
|
|
|
|
RelOptInfo *rel; |
|
|
|
|
|
|
|
|
|
/* statistics kind of this entry */ |
|
|
|
|
char kind; |
|
|
|
|
|
|
|
|
|
/* attnums of the columns covered */ |
|
|
|
|
Bitmapset *keys; |
|
|
|
|
|
|
|
|
|
/* expressions */ |
|
|
|
|
List *exprs; |
|
|
|
|
} StatisticExtInfo; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -1119,12 +1260,21 @@ typedef enum VolatileFunctionStatus |
|
|
|
|
typedef struct PathTarget |
|
|
|
|
{ |
|
|
|
|
NodeTag type; |
|
|
|
|
List *exprs; /* list of expressions to be computed */ |
|
|
|
|
Index *sortgrouprefs; /* corresponding sort/group refnos, or 0 */ |
|
|
|
|
QualCost cost; /* cost of evaluating the expressions */ |
|
|
|
|
int width; /* estimated avg width of result tuples */ |
|
|
|
|
VolatileFunctionStatus has_volatile_expr; /* indicates if exprs contain
|
|
|
|
|
* any volatile functions. */ |
|
|
|
|
|
|
|
|
|
/* list of expressions to be computed */ |
|
|
|
|
List *exprs; |
|
|
|
|
|
|
|
|
|
/* corresponding sort/group refnos, or 0 */ |
|
|
|
|
Index *sortgrouprefs; |
|
|
|
|
|
|
|
|
|
/* cost of evaluating the expressions */ |
|
|
|
|
QualCost cost; |
|
|
|
|
|
|
|
|
|
/* estimated avg width of result tuples */ |
|
|
|
|
int width; |
|
|
|
|
|
|
|
|
|
/* indicates if exprs contain any volatile functions */ |
|
|
|
|
VolatileFunctionStatus has_volatile_expr; |
|
|
|
|
} PathTarget; |
|
|
|
|
|
|
|
|
|
/* Convenience macro to get a sort/group refno from a PathTarget */ |
|
|
|
@ -1189,24 +1339,32 @@ typedef struct Path |
|
|
|
|
{ |
|
|
|
|
NodeTag type; |
|
|
|
|
|
|
|
|
|
NodeTag pathtype; /* tag identifying scan/join method */ |
|
|
|
|
/* tag identifying scan/join method */ |
|
|
|
|
NodeTag pathtype; |
|
|
|
|
|
|
|
|
|
RelOptInfo *parent; /* the relation this path can build */ |
|
|
|
|
PathTarget *pathtarget; /* list of Vars/Exprs, cost, width */ |
|
|
|
|
/* the relation this path can build */ |
|
|
|
|
RelOptInfo *parent; |
|
|
|
|
|
|
|
|
|
ParamPathInfo *param_info; /* parameterization info, or NULL if none */ |
|
|
|
|
/* list of Vars/Exprs, cost, width */ |
|
|
|
|
PathTarget *pathtarget; |
|
|
|
|
|
|
|
|
|
bool parallel_aware; /* engage parallel-aware logic? */ |
|
|
|
|
bool parallel_safe; /* OK to use as part of parallel plan? */ |
|
|
|
|
int parallel_workers; /* desired # of workers; 0 = not parallel */ |
|
|
|
|
/* parameterization info, or NULL if none */ |
|
|
|
|
ParamPathInfo *param_info; |
|
|
|
|
|
|
|
|
|
/* engage parallel-aware logic? */ |
|
|
|
|
bool parallel_aware; |
|
|
|
|
/* OK to use as part of parallel plan? */ |
|
|
|
|
bool parallel_safe; |
|
|
|
|
/* desired # of workers; 0 = not parallel */ |
|
|
|
|
int parallel_workers; |
|
|
|
|
|
|
|
|
|
/* estimated size/costs for path (see costsize.c for more info) */ |
|
|
|
|
Cardinality rows; /* estimated number of result tuples */ |
|
|
|
|
Cost startup_cost; /* cost expended before fetching any tuples */ |
|
|
|
|
Cost total_cost; /* total cost (assuming all tuples fetched) */ |
|
|
|
|
|
|
|
|
|
List *pathkeys; /* sort ordering of path's output */ |
|
|
|
|
/* pathkeys is a List of PathKey nodes; see above */ |
|
|
|
|
/* sort ordering of path's output; a List of PathKey nodes; see above */ |
|
|
|
|
List *pathkeys; |
|
|
|
|
} Path; |
|
|
|
|
|
|
|
|
|
/* Macro for extracting a path's parameterization relids; beware double eval */ |
|
|
|
@ -2072,22 +2230,29 @@ typedef struct RestrictInfo |
|
|
|
|
{ |
|
|
|
|
NodeTag type; |
|
|
|
|
|
|
|
|
|
Expr *clause; /* the represented clause of WHERE or JOIN */ |
|
|
|
|
/* the represented clause of WHERE or JOIN */ |
|
|
|
|
Expr *clause; |
|
|
|
|
|
|
|
|
|
bool is_pushed_down; /* true if clause was pushed down in level */ |
|
|
|
|
/* true if clause was pushed down in level */ |
|
|
|
|
bool is_pushed_down; |
|
|
|
|
|
|
|
|
|
bool outerjoin_delayed; /* true if delayed by lower outer join */ |
|
|
|
|
/* true if delayed by lower outer join */ |
|
|
|
|
bool outerjoin_delayed; |
|
|
|
|
|
|
|
|
|
bool can_join; /* see comment above */ |
|
|
|
|
/* see comment above */ |
|
|
|
|
bool can_join; |
|
|
|
|
|
|
|
|
|
bool pseudoconstant; /* see comment above */ |
|
|
|
|
/* see comment above */ |
|
|
|
|
bool pseudoconstant; |
|
|
|
|
|
|
|
|
|
bool leakproof; /* true if known to contain no leaked Vars */ |
|
|
|
|
/* true if known to contain no leaked Vars */ |
|
|
|
|
bool leakproof; |
|
|
|
|
|
|
|
|
|
VolatileFunctionStatus has_volatile; /* to indicate if clause contains
|
|
|
|
|
* any volatile functions. */ |
|
|
|
|
/* to indicate if clause contains any volatile functions. */ |
|
|
|
|
VolatileFunctionStatus has_volatile; |
|
|
|
|
|
|
|
|
|
Index security_level; /* see comment above */ |
|
|
|
|
/* see comment above */ |
|
|
|
|
Index security_level; |
|
|
|
|
|
|
|
|
|
/* The set of relids (varnos) actually referenced in the clause: */ |
|
|
|
|
Relids clause_relids; |
|
|
|
@ -2101,45 +2266,84 @@ typedef struct RestrictInfo |
|
|
|
|
/* The relids used in the clause that are nullable by lower outer joins: */ |
|
|
|
|
Relids nullable_relids; |
|
|
|
|
|
|
|
|
|
/* These fields are set for any binary opclause: */ |
|
|
|
|
Relids left_relids; /* relids in left side of clause */ |
|
|
|
|
Relids right_relids; /* relids in right side of clause */ |
|
|
|
|
/*
|
|
|
|
|
* Relids in the left/right side of the clause. These fields are set for |
|
|
|
|
* any binary opclause. |
|
|
|
|
*/ |
|
|
|
|
Relids left_relids; |
|
|
|
|
Relids right_relids; |
|
|
|
|
|
|
|
|
|
/* This field is NULL unless clause is an OR clause: */ |
|
|
|
|
Expr *orclause; /* modified clause with RestrictInfos */ |
|
|
|
|
/*
|
|
|
|
|
* Modified clause with RestrictInfos. This field is NULL unless clause |
|
|
|
|
* is an OR clause. |
|
|
|
|
*/ |
|
|
|
|
Expr *orclause; |
|
|
|
|
|
|
|
|
|
/* This field is NULL unless clause is potentially redundant: */ |
|
|
|
|
EquivalenceClass *parent_ec; /* generating EquivalenceClass */ |
|
|
|
|
/*
|
|
|
|
|
* Generating EquivalenceClass. This field is NULL unless clause is |
|
|
|
|
* potentially redundant. |
|
|
|
|
*/ |
|
|
|
|
EquivalenceClass *parent_ec; |
|
|
|
|
|
|
|
|
|
/* cache space for cost and selectivity */ |
|
|
|
|
QualCost eval_cost; /* eval cost of clause; -1 if not yet set */ |
|
|
|
|
Selectivity norm_selec; /* selectivity for "normal" (JOIN_INNER)
|
|
|
|
|
* semantics; -1 if not yet set; >1 means a |
|
|
|
|
* redundant clause */ |
|
|
|
|
Selectivity outer_selec; /* selectivity for outer join semantics; -1 if
|
|
|
|
|
* not yet set */ |
|
|
|
|
/*
|
|
|
|
|
* cache space for cost and selectivity |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* valid if clause is mergejoinable, else NIL */ |
|
|
|
|
List *mergeopfamilies; /* opfamilies containing clause operator */ |
|
|
|
|
/* eval cost of clause; -1 if not yet set */ |
|
|
|
|
QualCost eval_cost; |
|
|
|
|
|
|
|
|
|
/* cache space for mergeclause processing; NULL if not yet set */ |
|
|
|
|
EquivalenceClass *left_ec; /* EquivalenceClass containing lefthand */ |
|
|
|
|
EquivalenceClass *right_ec; /* EquivalenceClass containing righthand */ |
|
|
|
|
EquivalenceMember *left_em; /* EquivalenceMember for lefthand */ |
|
|
|
|
EquivalenceMember *right_em; /* EquivalenceMember for righthand */ |
|
|
|
|
List *scansel_cache; /* list of MergeScanSelCache structs */ |
|
|
|
|
/*
|
|
|
|
|
* selectivity for "normal" (JOIN_INNER) semantics; -1 if not yet set; >1 |
|
|
|
|
* means a redundant clause |
|
|
|
|
*/ |
|
|
|
|
Selectivity norm_selec; |
|
|
|
|
/* selectivity for outer join semantics; -1 if not yet set */ |
|
|
|
|
Selectivity outer_selec; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* opfamilies containing clause operator; valid if clause is |
|
|
|
|
* mergejoinable, else NIL |
|
|
|
|
*/ |
|
|
|
|
List *mergeopfamilies; |
|
|
|
|
|
|
|
|
|
/* transient workspace for use while considering a specific join path */ |
|
|
|
|
bool outer_is_left; /* T = outer var on left, F = on right */ |
|
|
|
|
/*
|
|
|
|
|
* cache space for mergeclause processing; NULL if not yet set |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* valid if clause is hashjoinable, else InvalidOid: */ |
|
|
|
|
Oid hashjoinoperator; /* copy of clause operator */ |
|
|
|
|
/* EquivalenceClass containing lefthand */ |
|
|
|
|
EquivalenceClass *left_ec; |
|
|
|
|
/* EquivalenceClass containing righthand */ |
|
|
|
|
EquivalenceClass *right_ec; |
|
|
|
|
/* EquivalenceMember for lefthand */ |
|
|
|
|
EquivalenceMember *left_em; |
|
|
|
|
/* EquivalenceMember for righthand */ |
|
|
|
|
EquivalenceMember *right_em; |
|
|
|
|
/* list of MergeScanSelCache structs */ |
|
|
|
|
List *scansel_cache; |
|
|
|
|
|
|
|
|
|
/* cache space for hashclause processing; -1 if not yet set */ |
|
|
|
|
Selectivity left_bucketsize; /* avg bucketsize of left side */ |
|
|
|
|
Selectivity right_bucketsize; /* avg bucketsize of right side */ |
|
|
|
|
Selectivity left_mcvfreq; /* left side's most common val's freq */ |
|
|
|
|
Selectivity right_mcvfreq; /* right side's most common val's freq */ |
|
|
|
|
/*
|
|
|
|
|
* transient workspace for use while considering a specific join path; T = |
|
|
|
|
* outer var on left, F = on right |
|
|
|
|
*/ |
|
|
|
|
bool outer_is_left; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* copy of clause operator; valid if clause is hashjoinable, else |
|
|
|
|
* InvalidOid |
|
|
|
|
*/ |
|
|
|
|
Oid hashjoinoperator; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* cache space for hashclause processing; -1 if not yet set |
|
|
|
|
*/ |
|
|
|
|
/* avg bucketsize of left side */ |
|
|
|
|
Selectivity left_bucketsize; |
|
|
|
|
/* avg bucketsize of right side */ |
|
|
|
|
Selectivity right_bucketsize; |
|
|
|
|
/* left side's most common val's freq */ |
|
|
|
|
Selectivity left_mcvfreq; |
|
|
|
|
/* right side's most common val's freq */ |
|
|
|
|
Selectivity right_mcvfreq; |
|
|
|
|
|
|
|
|
|
/* hash equality operators used for memoize nodes, else InvalidOid */ |
|
|
|
|
Oid left_hasheqoperator; |
|
|
|
@ -2198,10 +2402,18 @@ typedef struct MergeScanSelCache |
|
|
|
|
typedef struct PlaceHolderVar |
|
|
|
|
{ |
|
|
|
|
Expr xpr; |
|
|
|
|
Expr *phexpr; /* the represented expression */ |
|
|
|
|
Relids phrels; /* base relids syntactically within expr src */ |
|
|
|
|
Index phid; /* ID for PHV (unique within planner run) */ |
|
|
|
|
Index phlevelsup; /* > 0 if PHV belongs to outer query */ |
|
|
|
|
|
|
|
|
|
/* the represented expression */ |
|
|
|
|
Expr *phexpr; |
|
|
|
|
|
|
|
|
|
/* base relids syntactically within expr src */ |
|
|
|
|
Relids phrels; |
|
|
|
|
|
|
|
|
|
/* ID for PHV (unique within planner run) */ |
|
|
|
|
Index phid; |
|
|
|
|
|
|
|
|
|
/* > 0 if PHV belongs to outer query */ |
|
|
|
|
Index phlevelsup; |
|
|
|
|
} PlaceHolderVar; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -2360,7 +2572,7 @@ typedef struct AppendRelInfo |
|
|
|
|
* child column is dropped or doesn't exist in the parent. |
|
|
|
|
*/ |
|
|
|
|
int num_child_cols; /* length of array */ |
|
|
|
|
AttrNumber *parent_colnos; /* array of parent attnos, or zeroes */ |
|
|
|
|
AttrNumber *parent_colnos; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We store the parent table's OID here for inheritance, or InvalidOid for |
|
|
|
@ -2428,12 +2640,23 @@ typedef struct PlaceHolderInfo |
|
|
|
|
{ |
|
|
|
|
NodeTag type; |
|
|
|
|
|
|
|
|
|
Index phid; /* ID for PH (unique within planner run) */ |
|
|
|
|
PlaceHolderVar *ph_var; /* copy of PlaceHolderVar tree */ |
|
|
|
|
Relids ph_eval_at; /* lowest level we can evaluate value at */ |
|
|
|
|
Relids ph_lateral; /* relids of contained lateral refs, if any */ |
|
|
|
|
Relids ph_needed; /* highest level the value is needed at */ |
|
|
|
|
int32 ph_width; /* estimated attribute width */ |
|
|
|
|
/* ID for PH (unique within planner run) */ |
|
|
|
|
Index phid; |
|
|
|
|
|
|
|
|
|
/* copy of PlaceHolderVar tree */ |
|
|
|
|
PlaceHolderVar *ph_var; |
|
|
|
|
|
|
|
|
|
/* lowest level we can evaluate value at */ |
|
|
|
|
Relids ph_eval_at; |
|
|
|
|
|
|
|
|
|
/* relids of contained lateral refs, if any */ |
|
|
|
|
Relids ph_lateral; |
|
|
|
|
|
|
|
|
|
/* highest level the value is needed at */ |
|
|
|
|
Relids ph_needed; |
|
|
|
|
|
|
|
|
|
/* estimated attribute width */ |
|
|
|
|
int32 ph_width; |
|
|
|
|
} PlaceHolderInfo; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -2445,13 +2668,26 @@ typedef struct MinMaxAggInfo |
|
|
|
|
{ |
|
|
|
|
NodeTag type; |
|
|
|
|
|
|
|
|
|
Oid aggfnoid; /* pg_proc Oid of the aggregate */ |
|
|
|
|
Oid aggsortop; /* Oid of its sort operator */ |
|
|
|
|
Expr *target; /* expression we are aggregating on */ |
|
|
|
|
PlannerInfo *subroot; /* modified "root" for planning the subquery */ |
|
|
|
|
Path *path; /* access path for subquery */ |
|
|
|
|
Cost pathcost; /* estimated cost to fetch first row */ |
|
|
|
|
Param *param; /* param for subplan's output */ |
|
|
|
|
/* pg_proc Oid of the aggregate */ |
|
|
|
|
Oid aggfnoid; |
|
|
|
|
|
|
|
|
|
/* Oid of its sort operator */ |
|
|
|
|
Oid aggsortop; |
|
|
|
|
|
|
|
|
|
/* expression we are aggregating on */ |
|
|
|
|
Expr *target; |
|
|
|
|
|
|
|
|
|
/* modified "root" for planning the subquery */ |
|
|
|
|
PlannerInfo *subroot; |
|
|
|
|
|
|
|
|
|
/* access path for subquery */ |
|
|
|
|
Path *path; |
|
|
|
|
|
|
|
|
|
/* estimated cost to fetch first row */ |
|
|
|
|
Cost pathcost; |
|
|
|
|
|
|
|
|
|
/* param for subplan's output */ |
|
|
|
|
Param *param; |
|
|
|
|
} MinMaxAggInfo; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|