38 #ifdef OPTIMIZER_DEBUG
77 #define EXPRKIND_QUAL 0
78 #define EXPRKIND_TARGET 1
79 #define EXPRKIND_RTFUNC 2
80 #define EXPRKIND_RTFUNC_LATERAL 3
81 #define EXPRKIND_VALUES 4
82 #define EXPRKIND_VALUES_LATERAL 5
83 #define EXPRKIND_LIMIT 6
84 #define EXPRKIND_APPINFO 7
85 #define EXPRKIND_PHV 8
86 #define EXPRKIND_TABLESAMPLE 9
87 #define EXPRKIND_ARBITER_ELEM 10
88 #define EXPRKIND_TABLEFUNC 11
89 #define EXPRKIND_TABLEFUNC_LATERAL 12
130 int *tleref_to_colnum_map);
133 double tuple_fraction,
134 int64 *offset_est, int64 *count_est);
147 bool target_parallel_safe,
154 PathTarget *target,
bool target_parallel_safe,
175 bool output_target_parallel_safe,
177 List *activeWindows);
184 List *activeWindows);
198 bool target_parallel_safe,
199 double limit_tuples);
211 List *activeWindows);
216 bool *have_postponed_srfs);
218 List *targets,
List *targets_contain_srfs);
231 bool force_rel_creation);
236 List *scanjoin_targets,
237 List *scanjoin_targets_contain_srfs,
238 bool scanjoin_target_parallel_safe,
274 result = (*planner_hook) (
parse, query_string, cursorOptions, boundParams);
286 double tuple_fraction;
302 glob->boundParams = boundParams;
304 glob->subroots =
NIL;
344 !
parse->hasModifyingCTE &&
396 if (tuple_fraction >= 1.0)
397 tuple_fraction = 0.0;
398 else if (tuple_fraction <= 0.0)
399 tuple_fraction = 1
e-10;
404 tuple_fraction = 0.0;
409 false, tuple_fraction);
446 bool unsafe_initplans;
484 &initplan_cost, &unsafe_initplans);
491 top_plan = &gather->
plan;
582 if (glob->partition_directory != NULL)
620 bool hasRecursion,
double tuple_fraction)
623 List *newWithCheckOptions;
635 root->parent_root = parent_root;
652 memset(root->upper_rels, 0,
sizeof(root->upper_rels));
653 memset(root->upper_targets, 0,
sizeof(root->upper_targets));
658 root->grouping_map = NULL;
703 if (
parse->hasSubLinks)
726 if (
parse->setOperations)
741 hasOuterJoins =
false;
742 hasResultRTEs =
false;
743 foreach(l,
parse->rtable)
769 hasOuterJoins =
true;
772 hasResultRTEs =
true;
797 if (
parse->resultRelation)
830 if (
parse->hasTargetSRFs)
833 newWithCheckOptions =
NIL;
834 foreach(l,
parse->withCheckOptions)
840 if (wco->
qual != NULL)
841 newWithCheckOptions =
lappend(newWithCheckOptions, wco);
843 parse->withCheckOptions = newWithCheckOptions;
854 foreach(l,
parse->windowClause)
864 (
Node *) wc->runCondition,
873 if (
parse->onConflict)
875 parse->onConflict->arbiterElems = (
List *)
877 (
Node *)
parse->onConflict->arbiterElems,
879 parse->onConflict->arbiterWhere =
881 parse->onConflict->arbiterWhere,
883 parse->onConflict->onConflictSet = (
List *)
885 (
Node *)
parse->onConflict->onConflictSet,
887 parse->onConflict->onConflictWhere =
889 parse->onConflict->onConflictWhere,
894 foreach(l,
parse->mergeActionList)
913 foreach(l,
parse->rtable)
990 foreach(l,
parse->rtable)
1034 if ((
parse->groupClause &&
parse->groupingSets) ||
1040 newHaving =
lappend(newHaving, havingclause);
1042 else if (
parse->groupClause && !
parse->groupingSets)
1054 newHaving =
lappend(newHaving, havingclause);
1073 if (hasResultRTEs || hasOuterJoins)
1168 #ifdef OPTIMIZER_DEBUG
1169 printf(
"After canonicalize_qual()\n");
1185 if (root->
parse->hasSubLinks)
1243 elog(
ERROR,
"unrecognized node type: %d",
1291 int64 offset_est = 0;
1292 int64 count_est = 0;
1293 double limit_tuples = -1.0;
1294 bool have_postponed_srfs =
false;
1296 List *final_targets;
1297 List *final_targets_contain_srfs;
1298 bool final_target_parallel_safe;
1308 &offset_est, &count_est);
1314 if (count_est > 0 && offset_est >= 0)
1315 limit_tuples = (double) count_est + (
double) offset_est;
1321 if (
parse->setOperations)
1331 if (
parse->sortClause)
1360 final_target_parallel_safe =
1365 final_targets = final_targets_contain_srfs =
NIL;
1371 if (
parse->rowMarks)
1373 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1376 errmsg(
"%s is not allowed with UNION/INTERSECT/EXCEPT",
1378 parse->rowMarks)->strength))));
1392 List *sort_input_targets;
1393 List *sort_input_targets_contain_srfs;
1394 bool sort_input_target_parallel_safe;
1396 List *grouping_targets;
1397 List *grouping_targets_contain_srfs;
1398 bool grouping_target_parallel_safe;
1400 List *scanjoin_targets;
1401 List *scanjoin_targets_contain_srfs;
1402 bool scanjoin_target_parallel_safe;
1403 bool scanjoin_target_same_exprs;
1414 if (
parse->groupingSets)
1418 else if (
parse->groupClause)
1454 if (
parse->hasWindowFuncs)
1470 parse->hasWindowFuncs =
false;
1488 if (
parse->groupClause ||
1489 parse->groupingSets ||
1490 parse->distinctClause ||
1492 parse->hasWindowFuncs ||
1493 parse->hasTargetSRFs ||
1522 final_target_parallel_safe =
1530 if (
parse->sortClause)
1534 &have_postponed_srfs);
1535 sort_input_target_parallel_safe =
1540 sort_input_target = final_target;
1541 sort_input_target_parallel_safe = final_target_parallel_safe;
1554 grouping_target_parallel_safe =
1559 grouping_target = sort_input_target;
1560 grouping_target_parallel_safe = sort_input_target_parallel_safe;
1568 have_grouping = (
parse->groupClause ||
parse->groupingSets ||
1573 scanjoin_target_parallel_safe =
1578 scanjoin_target = grouping_target;
1579 scanjoin_target_parallel_safe = grouping_target_parallel_safe;
1588 if (
parse->hasTargetSRFs)
1593 &final_targets_contain_srfs);
1598 &sort_input_targets,
1599 &sort_input_targets_contain_srfs);
1605 &grouping_targets_contain_srfs);
1611 &scanjoin_targets_contain_srfs);
1618 final_targets = final_targets_contain_srfs =
NIL;
1619 sort_input_targets = sort_input_targets_contain_srfs =
NIL;
1620 grouping_targets = grouping_targets_contain_srfs =
NIL;
1621 scanjoin_targets =
list_make1(scanjoin_target);
1622 scanjoin_targets_contain_srfs =
NIL;
1626 scanjoin_target_same_exprs =
list_length(scanjoin_targets) == 1
1629 scanjoin_targets_contain_srfs,
1630 scanjoin_target_parallel_safe,
1631 scanjoin_target_same_exprs);
1657 grouping_target_parallel_safe,
1660 if (
parse->hasTargetSRFs)
1663 grouping_targets_contain_srfs);
1676 sort_input_target_parallel_safe,
1680 if (
parse->hasTargetSRFs)
1683 sort_input_targets_contain_srfs);
1690 if (
parse->distinctClause)
1705 if (
parse->sortClause)
1710 final_target_parallel_safe,
1711 have_postponed_srfs ? -1.0 :
1714 if (
parse->hasTargetSRFs)
1717 final_targets_contain_srfs);
1743 final_rel->fdwroutine = current_rel->fdwroutine;
1760 if (
parse->rowMarks)
1776 offset_est, count_est);
1786 List *updateColnosLists =
NIL;
1787 List *withCheckOptionLists =
NIL;
1796 parse->resultRelation);
1797 int resultRelation = -1;
1800 rootRelation =
parse->resultRelation;
1804 resultRelation)) >= 0)
1824 if (this_result_rel != top_result_rel)
1828 this_result_rel->
relid,
1829 top_result_rel->
relid);
1830 updateColnosLists =
lappend(updateColnosLists,
1833 if (
parse->withCheckOptions)
1835 List *withCheckOptions =
parse->withCheckOptions;
1837 if (this_result_rel != top_result_rel)
1838 withCheckOptions = (
List *)
1840 (
Node *) withCheckOptions,
1843 withCheckOptionLists =
lappend(withCheckOptionLists,
1846 if (
parse->returningList)
1848 List *returningList =
parse->returningList;
1850 if (this_result_rel != top_result_rel)
1851 returningList = (
List *)
1853 (
Node *) returningList,
1856 returningLists =
lappend(returningLists,
1859 if (
parse->mergeActionList)
1868 foreach(l,
parse->mergeActionList)
1878 leaf_action->targetList = (
List *)
1884 leaf_action->updateColnos =
1887 this_result_rel->
relid,
1888 top_result_rel->
relid);
1889 mergeActionList =
lappend(mergeActionList,
1893 mergeActionLists =
lappend(mergeActionLists,
1898 if (resultRelations ==
NIL)
1914 if (
parse->withCheckOptions)
1916 if (
parse->returningList)
1918 if (
parse->mergeActionList)
1929 if (
parse->withCheckOptions)
1931 if (
parse->returningList)
1933 if (
parse->mergeActionList)
1942 if (
parse->rowMarks)
1952 parse->resultRelation,
1957 withCheckOptionLists,
1994 if (final_rel->fdwroutine &&
1995 final_rel->fdwroutine->GetForeignUpperPaths)
1996 final_rel->fdwroutine->GetForeignUpperPaths(root,
UPPERREL_FINAL,
1997 current_rel, final_rel,
2003 current_rel, final_rel, &extra);
2036 if (
parse->groupClause)
2040 foreach(lc,
parse->groupClause)
2070 foreach(lc,
parse->groupingSets)
2091 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2092 errmsg(
"could not implement GROUP BY"),
2093 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
2096 sortable_sets =
lappend(sortable_sets, gset);
2107 foreach(lc_set, sets)
2198 int *tleref_to_colnum_map)
2204 foreach(lc, groupClause)
2217 foreach(lc2, gs->
set)
2222 result =
lappend(result, set);
2241 if (
parse->rowMarks)
2250 parse->rowMarks)->strength);
2270 if (
parse->resultRelation)
2277 foreach(l,
parse->rowMarks)
2310 prowmarks =
lappend(prowmarks, newrc);
2317 foreach(l,
parse->rtable)
2335 prowmarks =
lappend(prowmarks, newrc);
2352 else if (rte->
relkind == RELKIND_FOREIGN_TABLE)
2388 elog(
ERROR,
"unrecognized LockClauseStrength %d", (
int) strength);
2412 int64 *offset_est, int64 *count_est)
2416 double limit_fraction;
2425 if (
parse->limitCount)
2430 if (((
Const *) est)->constisnull)
2438 if (*count_est <= 0)
2448 if (
parse->limitOffset)
2453 if (((
Const *) est)->constisnull)
2461 if (*offset_est < 0)
2471 if (*count_est != 0)
2478 if (*count_est < 0 || *offset_est < 0)
2481 limit_fraction = 0.10;
2486 limit_fraction = (double) *count_est + (
double) *offset_est;
2496 if (tuple_fraction >= 1.0)
2498 if (limit_fraction >= 1.0)
2501 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2508 else if (tuple_fraction > 0.0)
2510 if (limit_fraction >= 1.0)
2513 tuple_fraction = limit_fraction;
2518 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2524 tuple_fraction = limit_fraction;
2527 else if (*offset_est != 0 && tuple_fraction > 0.0)
2538 if (*offset_est < 0)
2539 limit_fraction = 0.10;
2541 limit_fraction = (double) *offset_est;
2549 if (tuple_fraction >= 1.0)
2551 if (limit_fraction >= 1.0)
2554 tuple_fraction += limit_fraction;
2559 tuple_fraction = limit_fraction;
2564 if (limit_fraction >= 1.0)
2571 tuple_fraction += limit_fraction;
2572 if (tuple_fraction >= 1.0)
2573 tuple_fraction = 0.0;
2578 return tuple_fraction;
2600 node =
parse->limitCount;
2606 if (!((
Const *) node)->constisnull)
2613 node =
parse->limitOffset;
2619 if (!((
Const *) node)->constisnull)
2668 if (
parse->groupingSets)
2711 foreach(lc,
parse->rtable)
2729 if (rte->
inh && rte->
relkind != RELKIND_PARTITIONED_TABLE)
2733 relattnos = groupbyattnos[relid];
2742 if (pkattnos == NULL)
2755 if (surplusvars == NULL)
2769 if (surplusvars != NULL)
2786 surplusvars[var->
varno]))
2787 new_groupby =
lappend(new_groupby, sgc);
2811 new_groupclause =
lappend(new_groupclause, cl);
2813 return new_groupclause;
2848 short *adjacency_buf;
2864 lc1 =
lnext(groupingSets, lc1);
2889 orig_sets =
palloc0((num_sets_raw + 1) *
sizeof(
List *));
2891 adjacency =
palloc0((num_sets_raw + 1) *
sizeof(
short *));
2892 adjacency_buf =
palloc((num_sets_raw + 1) *
sizeof(
short));
2905 foreach(lc2, candidate)
2915 for (k =
j; k <
i; ++k)
2917 if (
bms_equal(set_masks[k], candidate_set))
2932 orig_sets[dup_of] =
lappend(orig_sets[dup_of], candidate);
2941 set_masks[
i] = candidate_set;
2945 for (k =
j - 1; k > 0; --k)
2948 adjacency_buf[++n_adj] = k;
2953 adjacency_buf[0] = n_adj;
2954 adjacency[
i] =
palloc((n_adj + 1) *
sizeof(
short));
2955 memcpy(adjacency[
i], adjacency_buf, (n_adj + 1) *
sizeof(
short));
2958 adjacency[
i] = NULL;
2977 chains =
palloc0((num_sets + 1) *
sizeof(
int));
2979 for (
i = 1;
i <= num_sets; ++
i)
2981 int u =
state->pair_vu[
i];
2982 int v =
state->pair_uv[
i];
2985 chains[
i] = chains[u];
2986 else if (v > 0 && v <
i)
2987 chains[
i] = chains[v];
2989 chains[
i] = ++num_chains;
2993 results =
palloc0((num_chains + 1) *
sizeof(
List *));
2995 for (
i = 1;
i <= num_sets; ++
i)
3005 while (num_empty-- > 0)
3006 results[1] =
lcons(
NIL, results[1]);
3009 for (
i = 1;
i <= num_chains; ++
i)
3010 result =
lappend(result, results[
i]);
3021 for (
i = 1;
i <= num_sets; ++
i)
3025 pfree(adjacency_buf);
3027 for (
i = 1;
i <= num_sets; ++
i)
3054 foreach(lc, groupingSets)
3082 result =
lcons(gs, result);
3104 if (pathkey->pk_eclass->ec_has_volatile)
3163 unprocessed_aggs = NULL;
3169 if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3230 if (currpathkeys ==
NIL)
3232 currpathkeys = pathkeys;
3235 if (grouppathkeys !=
NIL)
3247 if (grouppathkeys !=
NIL)
3256 currpathkeys = pathkeys;
3283 bestaggs = aggindexes;
3284 bestpathkeys = currpathkeys;
3293 if (bestpathkeys !=
NIL)
3313 aggref->aggpresorted =
true;
3396 if (activeWindows !=
NIL)
3413 if (
parse->distinctClause)
3487 if (
parse->groupClause)
3491 if (
parse->groupingSets)
3564 else if (
parse->groupingSets)
3604 bool target_parallel_safe,
3620 target_parallel_safe,
parse->havingQual);
3679 extra.
flags = flags;
3697 &agg_costs, gd, &extra,
3698 &partially_grouped_rel);
3715 PathTarget *target,
bool target_parallel_safe,
3754 grouped_rel->fdwroutine = input_rel->fdwroutine;
3807 while (--nrows >= 0)
3902 bool force_rel_creation;
3911 partially_grouped_rel =
3917 force_rel_creation);
3921 *partially_grouped_rel_p = partially_grouped_rel;
3926 partially_grouped_rel, agg_costs,
3932 Assert(partially_grouped_rel);
3934 if (partially_grouped_rel->
pathlist)
3951 cheapest_path->
rows,
3957 partially_grouped_rel, agg_costs, gd,
3963 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3964 errmsg(
"could not implement GROUP BY"),
3965 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
3971 if (grouped_rel->fdwroutine &&
3972 grouped_rel->fdwroutine->GetForeignUpperPaths)
3974 input_rel, grouped_rel,
3980 input_rel, grouped_rel,
4025 double exclude_groups = 0.0;
4049 if (l_start != NULL &&
4053 exclude_groups = unhashed_rollup->
numGroups;
4060 dNumGroups - exclude_groups);
4067 if (hashsize > hash_mem_limit && gd->
rollups)
4096 foreach(lc, sets_data)
4105 empty_sets_data =
lappend(empty_sets_data, gs);
4120 new_rollups =
lappend(new_rollups, rollup);
4128 if (new_rollups ==
NIL)
4135 Assert(!unhashed_rollup || !empty_sets);
4137 if (unhashed_rollup)
4139 new_rollups =
lappend(new_rollups, unhashed_rollup);
4142 else if (empty_sets)
4148 rollup->
gsets = empty_sets;
4152 new_rollups =
lappend(new_rollups, rollup);
4185 double availspace = hash_mem_limit;
4201 int *k_weights =
palloc(num_rollups *
sizeof(
int));
4227 scale =
Max(availspace / (20.0 * num_rollups), 1.0);
4228 k_capacity = (int) floor(availspace /
scale);
4252 k_weights[
i] = (int)
Min(floor(sz /
scale),
4282 rollups =
lappend(rollups, rollup);
4286 rollups =
lappend(rollups, rollup);
4291 if (!rollups && hash_sets)
4294 foreach(lc, hash_sets)
4309 rollups =
lcons(rollup, rollups);
4357 bool output_target_parallel_safe,
4359 List *activeWindows)
4382 window_rel->fdwroutine = input_rel->fdwroutine;
4411 if (window_rel->fdwroutine &&
4412 window_rel->fdwroutine->GetForeignUpperPaths)
4414 input_rel, window_rel,
4420 input_rel, window_rel, NULL);
4446 List *activeWindows)
4467 window_target = input_target;
4469 foreach(l, activeWindows)
4472 List *window_pathkeys;
4512 if (
lnext(activeWindows, l))
4522 int64 tuple_width = window_target->
width;
4538 window_target = output_target;
4555 wc, topwindow ? topqual :
NIL, topwindow);
4596 distinct_rel->fdwroutine = input_rel->fdwroutine;
4607 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4608 errmsg(
"could not implement DISTINCT"),
4609 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
4615 if (distinct_rel->fdwroutine &&
4616 distinct_rel->fdwroutine->GetForeignUpperPaths)
4617 distinct_rel->fdwroutine->GetForeignUpperPaths(root,
4626 distinct_rel, NULL);
4631 return distinct_rel;
4649 List *distinctExprs;
4650 double numDistinctRows;
4651 Path *cheapest_partial_path;
4661 if (
parse->hasDistinctOn)
4666 partial_distinct_rel->
reltarget = target;
4675 partial_distinct_rel->fdwroutine = input_rel->fdwroutine;
4684 cheapest_partial_path->
rows,
4705 sorted_path = input_path;
4715 if (input_path != cheapest_partial_path &&
4726 partial_distinct_rel,
4732 partial_distinct_rel,
4791 partial_distinct_rel,
4792 cheapest_partial_path,
4793 cheapest_partial_path->pathtarget,
4806 if (partial_distinct_rel->fdwroutine &&
4807 partial_distinct_rel->fdwroutine->GetForeignUpperPaths)
4808 partial_distinct_rel->fdwroutine->GetForeignUpperPaths(root,
4811 partial_distinct_rel,
4817 input_rel, partial_distinct_rel, NULL);
4830 final_distinct_rel);
4847 double numDistinctRows;
4859 numDistinctRows = cheapest_input_path->
rows;
4866 List *distinctExprs;
4871 cheapest_input_path->
rows,
4894 List *needed_pathkeys;
4898 if (
parse->hasDistinctOn &&
4917 sorted_path = input_path;
4927 if (input_path != cheapest_input_path &&
5018 cheapest_input_path,
5019 cheapest_input_path->pathtarget,
5028 return distinct_rel;
5052 bool target_parallel_safe,
5053 double limit_tuples)
5076 ordered_rel->fdwroutine = input_rel->fdwroutine;
5086 input_path->
pathkeys, &presorted_keys);
5089 sorted_path = input_path;
5099 if (input_path != cheapest_input_path &&
5124 if (sorted_path->pathtarget != target)
5126 sorted_path, target);
5128 add_path(ordered_rel, sorted_path);
5145 Path *cheapest_partial_path;
5155 double total_groups;
5171 if (input_path != cheapest_partial_path &&
5193 total_groups = input_path->
rows *
5195 sorted_path = (
Path *)
5198 sorted_path->pathtarget,
5203 if (sorted_path->pathtarget != target)
5205 sorted_path, target);
5207 add_path(ordered_rel, sorted_path);
5215 if (ordered_rel->fdwroutine &&
5216 ordered_rel->fdwroutine->GetForeignUpperPaths)
5218 input_rel, ordered_rel,
5224 input_rel, ordered_rel, NULL);
5268 List *non_group_cols;
5269 List *non_group_vars;
5278 non_group_cols =
NIL;
5281 foreach(lc, final_target->
exprs)
5301 non_group_cols =
lappend(non_group_cols, expr);
5310 if (
parse->havingQual)
5311 non_group_cols =
lappend(non_group_cols,
parse->havingQual);
5357 List *non_group_cols;
5358 List *non_group_exprs;
5363 non_group_cols =
NIL;
5366 foreach(lc, grouping_target->
exprs)
5387 non_group_cols =
lappend(non_group_cols, expr);
5397 non_group_cols =
lappend(non_group_cols, havingQual);
5418 foreach(lc, partial_target->
exprs)
5431 memcpy(newaggref, aggref,
sizeof(
Aggref));
5463 agg->aggsplit = aggsplit;
5473 agg->aggtype = BYTEAOID;
5475 agg->aggtype = agg->aggtranstype;
5495 foreach(l, new_tlist)
5501 if (new_tle->resjunk)
5504 Assert(orig_tlist_item != NULL);
5506 orig_tlist_item =
lnext(orig_tlist, orig_tlist_item);
5507 if (orig_tle->resjunk)
5508 elog(
ERROR,
"resjunk output columns are not implemented");
5512 if (orig_tlist_item != NULL)
5513 elog(
ERROR,
"resjunk output columns are not implemented");
5532 foreach(lc, windowClause)
5536 int optimizedFrameOptions = 0;
5557 req.
type = T_SupportRequestOptimizeWindowClause;
5579 optimizedFrameOptions =
res->frameOptions;
5586 else if (optimizedFrameOptions !=
res->frameOptions)
5591 if (lc2 == NULL && wc->
frameOptions != optimizedFrameOptions)
5611 foreach(lc3, windowClause)
5616 if (existing_wc == wc)
5677 foreach(lc, windowClause)
5686 actives[nActive].
wc = wc;
5730 for (
int i = 0;
i < nActive;
i++)
5731 result =
lappend(result, actives[
i].wc);
5826 List *activeWindows)
5830 List *flattenable_cols;
5831 List *flattenable_vars;
5842 foreach(lc, activeWindows)
5874 flattenable_cols =
NIL;
5877 foreach(lc, final_target->
exprs)
5901 flattenable_cols =
lappend(flattenable_cols, expr);
5952 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5953 errmsg(
"could not implement window PARTITION BY"),
5954 errdetail(
"Window partitioning columns must be of sortable datatypes.")));
5957 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5958 errmsg(
"could not implement window ORDER BY"),
5959 errdetail(
"Window ordering columns must be of sortable datatypes.")));
5987 List *orderby_pathkeys;
5994 if (window_pathkeys !=
NIL)
5997 window_pathkeys = orderby_pathkeys;
6000 return window_pathkeys;
6072 bool *have_postponed_srfs)
6081 bool have_expensive;
6082 bool have_srf_sortcols;
6084 List *postponable_cols;
6085 List *postponable_vars;
6092 *have_postponed_srfs =
false;
6096 col_is_srf = (
bool *)
palloc0(ncols *
sizeof(
bool));
6097 postpone_col = (
bool *)
palloc0(ncols *
sizeof(
bool));
6098 have_srf = have_volatile = have_expensive = have_srf_sortcols =
false;
6101 foreach(lc, final_target->
exprs)
6119 if (
parse->hasTargetSRFs &&
6123 col_is_srf[
i] =
true;
6129 postpone_col[
i] =
true;
6130 have_volatile =
true;
6150 postpone_col[
i] =
true;
6151 have_expensive =
true;
6158 if (!have_srf_sortcols &&
6159 parse->hasTargetSRFs &&
6161 have_srf_sortcols =
true;
6170 postpone_srfs = (have_srf && !have_srf_sortcols);
6175 if (!(postpone_srfs || have_volatile ||
6178 return final_target;
6186 *have_postponed_srfs = postpone_srfs;
6194 postponable_cols =
NIL;
6197 foreach(lc, final_target->
exprs)
6201 if (postpone_col[
i] || (postpone_srfs && col_is_srf[
i]))
6202 postponable_cols =
lappend(postponable_cols, expr);
6247 if (tuple_fraction <= 0.0)
6251 if (tuple_fraction >= 1.0 && best_path->
rows > 0)
6252 tuple_fraction /= best_path->
rows;
6285 List *targets,
List *targets_contain_srfs)
6314 forboth(lc1, targets, lc2, targets_contain_srfs)
6347 forboth(lc1, targets, lc2, targets_contain_srfs)
6413 return (
Expr *) result;
6428 List **relationOids,
6436 MemSet(&glob, 0,
sizeof(glob));
6437 glob.type = T_PlannerGlobal;
6441 MemSet(&root, 0,
sizeof(root));
6442 root.type = T_PlannerInfo;
6464 return (
Expr *) result;
6489 Cost comparisonCost;
6491 Path seqScanAndSortPath;
6506 root->
parse = query;
6516 rte->
relid = tableOid;
6517 rte->
relkind = RELKIND_RELATION;
6536 if (indexInfo->
indexoid == indexOid)
6609 int parallel_workers;
6628 root->
parse = query;
6645 rte->
relid = tableOid;
6646 rte->
relkind = RELKIND_RELATION;
6671 if (heap->
rd_rel->relpersistence == RELPERSISTENCE_TEMP ||
6675 parallel_workers = 0;
6716 while (parallel_workers > 0 &&
6724 return parallel_workers;
6735 Path *cheapest_path,
List *pathkeys)
6752 if (path != cheapest_path &&
6811 Path *path_save = path;
6812 List *pathkey_orderings =
NIL;
6819 foreach(lc2, pathkey_orderings)
6835 if (
parse->groupingSets)
6838 path,
true, can_hash,
6839 gd, agg_costs, dNumGroups);
6841 else if (
parse->hasAggs)
6859 else if (
parse->groupClause)
6885 if (partially_grouped_rel != NULL)
6887 foreach(lc, partially_grouped_rel->
pathlist)
6891 Path *path_save = path;
6892 List *pathkey_orderings =
NIL;
6900 foreach(lc2, pathkey_orderings)
6944 if (
parse->groupingSets)
6950 cheapest_path,
false,
true,
6951 gd, agg_costs, dNumGroups);
6975 if (partially_grouped_rel && partially_grouped_rel->
pathlist)
7025 bool force_rel_creation)
7031 Path *cheapest_partial_path = NULL;
7032 Path *cheapest_total_path = NULL;
7033 double dNumPartialGroups = 0;
7034 double dNumPartialPartialGroups = 0;
7063 if (cheapest_total_path == NULL &&
7064 cheapest_partial_path == NULL &&
7065 !force_rel_creation)
7081 partially_grouped_rel->fdwroutine = grouped_rel->fdwroutine;
7116 if (cheapest_total_path != NULL)
7119 cheapest_total_path->
rows,
7122 if (cheapest_partial_path != NULL)
7123 dNumPartialPartialGroups =
7125 cheapest_partial_path->
rows,
7129 if (can_sort && cheapest_total_path != NULL)
7142 Path *path_save = path;
7143 List *pathkey_orderings =
NIL;
7151 foreach(lc2, pathkey_orderings)
7159 partially_grouped_rel,
7161 cheapest_total_path,
7170 partially_grouped_rel,
7178 dNumPartialGroups));
7182 partially_grouped_rel,
7186 dNumPartialGroups));
7191 if (can_sort && cheapest_partial_path != NULL)
7198 Path *path_save = path;
7199 List *pathkey_orderings =
NIL;
7207 foreach(lc2, pathkey_orderings)
7216 partially_grouped_rel,
7218 cheapest_partial_path,
7227 partially_grouped_rel,
7235 dNumPartialPartialGroups));
7239 partially_grouped_rel,
7243 dNumPartialPartialGroups));
7251 if (can_hash && cheapest_total_path != NULL)
7258 partially_grouped_rel,
7259 cheapest_total_path,
7266 dNumPartialGroups));
7272 if (can_hash && cheapest_partial_path != NULL)
7276 partially_grouped_rel,
7277 cheapest_partial_path,
7284 dNumPartialPartialGroups));
7291 if (partially_grouped_rel->fdwroutine &&
7292 partially_grouped_rel->fdwroutine->GetForeignUpperPaths)
7294 FdwRoutine *fdwroutine = partially_grouped_rel->fdwroutine;
7298 input_rel, partially_grouped_rel,
7302 return partially_grouped_rel;
7322 Path *cheapest_partial_path;
7323 List *groupby_pathkeys;
7346 double total_groups;
7361 if (path != cheapest_partial_path &&
7416 else if (
parse->groupingSets)
7448 List *scanjoin_targets,
7449 List *scanjoin_targets_contain_srfs,
7450 bool scanjoin_target_parallel_safe,
7479 if (rel_is_partitioned)
7486 if (!scanjoin_target_parallel_safe)
7505 if (rel_is_partitioned)
7528 subpath->pathtarget->sortgrouprefs =
7529 scanjoin_target->sortgrouprefs;
7549 subpath->pathtarget->sortgrouprefs =
7550 scanjoin_target->sortgrouprefs;
7567 if (root->
parse->hasTargetSRFs)
7570 scanjoin_targets_contain_srfs);
7592 if (rel_is_partitioned)
7604 List *child_scanjoin_targets =
NIL;
7606 Assert(child_rel != NULL);
7615 foreach(lc, scanjoin_targets)
7623 nappinfos, appinfos);
7624 child_scanjoin_targets =
lappend(child_scanjoin_targets,
7631 child_scanjoin_targets,
7632 scanjoin_targets_contain_srfs,
7633 scanjoin_target_parallel_safe,
7638 live_children =
lappend(live_children, child_rel);
7690 List *grouped_live_children =
NIL;
7691 List *partially_grouped_live_children =
NIL;
7693 bool partial_grouping_valid =
true;
7698 partially_grouped_rel != NULL);
7704 RelOptInfo *child_input_rel = input_rel->part_rels[
i];
7712 Assert(child_input_rel != NULL);
7724 memcpy(&child_extra, extra,
sizeof(child_extra));
7732 nappinfos, appinfos);
7738 nappinfos, appinfos);
7742 nappinfos, appinfos);
7749 child_extra.
patype = patype;
7763 agg_costs, gd, &child_extra,
7764 &child_partially_grouped_rel);
7766 if (child_partially_grouped_rel)
7768 partially_grouped_live_children =
7769 lappend(partially_grouped_live_children,
7770 child_partially_grouped_rel);
7773 partial_grouping_valid =
false;
7778 grouped_live_children =
lappend(grouped_live_children,
7794 if (partially_grouped_rel && partial_grouping_valid)
7796 Assert(partially_grouped_live_children !=
NIL);
7799 partially_grouped_live_children);
7805 if (partially_grouped_rel->
pathlist)
7834 Assert(input_rel->part_scheme);
7837 if (!input_rel->partexprs)
7840 partnatts = input_rel->part_scheme->partnatts;
7842 for (cnt = 0; cnt < partnatts; cnt++)
7844 List *partexprs = input_rel->partexprs[cnt];
7848 foreach(lc, partexprs)
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)
Node * adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, RelOptInfo *childrel, RelOptInfo *parentrel)
List * adjust_inherited_attnums_multilevel(PlannerInfo *root, List *attnums, Index child_relid, Index top_parent_relid)
void pprint(const void *obj)
void BipartiteMatchFree(BipartiteMatchState *state)
BipartiteMatchState * BipartiteMatch(int u_size, int v_size, short **adjacency)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
BMS_Comparison bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
int bms_next_member(const Bitmapset *a, int prevbit)
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_make_singleton(int x)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_del_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)
WindowFuncLists * find_window_functions(Node *clause, Index maxWinRef)
bool contain_agg_clause(Node *clause)
void convert_saop_to_hashed_saop(Node *node)
char max_parallel_hazard(Query *parse)
bool is_parallel_safe(PlannerInfo *root, Node *node)
Node * eval_const_expressions(PlannerInfo *root, Node *node)
bool contain_subplans(Node *clause)
bool contain_volatile_functions(Node *clause)
Node * estimate_expression_value(PlannerInfo *root, Node *node)
bool enable_partitionwise_aggregate
int max_parallel_workers_per_gather
double parallel_setup_cost
PathTarget * set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target)
double parallel_tuple_cost
void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root)
void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root)
bool enable_presorted_aggregate
int32 clamp_width_est(int64 tuple_width)
void cost_sort(Path *path, PlannerInfo *root, List *pathkeys, Cost input_cost, double tuples, int width, Cost comparison_cost, int sort_mem, double limit_tuples)
bool enable_incremental_sort
Plan * create_plan(PlannerInfo *root, Path *best_path)
Plan * materialize_finished_plan(Plan *subplan)
static void PGresult * res
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)
Datum Int64GetDatum(int64 X)
#define OidFunctionCall1(functionId, arg1)
FdwRoutine * GetFdwRoutineByRelId(Oid relid)
int max_parallel_maintenance_workers
#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)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * list_delete_int(List *list, int datum)
List * list_concat_unique(List *list1, const List *list2)
List * lappend(List *list, void *datum)
List * list_difference_int(const List *list1, const List *list2)
List * list_copy_head(const List *oldlist, int len)
List * lappend_int(List *list, int datum)
List * list_copy(const List *oldlist)
void list_free(List *list)
bool list_member_int(const List *list, int datum)
List * list_concat(List *list1, const List *list2)
bool list_member(const List *list, const void *datum)
List * lcons(void *datum, List *list)
RegProcedure get_func_support(Oid funcid)
int32 get_typavgwidth(Oid typid, int32 typmod)
Datum subpath(PG_FUNCTION_ARGS)
List * make_ands_implicit(Expr *clause)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
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 PVC_RECURSE_AGGREGATES
#define PVC_RECURSE_WINDOWFUNCS
#define PVC_INCLUDE_WINDOWFUNCS
#define PVC_INCLUDE_PLACEHOLDERS
#define PVC_INCLUDE_AGGREGATES
int assign_special_exec_param(PlannerInfo *root)
List * expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit)
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 * get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
bool pathkeys_count_contained_in(List *keys1, List *keys2, int *n_common)
List * append_pathkeys(List *target, List *source)
List * make_pathkeys_for_sortclauses_extended(PlannerInfo *root, List **sortclauses, List *tlist, bool remove_redundant, bool *sortable)
List * make_pathkeys_for_sortclauses(PlannerInfo *root, List *sortclauses, List *tlist)
bool pathkeys_contained_in(List *keys1, List *keys2)
PathKeysComparison compare_pathkeys(List *keys1, List *keys2)
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)
SortPath * create_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *pathkeys, double limit_tuples)
GroupResultPath * create_group_result_path(PlannerInfo *root, RelOptInfo *rel, PathTarget *target, List *havingqual)
WindowAggPath * create_windowagg_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, List *windowFuncs, WindowClause *winclause, List *qual, bool topwindow)
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)
LimitPath * create_limit_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, Node *limitOffset, Node *limitCount, LimitOption limitOption, int64 offset_est, int64 count_est)
ProjectionPath * create_projection_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target)
GatherMergePath * create_gather_merge_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, List *pathkeys, Relids required_outer, double *rows)
UpperUniquePath * create_upper_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, int numCols, double numGroups)
LockRowsPath * create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *rowMarks, int epqParam)
void set_cheapest(RelOptInfo *parent_rel)
ProjectSetPath * create_set_projection_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target)
void add_partial_path(RelOptInfo *parent_rel, Path *new_path)
int compare_fractional_path_costs(Path *path1, Path *path2, double fraction)
GroupPath * create_group_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *groupClause, List *qual, double numGroups)
GroupingSetsPath * create_groupingsets_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *having_qual, AggStrategy aggstrategy, List *rollups, const AggClauseCosts *agg_costs)
IncrementalSortPath * create_incremental_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *pathkeys, int presorted_keys, double limit_tuples)
ModifyTablePath * create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, CmdType operation, bool canSetTag, Index nominalRelation, Index rootRelation, bool partColsUpdated, List *resultRelations, List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *rowMarks, OnConflictExpr *onconflict, List *mergeActionLists, int epqParam)
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)
void add_path(RelOptInfo *parent_rel, Path *new_path)
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)
PartitionwiseAggregateType
@ PARTITIONWISE_AGGREGATE_PARTIAL
@ PARTITIONWISE_AGGREGATE_FULL
@ PARTITIONWISE_AGGREGATE_NONE
#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)
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
bool has_subclass(Oid relationId)
#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 for_each_cell(cell, lst, initcell)
static ListCell * list_head(const List *l)
#define for_each_from(cell, lst, N)
static void * list_nth(const List *list, int n)
#define list_nth_node(type, list, n)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make1_int(x1)
#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)
Expr * expression_planner(Expr *expr)
static PathTarget * make_partial_grouping_target(PlannerInfo *root, PathTarget *grouping_target, Node *havingQual)
static void gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel)
static void preprocess_rowmarks(PlannerInfo *root)
#define EXPRKIND_TABLESAMPLE
static List * groupclause_apply_groupingset(PlannerInfo *root, List *force)
static void create_degenerate_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel)
planner_hook_type planner_hook
double cursor_tuple_fraction
static bool is_degenerate_grouping(PlannerInfo *root)
static void remove_useless_groupby_columns(PlannerInfo *root)
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)
static bool can_partial_agg(PlannerInfo *root)
static double preprocess_limit(PlannerInfo *root, double tuple_fraction, int64 *offset_est, int64 *count_est)
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 grouping_planner(PlannerInfo *root, double tuple_fraction)
static void create_partial_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *final_distinct_rel, PathTarget *target)
static Node * preprocess_expression(PlannerInfo *root, Node *expr, int kind)
static bool has_volatile_pathkey(List *keys)
PlannerInfo * subquery_planner(PlannerGlobal *glob, Query *parse, PlannerInfo *parent_root, bool hasRecursion, double tuple_fraction)
static RelOptInfo * create_partial_grouping_paths(PlannerInfo *root, RelOptInfo *grouped_rel, RelOptInfo *input_rel, grouping_sets_data *gd, GroupPathExtraData *extra, bool force_rel_creation)
PlannedStmt * planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams)
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)
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 RelOptInfo * make_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, Node *havingQual)
static List * select_active_windows(PlannerInfo *root, WindowFuncLists *wflists)
Expr * preprocess_phv_expression(PlannerInfo *root, Expr *expr)
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)
Expr * expression_planner_with_deps(Expr *expr, List **relationOids, List **invalItems)
static Path * make_ordered_path(PlannerInfo *root, RelOptInfo *rel, Path *path, Path *cheapest_path, List *pathkeys)
PlannedStmt * standard_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams)
static List * make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc, List *tlist)
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, double dNumGroups, GroupPathExtraData *extra)
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)
Path * get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction)
#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)
PlannedStmt *(* planner_hook_type)(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams)
void(* create_upper_paths_hook_type)(PlannerInfo *root, UpperRelationKind stage, RelOptInfo *input_rel, RelOptInfo *output_rel, void *extra)
@ ROW_MARK_NOKEYEXCLUSIVE
#define qsort(a, b, c, d)
void check_stack_depth(void)
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)
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)
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)
void setup_simple_rel_arrays(PlannerInfo *root)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
RelOptInfo * build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
RelOptInfo * fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids 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)
GetForeignRowMarkType_function GetForeignRowMarkType
GetForeignUpperPaths_function GetForeignUpperPaths
LockClauseStrength strength
LockWaitPolicy waitPolicy
Bitmapset * rewindPlanIDs
Bitmapset * rewindPlanIDs
Index qual_security_level
struct Path * non_recursive_path
List * processed_groupClause
bool hasAlternativeSubPlans
List * processed_distinctClause
Cardinality total_table_pages
Selectivity tuple_fraction
bool hasPseudoConstantQuals
Relids leaf_result_relids
struct TableSampleClause * tablesample
struct PathTarget * reltarget
struct Path * cheapest_startup_path
struct Path * cheapest_total_path
LockClauseStrength strength
LockWaitPolicy waitPolicy
struct WindowClause * window_clause
int * tleref_to_colnum_map
Bitmapset * unhashable_refs
Bitmapset * unsortable_refs
grouping_sets_data * gset_data
void SS_process_ctes(PlannerInfo *root)
void SS_identify_outer_params(PlannerInfo *root)
void SS_finalize_plan(PlannerInfo *root, Plan *plan)
Node * SS_replace_correlation_vars(PlannerInfo *root, Node *expr)
Node * SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual)
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)
#define FirstLowInvalidHeapAttributeNumber
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
List * get_sortgrouplist_exprs(List *sgClauses, List *targetList)
bool tlist_same_exprs(List *tlist1, List *tlist2)
PathTarget * copy_pathtarget(PathTarget *src)
SortGroupClause * get_sortgroupref_clause_noerr(Index sortref, List *clauses)
bool grouping_is_sortable(List *groupClause)
void add_new_columns_to_pathtarget(PathTarget *target, List *exprs)
PathTarget * create_empty_pathtarget(void)
TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)
SortGroupClause * get_sortgroupref_clause(Index sortref, List *clauses)
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)
List * pull_var_clause(Node *node, int flags)
Node * flatten_join_alias_vars(PlannerInfo *root, Query *query, Node *node)