55#define UNSAFE_HAS_VOLATILE_FUNC (1 << 0)
56#define UNSAFE_HAS_SET_FUNC (1 << 1)
57#define UNSAFE_NOTIN_DISTINCTON_CLAUSE (1 << 2)
58#define UNSAFE_NOTIN_PARTITIONBY_CLAUSE (1 << 3)
59#define UNSAFE_TYPE_MISMATCH (1 << 4)
212 for (rti = 1; rti <
root->simple_rel_array_size; rti++)
276 foreach(
lc,
root->join_info_list)
306 for (rti = 1; rti <
root->simple_rel_array_size; rti++)
321 rte =
root->simple_rte_array[rti];
331 if (
root->glob->parallelModeOK)
352 if (
root->agg_clause_list ==
NIL ||
356 for (rti = 1; rti <
root->simple_rel_array_size; rti++)
382 for (rti = 1; rti <
root->simple_rel_array_size; rti++)
448 else if (
rte->tablesample !=
NULL)
484 if (
rte->self_reference)
536 else if (
rte->tablesample !=
NULL)
584 (*set_rel_pathlist_hook) (
root, rel, rti,
rte);
616#ifdef OPTIMIZER_DEBUG
659 switch (
rte->rtekind)
701 if (!rel->fdwroutine->IsForeignScanParallelSafe)
703 if (!rel->fdwroutine->IsForeignScanParallelSafe(
root, rel,
rte))
862 int parallel_workers;
868 if (parallel_workers <= 0)
899 tsm->SampleScanGetSampleSize(
root, rel,
tsc->args,
951 if ((
root->query_level > 1 ||
974 rel->fdwroutine->GetForeignRelSize(
root, rel,
rte->
relid);
995 rel->fdwroutine->GetForeignPaths(
root, rel,
rte->
relid);
1068 foreach(l,
root->append_rel_list)
1184 childrel->consider_partitionwise_join =
true;
1279 for (
i = 0;
i < nattrs;
i++)
1316 foreach(l,
root->append_rel_list)
1376 if (
root->agg_clause_list ==
NIL ||
1464 if (
root->tuple_fraction > 0.0)
1467 root->tuple_fraction);
1626 int parallel_workers = 0;
1635 Assert(parallel_workers > 0);
1648 parallel_workers =
Max(parallel_workers,
1650 parallel_workers =
Min(parallel_workers,
1653 Assert(parallel_workers > 0);
1681 int parallel_workers = 0;
1699 parallel_workers =
Max(parallel_workers,
1701 parallel_workers =
Min(parallel_workers,
1703 Assert(parallel_workers > 0);
1707 NIL,
NULL, parallel_workers,
true,
1978 if (
root->tuple_fraction > 0)
2232 if (!
apath->path.parallel_aware ||
apath->first_partial_path == 0)
2244 apath->first_partial_path));
2246 apath->first_partial_path);
2260 *subpaths =
lappend(*subpaths, path);
2404 req.window_func = wfunc;
2513 wfuncrc->wfunc_left = wfunc_left;
2624 double tuple_fraction;
2697 if (rinfo->pseudoconstant)
2718 if (!subquery->hasWindowFuncs ||
2756 if (
parse->hasAggs ||
2757 parse->groupClause ||
2758 parse->groupingSets ||
2759 root->hasHavingQual ||
2760 parse->distinctClause ||
2761 parse->sortClause ||
2763 tuple_fraction = 0.0;
2765 tuple_fraction =
root->tuple_fraction;
2773 root,
false, tuple_fraction,
NULL);
2820 if (var->
varno != rti ||
2902 if (
rte->funcordinality)
3012 levelsup =
rte->ctelevelsup;
3014 while (levelsup-- > 0)
3018 elog(
ERROR,
"bad levelsup for CTE \"%s\"",
rte->ctename);
3036 elog(
ERROR,
"could not find CTE \"%s\"",
rte->ctename);
3038 elog(
ERROR,
"could not find plan for CTE \"%s\"",
rte->ctename);
3041 elog(
ERROR,
"no plan was made for CTE \"%s\"",
rte->ctename);
3141 levelsup =
rte->ctelevelsup;
3143 elog(
ERROR,
"bad levelsup for CTE \"%s\"",
rte->ctename);
3146 while (levelsup-- > 0)
3150 elog(
ERROR,
"bad levelsup for CTE \"%s\"",
rte->ctename);
3154 elog(
ERROR,
"could not find path for CTE \"%s\"",
rte->ctename);
3268 if (
root->query_pathkeys)
3273 foreach(
lc,
root->query_pathkeys)
3304 root->query_pathkeys);
3523 if (cheapest_total_path !=
NULL)
3526 cheapest_total_path->
rows,
3715 cheapest_total_path,
3820 elog(
ERROR,
"unrecognized joinlist node type: %d",
3844 root->initial_rels = initial_rels;
3909 root->join_rel_level[1] = initial_rels;
3975#ifdef OPTIMIZER_DEBUG
4095 subquery->hasWindowFuncs ||
4096 subquery->hasTargetSRFs)
4163 elog(
ERROR,
"unrecognized node type: %d",
4227 if (subquery->hasGroupRTE)
4241 if (subquery->hasTargetSRFs &&
4260 if (subquery->hasDistinctOn &&
4271 if (subquery->hasWindowFuncs &&
4314 elog(
ERROR,
"wrong number of tlist entries");
4320 elog(
ERROR,
"wrong number of tlist entries");
4434 if (var->
varno != rti)
4499 subquery->resultRelation,
4501 &subquery->hasSubLinks);
4547 elog(
ERROR,
"unrecognized node type: %d",
4649 if (
tle->ressortgroupref ||
tle->resjunk)
4663 if (subquery->hasTargetSRFs &&
4693 int parallel_workers;
4703 if (parallel_workers <= 0)
4729 int parallel_workers = 0;
4791 if (parallel_workers > 0)
4801 return parallel_workers;
4877 root->all_query_rels))
4887#ifdef OPTIMIZER_DEBUG
static void set_base_rel_sizes(PlannerInfo *root)
static List * get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel, bool require_parallel_safe)
static void set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
#define UNSAFE_TYPE_MISMATCH
static Path * get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)
static void set_namedtuplestore_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void subquery_push_qual(Query *subquery, RangeTblEntry *rte, Index rti, Node *qual)
void generate_partitionwise_join_paths(PlannerInfo *root, RelOptInfo *rel)
void generate_grouped_paths(PlannerInfo *root, RelOptInfo *grouped_rel, RelOptInfo *rel)
static void set_base_rel_consider_startup(PlannerInfo *root)
#define UNSAFE_HAS_VOLATILE_FUNC
#define UNSAFE_NOTIN_DISTINCTON_CLAUSE
static void set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
static Path * get_singleton_append_subpath(Path *path)
static void set_tablesample_rel_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void set_tablesample_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void set_base_rel_pathlists(PlannerInfo *root)
RelOptInfo * standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
static void set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
static pushdown_safe_type qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo, pushdown_safety_info *safetyInfo)
static void set_result_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
int compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages, int max_workers)
static bool check_and_push_window_quals(Query *subquery, Node *clause, Bitmapset **run_cond_attrs)
void generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows)
static void set_dummy_rel_pathlist(RelOptInfo *rel)
static void compare_tlist_datatypes(List *tlist, List *colTypes, pushdown_safety_info *safetyInfo)
static void set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static bool targetIsInAllPartitionLists(TargetEntry *tle, Query *query)
static void create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel)
static bool subquery_is_pushdown_safe(Query *subquery, Query *topquery, pushdown_safety_info *safetyInfo)
join_search_hook_type join_search_hook
void generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows)
static RelOptInfo * make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
static void set_function_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void recurse_push_qual(Node *setOp, Query *topquery, RangeTblEntry *rte, Index rti, Node *qual)
static void set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void setup_simple_grouped_rels(PlannerInfo *root)
static void remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel, Bitmapset *extra_used_attrs)
static void check_output_expressions(Query *subquery, pushdown_safety_info *safetyInfo)
static void set_tablefunc_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void set_foreign_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
set_rel_pathlist_hook_type set_rel_pathlist_hook
static void set_values_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
RelOptInfo * make_one_rel(PlannerInfo *root, List *joinlist)
#define UNSAFE_HAS_SET_FUNC
static void set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
bool enable_eager_aggregate
static void set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void set_grouped_rel_pathlist(PlannerInfo *root, RelOptInfo *rel)
static void set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
void create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel, Path *bitmapqual)
static void set_plain_rel_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
double min_eager_agg_group_size
void add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, List *live_childrels)
static void set_rel_size(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
static void generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, List *live_childrels, List *all_child_pathkeys)
#define UNSAFE_NOTIN_PARTITIONBY_CLAUSE
static bool find_window_run_conditions(Query *subquery, AttrNumber attno, WindowFunc *wfunc, OpExpr *opexpr, bool wfunc_left, bool *keep_original, Bitmapset **run_cond_attrs)
static bool recurse_pushdown_safe(Node *setOp, Query *topquery, pushdown_safety_info *safetyInfo)
@ PUSHDOWN_WINDOWCLAUSE_RUNCOND
static void accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths)
int min_parallel_index_scan_size
int min_parallel_table_scan_size
Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)
#define InvalidAttrNumber
void pprint(const void *obj)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
BMS_Membership bms_membership(const Bitmapset *a)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
bool bms_get_singleton_member(const Bitmapset *a, int *member)
#define Assert(condition)
#define MemSet(start, val, len)
#define OidIsValid(objectId)
bool is_pseudo_constant_clause(Node *clause)
bool contain_leaked_vars(Node *clause)
bool is_parallel_safe(PlannerInfo *root, Node *node)
bool contain_subplans(Node *clause)
bool contain_volatile_functions(Node *clause)
void set_namedtuplestore_size_estimates(PlannerInfo *root, RelOptInfo *rel)
int max_parallel_workers_per_gather
void set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel)
void set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel)
void set_cte_size_estimates(PlannerInfo *root, RelOptInfo *rel, double cte_rows)
double compute_gather_rows(Path *path)
void set_result_size_estimates(PlannerInfo *root, RelOptInfo *rel)
bool enable_partitionwise_join
double compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel, Path *bitmapqual, double loop_count, Cost *cost_p, double *tuples_p)
void set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel)
bool enable_parallel_append
void set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel)
double clamp_row_est(double nrows)
void set_tablefunc_size_estimates(PlannerInfo *root, RelOptInfo *rel)
void set_values_size_estimates(PlannerInfo *root, RelOptInfo *rel)
bool enable_incremental_sort
void add_child_rel_equivalences(PlannerInfo *root, AppendRelInfo *appinfo, RelOptInfo *parent_rel, RelOptInfo *child_rel)
bool relation_can_be_sorted_early(PlannerInfo *root, RelOptInfo *rel, EquivalenceClass *ec, bool require_parallel_safe)
#define OidFunctionCall1(functionId, arg1)
RelOptInfo * geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
void check_index_predicates(PlannerInfo *root, RelOptInfo *rel)
void create_index_paths(PlannerInfo *root, RelOptInfo *rel)
void join_search_one_level(PlannerInfo *root, int level)
void mark_dummy_rel(RelOptInfo *rel)
List * lappend(List *list, void *datum)
List * list_copy_tail(const List *oldlist, int nskip)
List * list_concat(List *list1, const List *list2)
void list_free(List *list)
List * list_copy_head(const List *oldlist, int len)
char get_rel_persistence(Oid relid)
char func_parallel(Oid funcid)
Oid get_opfamily_member_for_cmptype(Oid opfamily, Oid lefttype, Oid righttype, CompareType cmptype)
RegProcedure get_func_support(Oid funcid)
bool func_strict(Oid funcid)
List * get_op_index_interpretation(Oid opno)
int32 get_typavgwidth(Oid typid, int32 typmod)
Datum subpath(PG_FUNCTION_ARGS)
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Node * make_and_qual(Node *qual1, Node *qual2)
void pfree(void *pointer)
void * palloc0(Size size)
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
bool expression_returns_set(Node *clause)
void set_opfuncid(OpExpr *opexpr)
#define IsA(nodeptr, _type_)
@ AGGSPLIT_INITIAL_SERIAL
#define castNode(_type_, nodeptr)
#define PVC_INCLUDE_PLACEHOLDERS
bool targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList)
#define rt_fetch(rangetable_index, rangetable)
bool partitions_are_ordered(PartitionBoundInfo boundinfo, Bitmapset *live_parts)
Path * get_cheapest_fractional_path_for_pathkeys(List *paths, List *pathkeys, Relids required_outer, double fraction)
Path * get_cheapest_path_for_pathkeys(List *paths, List *pathkeys, Relids required_outer, CostSelector cost_criterion, bool require_parallel_safe)
bool pathkeys_count_contained_in(List *keys1, List *keys2, int *n_common)
bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel)
List * make_pathkeys_for_sortclauses(PlannerInfo *root, List *sortclauses, List *tlist)
List * build_expression_pathkey(PlannerInfo *root, Expr *expr, Oid opno, Relids rel, bool create_it)
List * build_partition_pathkeys(PlannerInfo *root, RelOptInfo *partrel, ScanDirection scandir, bool *partialkeys)
List * convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, List *subquery_pathkeys, List *subquery_tlist)
bool pathkeys_contained_in(List *keys1, List *keys2)
PathKeysComparison compare_pathkeys(List *keys1, List *keys2)
Path * get_cheapest_parallel_safe_total_inner(List *paths)
Path * create_functionscan_path(PlannerInfo *root, RelOptInfo *rel, List *pathkeys, Relids required_outer)
Path * create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)
Path * create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)
ProjectionPath * create_projection_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target)
Path * create_seqscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer, int parallel_workers)
GatherMergePath * create_gather_merge_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, List *pathkeys, Relids required_outer, double *rows)
void set_cheapest(RelOptInfo *parent_rel)
void add_partial_path(RelOptInfo *parent_rel, Path *new_path)
AppendPath * create_append_path(PlannerInfo *root, RelOptInfo *rel, List *subpaths, List *partial_subpaths, List *pathkeys, Relids required_outer, int parallel_workers, bool parallel_aware, double rows)
Path * create_namedtuplestorescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)
SubqueryScanPath * create_subqueryscan_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, bool trivial_pathtarget, List *pathkeys, Relids required_outer)
IncrementalSortPath * create_incremental_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *pathkeys, int presorted_keys, double limit_tuples)
BitmapHeapPath * create_bitmap_heap_path(PlannerInfo *root, RelOptInfo *rel, Path *bitmapqual, Relids required_outer, double loop_count, int parallel_degree)
Path * create_tablefuncscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)
SortPath * create_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *pathkeys, double limit_tuples)
GatherPath * create_gather_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, Relids required_outer, double *rows)
Path * create_samplescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)
MaterialPath * create_material_path(RelOptInfo *rel, Path *subpath)
void add_path(RelOptInfo *parent_rel, Path *new_path)
int compare_path_costs(Path *path1, Path *path2, CostSelector criterion)
Path * create_resultscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)
Path * create_ctescan_path(PlannerInfo *root, RelOptInfo *rel, List *pathkeys, Relids required_outer)
AggPath * create_agg_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, AggStrategy aggstrategy, AggSplit aggsplit, List *groupClause, List *qual, const AggClauseCosts *aggcosts, double numGroups)
MergeAppendPath * create_merge_append_path(PlannerInfo *root, RelOptInfo *rel, List *subpaths, List *pathkeys, Relids required_outer)
Path * reparameterize_path(PlannerInfo *root, Path *path, Relids required_outer, double loop_count)
#define IS_SIMPLE_REL(rel)
#define IS_PARTITIONED_REL(rel)
#define IS_GROUPED_REL(rel)
#define PATH_REQ_OUTER(path)
@ RELOPT_OTHER_MEMBER_REL
#define IS_OTHER_REL(rel)
void(* set_rel_pathlist_hook_type)(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
RelOptInfo *(* join_search_hook_type)(PlannerInfo *root, int levels_needed, List *initial_rels)
static int pg_leftmost_one_pos32(uint32 word)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define foreach_current_index(var_or_cell)
#define for_each_from(cell, lst, N)
static void * list_nth(const List *list, int n)
static ListCell * list_head(const List *l)
#define list_nth_node(type, list, n)
static ListCell * lnext(const List *l, const ListCell *c)
static int list_nth_int(const List *list, int n)
bool relation_excluded_by_constraints(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
char * choose_plan_name(PlannerGlobal *glob, const char *name, bool always_number)
PlannerInfo * subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, PlannerInfo *parent_root, bool hasRecursion, double tuple_fraction, SetOperationStmt *setops)
Path * get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction)
bool limit_needed(Query *parse)
@ MONOTONICFUNC_DECREASING
@ MONOTONICFUNC_INCREASING
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
void get_agg_clause_costs(PlannerInfo *root, AggSplit aggsplit, AggClauseCosts *costs)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
RelOptInfo * build_simple_grouped_rel(PlannerInfo *root, RelOptInfo *rel)
RelOptInfo * fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids)
Node * ReplaceVarsFromTargetList(Node *node, int target_varno, int sublevels_up, RangeTblEntry *target_rte, List *targetlist, int result_relation, ReplaceVarsNoMatchOption nomatch_option, int nomatch_varno, bool *outer_hasSubLinks)
@ REPLACEVARS_REPORT_ERROR
double estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, List **pgset, EstimationInfo *estinfo)
void check_stack_depth(void)
struct PathTarget * agg_input
struct PathTarget * target
bool consider_param_startup
struct PathTarget * reltarget
struct RelAggInfo * agg_info
struct Path * cheapest_total_path
struct RelOptInfo * grouped_rel
bool consider_partitionwise_join
MonotonicFunction monotonic
bool repeatable_across_scans
unsigned char * unsafeFlags
#define FirstLowInvalidHeapAttributeNumber
TsmRoutine * GetTsmRoutine(Oid tsmhandler)
bool create_tidscan_paths(PlannerInfo *root, RelOptInfo *rel)
bool grouping_is_sortable(List *groupClause)
List * make_tlist_from_pathtarget(PathTarget *target)
bool grouping_is_hashable(List *groupClause)
Node * flatten_group_exprs(PlannerInfo *root, Query *query, Node *node)
List * pull_var_clause(Node *node, int flags)
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)