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;
347 !
parse->hasModifyingCTE &&
399 if (tuple_fraction >= 1.0)
400 tuple_fraction = 0.0;
401 else if (tuple_fraction <= 0.0)
402 tuple_fraction = 1
e-10;
407 tuple_fraction = 0.0;
412 false, tuple_fraction);
476 top_plan = &gather->
plan;
568 if (glob->partition_directory != NULL)
606 bool hasRecursion,
double tuple_fraction)
609 List *newWithCheckOptions;
621 root->parent_root = parent_root;
638 memset(root->upper_rels, 0,
sizeof(root->upper_rels));
639 memset(root->upper_targets, 0,
sizeof(root->upper_targets));
644 root->grouping_map = NULL;
689 if (
parse->hasSubLinks)
712 if (
parse->setOperations)
727 hasOuterJoins =
false;
728 hasResultRTEs =
false;
729 foreach(l,
parse->rtable)
755 hasOuterJoins =
true;
758 hasResultRTEs =
true;
783 if (
parse->resultRelation)
816 if (
parse->hasTargetSRFs)
819 newWithCheckOptions =
NIL;
820 foreach(l,
parse->withCheckOptions)
826 if (wco->
qual != NULL)
827 newWithCheckOptions =
lappend(newWithCheckOptions, wco);
829 parse->withCheckOptions = newWithCheckOptions;
840 foreach(l,
parse->windowClause)
850 (
Node *) wc->runCondition,
859 if (
parse->onConflict)
861 parse->onConflict->arbiterElems = (
List *)
863 (
Node *)
parse->onConflict->arbiterElems,
865 parse->onConflict->arbiterWhere =
867 parse->onConflict->arbiterWhere,
869 parse->onConflict->onConflictSet = (
List *)
871 (
Node *)
parse->onConflict->onConflictSet,
873 parse->onConflict->onConflictWhere =
875 parse->onConflict->onConflictWhere,
880 foreach(l,
parse->mergeActionList)
899 foreach(l,
parse->rtable)
976 foreach(l,
parse->rtable)
1020 if ((
parse->groupClause &&
parse->groupingSets) ||
1026 newHaving =
lappend(newHaving, havingclause);
1028 else if (
parse->groupClause && !
parse->groupingSets)
1040 newHaving =
lappend(newHaving, havingclause);
1059 if (hasResultRTEs || hasOuterJoins)
1154 #ifdef OPTIMIZER_DEBUG
1155 printf(
"After canonicalize_qual()\n");
1171 if (root->
parse->hasSubLinks)
1229 elog(
ERROR,
"unrecognized node type: %d",
1277 int64 offset_est = 0;
1278 int64 count_est = 0;
1279 double limit_tuples = -1.0;
1280 bool have_postponed_srfs =
false;
1282 List *final_targets;
1283 List *final_targets_contain_srfs;
1284 bool final_target_parallel_safe;
1294 &offset_est, &count_est);
1300 if (count_est > 0 && offset_est >= 0)
1301 limit_tuples = (double) count_est + (
double) offset_est;
1307 if (
parse->setOperations)
1317 if (
parse->sortClause)
1346 final_target_parallel_safe =
1351 final_targets = final_targets_contain_srfs =
NIL;
1357 if (
parse->rowMarks)
1359 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1362 errmsg(
"%s is not allowed with UNION/INTERSECT/EXCEPT",
1364 parse->rowMarks)->strength))));
1378 List *sort_input_targets;
1379 List *sort_input_targets_contain_srfs;
1380 bool sort_input_target_parallel_safe;
1382 List *grouping_targets;
1383 List *grouping_targets_contain_srfs;
1384 bool grouping_target_parallel_safe;
1386 List *scanjoin_targets;
1387 List *scanjoin_targets_contain_srfs;
1388 bool scanjoin_target_parallel_safe;
1389 bool scanjoin_target_same_exprs;
1400 if (
parse->groupingSets)
1404 else if (
parse->groupClause)
1440 if (
parse->hasWindowFuncs)
1456 parse->hasWindowFuncs =
false;
1474 if (
parse->groupClause ||
1475 parse->groupingSets ||
1476 parse->distinctClause ||
1478 parse->hasWindowFuncs ||
1479 parse->hasTargetSRFs ||
1508 final_target_parallel_safe =
1516 if (
parse->sortClause)
1520 &have_postponed_srfs);
1521 sort_input_target_parallel_safe =
1526 sort_input_target = final_target;
1527 sort_input_target_parallel_safe = final_target_parallel_safe;
1540 grouping_target_parallel_safe =
1545 grouping_target = sort_input_target;
1546 grouping_target_parallel_safe = sort_input_target_parallel_safe;
1554 have_grouping = (
parse->groupClause ||
parse->groupingSets ||
1559 scanjoin_target_parallel_safe =
1564 scanjoin_target = grouping_target;
1565 scanjoin_target_parallel_safe = grouping_target_parallel_safe;
1574 if (
parse->hasTargetSRFs)
1579 &final_targets_contain_srfs);
1584 &sort_input_targets,
1585 &sort_input_targets_contain_srfs);
1591 &grouping_targets_contain_srfs);
1597 &scanjoin_targets_contain_srfs);
1604 final_targets = final_targets_contain_srfs =
NIL;
1605 sort_input_targets = sort_input_targets_contain_srfs =
NIL;
1606 grouping_targets = grouping_targets_contain_srfs =
NIL;
1607 scanjoin_targets =
list_make1(scanjoin_target);
1608 scanjoin_targets_contain_srfs =
NIL;
1612 scanjoin_target_same_exprs =
list_length(scanjoin_targets) == 1
1615 scanjoin_targets_contain_srfs,
1616 scanjoin_target_parallel_safe,
1617 scanjoin_target_same_exprs);
1643 grouping_target_parallel_safe,
1646 if (
parse->hasTargetSRFs)
1649 grouping_targets_contain_srfs);
1662 sort_input_target_parallel_safe,
1666 if (
parse->hasTargetSRFs)
1669 sort_input_targets_contain_srfs);
1676 if (
parse->distinctClause)
1690 if (
parse->sortClause)
1695 final_target_parallel_safe,
1696 have_postponed_srfs ? -1.0 :
1699 if (
parse->hasTargetSRFs)
1702 final_targets_contain_srfs);
1728 final_rel->fdwroutine = current_rel->fdwroutine;
1745 if (
parse->rowMarks)
1761 offset_est, count_est);
1771 List *updateColnosLists =
NIL;
1772 List *withCheckOptionLists =
NIL;
1781 parse->resultRelation);
1782 int resultRelation = -1;
1786 resultRelation)) >= 0)
1806 if (this_result_rel != top_result_rel)
1810 this_result_rel->
relid,
1811 top_result_rel->
relid);
1812 updateColnosLists =
lappend(updateColnosLists,
1815 if (
parse->withCheckOptions)
1817 List *withCheckOptions =
parse->withCheckOptions;
1819 if (this_result_rel != top_result_rel)
1820 withCheckOptions = (
List *)
1822 (
Node *) withCheckOptions,
1825 withCheckOptionLists =
lappend(withCheckOptionLists,
1828 if (
parse->returningList)
1830 List *returningList =
parse->returningList;
1832 if (this_result_rel != top_result_rel)
1833 returningList = (
List *)
1835 (
Node *) returningList,
1838 returningLists =
lappend(returningLists,
1841 if (
parse->mergeActionList)
1850 foreach(l,
parse->mergeActionList)
1860 leaf_action->targetList = (
List *)
1866 leaf_action->updateColnos =
1869 this_result_rel->
relid,
1870 top_result_rel->
relid);
1871 mergeActionList =
lappend(mergeActionList,
1875 mergeActionLists =
lappend(mergeActionLists,
1880 if (resultRelations ==
NIL)
1896 if (
parse->withCheckOptions)
1898 if (
parse->returningList)
1900 if (
parse->mergeActionList)
1910 if (
parse->withCheckOptions)
1912 if (
parse->returningList)
1914 if (
parse->mergeActionList)
1923 RELKIND_PARTITIONED_TABLE)
1924 rootRelation =
parse->resultRelation;
1933 if (
parse->rowMarks)
1943 parse->resultRelation,
1948 withCheckOptionLists,
1985 if (final_rel->fdwroutine &&
1986 final_rel->fdwroutine->GetForeignUpperPaths)
1987 final_rel->fdwroutine->GetForeignUpperPaths(root,
UPPERREL_FINAL,
1988 current_rel, final_rel,
1994 current_rel, final_rel, &extra);
2027 if (
parse->groupClause)
2031 foreach(lc,
parse->groupClause)
2061 foreach(lc,
parse->groupingSets)
2082 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2083 errmsg(
"could not implement GROUP BY"),
2084 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
2087 sortable_sets =
lappend(sortable_sets, gset);
2098 foreach(lc_set, sets)
2189 int *tleref_to_colnum_map)
2195 foreach(lc, groupClause)
2208 foreach(lc2, gs->
set)
2213 result =
lappend(result, set);
2232 if (
parse->rowMarks)
2241 parse->rowMarks)->strength);
2260 if (
parse->resultRelation)
2267 foreach(l,
parse->rowMarks)
2300 prowmarks =
lappend(prowmarks, newrc);
2307 foreach(l,
parse->rtable)
2325 prowmarks =
lappend(prowmarks, newrc);
2342 else if (rte->
relkind == RELKIND_FOREIGN_TABLE)
2378 elog(
ERROR,
"unrecognized LockClauseStrength %d", (
int) strength);
2402 int64 *offset_est, int64 *count_est)
2406 double limit_fraction;
2415 if (
parse->limitCount)
2420 if (((
Const *) est)->constisnull)
2428 if (*count_est <= 0)
2438 if (
parse->limitOffset)
2443 if (((
Const *) est)->constisnull)
2451 if (*offset_est < 0)
2461 if (*count_est != 0)
2468 if (*count_est < 0 || *offset_est < 0)
2471 limit_fraction = 0.10;
2476 limit_fraction = (double) *count_est + (
double) *offset_est;
2486 if (tuple_fraction >= 1.0)
2488 if (limit_fraction >= 1.0)
2491 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2498 else if (tuple_fraction > 0.0)
2500 if (limit_fraction >= 1.0)
2503 tuple_fraction = limit_fraction;
2508 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2514 tuple_fraction = limit_fraction;
2517 else if (*offset_est != 0 && tuple_fraction > 0.0)
2528 if (*offset_est < 0)
2529 limit_fraction = 0.10;
2531 limit_fraction = (double) *offset_est;
2539 if (tuple_fraction >= 1.0)
2541 if (limit_fraction >= 1.0)
2544 tuple_fraction += limit_fraction;
2549 tuple_fraction = limit_fraction;
2554 if (limit_fraction >= 1.0)
2561 tuple_fraction += limit_fraction;
2562 if (tuple_fraction >= 1.0)
2563 tuple_fraction = 0.0;
2568 return tuple_fraction;
2590 node =
parse->limitCount;
2596 if (!((
Const *) node)->constisnull)
2603 node =
parse->limitOffset;
2609 if (!((
Const *) node)->constisnull)
2658 if (
parse->groupingSets)
2701 foreach(lc,
parse->rtable)
2719 if (rte->
inh && rte->
relkind != RELKIND_PARTITIONED_TABLE)
2723 relattnos = groupbyattnos[relid];
2732 if (pkattnos == NULL)
2745 if (surplusvars == NULL)
2759 if (surplusvars != NULL)
2776 surplusvars[var->
varno]))
2777 new_groupby =
lappend(new_groupby, sgc);
2826 new_groupclause =
lappend(new_groupclause, cl);
2829 return new_groupclause;
2842 foreach(sl,
parse->sortClause)
2846 foreach(gl,
parse->groupClause)
2852 new_groupclause =
lappend(new_groupclause, gc);
2861 partial_match = (sl != NULL);
2864 if (new_groupclause ==
NIL)
2875 foreach(gl,
parse->groupClause)
2885 new_groupclause =
lappend(new_groupclause, gc);
2890 return new_groupclause;
2925 short *adjacency_buf;
2941 lc1 =
lnext(groupingSets, lc1);
2966 orig_sets =
palloc0((num_sets_raw + 1) *
sizeof(
List *));
2968 adjacency =
palloc0((num_sets_raw + 1) *
sizeof(
short *));
2969 adjacency_buf =
palloc((num_sets_raw + 1) *
sizeof(
short));
2982 foreach(lc2, candidate)
2992 for (k =
j; k <
i; ++k)
2994 if (
bms_equal(set_masks[k], candidate_set))
3009 orig_sets[dup_of] =
lappend(orig_sets[dup_of], candidate);
3018 set_masks[
i] = candidate_set;
3022 for (k =
j - 1; k > 0; --k)
3025 adjacency_buf[++n_adj] = k;
3030 adjacency_buf[0] = n_adj;
3031 adjacency[
i] =
palloc((n_adj + 1) *
sizeof(
short));
3032 memcpy(adjacency[
i], adjacency_buf, (n_adj + 1) *
sizeof(
short));
3035 adjacency[
i] = NULL;
3054 chains =
palloc0((num_sets + 1) *
sizeof(
int));
3056 for (
i = 1;
i <= num_sets; ++
i)
3058 int u =
state->pair_vu[
i];
3059 int v =
state->pair_uv[
i];
3062 chains[
i] = chains[u];
3063 else if (v > 0 && v <
i)
3064 chains[
i] = chains[v];
3066 chains[
i] = ++num_chains;
3070 results =
palloc0((num_chains + 1) *
sizeof(
List *));
3072 for (
i = 1;
i <= num_sets; ++
i)
3082 while (num_empty-- > 0)
3083 results[1] =
lcons(
NIL, results[1]);
3086 for (
i = 1;
i <= num_chains; ++
i)
3087 result =
lappend(result, results[
i]);
3098 for (
i = 1;
i <= num_sets; ++
i)
3102 pfree(adjacency_buf);
3104 for (
i = 1;
i <= num_sets; ++
i)
3131 foreach(lc, groupingSets)
3159 result =
lcons(gs, result);
3181 if (pathkey->pk_eclass->ec_has_volatile)
3240 unprocessed_aggs = NULL;
3246 if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3307 if (currpathkeys ==
NIL)
3309 currpathkeys = pathkeys;
3312 if (grouppathkeys !=
NIL)
3324 if (grouppathkeys !=
NIL)
3333 currpathkeys = pathkeys;
3360 bestaggs = aggindexes;
3361 bestpathkeys = currpathkeys;
3370 if (bestpathkeys !=
NIL)
3390 aggref->aggpresorted =
true;
3473 if (activeWindows !=
NIL)
3490 if (
parse->distinctClause)
3564 if (
parse->groupClause)
3568 if (
parse->groupingSets)
3641 else if (
parse->groupingSets)
3681 bool target_parallel_safe,
3697 target_parallel_safe,
parse->havingQual);
3756 extra.
flags = flags;
3774 &agg_costs, gd, &extra,
3775 &partially_grouped_rel);
3792 PathTarget *target,
bool target_parallel_safe,
3831 grouped_rel->fdwroutine = input_rel->fdwroutine;
3884 while (--nrows >= 0)
3979 bool force_rel_creation;
3988 partially_grouped_rel =
3994 force_rel_creation);
3998 *partially_grouped_rel_p = partially_grouped_rel;
4003 partially_grouped_rel, agg_costs,
4009 Assert(partially_grouped_rel);
4011 if (partially_grouped_rel->
pathlist)
4028 cheapest_path->
rows,
4034 partially_grouped_rel, agg_costs, gd,
4040 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4041 errmsg(
"could not implement GROUP BY"),
4042 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
4048 if (grouped_rel->fdwroutine &&
4049 grouped_rel->fdwroutine->GetForeignUpperPaths)
4051 input_rel, grouped_rel,
4057 input_rel, grouped_rel,
4102 double exclude_groups = 0.0;
4126 if (l_start != NULL &&
4130 exclude_groups = unhashed_rollup->
numGroups;
4137 dNumGroups - exclude_groups);
4144 if (hashsize > hash_mem_limit && gd->
rollups)
4173 foreach(lc, sets_data)
4182 empty_sets_data =
lappend(empty_sets_data, gs);
4197 new_rollups =
lappend(new_rollups, rollup);
4205 if (new_rollups ==
NIL)
4212 Assert(!unhashed_rollup || !empty_sets);
4214 if (unhashed_rollup)
4216 new_rollups =
lappend(new_rollups, unhashed_rollup);
4219 else if (empty_sets)
4225 rollup->
gsets = empty_sets;
4229 new_rollups =
lappend(new_rollups, rollup);
4262 double availspace = hash_mem_limit;
4278 int *k_weights =
palloc(num_rollups *
sizeof(
int));
4304 scale =
Max(availspace / (20.0 * num_rollups), 1.0);
4305 k_capacity = (int) floor(availspace /
scale);
4329 k_weights[
i] = (int)
Min(floor(sz /
scale),
4359 rollups =
lappend(rollups, rollup);
4363 rollups =
lappend(rollups, rollup);
4368 if (!rollups && hash_sets)
4371 foreach(lc, hash_sets)
4386 rollups =
lcons(rollup, rollups);
4434 bool output_target_parallel_safe,
4436 List *activeWindows)
4459 window_rel->fdwroutine = input_rel->fdwroutine;
4488 if (window_rel->fdwroutine &&
4489 window_rel->fdwroutine->GetForeignUpperPaths)
4491 input_rel, window_rel,
4497 input_rel, window_rel, NULL);
4523 List *activeWindows)
4544 window_target = input_target;
4546 foreach(l, activeWindows)
4549 List *window_pathkeys;
4589 if (
lnext(activeWindows, l))
4613 window_target = output_target;
4630 wc, topwindow ? topqual :
NIL, topwindow);
4669 distinct_rel->fdwroutine = input_rel->fdwroutine;
4680 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4681 errmsg(
"could not implement DISTINCT"),
4682 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
4688 if (distinct_rel->fdwroutine &&
4689 distinct_rel->fdwroutine->GetForeignUpperPaths)
4690 distinct_rel->fdwroutine->GetForeignUpperPaths(root,
4699 distinct_rel, NULL);
4704 return distinct_rel;
4721 List *distinctExprs;
4722 double numDistinctRows;
4723 Path *cheapest_partial_path;
4733 if (
parse->hasDistinctOn)
4747 partial_distinct_rel->fdwroutine = input_rel->fdwroutine;
4756 cheapest_partial_path->
rows,
4777 sorted_path = input_path;
4787 if (input_path != cheapest_partial_path &&
4798 partial_distinct_rel,
4804 partial_distinct_rel,
4829 partial_distinct_rel,
4830 cheapest_partial_path,
4831 cheapest_partial_path->pathtarget,
4844 if (partial_distinct_rel->fdwroutine &&
4845 partial_distinct_rel->fdwroutine->GetForeignUpperPaths)
4846 partial_distinct_rel->fdwroutine->GetForeignUpperPaths(root,
4849 partial_distinct_rel,
4855 input_rel, partial_distinct_rel, NULL);
4868 final_distinct_rel);
4885 double numDistinctRows;
4897 numDistinctRows = cheapest_input_path->
rows;
4904 List *distinctExprs;
4909 cheapest_input_path->
rows,
4932 List *needed_pathkeys;
4936 if (
parse->hasDistinctOn &&
4955 sorted_path = input_path;
4965 if (input_path != cheapest_input_path &&
5056 cheapest_input_path,
5057 cheapest_input_path->pathtarget,
5066 return distinct_rel;
5090 bool target_parallel_safe,
5091 double limit_tuples)
5114 ordered_rel->fdwroutine = input_rel->fdwroutine;
5124 input_path->
pathkeys, &presorted_keys);
5127 sorted_path = input_path;
5137 if (input_path != cheapest_input_path &&
5162 if (sorted_path->pathtarget != target)
5164 sorted_path, target);
5166 add_path(ordered_rel, sorted_path);
5182 Path *cheapest_partial_path;
5194 double total_groups;
5198 cheapest_partial_path,
5202 total_groups = cheapest_partial_path->
rows *
5212 if (path->pathtarget != target)
5234 double total_groups;
5251 if (presorted_keys == 0)
5261 total_groups = input_path->
rows *
5263 sorted_path = (
Path *)
5266 sorted_path->pathtarget,
5271 if (sorted_path->pathtarget != target)
5273 sorted_path, target);
5275 add_path(ordered_rel, sorted_path);
5284 if (ordered_rel->fdwroutine &&
5285 ordered_rel->fdwroutine->GetForeignUpperPaths)
5287 input_rel, ordered_rel,
5293 input_rel, ordered_rel, NULL);
5337 List *non_group_cols;
5338 List *non_group_vars;
5347 non_group_cols =
NIL;
5350 foreach(lc, final_target->
exprs)
5370 non_group_cols =
lappend(non_group_cols, expr);
5379 if (
parse->havingQual)
5380 non_group_cols =
lappend(non_group_cols,
parse->havingQual);
5426 List *non_group_cols;
5427 List *non_group_exprs;
5432 non_group_cols =
NIL;
5435 foreach(lc, grouping_target->
exprs)
5456 non_group_cols =
lappend(non_group_cols, expr);
5466 non_group_cols =
lappend(non_group_cols, havingQual);
5487 foreach(lc, partial_target->
exprs)
5500 memcpy(newaggref, aggref,
sizeof(
Aggref));
5532 agg->aggsplit = aggsplit;
5542 agg->aggtype = BYTEAOID;
5544 agg->aggtype = agg->aggtranstype;
5564 foreach(l, new_tlist)
5570 if (new_tle->resjunk)
5573 Assert(orig_tlist_item != NULL);
5575 orig_tlist_item =
lnext(orig_tlist, orig_tlist_item);
5576 if (orig_tle->resjunk)
5577 elog(
ERROR,
"resjunk output columns are not implemented");
5581 if (orig_tlist_item != NULL)
5582 elog(
ERROR,
"resjunk output columns are not implemented");
5601 foreach(lc, windowClause)
5605 int optimizedFrameOptions = 0;
5626 req.
type = T_SupportRequestOptimizeWindowClause;
5648 optimizedFrameOptions =
res->frameOptions;
5655 else if (optimizedFrameOptions !=
res->frameOptions)
5660 if (lc2 == NULL && wc->
frameOptions != optimizedFrameOptions)
5680 foreach(lc3, windowClause)
5685 if (existing_wc == wc)
5746 foreach(lc, windowClause)
5755 actives[nActive].
wc = wc;
5799 for (
int i = 0;
i < nActive;
i++)
5800 result =
lappend(result, actives[
i].wc);
<