87#define EXPRKIND_QUAL 0
88#define EXPRKIND_TARGET 1
89#define EXPRKIND_RTFUNC 2
90#define EXPRKIND_RTFUNC_LATERAL 3
91#define EXPRKIND_VALUES 4
92#define EXPRKIND_VALUES_LATERAL 5
93#define EXPRKIND_LIMIT 6
94#define EXPRKIND_APPINFO 7
96#define EXPRKIND_TABLESAMPLE 9
97#define EXPRKIND_ARBITER_ELEM 10
98#define EXPRKIND_TABLEFUNC 11
99#define EXPRKIND_TABLEFUNC_LATERAL 12
100#define EXPRKIND_GROUPEXPR 13
144 int *tleref_to_colnum_map);
147 double tuple_fraction,
160 bool target_parallel_safe,
167 PathTarget *target,
bool target_parallel_safe,
188 bool output_target_parallel_safe,
190 List *activeWindows);
197 List *activeWindows);
209 List *needed_pathkeys,
210 List *path_pathkeys);
214 bool target_parallel_safe,
215 double limit_tuples);
228 List *activeWindows);
233 bool *have_postponed_srfs);
235 List *targets,
List *targets_contain_srfs);
247 bool force_rel_creation);
253 double limit_tuples);
258 List *scanjoin_targets,
259 List *scanjoin_targets_contain_srfs,
260 bool scanjoin_target_parallel_safe,
277 List *sortPathkeys,
List *groupClause,
280 List *sortPathkeys,
List *groupClause,
321 result = (*planner_hook) (
parse, query_string, cursorOptions,
338 double tuple_fraction;
354 glob->boundParams = boundParams;
357 glob->subroots =
NIL;
375 glob->partition_directory = NULL;
376 glob->rel_notnullatts_hash = NULL;
402 !
parse->hasModifyingCTE &&
454 if (tuple_fraction >= 1.0)
455 tuple_fraction = 0.0;
456 else if (tuple_fraction <= 0.0)
457 tuple_fraction = 1
e-10;
462 tuple_fraction = 0.0;
467 (*planner_setup_hook) (glob,
parse, query_string, &tuple_fraction, es);
508 bool unsafe_initplans;
546 &initplan_cost, &unsafe_initplans);
551 root->glob->parallelModeNeeded =
true;
553 top_plan = &gather->
plan;
650 (*planner_shutdown_hook) (glob,
parse, query_string, result);
652 if (glob->partition_directory != NULL)
698 List *newWithCheckOptions;
710 root->plan_name = plan_name;
711 root->parent_root = parent_root;
713 root->outer_params = NULL;
720 root->ec_merging_done =
false;
721 root->last_rinfo_serial = 0;
722 root->all_result_relids =
724 root->leaf_result_relids = NULL;
728 memset(
root->upper_rels, 0,
sizeof(
root->upper_rels));
729 memset(
root->upper_targets, 0,
sizeof(
root->upper_targets));
730 root->processed_groupClause =
NIL;
731 root->processed_distinctClause =
NIL;
734 root->grouping_map = NULL;
736 root->qual_security_level = 0;
737 root->hasPseudoConstantQuals =
false;
738 root->hasAlternativeSubPlans =
false;
739 root->placeholdersFrozen =
false;
740 root->hasRecursion = hasRecursion;
741 root->assumeReplanning =
false;
745 root->wt_param_id = -1;
746 root->non_recursive_path = NULL;
791 if (
parse->hasSubLinks)
814 if (
parse->setOperations)
827 root->hasJoinRTEs =
false;
828 root->hasLateralRTEs =
false;
829 root->group_rtindex = 0;
830 hasOuterJoins =
false;
831 hasResultRTEs =
false;
832 foreach(l,
parse->rtable)
839 root->hasJoinRTEs =
true;
841 hasOuterJoins =
true;
844 hasResultRTEs =
true;
856 root->hasLateralRTEs =
true;
864 if (rte->securityQuals)
865 root->qual_security_level =
Max(
root->qual_security_level,
873 if (
parse->resultRelation)
878 root->leaf_result_relids =
896 foreach(l,
parse->rtable)
900 if (rte->perminfoindex != 0 &&
901 rte->relkind == RELKIND_VIEW)
925 root->hasHavingQual = (
parse->havingQual != NULL);
937 newWithCheckOptions =
NIL;
938 foreach(l,
parse->withCheckOptions)
944 if (wco->
qual != NULL)
945 newWithCheckOptions =
lappend(newWithCheckOptions, wco);
947 parse->withCheckOptions = newWithCheckOptions;
958 foreach(l,
parse->windowClause)
974 if (
parse->onConflict)
976 parse->onConflict->arbiterElems = (
List *)
978 (
Node *)
parse->onConflict->arbiterElems,
980 parse->onConflict->arbiterWhere =
982 parse->onConflict->arbiterWhere,
984 parse->onConflict->onConflictSet = (
List *)
986 (
Node *)
parse->onConflict->onConflictSet,
988 parse->onConflict->onConflictWhere =
990 parse->onConflict->onConflictWhere,
995 foreach(l,
parse->mergeActionList)
1009 parse->mergeJoinCondition =
1017 foreach(l,
parse->rtable)
1040 if (rte->lateral &&
root->hasJoinRTEs)
1069 rte->groupexprs = (
List *)
1080 foreach(lcsq, rte->securityQuals)
1099 if (
root->hasJoinRTEs)
1101 foreach(l,
parse->rtable)
1105 rte->joinaliasvars =
NIL;
1118 if (
parse->hasGroupRTE)
1127 if (
parse->hasTargetSRFs)
1136 if (
parse->groupingSets)
1138 parse->groupingSets =
1192 (
parse->groupClause &&
parse->groupingSets &&
1196 newHaving =
lappend(newHaving, havingclause);
1198 else if (
parse->groupClause &&
1211 (
List *) whereclause);
1224 (
List *) whereclause);
1226 newHaving =
lappend(newHaving, havingclause);
1245 if (hasResultRTEs || hasOuterJoins)
1304 if (
root->hasJoinRTEs &&
1340#ifdef OPTIMIZER_DEBUG
1341 printf(
"After canonicalize_qual()\n");
1357 if (
root->parse->hasSubLinks)
1366 if (
root->query_level > 1)
1415 elog(
ERROR,
"unrecognized node type: %d",
1468 int64 offset_est = 0;
1469 int64 count_est = 0;
1470 double limit_tuples = -1.0;
1471 bool have_postponed_srfs =
false;
1473 List *final_targets;
1474 List *final_targets_contain_srfs;
1475 bool final_target_parallel_safe;
1485 &offset_est, &count_est);
1491 if (count_est > 0 && offset_est >= 0)
1492 limit_tuples = (double) count_est + (
double) offset_est;
1496 root->tuple_fraction = tuple_fraction;
1498 if (
parse->setOperations)
1518 root->processed_tlist =
1526 final_target_parallel_safe =
1531 final_targets = final_targets_contain_srfs =
NIL;
1537 if (
parse->rowMarks)
1539 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1542 errmsg(
"%s is not allowed with UNION/INTERSECT/EXCEPT",
1544 parse->rowMarks)->strength))));
1552 root->processed_tlist);
1558 List *sort_input_targets;
1559 List *sort_input_targets_contain_srfs;
1560 bool sort_input_target_parallel_safe;
1562 List *grouping_targets;
1563 List *grouping_targets_contain_srfs;
1564 bool grouping_target_parallel_safe;
1566 List *scanjoin_targets;
1567 List *scanjoin_targets_contain_srfs;
1568 bool scanjoin_target_parallel_safe;
1569 bool scanjoin_target_same_exprs;
1580 if (
parse->groupingSets)
1584 else if (
parse->groupClause)
1618 if (
parse->hasWindowFuncs)
1638 parse->hasWindowFuncs =
false;
1656 if (
parse->groupClause ||
1657 parse->groupingSets ||
1658 parse->distinctClause ||
1660 parse->hasWindowFuncs ||
1661 parse->hasTargetSRFs ||
1662 root->hasHavingQual)
1663 root->limit_tuples = -1.0;
1665 root->limit_tuples = limit_tuples;
1675 qp_extra.
setop = setops;
1696 final_target_parallel_safe =
1704 if (
parse->sortClause)
1708 &have_postponed_srfs);
1709 sort_input_target_parallel_safe =
1714 sort_input_target = final_target;
1715 sort_input_target_parallel_safe = final_target_parallel_safe;
1728 grouping_target_parallel_safe =
1733 grouping_target = sort_input_target;
1734 grouping_target_parallel_safe = sort_input_target_parallel_safe;
1742 have_grouping = (
parse->groupClause ||
parse->groupingSets ||
1747 scanjoin_target_parallel_safe =
1752 scanjoin_target = grouping_target;
1753 scanjoin_target_parallel_safe = grouping_target_parallel_safe;
1762 if (
parse->hasTargetSRFs)
1767 &final_targets_contain_srfs);
1772 &sort_input_targets,
1773 &sort_input_targets_contain_srfs);
1778 grouping_target, scanjoin_target,
1780 &grouping_targets_contain_srfs);
1786 &scanjoin_targets_contain_srfs);
1793 final_targets = final_targets_contain_srfs =
NIL;
1794 sort_input_targets = sort_input_targets_contain_srfs =
NIL;
1795 grouping_targets = grouping_targets_contain_srfs =
NIL;
1796 scanjoin_targets =
list_make1(scanjoin_target);
1797 scanjoin_targets_contain_srfs =
NIL;
1801 scanjoin_target_same_exprs =
list_length(scanjoin_targets) == 1
1804 scanjoin_targets_contain_srfs,
1805 scanjoin_target_parallel_safe,
1806 scanjoin_target_same_exprs);
1832 grouping_target_parallel_safe,
1835 if (
parse->hasTargetSRFs)
1838 grouping_targets_contain_srfs);
1851 sort_input_target_parallel_safe,
1855 if (
parse->hasTargetSRFs)
1858 sort_input_targets_contain_srfs);
1865 if (
parse->distinctClause)
1880 if (
parse->sortClause)
1885 final_target_parallel_safe,
1886 have_postponed_srfs ? -1.0 :
1889 if (
parse->hasTargetSRFs)
1892 final_targets_contain_srfs);
1918 final_rel->fdwroutine = current_rel->fdwroutine;
1935 if (
parse->rowMarks)
1951 offset_est, count_est);
1961 List *updateColnosLists =
NIL;
1962 List *withCheckOptionLists =
NIL;
1965 List *mergeJoinConditions =
NIL;
1972 parse->resultRelation);
1973 int resultRelation = -1;
1976 rootRelation =
parse->resultRelation;
1980 resultRelation)) >= 0)
1998 List *update_colnos =
root->update_colnos;
2000 if (this_result_rel != top_result_rel)
2004 this_result_rel->
relid,
2005 top_result_rel->
relid);
2006 updateColnosLists =
lappend(updateColnosLists,
2009 if (
parse->withCheckOptions)
2011 List *withCheckOptions =
parse->withCheckOptions;
2013 if (this_result_rel != top_result_rel)
2014 withCheckOptions = (
List *)
2016 (
Node *) withCheckOptions,
2019 withCheckOptionLists =
lappend(withCheckOptionLists,
2022 if (
parse->returningList)
2024 List *returningList =
parse->returningList;
2026 if (this_result_rel != top_result_rel)
2027 returningList = (
List *)
2029 (
Node *) returningList,
2032 returningLists =
lappend(returningLists,
2035 if (
parse->mergeActionList)
2044 foreach(l,
parse->mergeActionList)
2054 leaf_action->targetList = (
List *)
2060 leaf_action->updateColnos =
2063 this_result_rel->
relid,
2064 top_result_rel->
relid);
2065 mergeActionList =
lappend(mergeActionList,
2069 mergeActionLists =
lappend(mergeActionLists,
2074 Node *mergeJoinCondition =
parse->mergeJoinCondition;
2076 if (this_result_rel != top_result_rel)
2077 mergeJoinCondition =
2082 mergeJoinConditions =
lappend(mergeJoinConditions,
2083 mergeJoinCondition);
2087 if (resultRelations ==
NIL)
2103 if (
parse->withCheckOptions)
2105 if (
parse->returningList)
2107 if (
parse->mergeActionList)
2120 if (
parse->withCheckOptions)
2122 if (
parse->returningList)
2124 if (
parse->mergeActionList)
2135 if (
parse->rowMarks)
2138 rowMarks =
root->rowMarks;
2145 parse->resultRelation,
2149 withCheckOptionLists,
2154 mergeJoinConditions,
2187 if (final_rel->fdwroutine &&
2188 final_rel->fdwroutine->GetForeignUpperPaths)
2190 current_rel, final_rel,
2196 current_rel, final_rel, &extra);
2223 root->processed_groupClause =
parse->groupClause;
2231 if (
parse->groupClause)
2235 foreach(lc,
parse->groupClause)
2265 foreach(lc,
parse->groupingSets)
2286 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2287 errmsg(
"could not implement GROUP BY"),
2288 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
2291 sortable_sets =
lappend(sortable_sets, gset);
2302 foreach(lc_set, sets)
2393 int *tleref_to_colnum_map)
2399 foreach(lc, groupClause)
2412 foreach(lc2, gs->
set)
2417 result =
lappend(result, set);
2436 if (
parse->rowMarks)
2445 parse->rowMarks)->strength);
2465 if (
parse->resultRelation)
2472 foreach(l,
parse->rowMarks)
2505 prowmarks =
lappend(prowmarks, newrc);
2512 foreach(l,
parse->rtable)
2530 prowmarks =
lappend(prowmarks, newrc);
2533 root->rowMarks = prowmarks;
2547 else if (rte->relkind == RELKIND_FOREIGN_TABLE)
2583 elog(
ERROR,
"unrecognized LockClauseStrength %d", (
int) strength);
2611 double limit_fraction;
2620 if (
parse->limitCount)
2625 if (((
Const *) est)->constisnull)
2633 if (*count_est <= 0)
2643 if (
parse->limitOffset)
2648 if (((
Const *) est)->constisnull)
2656 if (*offset_est < 0)
2666 if (*count_est != 0)
2673 if (*count_est < 0 || *offset_est < 0)
2676 limit_fraction = 0.10;
2681 limit_fraction = (double) *count_est + (
double) *offset_est;
2691 if (tuple_fraction >= 1.0)
2693 if (limit_fraction >= 1.0)
2696 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2703 else if (tuple_fraction > 0.0)
2705 if (limit_fraction >= 1.0)
2708 tuple_fraction = limit_fraction;
2713 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2719 tuple_fraction = limit_fraction;
2722 else if (*offset_est != 0 && tuple_fraction > 0.0)
2733 if (*offset_est < 0)
2734 limit_fraction = 0.10;
2736 limit_fraction = (double) *offset_est;
2744 if (tuple_fraction >= 1.0)
2746 if (limit_fraction >= 1.0)
2749 tuple_fraction += limit_fraction;
2754 tuple_fraction = limit_fraction;
2759 if (limit_fraction >= 1.0)
2766 tuple_fraction += limit_fraction;
2767 if (tuple_fraction >= 1.0)
2768 tuple_fraction = 0.0;
2773 return tuple_fraction;
2795 node =
parse->limitCount;
2801 if (!((
Const *) node)->constisnull)
2808 node =
parse->limitOffset;
2814 if (!((
Const *) node)->constisnull)
2872 new_groupclause =
lappend(new_groupclause, cl);
2875 return new_groupclause;
2888 foreach(sl,
parse->sortClause)
2892 foreach(gl,
parse->groupClause)
2898 new_groupclause =
lappend(new_groupclause, gc);
2908 if (new_groupclause ==
NIL)
2917 foreach(gl,
parse->groupClause)
2925 new_groupclause =
lappend(new_groupclause, gc);
2930 return new_groupclause;
2965 short *adjacency_buf;
2981 lc1 =
lnext(groupingSets, lc1);
3006 orig_sets =
palloc0((num_sets_raw + 1) *
sizeof(
List *));
3008 adjacency =
palloc0((num_sets_raw + 1) *
sizeof(
short *));
3009 adjacency_buf =
palloc((num_sets_raw + 1) *
sizeof(
short));
3022 foreach(lc2, candidate)
3032 for (k =
j; k <
i; ++k)
3034 if (
bms_equal(set_masks[k], candidate_set))
3049 orig_sets[dup_of] =
lappend(orig_sets[dup_of], candidate);
3058 set_masks[
i] = candidate_set;
3062 for (k =
j - 1; k > 0; --k)
3065 adjacency_buf[++n_adj] = k;
3070 adjacency_buf[0] = n_adj;
3071 adjacency[
i] =
palloc((n_adj + 1) *
sizeof(
short));
3072 memcpy(adjacency[
i], adjacency_buf, (n_adj + 1) *
sizeof(
short));
3075 adjacency[
i] = NULL;
3094 chains =
palloc0((num_sets + 1) *
sizeof(
int));
3096 for (
i = 1;
i <= num_sets; ++
i)
3098 int u =
state->pair_vu[
i];
3099 int v =
state->pair_uv[
i];
3102 chains[
i] = chains[u];
3103 else if (v > 0 && v <
i)
3104 chains[
i] = chains[v];
3106 chains[
i] = ++num_chains;
3110 results =
palloc0((num_chains + 1) *
sizeof(
List *));
3112 for (
i = 1;
i <= num_sets; ++
i)
3122 while (num_empty-- > 0)
3123 results[1] =
lcons(
NIL, results[1]);
3126 for (
i = 1;
i <= num_chains; ++
i)
3127 result =
lappend(result, results[
i]);
3138 for (
i = 1;
i <= num_sets; ++
i)
3142 pfree(adjacency_buf);
3144 for (
i = 1;
i <= num_sets; ++
i)
3171 foreach(lc, groupingSets)
3199 result =
lcons(gs, result);
3221 if (pathkey->pk_eclass->ec_has_volatile)
3260 List *grouppathkeys =
root->group_pathkeys;
3280 unprocessed_aggs = NULL;
3281 foreach(lc,
root->agginfos)
3286 if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3297 bool allow_presort =
true;
3312 foreach(lc2, aggref->
args)
3325 allow_presort =
false;
3390 if (currpathkeys ==
NIL)
3392 currpathkeys = pathkeys;
3395 if (grouppathkeys !=
NIL)
3407 if (grouppathkeys !=
NIL)
3416 currpathkeys = pathkeys;
3443 bestaggs = aggindexes;
3444 bestpathkeys = currpathkeys;
3453 if (bestpathkeys !=
NIL)
3454 root->group_pathkeys = bestpathkeys;
3473 aggref->aggpresorted =
true;
3486 List *tlist =
root->processed_tlist;
3514 root->group_pathkeys =
3528 root->num_groupby_pathkeys = 0;
3531 else if (
parse->groupClause ||
root->numOrderedAggs > 0)
3547 root->group_pathkeys =
3549 &
root->processed_groupClause,
3559 root->num_groupby_pathkeys = 0;
3565 if (
root->numOrderedAggs > 0)
3572 root->num_groupby_pathkeys = 0;
3576 if (activeWindows !=
NIL)
3593 if (
parse->distinctClause)
3599 root->distinct_pathkeys =
3601 &
root->processed_distinctClause,
3608 root->distinct_pathkeys =
NIL;
3611 root->distinct_pathkeys =
NIL;
3613 root->sort_pathkeys =
3619 if (qp_extra->
setop != NULL)
3626 root->setop_pathkeys =
3660 if (
root->group_pathkeys)
3661 root->query_pathkeys =
root->group_pathkeys;
3662 else if (
root->window_pathkeys)
3663 root->query_pathkeys =
root->window_pathkeys;
3666 root->query_pathkeys =
root->distinct_pathkeys;
3667 else if (
root->sort_pathkeys)
3668 root->query_pathkeys =
root->sort_pathkeys;
3669 else if (
root->setop_pathkeys !=
NIL)
3670 root->query_pathkeys =
root->setop_pathkeys;
3695 if (
parse->groupClause)
3699 if (
parse->groupingSets)
3772 else if (
parse->groupingSets)
3777 else if (
parse->hasAggs ||
root->hasHavingQual)
3812 bool target_parallel_safe,
3828 target_parallel_safe,
parse->havingQual);
3877 root->numOrderedAggs == 0 &&
3887 extra.
flags = flags;
3905 &agg_costs, gd, &extra,
3906 &partially_grouped_rel);
3923 PathTarget *target,
bool target_parallel_safe,
3962 grouped_rel->fdwroutine = input_rel->fdwroutine;
3979 return (
root->hasHavingQual ||
parse->groupingSets) &&
4015 while (--nrows >= 0)
4094 root->parse->groupClause))
4109 bool force_rel_creation;
4118 partially_grouped_rel =
4124 force_rel_creation);
4128 *partially_grouped_rel_p = partially_grouped_rel;
4133 partially_grouped_rel, agg_costs,
4139 Assert(partially_grouped_rel);
4141 if (partially_grouped_rel->
pathlist)
4152 if (partially_grouped_rel && partially_grouped_rel->
pathlist)
4157 partially_grouped_rel, agg_costs, gd,
4163 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4164 errmsg(
"could not implement GROUP BY"),
4165 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
4171 if (grouped_rel->fdwroutine &&
4172 grouped_rel->fdwroutine->GetForeignUpperPaths)
4174 input_rel, grouped_rel,
4180 input_rel, grouped_rel,
4225 double exclude_groups = 0.0;
4249 if (l_start != NULL &&
4253 exclude_groups = unhashed_rollup->
numGroups;
4260 dNumGroups - exclude_groups);
4267 if (hashsize > hash_mem_limit && gd->
rollups)
4296 foreach(lc, sets_data)
4305 empty_sets_data =
lappend(empty_sets_data, gs);
4320 new_rollups =
lappend(new_rollups, rollup);
4328 if (new_rollups ==
NIL)
4335 Assert(!unhashed_rollup || !empty_sets);
4337 if (unhashed_rollup)
4339 new_rollups =
lappend(new_rollups, unhashed_rollup);
4342 else if (empty_sets)
4348 rollup->
gsets = empty_sets;
4352 new_rollups =
lappend(new_rollups, rollup);
4385 double availspace = hash_mem_limit;
4401 int *k_weights =
palloc(num_rollups *
sizeof(
int));
4427 scale =
Max(availspace / (20.0 * num_rollups), 1.0);
4428 k_capacity = (int) floor(availspace /
scale);
4452 k_weights[
i] = (int)
Min(floor(sz /
scale),
4482 rollups =
lappend(rollups, rollup);
4486 rollups =
lappend(rollups, rollup);
4491 if (!rollups && hash_sets)
4494 foreach(lc, hash_sets)
4509 rollups =
lcons(rollup, rollups);
4557 bool output_target_parallel_safe,
4559 List *activeWindows)
4582 window_rel->fdwroutine = input_rel->fdwroutine;
4611 if (window_rel->fdwroutine &&
4612 window_rel->fdwroutine->GetForeignUpperPaths)
4614 input_rel, window_rel,
4620 input_rel, window_rel, NULL);
4646 List *activeWindows)
4667 window_target = input_target;
4669 foreach(l, activeWindows)
4672 List *window_pathkeys;
4681 root->processed_tlist);
4714 if (
lnext(activeWindows, l))
4739 window_target = output_target;
4754 foreach(lc3, wfunc->runCondition)
4779 wfuncrc->inputcollid);
4781 runcondition =
lappend(runcondition, opexpr);
4784 topqual =
lappend(topqual, opexpr);
4792 topwindow ? topqual :
NIL, topwindow);
4833 distinct_rel->fdwroutine = input_rel->fdwroutine;
4844 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4845 errmsg(
"could not implement DISTINCT"),
4846 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
4852 if (distinct_rel->fdwroutine &&
4853 distinct_rel->fdwroutine->GetForeignUpperPaths)
4854 distinct_rel->fdwroutine->GetForeignUpperPaths(
root,
4863 distinct_rel, NULL);
4868 return distinct_rel;
4886 List *distinctExprs;
4887 double numDistinctRows;
4888 Path *cheapest_partial_path;
4898 if (
parse->hasDistinctOn)
4903 partial_distinct_rel->
reltarget = target;
4912 partial_distinct_rel->fdwroutine = input_rel->fdwroutine;
4921 cheapest_partial_path->
rows,
4937 List *useful_pathkeys_list =
NIL;
4939 useful_pathkeys_list =
4941 root->distinct_pathkeys,
4948 partial_distinct_rel,
4950 cheapest_partial_path,
4954 if (sorted_path == NULL)
4962 if (
root->distinct_pathkeys ==
NIL)
5012 partial_distinct_rel,
5013 cheapest_partial_path,
5014 cheapest_partial_path->pathtarget,
5017 root->processed_distinctClause,
5027 if (partial_distinct_rel->fdwroutine &&
5028 partial_distinct_rel->fdwroutine->GetForeignUpperPaths)
5029 partial_distinct_rel->fdwroutine->GetForeignUpperPaths(
root,
5032 partial_distinct_rel,
5038 input_rel, partial_distinct_rel, NULL);
5051 final_distinct_rel);
5068 double numDistinctRows;
5073 root->hasHavingQual)
5080 numDistinctRows = cheapest_input_path->
rows;
5087 List *distinctExprs;
5092 cheapest_input_path->
rows,
5117 List *needed_pathkeys;
5119 double limittuples =
root->distinct_pathkeys ==
NIL ? 1.0 : -1.0;
5121 if (
parse->hasDistinctOn &&
5124 needed_pathkeys =
root->sort_pathkeys;
5126 needed_pathkeys =
root->distinct_pathkeys;
5132 List *useful_pathkeys_list =
NIL;
5134 useful_pathkeys_list =
5145 cheapest_input_path,
5149 if (sorted_path == NULL)
5165 if (
root->distinct_pathkeys ==
NIL)
5221 cheapest_input_path,
5222 cheapest_input_path->pathtarget,
5225 root->processed_distinctClause,
5231 return distinct_rel;
5244 List *path_pathkeys)
5246 List *useful_pathkeys_list =
NIL;
5250 useful_pathkeys_list =
lappend(useful_pathkeys_list,
5254 return useful_pathkeys_list;
5273 if (
root->parse->hasDistinctOn &&
5277 useful_pathkeys =
lappend(useful_pathkeys, pathkey);
5281 if (useful_pathkeys ==
NIL)
5282 return useful_pathkeys_list;
5290 return useful_pathkeys_list;
5302 return useful_pathkeys_list;
5304 useful_pathkeys_list =
lappend(useful_pathkeys_list,
5307 return useful_pathkeys_list;
5331 bool target_parallel_safe,
5332 double limit_tuples)
5355 ordered_rel->fdwroutine = input_rel->fdwroutine;
5365 input_path->
pathkeys, &presorted_keys);
5368 sorted_path = input_path;
5378 if (input_path != cheapest_input_path &&
5391 root->sort_pathkeys,
5397 root->sort_pathkeys,
5406 if (!
equal(sorted_path->pathtarget->exprs, target->
exprs))
5408 sorted_path, target);
5410 add_path(ordered_rel, sorted_path);
5427 Path *cheapest_partial_path;
5437 double total_groups;
5453 if (input_path != cheapest_partial_path &&
5466 root->sort_pathkeys,
5472 root->sort_pathkeys,
5476 sorted_path = (
Path *)
5479 sorted_path->pathtarget,
5480 root->sort_pathkeys, NULL,
5487 if (!
equal(sorted_path->pathtarget->exprs, target->
exprs))
5489 sorted_path, target);
5491 add_path(ordered_rel, sorted_path);
5499 if (ordered_rel->fdwroutine &&
5500 ordered_rel->fdwroutine->GetForeignUpperPaths)
5502 input_rel, ordered_rel,
5508 input_rel, ordered_rel, NULL);
5552 List *non_group_cols;
5553 List *non_group_vars;
5562 non_group_cols =
NIL;
5565 foreach(lc, final_target->
exprs)
5570 if (sgref &&
root->processed_groupClause &&
5572 root->processed_groupClause) != NULL)
5597 non_group_cols =
lappend(non_group_cols, expr);
5606 if (
parse->havingQual)
5607 non_group_cols =
lappend(non_group_cols,
parse->havingQual);
5628 non_group_vars = (
List *)
5665 List *non_group_cols;
5666 List *non_group_exprs;
5671 non_group_cols =
NIL;
5674 foreach(lc, grouping_target->
exprs)
5679 if (sgref &&
root->processed_groupClause &&
5681 root->processed_groupClause) != NULL)
5695 non_group_cols =
lappend(non_group_cols, expr);
5705 non_group_cols =
lappend(non_group_cols, havingQual);
5726 foreach(lc, partial_target->
exprs)
5739 memcpy(newaggref, aggref,
sizeof(
Aggref));
5771 agg->aggsplit = aggsplit;
5781 agg->aggtype = BYTEAOID;
5783 agg->aggtype = agg->aggtranstype;
5803 foreach(l, new_tlist)
5809 if (new_tle->resjunk)
5812 Assert(orig_tlist_item != NULL);
5814 orig_tlist_item =
lnext(orig_tlist, orig_tlist_item);
5815 if (orig_tle->resjunk)
5816 elog(
ERROR,
"resjunk output columns are not implemented");
5820 if (orig_tlist_item != NULL)
5821 elog(
ERROR,
"resjunk output columns are not implemented");
5837 List *windowClause =
root->parse->windowClause;
5840 foreach(lc, windowClause)
5844 int optimizedFrameOptions = 0;
5865 req.
type = T_SupportRequestOptimizeWindowClause;
5899 if (lc2 == NULL && wc->
frameOptions != optimizedFrameOptions)
5919 foreach(lc3, windowClause)
5924 if (existing_wc == wc)
5977 List *windowClause =
root->parse->windowClause;
5985 foreach(lc, windowClause)
5994 actives[nActive].
wc = wc;
6038 for (
int i = 0;
i < nActive;
i++)
6039 result =
lappend(result, actives[
i].wc);
6064 foreach(lc, activeWindows)
6077 snprintf(newname,
sizeof(newname),
"w%d", next_n++);
6078 foreach(lc2, activeWindows)
6082 if (wc2->name && strcmp(wc2->name, newname) == 0)
6180 List *activeWindows)
6184 List *flattenable_cols;
6185 List *flattenable_vars;
6196 foreach(lc, activeWindows)
6216 foreach(lc,
root->processed_groupClause)
6228 flattenable_cols =
NIL;
6231 foreach(lc, final_target->
exprs)
6255 flattenable_cols =
lappend(flattenable_cols, expr);
6306 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6307 errmsg(
"could not implement window PARTITION BY"),
6308 errdetail(
"Window partitioning columns must be of sortable datatypes.")));
6311 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6312 errmsg(
"could not implement window ORDER BY"),
6313 errdetail(
"Window ordering columns must be of sortable datatypes.")));
6343 List *orderby_pathkeys;
6350 if (window_pathkeys !=
NIL)
6353 window_pathkeys = orderby_pathkeys;
6356 return window_pathkeys;
6428 bool *have_postponed_srfs)
6437 bool have_expensive;
6438 bool have_srf_sortcols;
6440 List *postponable_cols;
6441 List *postponable_vars;
6448 *have_postponed_srfs =
false;
6452 col_is_srf = (
bool *)
palloc0(ncols *
sizeof(
bool));
6453 postpone_col = (
bool *)
palloc0(ncols *
sizeof(
bool));
6454 have_srf = have_volatile = have_expensive = have_srf_sortcols =
false;
6457 foreach(lc, final_target->
exprs)
6475 if (
parse->hasTargetSRFs &&
6479 col_is_srf[
i] =
true;
6485 postpone_col[
i] =
true;
6486 have_volatile =
true;
6506 postpone_col[
i] =
true;
6507 have_expensive =
true;
6514 if (!have_srf_sortcols &&
6515 parse->hasTargetSRFs &&
6517 have_srf_sortcols =
true;
6526 postpone_srfs = (have_srf && !have_srf_sortcols);
6531 if (!(postpone_srfs || have_volatile ||
6533 (
parse->limitCount ||
root->tuple_fraction > 0))))
6534 return final_target;
6542 *have_postponed_srfs = postpone_srfs;
6550 postponable_cols =
NIL;
6553 foreach(lc, final_target->
exprs)
6557 if (postpone_col[
i] || (postpone_srfs && col_is_srf[
i]))
6558 postponable_cols =
lappend(postponable_cols, expr);
6608 if (tuple_fraction <= 0.0)
6612 if (tuple_fraction >= 1.0 && best_path->
rows > 0)
6613 tuple_fraction /= best_path->
rows;
6619 if (path->param_info)
6649 List *targets,
List *targets_contain_srfs)
6678 forboth(lc1, targets, lc2, targets_contain_srfs)
6711 forboth(lc1, targets, lc2, targets_contain_srfs)
6777 return (
Expr *) result;
6792 List **relationOids,
6800 MemSet(&glob, 0,
sizeof(glob));
6801 glob.type = T_PlannerGlobal;
6806 root.type = T_PlannerInfo;
6828 return (
Expr *) result;
6853 Cost comparisonCost;
6855 Path seqScanAndSortPath;
6870 root->parse = query;
6872 root->query_level = 1;
6874 root->wt_param_id = -1;
6880 rte->relid = tableOid;
6881 rte->relkind = RELKIND_RELATION;
6883 rte->lateral =
false;
6885 rte->inFromCl =
true;
6900 if (indexInfo->
indexoid == indexOid)
6975 int parallel_workers;
6994 root->parse = query;
6996 root->query_level = 1;
6998 root->wt_param_id = -1;
7011 rte->relid = tableOid;
7012 rte->relkind = RELKIND_RELATION;
7014 rte->lateral =
false;
7016 rte->inFromCl =
true;
7037 if (heap->
rd_rel->relpersistence == RELPERSISTENCE_TEMP ||
7041 parallel_workers = 0;
7082 while (parallel_workers > 0 &&
7090 return parallel_workers;
7108 Path *cheapest_partially_grouped_path = NULL;
7114 double dNumGroups = 0;
7115 double dNumFinalGroups = 0;
7121 cheapest_path->
rows,
7125 if (partially_grouped_rel && partially_grouped_rel->
pathlist)
7127 cheapest_partially_grouped_path =
7135 cheapest_partially_grouped_path->
rows,
7151 Path *path_save = path;
7152 List *pathkey_orderings =
NIL;
7159 foreach(lc2, pathkey_orderings)
7176 if (
parse->groupingSets)
7179 path,
true, can_hash,
7180 gd, agg_costs, dNumGroups);
7182 else if (
parse->hasAggs)
7200 else if (
parse->groupClause)
7226 if (partially_grouped_rel != NULL)
7228 foreach(lc, partially_grouped_rel->
pathlist)
7232 Path *path_save = path;
7233 List *pathkey_orderings =
NIL;
7241 foreach(lc2, pathkey_orderings)
7251 cheapest_partially_grouped_path,
7286 if (
parse->groupingSets)
7292 cheapest_path,
false,
true,
7293 gd, agg_costs, dNumGroups);
7307 root->processed_groupClause,
7317 if (partially_grouped_rel && partially_grouped_rel->
pathlist)
7322 cheapest_partially_grouped_path,
7326 root->processed_groupClause,
7365 bool force_rel_creation)
7372 Path *cheapest_partial_path = NULL;
7373 Path *cheapest_total_path = NULL;
7374 double dNumPartialGroups = 0;
7375 double dNumPartialPartialGroups = 0;
7414 if (cheapest_total_path == NULL &&
7415 cheapest_partial_path == NULL &&
7416 eager_agg_rel == NULL &&
7417 !force_rel_creation)
7433 partially_grouped_rel->fdwroutine = grouped_rel->fdwroutine;
7468 if (cheapest_total_path != NULL)
7471 cheapest_total_path->
rows,
7474 if (cheapest_partial_path != NULL)
7475 dNumPartialPartialGroups =
7477 cheapest_partial_path->
rows,
7481 if (can_sort && cheapest_total_path != NULL)
7494 Path *path_save = path;
7495 List *pathkey_orderings =
NIL;
7503 foreach(lc2, pathkey_orderings)
7511 partially_grouped_rel,
7513 cheapest_total_path,
7523 partially_grouped_rel,
7531 dNumPartialGroups));
7535 partially_grouped_rel,
7539 dNumPartialGroups));
7544 if (can_sort && cheapest_partial_path != NULL)
7551 Path *path_save = path;
7552 List *pathkey_orderings =
NIL;
7560 foreach(lc2, pathkey_orderings)
7569 partially_grouped_rel,
7571 cheapest_partial_path,
7581 partially_grouped_rel,
7589 dNumPartialPartialGroups));
7593 partially_grouped_rel,
7597 dNumPartialPartialGroups));
7605 if (can_hash && cheapest_total_path != NULL)
7612 partially_grouped_rel,
7613 cheapest_total_path,
7617 root->processed_groupClause,
7620 dNumPartialGroups));
7626 if (can_hash && cheapest_partial_path != NULL)
7630 partially_grouped_rel,
7631 cheapest_partial_path,
7635 root->processed_groupClause,
7638 dNumPartialPartialGroups));
7648 foreach(lc, eager_agg_rel->
pathlist)
7653 Assert(path->param_info == NULL);
7656 partially_grouped_rel,
7660 add_path(partially_grouped_rel, path);
7674 Assert(path->param_info == NULL);
7677 partially_grouped_rel,
7690 if (partially_grouped_rel->fdwroutine &&
7691 partially_grouped_rel->fdwroutine->GetForeignUpperPaths)
7693 FdwRoutine *fdwroutine = partially_grouped_rel->fdwroutine;
7697 input_rel, partially_grouped_rel,
7701 return partially_grouped_rel;
7712 Path *cheapest_path,
List *pathkeys,
double limit_tuples)
7729 if (path != cheapest_path &&
7773 Path *cheapest_partial_path;
7774 List *groupby_pathkeys;
7782 root->num_groupby_pathkeys);
7784 groupby_pathkeys =
root->group_pathkeys;
7797 double total_groups;
7812 if (path != cheapest_partial_path &&
7865 else if (
parse->groupingSets)
7870 else if (
root->hasNonPartialAggs ||
root->hasNonSerialAggs)
7897 List *scanjoin_targets,
7898 List *scanjoin_targets_contain_srfs,
7899 bool scanjoin_target_parallel_safe,
7941 if (!scanjoin_target_parallel_safe)
7983 subpath->pathtarget->sortgrouprefs =
7984 scanjoin_target->sortgrouprefs;
8004 subpath->pathtarget->sortgrouprefs =
8005 scanjoin_target->sortgrouprefs;
8022 if (
root->parse->hasTargetSRFs)
8025 scanjoin_targets_contain_srfs);
8047 if (rel_is_partitioned)
8059 List *child_scanjoin_targets =
NIL;
8061 Assert(child_rel != NULL);
8070 foreach(lc, scanjoin_targets)
8078 nappinfos, appinfos);
8079 child_scanjoin_targets =
lappend(child_scanjoin_targets,
8086 child_scanjoin_targets,
8087 scanjoin_targets_contain_srfs,
8088 scanjoin_target_parallel_safe,
8093 live_children =
lappend(live_children, child_rel);
8145 List *grouped_live_children =
NIL;
8146 List *partially_grouped_live_children =
NIL;
8148 bool partial_grouping_valid =
true;
8153 partially_grouped_rel != NULL);
8159 RelOptInfo *child_input_rel = input_rel->part_rels[
i];
8167 Assert(child_input_rel != NULL);
8179 memcpy(&child_extra, extra,
sizeof(child_extra));
8187 nappinfos, appinfos);
8193 nappinfos, appinfos);
8197 nappinfos, appinfos);
8204 child_extra.
patype = patype;
8218 agg_costs, gd, &child_extra,
8219 &child_partially_grouped_rel);
8221 if (child_partially_grouped_rel)
8223 partially_grouped_live_children =
8224 lappend(partially_grouped_live_children,
8225 child_partially_grouped_rel);
8228 partial_grouping_valid =
false;
8233 grouped_live_children =
lappend(grouped_live_children,
8249 if (partially_grouped_rel && partial_grouping_valid)
8251 Assert(partially_grouped_live_children !=
NIL);
8254 partially_grouped_live_children);
8282 Assert(input_rel->part_scheme);
8285 if (!input_rel->partexprs)
8288 partnatts = input_rel->part_scheme->partnatts;
8290 for (cnt = 0; cnt < partnatts; cnt++)
8292 List *partexprs = input_rel->partexprs[cnt];
8296 foreach(lc, partexprs)
8300 Oid partcoll = input_rel->part_scheme->partcollation[cnt];
8302 foreach(lg, groupexprs)
8315 if (
equal(groupexpr, partexpr))
8322 partcoll != groupcoll)
8369 foreach(lt, targetlist)
8392 lg =
lnext(grouplist, lg);
8393 ct =
lnext(op->colTypes, ct);
8494 unique_rel->
reltarget = child_unique_target;
8530 bool made_tle =
false;
8539 newtlist =
lappend(newtlist, tle);
8564 elog(
ERROR,
"could not find equality operator for ordering operator %u",
8569 sortcl->
eqop = eqop;
8573 sortcl->hashable =
false;
8574 sortList =
lappend(sortList, sortcl);
8599 elog(
ERROR,
"could not find ordering operator for equality operator %u",
8616 elog(
ERROR,
"could not find compatible hash operator for operator %u",
8621 groupcl->
eqop = eq_oper;
8622 groupcl->
sortop = sortop;
8625 groupcl->hashable =
true;
8626 groupClause =
lappend(groupClause, groupcl);
8643 if (sortPathkeys ==
NIL && groupClause ==
NIL)
8655 sjinfo, unique_rel);
8659 sjinfo, unique_rel);
8686 List *sortPathkeys,
List *groupClause,
8694 cheapest_input_path->
rows,
8722 if (input_path->param_info &&
8723 input_path != cheapest_input_path)
8735 if (!is_sorted && input_path != cheapest_input_path &&
8787 cheapest_input_path,
8793 cheapest_input_path->pathtarget,
8811 List *sortPathkeys,
List *groupClause,
8815 Path *cheapest_partial_path;
8831 memcpy(partial_unique_rel, input_rel,
sizeof(
RelOptInfo));
8846 cheapest_partial_path->
rows,
8877 if (!is_sorted && input_path != cheapest_partial_path &&
8913 partial_unique_rel->
rows);
8929 cheapest_partial_path,
8935 cheapest_partial_path->pathtarget,
8941 partial_unique_rel->
rows);
8957 sortPathkeys, groupClause,
8958 sjinfo, unique_rel);
8981 foreach_ptr(
char, subplan_name, glob->subplanNames)
8983 if (strcmp(subplan_name,
name) == 0)
8995 glob->subplanNames =
lappend(glob->subplanNames, chosen_name);
9005 for (n = 1;
true; ++n)
9010 foreach_ptr(
char, subplan_name, glob->subplanNames)
9012 if (strcmp(subplan_name, proposed_name) == 0)
9021 glob->subplanNames =
lappend(glob->subplanNames, proposed_name);
9022 return proposed_name;
9025 pfree(proposed_name);
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
int compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages, int max_workers)
void generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows)
void add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, List *live_childrels)
AppendRelInfo ** find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos)
Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)
List * adjust_inherited_attnums_multilevel(PlannerInfo *root, List *attnums, Index child_relid, Index top_parent_relid)
Node * adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, RelOptInfo *childrel, RelOptInfo *parentrel)
void pprint(const void *obj)
void pgstat_report_plan_id(int64 plan_id, bool force)
BipartiteMatchState * BipartiteMatch(int u_size, int v_size, short **adjacency)
void BipartiteMatchFree(BipartiteMatchState *state)
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_make_singleton(int x)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_del_member(Bitmapset *a, int x)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
void bms_free(Bitmapset *a)
int bms_num_members(const Bitmapset *a)
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_list(const Bitmapset *a, const List *b)
#define MemSet(start, val, len)
#define OidIsValid(objectId)
bool contain_agg_clause(Node *clause)
Node * estimate_expression_value(PlannerInfo *root, Node *node)
WindowFuncLists * find_window_functions(Node *clause, Index maxWinRef)
Node * eval_const_expressions(PlannerInfo *root, Node *node)
void convert_saop_to_hashed_saop(Node *node)
char max_parallel_hazard(Query *parse)
bool is_parallel_safe(PlannerInfo *root, Node *node)
bool contain_subplans(Node *clause)
bool contain_volatile_functions(Node *clause)
bool enable_partitionwise_aggregate
int max_parallel_workers_per_gather
double parallel_setup_cost
double parallel_tuple_cost
void cost_sort(Path *path, PlannerInfo *root, List *pathkeys, int input_disabled_nodes, Cost input_cost, double tuples, int width, Cost comparison_cost, int sort_mem, double limit_tuples)
double compute_gather_rows(Path *path)
void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root)
PathTarget * set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target)
void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root)
bool enable_presorted_aggregate
int32 clamp_width_est(int64 tuple_width)
bool enable_incremental_sort
Plan * materialize_finished_plan(Plan *subplan)
Plan * create_plan(PlannerInfo *root, Path *best_path)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
bool ExecSupportsBackwardScan(Plan *node)
bool ExecCheckOneRelPerms(RTEPermissionInfo *perminfo)
#define palloc_array(type, count)
#define palloc0_object(type)
#define OidFunctionCall1(functionId, arg1)
FdwRoutine * GetFdwRoutineByRelId(Oid relid)
int max_parallel_maintenance_workers
Assert(PointerIsAligned(start, uint64))
#define IsParallelWorker()
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
if(TABLE==NULL||TABLE_index==NULL)
double jit_optimize_above_cost
double jit_inline_above_cost
Bitmapset * DiscreteKnapsack(int max_weight, int num_items, int *item_weights, double *item_values)
List * lappend(List *list, void *datum)
List * list_difference_int(const List *list1, const List *list2)
List * list_concat_unique_ptr(List *list1, const List *list2)
List * list_concat(List *list1, const List *list2)
List * list_copy(const List *oldlist)
List * lappend_int(List *list, int datum)
List * lcons(void *datum, List *list)
List * list_delete_int(List *list, int datum)
List * list_delete_last(List *list)
bool list_member_ptr(const List *list, const void *datum)
void list_free(List *list)
bool list_member_int(const List *list, int datum)
List * list_copy_head(const List *oldlist, int len)
List * list_concat_unique(List *list1, const List *list2)
char * get_rel_name(Oid relid)
bool get_compatible_hash_operators(Oid opno, Oid *lhs_opno, Oid *rhs_opno)
RegProcedure get_func_support(Oid funcid)
Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse)
Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
int32 get_typavgwidth(Oid typid, int32 typmod)
Datum subpath(PG_FUNCTION_ARGS)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Expr * make_opclause(Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
List * make_ands_implicit(Expr *clause)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
MemoryContext GetMemoryChunkContext(void *pointer)
Oid exprType(const Node *expr)
Oid exprCollation(const Node *expr)
bool expression_returns_set(Node *clause)
void fix_opfuncids(Node *node)
size_t get_hash_memory_limit(void)
#define DO_AGGSPLIT_SKIPFINAL(as)
#define IsA(nodeptr, _type_)
#define IS_OUTER_JOIN(jointype)
#define DO_AGGSPLIT_SERIALIZE(as)
@ AGGSPLIT_FINAL_DESERIAL
@ AGGSPLIT_INITIAL_SERIAL
#define castNode(_type_, nodeptr)
#define PVC_RECURSE_AGGREGATES
#define PVC_RECURSE_WINDOWFUNCS
#define PVC_INCLUDE_WINDOWFUNCS
#define PVC_INCLUDE_PLACEHOLDERS
#define PVC_INCLUDE_AGGREGATES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
int assign_special_exec_param(PlannerInfo *root)
List * expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit)
Index assignSortGroupRef(TargetEntry *tle, List *tlist)
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
RTEPermissionInfo * addRTEPermissionInfo(List **rteperminfos, RangeTblEntry *rte)
#define CURSOR_OPT_SCROLL
#define CURSOR_OPT_FAST_PLAN
#define CURSOR_OPT_PARALLEL_OK
void CheckSelectLocking(Query *qry, LockClauseStrength strength)
const char * LCS_asString(LockClauseStrength strength)
#define rt_fetch(rangetable_index, rangetable)
void DestroyPartitionDirectory(PartitionDirectory pdir)
List * append_pathkeys(List *target, List *source)
bool pathkeys_count_contained_in(List *keys1, List *keys2, int *n_common)
List * make_pathkeys_for_sortclauses(PlannerInfo *root, List *sortclauses, List *tlist)
List * make_pathkeys_for_sortclauses_extended(PlannerInfo *root, List **sortclauses, List *tlist, bool remove_redundant, bool remove_group_rtindex, bool *sortable, bool set_ec_sortref)
bool pathkeys_contained_in(List *keys1, List *keys2)
PathKeysComparison compare_pathkeys(List *keys1, List *keys2)
List * get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
ModifyTablePath * create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, CmdType operation, bool canSetTag, Index nominalRelation, Index rootRelation, List *resultRelations, List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *rowMarks, OnConflictExpr *onconflict, List *mergeActionLists, List *mergeJoinConditions, int epqParam)
IndexPath * create_index_path(PlannerInfo *root, IndexOptInfo *index, List *indexclauses, List *indexorderbys, List *indexorderbycols, List *pathkeys, ScanDirection indexscandir, bool indexonly, Relids required_outer, double loop_count, bool partial_path)
ProjectSetPath * create_set_projection_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target)
ProjectionPath * create_projection_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target)
WindowAggPath * create_windowagg_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, List *windowFuncs, List *runCondition, WindowClause *winclause, List *qual, bool topwindow)
LockRowsPath * create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *rowMarks, int epqParam)
Path * apply_projection_to_path(PlannerInfo *root, RelOptInfo *rel, Path *path, 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)
LimitPath * create_limit_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, Node *limitOffset, Node *limitCount, LimitOption limitOption, int64 offset_est, int64 count_est)
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)
int compare_fractional_path_costs(Path *path1, Path *path2, double fraction)
IncrementalSortPath * create_incremental_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *pathkeys, int presorted_keys, double limit_tuples)
GroupingSetsPath * create_groupingsets_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *having_qual, AggStrategy aggstrategy, List *rollups, const AggClauseCosts *agg_costs)
SortPath * create_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *pathkeys, double limit_tuples)
GroupPath * create_group_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *groupClause, List *qual, double numGroups)
void add_path(RelOptInfo *parent_rel, Path *new_path)
UniquePath * create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, int numCols, double numGroups)
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)
GroupResultPath * create_group_result_path(PlannerInfo *root, RelOptInfo *rel, PathTarget *target, List *havingqual)
PartitionwiseAggregateType
@ PARTITIONWISE_AGGREGATE_PARTIAL
@ PARTITIONWISE_AGGREGATE_FULL
@ PARTITIONWISE_AGGREGATE_NONE
#define IS_SIMPLE_REL(rel)
#define GROUPING_CAN_USE_HASH
#define get_pathtarget_sortgroupref(target, colno)
#define IS_PARTITIONED_REL(rel)
#define GROUPING_CAN_USE_SORT
#define GROUPING_CAN_PARTIAL_AGG
@ UPPERREL_PARTIAL_GROUP_AGG
@ UPPERREL_PARTIAL_DISTINCT
#define IS_OTHER_REL(rel)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
#define forboth(cell1, list1, cell2, list2)
#define foreach_current_index(var_or_cell)
#define foreach_ptr(type, var, lst)
#define for_each_cell(cell, lst, initcell)
#define for_each_from(cell, lst, N)
static void * list_nth(const List *list, int n)
#define foreach_node(type, var, lst)
static ListCell * list_head(const List *l)
#define list_nth_node(type, list, n)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make1_int(x1)
static int list_cell_number(const List *l, const ListCell *c)
#define llast_node(type, l)
void preprocess_minmax_aggregates(PlannerInfo *root)
void estimate_rel_size(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
int32 get_relation_data_width(Oid relid, int32 *attr_widths)
RelOptInfo * query_planner(PlannerInfo *root, query_pathkeys_callback qp_callback, void *qp_extra)
#define DEFAULT_CURSOR_TUPLE_FRACTION
#define EXPRKIND_TABLEFUNC_LATERAL
static RelOptInfo * create_final_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *distinct_rel)
static List * postprocess_setop_tlist(List *new_tlist, List *orig_tlist)
static PathTarget * make_partial_grouping_target(PlannerInfo *root, PathTarget *grouping_target, Node *havingQual)
Expr * expression_planner_with_deps(Expr *expr, List **relationOids, List **invalItems)
static void gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel)
static void preprocess_rowmarks(PlannerInfo *root)
#define EXPRKIND_TABLESAMPLE
static void add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel, RelOptInfo *partially_grouped_rel, const AggClauseCosts *agg_costs, grouping_sets_data *gd, GroupPathExtraData *extra)
PlannedStmt * planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
static void create_degenerate_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel)
char * choose_plan_name(PlannerGlobal *glob, const char *name, bool always_number)
#define EXPRKIND_GROUPEXPR
planner_hook_type planner_hook
double cursor_tuple_fraction
static bool is_degenerate_grouping(PlannerInfo *root)
planner_shutdown_hook_type planner_shutdown_hook
bool plan_cluster_use_sort(Oid tableOid, Oid indexOid)
static void preprocess_qual_conditions(PlannerInfo *root, Node *jtnode)
int plan_create_index_workers(Oid tableOid, Oid indexOid)
#define EXPRKIND_RTFUNC_LATERAL
#define EXPRKIND_VALUES_LATERAL
static void create_ordinary_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel, const AggClauseCosts *agg_costs, grouping_sets_data *gd, GroupPathExtraData *extra, RelOptInfo **partially_grouped_rel_p)
RelOptInfo * create_unique_paths(PlannerInfo *root, RelOptInfo *rel, SpecialJoinInfo *sjinfo)
PlannerInfo * subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, PlannerInfo *parent_root, bool hasRecursion, double tuple_fraction, SetOperationStmt *setops)
static bool can_partial_agg(PlannerInfo *root)
static double preprocess_limit(PlannerInfo *root, double tuple_fraction, int64 *offset_est, int64 *count_est)
Path * get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction)
Expr * preprocess_phv_expression(PlannerInfo *root, Expr *expr)
static List * get_useful_pathkeys_for_distinct(PlannerInfo *root, List *needed_pathkeys, List *path_pathkeys)
planner_setup_hook_type planner_setup_hook
bool parallel_leader_participation
static PathTarget * make_window_input_target(PlannerInfo *root, PathTarget *final_target, List *activeWindows)
static void apply_scanjoin_target_to_paths(PlannerInfo *root, RelOptInfo *rel, List *scanjoin_targets, List *scanjoin_targets_contain_srfs, bool scanjoin_target_parallel_safe, bool tlist_same_exprs)
static RelOptInfo * create_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target)
static void optimize_window_clauses(PlannerInfo *root, WindowFuncLists *wflists)
RowMarkType select_rowmark_type(RangeTblEntry *rte, LockClauseStrength strength)
static void adjust_paths_for_srfs(PlannerInfo *root, RelOptInfo *rel, List *targets, List *targets_contain_srfs)
static void create_partial_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *final_distinct_rel, PathTarget *target)
static List * preprocess_groupclause(PlannerInfo *root, List *force)
static Node * preprocess_expression(PlannerInfo *root, Node *expr, int kind)
static Path * make_ordered_path(PlannerInfo *root, RelOptInfo *rel, Path *path, Path *cheapest_path, List *pathkeys, double limit_tuples)
static bool has_volatile_pathkey(List *keys)
static RelOptInfo * create_partial_grouping_paths(PlannerInfo *root, RelOptInfo *grouped_rel, RelOptInfo *input_rel, grouping_sets_data *gd, GroupPathExtraData *extra, bool force_rel_creation)
static void name_active_windows(List *activeWindows)
static void create_final_unique_paths(PlannerInfo *root, RelOptInfo *input_rel, List *sortPathkeys, List *groupClause, SpecialJoinInfo *sjinfo, RelOptInfo *unique_rel)
static PathTarget * make_sort_input_target(PlannerInfo *root, PathTarget *final_target, bool *have_postponed_srfs)
static void create_one_window_path(PlannerInfo *root, RelOptInfo *window_rel, Path *path, PathTarget *input_target, PathTarget *output_target, WindowFuncLists *wflists, List *activeWindows)
bool enable_distinct_reordering
void mark_partial_aggref(Aggref *agg, AggSplit aggsplit)
static grouping_sets_data * preprocess_grouping_sets(PlannerInfo *root)
static List * remap_to_groupclause_idx(List *groupClause, List *gsets, int *tleref_to_colnum_map)
static void adjust_group_pathkeys_for_groupagg(PlannerInfo *root)
static PathTarget * make_group_input_target(PlannerInfo *root, PathTarget *final_target)
static List * reorder_grouping_sets(List *groupingSets, List *sortclause)
static int common_prefix_cmp(const void *a, const void *b)
static void grouping_planner(PlannerInfo *root, double tuple_fraction, SetOperationStmt *setops)
static RelOptInfo * make_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, Node *havingQual)
static List * generate_setop_child_grouplist(SetOperationStmt *op, List *targetlist)
PlannedStmt * standard_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
static List * select_active_windows(PlannerInfo *root, WindowFuncLists *wflists)
Expr * expression_planner(Expr *expr)
static void create_partial_unique_paths(PlannerInfo *root, RelOptInfo *input_rel, List *sortPathkeys, List *groupClause, SpecialJoinInfo *sjinfo, RelOptInfo *unique_rel)
bool limit_needed(Query *parse)
create_upper_paths_hook_type create_upper_paths_hook
#define EXPRKIND_TABLEFUNC
static void consider_groupingsets_paths(PlannerInfo *root, RelOptInfo *grouped_rel, Path *path, bool is_sorted, bool can_hash, grouping_sets_data *gd, const AggClauseCosts *agg_costs, double dNumGroups)
static List * make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc, List *tlist)
static RelOptInfo * create_ordered_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, double limit_tuples)
static double get_number_of_groups(PlannerInfo *root, double path_rows, grouping_sets_data *gd, List *target_list)
static List * extract_rollup_sets(List *groupingSets)
static RelOptInfo * create_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, grouping_sets_data *gd)
static void create_partitionwise_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel, RelOptInfo *partially_grouped_rel, const AggClauseCosts *agg_costs, grouping_sets_data *gd, PartitionwiseAggregateType patype, GroupPathExtraData *extra)
#define EXPRKIND_ARBITER_ELEM
static bool group_by_has_partkey(RelOptInfo *input_rel, List *targetList, List *groupClause)
static void standard_qp_callback(PlannerInfo *root, void *extra)
static RelOptInfo * create_window_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *input_target, PathTarget *output_target, bool output_target_parallel_safe, WindowFuncLists *wflists, List *activeWindows)
void(* planner_setup_hook_type)(PlannerGlobal *glob, Query *parse, const char *query_string, double *tuple_fraction, ExplainState *es)
PlannedStmt *(* planner_hook_type)(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
void(* create_upper_paths_hook_type)(PlannerInfo *root, UpperRelationKind stage, RelOptInfo *input_rel, RelOptInfo *output_rel, void *extra)
void(* planner_shutdown_hook_type)(PlannerGlobal *glob, Query *parse, const char *query_string, PlannedStmt *pstmt)
@ ROW_MARK_NOKEYEXCLUSIVE
#define qsort(a, b, c, d)
static Datum Int64GetDatum(int64 X)
static int64 DatumGetInt64(Datum X)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
void get_agg_clause_costs(PlannerInfo *root, AggSplit aggsplit, AggClauseCosts *costs)
void preprocess_aggrefs(PlannerInfo *root, Node *clause)
void preprocess_function_rtes(PlannerInfo *root)
void flatten_simple_union_all(PlannerInfo *root)
void transform_MERGE_to_join(Query *parse)
void remove_useless_result_rtes(PlannerInfo *root)
void pull_up_sublinks(PlannerInfo *root)
void replace_empty_jointree(Query *parse)
void pull_up_subqueries(PlannerInfo *root)
Relids get_relids_in_jointree(Node *jtnode, bool include_outer_joins, bool include_inner_joins)
Query * preprocess_relation_rtes(PlannerInfo *root)
void reduce_outer_joins(PlannerInfo *root)
Expr * canonicalize_qual(Expr *qual, bool is_check)
void preprocess_targetlist(PlannerInfo *root)
RelOptInfo * plan_set_operations(PlannerInfo *root)
char * psprintf(const char *fmt,...)
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
List * RelationGetIndexPredicate(Relation relation)
List * RelationGetIndexExpressions(Relation relation)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
void setup_simple_rel_arrays(PlannerInfo *root)
RelOptInfo * fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids)
RelOptInfo * build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
Node * remove_nulling_relids(Node *node, const Bitmapset *removable_relids, const Bitmapset *except_relids)
double estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, List **pgset, EstimationInfo *estinfo)
double estimate_hashagg_tablesize(PlannerInfo *root, Path *path, const AggClauseCosts *agg_costs, double dNumGroups)
Plan * set_plan_references(PlannerInfo *root, Plan *plan)
bool extract_query_dependencies_walker(Node *node, PlannerInfo *context)
void check_stack_depth(void)
GetForeignRowMarkType_function GetForeignRowMarkType
GetForeignUpperPaths_function GetForeignUpperPaths
LockClauseStrength strength
LockWaitPolicy waitPolicy
Bitmapset * rewindPlanIDs
PlannedStmtOrigin planOrigin
Bitmapset * unprunableRelids
Bitmapset * prunableRelids
Bitmapset * rewindPlanIDs
struct TableSampleClause * tablesample
struct PathTarget * reltarget
List * cheapest_parameterized_paths
struct Path * cheapest_startup_path
struct Path * cheapest_total_path
List * unique_groupclause
struct RelOptInfo * grouped_rel
struct RelOptInfo * unique_rel
LockClauseStrength strength
LockWaitPolicy waitPolicy
WindowClause * window_clause
int * tleref_to_colnum_map
Bitmapset * unhashable_refs
Bitmapset * unsortable_refs
grouping_sets_data * gset_data
Node * SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual)
void SS_process_ctes(PlannerInfo *root)
void SS_identify_outer_params(PlannerInfo *root)
Node * SS_replace_correlation_vars(PlannerInfo *root, Node *expr)
void SS_finalize_plan(PlannerInfo *root, Plan *plan)
void SS_compute_initplan_cost(List *init_plans, Cost *initplan_cost_p, bool *unsafe_initplans_p)
void SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
void split_pathtarget_at_srfs_grouping(PlannerInfo *root, PathTarget *target, PathTarget *input_target, List **targets, List **targets_contain_srfs)
TargetEntry * tlist_member(Expr *node, List *targetlist)
bool tlist_same_exprs(List *tlist1, List *tlist2)
SortGroupClause * get_sortgroupref_clause_noerr(Index sortref, List *clauses)
SortGroupClause * get_sortgroupref_clause(Index sortref, List *clauses)
bool grouping_is_sortable(List *groupClause)
List * make_tlist_from_pathtarget(PathTarget *target)
PathTarget * copy_pathtarget(PathTarget *src)
void add_new_columns_to_pathtarget(PathTarget *target, List *exprs)
PathTarget * create_empty_pathtarget(void)
List * get_sortgrouplist_exprs(List *sgClauses, List *targetList)
void split_pathtarget_at_srfs(PlannerInfo *root, PathTarget *target, PathTarget *input_target, List **targets, List **targets_contain_srfs)
bool grouping_is_hashable(List *groupClause)
void add_column_to_pathtarget(PathTarget *target, Expr *expr, Index sortgroupref)
#define create_pathtarget(root, tlist)
Node * flatten_group_exprs(PlannerInfo *root, Query *query, Node *node)
Relids pull_varnos(PlannerInfo *root, Node *node)
List * pull_var_clause(Node *node, int flags)
Node * flatten_join_alias_vars(PlannerInfo *root, Query *query, Node *node)