41 #ifdef OPTIMIZER_DEBUG
84 #define EXPRKIND_QUAL 0
85 #define EXPRKIND_TARGET 1
86 #define EXPRKIND_RTFUNC 2
87 #define EXPRKIND_RTFUNC_LATERAL 3
88 #define EXPRKIND_VALUES 4
89 #define EXPRKIND_VALUES_LATERAL 5
90 #define EXPRKIND_LIMIT 6
91 #define EXPRKIND_APPINFO 7
92 #define EXPRKIND_PHV 8
93 #define EXPRKIND_TABLESAMPLE 9
94 #define EXPRKIND_ARBITER_ELEM 10
95 #define EXPRKIND_TABLEFUNC 11
96 #define EXPRKIND_TABLEFUNC_LATERAL 12
137 int *tleref_to_colnum_map);
140 double tuple_fraction,
141 int64 *offset_est, int64 *count_est);
154 bool target_parallel_safe,
161 PathTarget *target,
bool target_parallel_safe,
182 bool output_target_parallel_safe,
184 List *activeWindows);
191 List *activeWindows);
203 bool target_parallel_safe,
204 double limit_tuples);
216 List *activeWindows);
221 bool *have_postponed_srfs);
223 List *targets,
List *targets_contain_srfs);
236 bool force_rel_creation);
241 List *scanjoin_targets,
242 List *scanjoin_targets_contain_srfs,
243 bool scanjoin_target_parallel_safe,
279 result = (*planner_hook) (
parse, query_string, cursorOptions, boundParams);
291 double tuple_fraction;
307 glob->boundParams = boundParams;
309 glob->subroots =
NIL;
349 !
parse->hasModifyingCTE &&
401 if (tuple_fraction >= 1.0)
402 tuple_fraction = 0.0;
403 else if (tuple_fraction <= 0.0)
404 tuple_fraction = 1
e-10;
409 tuple_fraction = 0.0;
414 false, tuple_fraction);
451 bool unsafe_initplans;
489 &initplan_cost, &unsafe_initplans);
496 top_plan = &gather->
plan;
587 if (glob->partition_directory != NULL)
625 bool hasRecursion,
double tuple_fraction)
628 List *newWithCheckOptions;
640 root->parent_root = parent_root;
657 memset(root->upper_rels, 0,
sizeof(root->upper_rels));
658 memset(root->upper_targets, 0,
sizeof(root->upper_targets));
663 root->grouping_map = NULL;
708 if (
parse->hasSubLinks)
731 if (
parse->setOperations)
746 hasOuterJoins =
false;
747 hasResultRTEs =
false;
748 foreach(l,
parse->rtable)
774 hasOuterJoins =
true;
777 hasResultRTEs =
true;
802 if (
parse->resultRelation)
835 if (
parse->hasTargetSRFs)
838 newWithCheckOptions =
NIL;
839 foreach(l,
parse->withCheckOptions)
845 if (wco->
qual != NULL)
846 newWithCheckOptions =
lappend(newWithCheckOptions, wco);
848 parse->withCheckOptions = newWithCheckOptions;
859 foreach(l,
parse->windowClause)
869 (
Node *) wc->runCondition,
878 if (
parse->onConflict)
880 parse->onConflict->arbiterElems = (
List *)
882 (
Node *)
parse->onConflict->arbiterElems,
884 parse->onConflict->arbiterWhere =
886 parse->onConflict->arbiterWhere,
888 parse->onConflict->onConflictSet = (
List *)
890 (
Node *)
parse->onConflict->onConflictSet,
892 parse->onConflict->onConflictWhere =
894 parse->onConflict->onConflictWhere,
899 foreach(l,
parse->mergeActionList)
918 foreach(l,
parse->rtable)
995 foreach(l,
parse->rtable)
1039 if ((
parse->groupClause &&
parse->groupingSets) ||
1045 newHaving =
lappend(newHaving, havingclause);
1047 else if (
parse->groupClause && !
parse->groupingSets)
1059 newHaving =
lappend(newHaving, havingclause);
1078 if (hasResultRTEs || hasOuterJoins)
1173 #ifdef OPTIMIZER_DEBUG
1174 printf(
"After canonicalize_qual()\n");
1190 if (root->
parse->hasSubLinks)
1248 elog(
ERROR,
"unrecognized node type: %d",
1296 int64 offset_est = 0;
1297 int64 count_est = 0;
1298 double limit_tuples = -1.0;
1299 bool have_postponed_srfs =
false;
1301 List *final_targets;
1302 List *final_targets_contain_srfs;
1303 bool final_target_parallel_safe;
1313 &offset_est, &count_est);
1319 if (count_est > 0 && offset_est >= 0)
1320 limit_tuples = (double) count_est + (
double) offset_est;
1326 if (
parse->setOperations)
1336 if (
parse->sortClause)
1365 final_target_parallel_safe =
1370 final_targets = final_targets_contain_srfs =
NIL;
1376 if (
parse->rowMarks)
1378 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1381 errmsg(
"%s is not allowed with UNION/INTERSECT/EXCEPT",
1383 parse->rowMarks)->strength))));
1397 List *sort_input_targets;
1398 List *sort_input_targets_contain_srfs;
1399 bool sort_input_target_parallel_safe;
1401 List *grouping_targets;
1402 List *grouping_targets_contain_srfs;
1403 bool grouping_target_parallel_safe;
1405 List *scanjoin_targets;
1406 List *scanjoin_targets_contain_srfs;
1407 bool scanjoin_target_parallel_safe;
1408 bool scanjoin_target_same_exprs;
1419 if (
parse->groupingSets)
1423 else if (
parse->groupClause)
1459 if (
parse->hasWindowFuncs)
1475 parse->hasWindowFuncs =
false;
1493 if (
parse->groupClause ||
1494 parse->groupingSets ||
1495 parse->distinctClause ||
1497 parse->hasWindowFuncs ||
1498 parse->hasTargetSRFs ||
1527 final_target_parallel_safe =
1535 if (
parse->sortClause)
1539 &have_postponed_srfs);
1540 sort_input_target_parallel_safe =
1545 sort_input_target = final_target;
1546 sort_input_target_parallel_safe = final_target_parallel_safe;
1559 grouping_target_parallel_safe =
1564 grouping_target = sort_input_target;
1565 grouping_target_parallel_safe = sort_input_target_parallel_safe;
1573 have_grouping = (
parse->groupClause ||
parse->groupingSets ||
1578 scanjoin_target_parallel_safe =
1583 scanjoin_target = grouping_target;
1584 scanjoin_target_parallel_safe = grouping_target_parallel_safe;
1593 if (
parse->hasTargetSRFs)
1598 &final_targets_contain_srfs);
1603 &sort_input_targets,
1604 &sort_input_targets_contain_srfs);
1610 &grouping_targets_contain_srfs);
1616 &scanjoin_targets_contain_srfs);
1623 final_targets = final_targets_contain_srfs =
NIL;
1624 sort_input_targets = sort_input_targets_contain_srfs =
NIL;
1625 grouping_targets = grouping_targets_contain_srfs =
NIL;
1626 scanjoin_targets =
list_make1(scanjoin_target);
1627 scanjoin_targets_contain_srfs =
NIL;
1631 scanjoin_target_same_exprs =
list_length(scanjoin_targets) == 1
1634 scanjoin_targets_contain_srfs,
1635 scanjoin_target_parallel_safe,
1636 scanjoin_target_same_exprs);
1662 grouping_target_parallel_safe,
1665 if (
parse->hasTargetSRFs)
1668 grouping_targets_contain_srfs);
1681 sort_input_target_parallel_safe,
1685 if (
parse->hasTargetSRFs)
1688 sort_input_targets_contain_srfs);
1695 if (
parse->distinctClause)
1709 if (
parse->sortClause)
1714 final_target_parallel_safe,
1715 have_postponed_srfs ? -1.0 :
1718 if (
parse->hasTargetSRFs)
1721 final_targets_contain_srfs);
1747 final_rel->fdwroutine = current_rel->fdwroutine;
1764 if (
parse->rowMarks)
1780 offset_est, count_est);
1790 List *updateColnosLists =
NIL;
1791 List *withCheckOptionLists =
NIL;
1800 parse->resultRelation);
1801 int resultRelation = -1;
1805 resultRelation)) >= 0)
1825 if (this_result_rel != top_result_rel)
1829 this_result_rel->
relid,
1830 top_result_rel->
relid);
1831 updateColnosLists =
lappend(updateColnosLists,
1834 if (
parse->withCheckOptions)
1836 List *withCheckOptions =
parse->withCheckOptions;
1838 if (this_result_rel != top_result_rel)
1839 withCheckOptions = (
List *)
1841 (
Node *) withCheckOptions,
1844 withCheckOptionLists =
lappend(withCheckOptionLists,
1847 if (
parse->returningList)
1849 List *returningList =
parse->returningList;
1851 if (this_result_rel != top_result_rel)
1852 returningList = (
List *)
1854 (
Node *) returningList,
1857 returningLists =
lappend(returningLists,
1860 if (
parse->mergeActionList)
1869 foreach(l,
parse->mergeActionList)
1879 leaf_action->targetList = (
List *)
1885 leaf_action->updateColnos =
1888 this_result_rel->
relid,
1889 top_result_rel->
relid);
1890 mergeActionList =
lappend(mergeActionList,
1894 mergeActionLists =
lappend(mergeActionLists,
1899 if (resultRelations ==
NIL)
1915 if (
parse->withCheckOptions)
1917 if (
parse->returningList)
1919 if (
parse->mergeActionList)
1929 if (
parse->withCheckOptions)
1931 if (
parse->returningList)
1933 if (
parse->mergeActionList)
1942 RELKIND_PARTITIONED_TABLE)
1943 rootRelation =
parse->resultRelation;
1952 if (
parse->rowMarks)
1962 parse->resultRelation,
1967 withCheckOptionLists,
2004 if (final_rel->fdwroutine &&
2005 final_rel->fdwroutine->GetForeignUpperPaths)
2006 final_rel->fdwroutine->GetForeignUpperPaths(root,
UPPERREL_FINAL,
2007 current_rel, final_rel,
2013 current_rel, final_rel, &extra);
2046 if (
parse->groupClause)
2050 foreach(lc,
parse->groupClause)
2080 foreach(lc,
parse->groupingSets)
2101 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2102 errmsg(
"could not implement GROUP BY"),
2103 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
2106 sortable_sets =
lappend(sortable_sets, gset);
2117 foreach(lc_set, sets)
2208 int *tleref_to_colnum_map)
2214 foreach(lc, groupClause)
2227 foreach(lc2, gs->
set)
2232 result =
lappend(result, set);
2251 if (
parse->rowMarks)
2260 parse->rowMarks)->strength);
2279 if (
parse->resultRelation)
2286 foreach(l,
parse->rowMarks)
2319 prowmarks =
lappend(prowmarks, newrc);
2326 foreach(l,
parse->rtable)
2344 prowmarks =
lappend(prowmarks, newrc);
2361 else if (rte->
relkind == RELKIND_FOREIGN_TABLE)
2397 elog(
ERROR,
"unrecognized LockClauseStrength %d", (
int) strength);
2421 int64 *offset_est, int64 *count_est)
2425 double limit_fraction;
2434 if (
parse->limitCount)
2439 if (((
Const *) est)->constisnull)
2447 if (*count_est <= 0)
2457 if (
parse->limitOffset)
2462 if (((
Const *) est)->constisnull)
2470 if (*offset_est < 0)
2480 if (*count_est != 0)
2487 if (*count_est < 0 || *offset_est < 0)
2490 limit_fraction = 0.10;
2495 limit_fraction = (double) *count_est + (
double) *offset_est;
2505 if (tuple_fraction >= 1.0)
2507 if (limit_fraction >= 1.0)
2510 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2517 else if (tuple_fraction > 0.0)
2519 if (limit_fraction >= 1.0)
2522 tuple_fraction = limit_fraction;
2527 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2533 tuple_fraction = limit_fraction;
2536 else if (*offset_est != 0 && tuple_fraction > 0.0)
2547 if (*offset_est < 0)
2548 limit_fraction = 0.10;
2550 limit_fraction = (double) *offset_est;
2558 if (tuple_fraction >= 1.0)
2560 if (limit_fraction >= 1.0)
2563 tuple_fraction += limit_fraction;
2568 tuple_fraction = limit_fraction;
2573 if (limit_fraction >= 1.0)
2580 tuple_fraction += limit_fraction;
2581 if (tuple_fraction >= 1.0)
2582 tuple_fraction = 0.0;
2587 return tuple_fraction;
2609 node =
parse->limitCount;
2615 if (!((
Const *) node)->constisnull)
2622 node =
parse->limitOffset;
2628 if (!((
Const *) node)->constisnull)
2677 if (
parse->groupingSets)
2720 foreach(lc,
parse->rtable)
2738 if (rte->
inh && rte->
relkind != RELKIND_PARTITIONED_TABLE)
2742 relattnos = groupbyattnos[relid];
2751 if (pkattnos == NULL)
2764 if (surplusvars == NULL)
2778 if (surplusvars != NULL)
2795 surplusvars[var->
varno]))
2796 new_groupby =
lappend(new_groupby, sgc);
2845 new_groupclause =
lappend(new_groupclause, cl);
2848 return new_groupclause;
2861 foreach(sl,
parse->sortClause)
2865 foreach(gl,
parse->groupClause)
2871 new_groupclause =
lappend(new_groupclause, gc);
2880 partial_match = (sl != NULL);
2883 if (new_groupclause ==
NIL)
2894 foreach(gl,
parse->groupClause)
2904 new_groupclause =
lappend(new_groupclause, gc);
2909 return new_groupclause;
2944 short *adjacency_buf;
2960 lc1 =
lnext(groupingSets, lc1);
2985 orig_sets =
palloc0((num_sets_raw + 1) *
sizeof(
List *));
2987 adjacency =
palloc0((num_sets_raw + 1) *
sizeof(
short *));
2988 adjacency_buf =
palloc((num_sets_raw + 1) *
sizeof(
short));
3001 foreach(lc2, candidate)
3011 for (k =
j; k <
i; ++k)
3013 if (
bms_equal(set_masks[k], candidate_set))
3028 orig_sets[dup_of] =
lappend(orig_sets[dup_of], candidate);
3037 set_masks[
i] = candidate_set;
3041 for (k =
j - 1; k > 0; --k)
3044 adjacency_buf[++n_adj] = k;
3049 adjacency_buf[0] = n_adj;
3050 adjacency[
i] =
palloc((n_adj + 1) *
sizeof(
short));
3051 memcpy(adjacency[
i], adjacency_buf, (n_adj + 1) *
sizeof(
short));
3054 adjacency[
i] = NULL;
3073 chains =
palloc0((num_sets + 1) *
sizeof(
int));
3075 for (
i = 1;
i <= num_sets; ++
i)
3077 int u =
state->pair_vu[
i];
3078 int v =
state->pair_uv[
i];
3081 chains[
i] = chains[u];
3082 else if (v > 0 && v <
i)
3083 chains[
i] = chains[v];
3085 chains[
i] = ++num_chains;
3089 results =
palloc0((num_chains + 1) *
sizeof(
List *));
3091 for (
i = 1;
i <= num_sets; ++
i)
3101 while (num_empty-- > 0)
3102 results[1] =
lcons(
NIL, results[1]);
3105 for (
i = 1;
i <= num_chains; ++
i)
3106 result =
lappend(result, results[
i]);
3117 for (
i = 1;
i <= num_sets; ++
i)
3121 pfree(adjacency_buf);
3123 for (
i = 1;
i <= num_sets; ++
i)
3150 foreach(lc, groupingSets)
3178 result =
lcons(gs, result);
3200 if (pathkey->pk_eclass->ec_has_volatile)
3259 unprocessed_aggs = NULL;
3265 if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3326 if (currpathkeys ==
NIL)
3328 currpathkeys = pathkeys;
3331 if (grouppathkeys !=
NIL)
3343 if (grouppathkeys !=
NIL)
3352 currpathkeys = pathkeys;
3379 bestaggs = aggindexes;
3380 bestpathkeys = currpathkeys;
3389 if (bestpathkeys !=
NIL)
3409 aggref->aggpresorted =
true;
3492 if (activeWindows !=
NIL)
3509 if (
parse->distinctClause)
3583 if (
parse->groupClause)
3587 if (
parse->groupingSets)
3660 else if (
parse->groupingSets)
3700 bool target_parallel_safe,
3716 target_parallel_safe,
parse->havingQual);
3775 extra.
flags = flags;
3793 &agg_costs, gd, &extra,
3794 &partially_grouped_rel);
3811 PathTarget *target,
bool target_parallel_safe,
3850 grouped_rel->fdwroutine = input_rel->fdwroutine;
3903 while (--nrows >= 0)
3998 bool force_rel_creation;
4007 partially_grouped_rel =
4013 force_rel_creation);
4017 *partially_grouped_rel_p = partially_grouped_rel;
4022 partially_grouped_rel, agg_costs,
4028 Assert(partially_grouped_rel);
4030 if (partially_grouped_rel->
pathlist)
4047 cheapest_path->
rows,
4053 partially_grouped_rel, agg_costs, gd,
4059 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4060 errmsg(
"could not implement GROUP BY"),
4061 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
4067 if (grouped_rel->fdwroutine &&
4068 grouped_rel->fdwroutine->GetForeignUpperPaths)
4070 input_rel, grouped_rel,
4076 input_rel, grouped_rel,
4121 double exclude_groups = 0.0;
4145 if (l_start != NULL &&
4149 exclude_groups = unhashed_rollup->
numGroups;
4156 dNumGroups - exclude_groups);
4163 if (hashsize > hash_mem_limit && gd->
rollups)
4192 foreach(lc, sets_data)
4201 empty_sets_data =
lappend(empty_sets_data, gs);
4216 new_rollups =
lappend(new_rollups, rollup);
4224 if (new_rollups ==
NIL)
4231 Assert(!unhashed_rollup || !empty_sets);
4233 if (unhashed_rollup)
4235 new_rollups =
lappend(new_rollups, unhashed_rollup);
4238 else if (empty_sets)
4244 rollup->
gsets = empty_sets;
4248 new_rollups =
lappend(new_rollups, rollup);
4281 double availspace = hash_mem_limit;
4297 int *k_weights =
palloc(num_rollups *
sizeof(
int));
4323 scale =
Max(availspace / (20.0 * num_rollups), 1.0);
4324 k_capacity = (int) floor(availspace /
scale);
4348 k_weights[
i] = (int)
Min(floor(sz /
scale),
4378 rollups =
lappend(rollups, rollup);
4382 rollups =
lappend(rollups, rollup);
4387 if (!rollups && hash_sets)
4390 foreach(lc, hash_sets)
4405 rollups =
lcons(rollup, rollups);
4453 bool output_target_parallel_safe,
4455 List *activeWindows)
4478 window_rel->fdwroutine = input_rel->fdwroutine;
4507 if (window_rel->fdwroutine &&
4508 window_rel->fdwroutine->GetForeignUpperPaths)
4510 input_rel, window_rel,
4516 input_rel, window_rel, NULL);
4542 List *activeWindows)
4563 window_target = input_target;
4565 foreach(l, activeWindows)
4568 List *window_pathkeys;
4608 if (
lnext(activeWindows, l))
4632 window_target = output_target;
4649 wc, topwindow ? topqual :
NIL, topwindow);
4688 distinct_rel->fdwroutine = input_rel->fdwroutine;
4699 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4700 errmsg(
"could not implement DISTINCT"),
4701 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
4707 if (distinct_rel->fdwroutine &&
4708 distinct_rel->fdwroutine->GetForeignUpperPaths)
4709 distinct_rel->fdwroutine->GetForeignUpperPaths(root,
4718 distinct_rel, NULL);
4723 return distinct_rel;
4740 List *distinctExprs;
4741 double numDistinctRows;
4742 Path *cheapest_partial_path;
4752 if (
parse->hasDistinctOn)
4766 partial_distinct_rel->fdwroutine = input_rel->fdwroutine;
4775 cheapest_partial_path->
rows,
4796 sorted_path = input_path;
4806 if (input_path != cheapest_partial_path &&
4817 partial_distinct_rel,
4823 partial_distinct_rel,
4848 partial_distinct_rel,
4849 cheapest_partial_path,
4850 cheapest_partial_path->pathtarget,
4863 if (partial_distinct_rel->fdwroutine &&
4864 partial_distinct_rel->fdwroutine->GetForeignUpperPaths)
4865 partial_distinct_rel->fdwroutine->GetForeignUpperPaths(root,
4868 partial_distinct_rel,
4874 input_rel, partial_distinct_rel, NULL);
4887 final_distinct_rel);
4904 double numDistinctRows;
4916 numDistinctRows = cheapest_input_path->
rows;
4923 List *distinctExprs;
4928 cheapest_input_path->
rows,
4951 List *needed_pathkeys;
4955 if (
parse->hasDistinctOn &&
4974 sorted_path = input_path;
4984 if (input_path != cheapest_input_path &&
5075 cheapest_input_path,
5076 cheapest_input_path->pathtarget,
5085 return distinct_rel;
5109 bool target_parallel_safe,
5110 double limit_tuples)
5133 ordered_rel->fdwroutine = input_rel->fdwroutine;
5143 input_path->
pathkeys, &presorted_keys);
5146 sorted_path = input_path;
5156 if (input_path != cheapest_input_path &&
5181 if (sorted_path->pathtarget != target)
5183 sorted_path, target);
5185 add_path(ordered_rel, sorted_path);
5201 Path *cheapest_partial_path;
5213 double total_groups;
5217 cheapest_partial_path,
5221 total_groups = cheapest_partial_path->
rows *
5231 if (path->pathtarget != target)
5253 double total_groups;
5270 if (presorted_keys == 0)
5280 total_groups = input_path->
rows *
5282 sorted_path = (
Path *)
5285 sorted_path->pathtarget,
5290 if (sorted_path->pathtarget != target)
5292 sorted_path, target);
5294 add_path(ordered_rel, sorted_path);
5303 if (ordered_rel->fdwroutine &&
5304 ordered_rel->fdwroutine->GetForeignUpperPaths)
5306 input_rel, ordered_rel,
5312 input_rel, ordered_rel, NULL);
5356 List *non_group_cols;
5357 List *non_group_vars;
5366 non_group_cols =
NIL;
5369 foreach(lc, final_target->
exprs)
5389 non_group_cols =
lappend(non_group_cols, expr);
5398 if (
parse->havingQual)
5399 non_group_cols =
lappend(non_group_cols,
parse->havingQual);
5445 List *non_group_cols;
5446 List *non_group_exprs;
5451 non_group_cols =
NIL;
5454 foreach(lc, grouping_target->
exprs)
5475 non_group_cols =
lappend(non_group_cols, expr);
5485 non_group_cols =
lappend(non_group_cols, havingQual);
5506 foreach(lc, partial_target->
exprs)
5519 memcpy(newaggref, aggref,
sizeof(
Aggref));
5551 agg->aggsplit = aggsplit;
5561 agg->aggtype = BYTEAOID;
5563 agg->aggtype = agg->aggtranstype;
5583 foreach(l, new_tlist)
5589 if (new_tle->resjunk)
5592 Assert(orig_tlist_item != NULL);
5594 orig_tlist_item =
lnext(orig_tlist, orig_tlist_item);
5595 if (orig_tle->resjunk)
5596 elog(
ERROR,
"resjunk output columns are not implemented");
5600 if (orig_tlist_item != NULL)
5601 elog(
ERROR,
"resjunk output columns are not implemented");
5620 foreach(lc, windowClause)
5624 int optimizedFrameOptions = 0;
5645 req.
type = T_SupportRequestOptimizeWindowClause;
5667 optimizedFrameOptions =
res->frameOptions;
5674 else if (optimizedFrameOptions !=
res->frameOptions)
5679 if (lc2 == NULL && wc->
frameOptions != optimizedFrameOptions)
5699 foreach(lc3, windowClause)
5704 if (existing_wc == wc)
5765 foreach(lc, windowClause)
5774 actives[nActive].
wc = wc;
5818 for (
int i = 0;
i < nActive;
i++)
5819 result =
lappend(result, actives[
i].wc);