40 #ifdef OPTIMIZER_DEBUG
81 #define EXPRKIND_QUAL 0
82 #define EXPRKIND_TARGET 1
83 #define EXPRKIND_RTFUNC 2
84 #define EXPRKIND_RTFUNC_LATERAL 3
85 #define EXPRKIND_VALUES 4
86 #define EXPRKIND_VALUES_LATERAL 5
87 #define EXPRKIND_LIMIT 6
88 #define EXPRKIND_APPINFO 7
89 #define EXPRKIND_PHV 8
90 #define EXPRKIND_TABLESAMPLE 9
91 #define EXPRKIND_ARBITER_ELEM 10
92 #define EXPRKIND_TABLEFUNC 11
93 #define EXPRKIND_TABLEFUNC_LATERAL 12
135 int *tleref_to_colnum_map);
138 double tuple_fraction,
139 int64 *offset_est, int64 *count_est);
152 bool target_parallel_safe,
159 PathTarget *target,
bool target_parallel_safe,
180 bool output_target_parallel_safe,
182 List *activeWindows);
189 List *activeWindows);
201 bool target_parallel_safe,
202 double limit_tuples);
212 List *activeWindows);
217 bool *have_postponed_srfs);
219 List *targets,
List *targets_contain_srfs);
232 bool force_rel_creation);
237 List *scanjoin_targets,
238 List *scanjoin_targets_contain_srfs,
239 bool scanjoin_target_parallel_safe,
275 result = (*planner_hook) (
parse, query_string, cursorOptions, boundParams);
287 double tuple_fraction;
342 !
parse->hasModifyingCTE &&
394 if (tuple_fraction >= 1.0)
395 tuple_fraction = 0.0;
396 else if (tuple_fraction <= 0.0)
397 tuple_fraction = 1
e-10;
402 tuple_fraction = 0.0;
407 false, tuple_fraction);
471 top_plan = &gather->
plan;
598 bool hasRecursion,
double tuple_fraction)
601 List *newWithCheckOptions;
669 if (
parse->hasSubLinks)
692 if (
parse->setOperations)
707 hasOuterJoins =
false;
708 hasResultRTEs =
false;
709 foreach(l,
parse->rtable)
735 hasOuterJoins =
true;
738 hasResultRTEs =
true;
763 if (
parse->resultRelation)
796 if (
parse->hasTargetSRFs)
799 newWithCheckOptions =
NIL;
800 foreach(l,
parse->withCheckOptions)
806 if (wco->
qual != NULL)
807 newWithCheckOptions =
lappend(newWithCheckOptions, wco);
809 parse->withCheckOptions = newWithCheckOptions;
820 foreach(l,
parse->windowClause)
836 if (
parse->onConflict)
838 parse->onConflict->arbiterElems = (
List *)
840 (
Node *)
parse->onConflict->arbiterElems,
842 parse->onConflict->arbiterWhere =
844 parse->onConflict->arbiterWhere,
846 parse->onConflict->onConflictSet = (
List *)
848 (
Node *)
parse->onConflict->onConflictSet,
850 parse->onConflict->onConflictWhere =
852 parse->onConflict->onConflictWhere,
857 foreach(l,
parse->mergeActionList)
876 foreach(l,
parse->rtable)
953 foreach(l,
parse->rtable)
997 if ((
parse->groupClause &&
parse->groupingSets) ||
1003 newHaving =
lappend(newHaving, havingclause);
1005 else if (
parse->groupClause && !
parse->groupingSets)
1017 newHaving =
lappend(newHaving, havingclause);
1133 #ifdef OPTIMIZER_DEBUG
1134 printf(
"After canonicalize_qual()\n");
1208 elog(
ERROR,
"unrecognized node type: %d",
1256 int64 offset_est = 0;
1257 int64 count_est = 0;
1258 double limit_tuples = -1.0;
1259 bool have_postponed_srfs =
false;
1261 List *final_targets;
1262 List *final_targets_contain_srfs;
1263 bool final_target_parallel_safe;
1273 &offset_est, &count_est);
1279 if (count_est > 0 && offset_est >= 0)
1280 limit_tuples = (double) count_est + (
double) offset_est;
1286 if (
parse->setOperations)
1296 if (
parse->sortClause)
1325 final_target_parallel_safe =
1330 final_targets = final_targets_contain_srfs =
NIL;
1336 if (
parse->rowMarks)
1338 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1341 errmsg(
"%s is not allowed with UNION/INTERSECT/EXCEPT",
1343 parse->rowMarks)->strength))));
1357 List *sort_input_targets;
1358 List *sort_input_targets_contain_srfs;
1359 bool sort_input_target_parallel_safe;
1361 List *grouping_targets;
1362 List *grouping_targets_contain_srfs;
1363 bool grouping_target_parallel_safe;
1365 List *scanjoin_targets;
1366 List *scanjoin_targets_contain_srfs;
1367 bool scanjoin_target_parallel_safe;
1368 bool scanjoin_target_same_exprs;
1379 if (
parse->groupingSets)
1386 if (
parse->groupClause)
1418 if (
parse->hasWindowFuncs)
1425 parse->hasWindowFuncs =
false;
1443 if (
parse->groupClause ||
1444 parse->groupingSets ||
1445 parse->distinctClause ||
1447 parse->hasWindowFuncs ||
1448 parse->hasTargetSRFs ||
1458 :
parse->groupClause);
1479 final_target_parallel_safe =
1487 if (
parse->sortClause)
1491 &have_postponed_srfs);
1492 sort_input_target_parallel_safe =
1497 sort_input_target = final_target;
1498 sort_input_target_parallel_safe = final_target_parallel_safe;
1511 grouping_target_parallel_safe =
1516 grouping_target = sort_input_target;
1517 grouping_target_parallel_safe = sort_input_target_parallel_safe;
1525 have_grouping = (
parse->groupClause ||
parse->groupingSets ||
1530 scanjoin_target_parallel_safe =
1535 scanjoin_target = grouping_target;
1536 scanjoin_target_parallel_safe = grouping_target_parallel_safe;
1545 if (
parse->hasTargetSRFs)
1550 &final_targets_contain_srfs);
1555 &sort_input_targets,
1556 &sort_input_targets_contain_srfs);
1562 &grouping_targets_contain_srfs);
1568 &scanjoin_targets_contain_srfs);
1575 final_targets = final_targets_contain_srfs =
NIL;
1576 sort_input_targets = sort_input_targets_contain_srfs =
NIL;
1577 grouping_targets = grouping_targets_contain_srfs =
NIL;
1578 scanjoin_targets =
list_make1(scanjoin_target);
1579 scanjoin_targets_contain_srfs =
NIL;
1583 scanjoin_target_same_exprs =
list_length(scanjoin_targets) == 1
1586 scanjoin_targets_contain_srfs,
1587 scanjoin_target_parallel_safe,
1588 scanjoin_target_same_exprs);
1614 grouping_target_parallel_safe,
1617 if (
parse->hasTargetSRFs)
1620 grouping_targets_contain_srfs);
1633 sort_input_target_parallel_safe,
1637 if (
parse->hasTargetSRFs)
1640 sort_input_targets_contain_srfs);
1647 if (
parse->distinctClause)
1661 if (
parse->sortClause)
1666 final_target_parallel_safe,
1667 have_postponed_srfs ? -1.0 :
1670 if (
parse->hasTargetSRFs)
1673 final_targets_contain_srfs);
1716 if (
parse->rowMarks)
1732 offset_est, count_est);
1742 List *updateColnosLists =
NIL;
1743 List *withCheckOptionLists =
NIL;
1752 parse->resultRelation);
1753 int resultRelation = -1;
1757 resultRelation)) >= 0)
1777 if (this_result_rel != top_result_rel)
1781 this_result_rel->
relid,
1782 top_result_rel->
relid);
1783 updateColnosLists =
lappend(updateColnosLists,
1786 if (
parse->withCheckOptions)
1788 List *withCheckOptions =
parse->withCheckOptions;
1790 if (this_result_rel != top_result_rel)
1791 withCheckOptions = (
List *)
1793 (
Node *) withCheckOptions,
1796 withCheckOptionLists =
lappend(withCheckOptionLists,
1799 if (
parse->returningList)
1801 List *returningList =
parse->returningList;
1803 if (this_result_rel != top_result_rel)
1804 returningList = (
List *)
1806 (
Node *) returningList,
1809 returningLists =
lappend(returningLists,
1812 if (
parse->mergeActionList)
1821 foreach(l,
parse->mergeActionList)
1831 leaf_action->targetList = (
List *)
1837 leaf_action->updateColnos =
1840 this_result_rel->
relid,
1841 top_result_rel->
relid);
1842 mergeActionList =
lappend(mergeActionList,
1846 mergeActionLists =
lappend(mergeActionLists,
1851 if (resultRelations ==
NIL)
1867 if (
parse->withCheckOptions)
1869 if (
parse->returningList)
1871 if (
parse->mergeActionList)
1881 if (
parse->withCheckOptions)
1883 if (
parse->returningList)
1885 if (
parse->mergeActionList)
1894 RELKIND_PARTITIONED_TABLE)
1895 rootRelation =
parse->resultRelation;
1904 if (
parse->rowMarks)
1914 parse->resultRelation,
1919 withCheckOptionLists,
1959 current_rel, final_rel,
1965 current_rel, final_rel, &extra);
1993 if (
parse->groupClause)
1997 foreach(lc,
parse->groupClause)
2026 foreach(lc,
parse->groupingSets)
2047 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2048 errmsg(
"could not implement GROUP BY"),
2049 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
2052 sortable_sets =
lappend(sortable_sets, gset);
2063 foreach(lc_set, sets)
2154 int *tleref_to_colnum_map)
2160 foreach(lc, groupClause)
2173 foreach(lc2, gs->
set)
2178 result =
lappend(result, set);
2197 if (
parse->rowMarks)
2206 parse->rowMarks)->strength);
2225 if (
parse->resultRelation)
2232 foreach(l,
parse->rowMarks)
2265 prowmarks =
lappend(prowmarks, newrc);
2272 foreach(l,
parse->rtable)
2290 prowmarks =
lappend(prowmarks, newrc);
2307 else if (rte->
relkind == RELKIND_FOREIGN_TABLE)
2343 elog(
ERROR,
"unrecognized LockClauseStrength %d", (
int) strength);
2367 int64 *offset_est, int64 *count_est)
2371 double limit_fraction;
2380 if (
parse->limitCount)
2385 if (((
Const *) est)->constisnull)
2393 if (*count_est <= 0)
2403 if (
parse->limitOffset)
2408 if (((
Const *) est)->constisnull)
2416 if (*offset_est < 0)
2426 if (*count_est != 0)
2433 if (*count_est < 0 || *offset_est < 0)
2436 limit_fraction = 0.10;
2441 limit_fraction = (double) *count_est + (
double) *offset_est;
2451 if (tuple_fraction >= 1.0)
2453 if (limit_fraction >= 1.0)
2456 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2463 else if (tuple_fraction > 0.0)
2465 if (limit_fraction >= 1.0)
2468 tuple_fraction = limit_fraction;
2473 tuple_fraction =
Min(tuple_fraction, limit_fraction);
2479 tuple_fraction = limit_fraction;
2482 else if (*offset_est != 0 && tuple_fraction > 0.0)
2493 if (*offset_est < 0)
2494 limit_fraction = 0.10;
2496 limit_fraction = (double) *offset_est;
2504 if (tuple_fraction >= 1.0)
2506 if (limit_fraction >= 1.0)
2509 tuple_fraction += limit_fraction;
2514 tuple_fraction = limit_fraction;
2519 if (limit_fraction >= 1.0)
2526 tuple_fraction += limit_fraction;
2527 if (tuple_fraction >= 1.0)
2528 tuple_fraction = 0.0;
2533 return tuple_fraction;
2555 node =
parse->limitCount;
2561 if (!((
Const *) node)->constisnull)
2568 node =
parse->limitOffset;
2574 if (!((
Const *) node)->constisnull)
2623 if (
parse->groupingSets)
2633 foreach(lc,
parse->groupClause)
2666 foreach(lc,
parse->rtable)
2684 if (rte->
inh && rte->
relkind != RELKIND_PARTITIONED_TABLE)
2688 relattnos = groupbyattnos[relid];
2697 if (pkattnos == NULL)
2710 if (surplusvars == NULL)
2724 if (surplusvars != NULL)
2728 foreach(lc,
parse->groupClause)
2741 surplusvars[var->
varno]))
2742 new_groupby =
lappend(new_groupby, sgc);
2745 parse->groupClause = new_groupby;
2787 new_groupclause =
lappend(new_groupclause, cl);
2790 return new_groupclause;
2795 return parse->groupClause;
2803 foreach(sl,
parse->sortClause)
2807 foreach(gl,
parse->groupClause)
2813 new_groupclause =
lappend(new_groupclause, gc);
2822 partial_match = (sl != NULL);
2825 if (new_groupclause ==
NIL)
2826 return parse->groupClause;
2836 foreach(gl,
parse->groupClause)
2843 return parse->groupClause;
2845 return parse->groupClause;
2846 new_groupclause =
lappend(new_groupclause, gc);
2851 return new_groupclause;
2886 short *adjacency_buf;
2902 lc1 =
lnext(groupingSets, lc1);
2927 orig_sets =
palloc0((num_sets_raw + 1) *
sizeof(
List *));
2929 adjacency =
palloc0((num_sets_raw + 1) *
sizeof(
short *));
2930 adjacency_buf =
palloc((num_sets_raw + 1) *
sizeof(
short));
2943 foreach(lc2, candidate)
2953 for (k =
j; k <
i; ++k)
2955 if (
bms_equal(set_masks[k], candidate_set))
2970 orig_sets[dup_of] =
lappend(orig_sets[dup_of], candidate);
2979 set_masks[
i] = candidate_set;
2983 for (k =
j - 1; k > 0; --k)
2986 adjacency_buf[++n_adj] = k;
2991 adjacency_buf[0] = n_adj;
2992 adjacency[
i] =
palloc((n_adj + 1) *
sizeof(
short));
2993 memcpy(adjacency[
i], adjacency_buf, (n_adj + 1) *
sizeof(
short));
2996 adjacency[
i] = NULL;
3015 chains =
palloc0((num_sets + 1) *
sizeof(
int));
3017 for (
i = 1;
i <= num_sets; ++
i)
3019 int u =
state->pair_vu[
i];
3020 int v =
state->pair_uv[
i];
3023 chains[
i] = chains[u];
3024 else if (v > 0 && v <
i)
3025 chains[
i] = chains[v];
3027 chains[
i] = ++num_chains;
3031 results =
palloc0((num_chains + 1) *
sizeof(
List *));
3033 for (
i = 1;
i <= num_sets; ++
i)
3043 while (num_empty-- > 0)
3044 results[1] =
lcons(
NIL, results[1]);
3047 for (
i = 1;
i <= num_chains; ++
i)
3048 result =
lappend(result, results[
i]);
3059 for (
i = 1;
i <= num_sets; ++
i)
3063 pfree(adjacency_buf);
3065 for (
i = 1;
i <= num_sets; ++
i)
3092 foreach(lc, groupingsets)
3120 result =
lcons(gs, result);
3154 if (activeWindows !=
NIL)
3165 if (
parse->distinctClause &&
3169 parse->distinctClause,
3230 if (
parse->groupClause)
3234 if (
parse->groupingSets)
3307 else if (
parse->groupingSets)
3347 bool target_parallel_safe,
3363 target_parallel_safe,
parse->havingQual);
3422 extra.
flags = flags;
3440 &agg_costs, gd, &extra,
3441 &partially_grouped_rel);
3458 PathTarget *target,
bool target_parallel_safe,
3550 while (--nrows >= 0)
3642 bool force_rel_creation;
3651 partially_grouped_rel =
3657 force_rel_creation);
3661 *partially_grouped_rel_p = partially_grouped_rel;
3666 partially_grouped_rel, agg_costs,
3672 Assert(partially_grouped_rel);
3674 if (partially_grouped_rel->
pathlist)
3691 cheapest_path->
rows,
3697 partially_grouped_rel, agg_costs, gd,
3703 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3704 errmsg(
"could not implement GROUP BY"),
3705 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
3714 input_rel, grouped_rel,
3720 input_rel, grouped_rel,
3765 double exclude_groups = 0.0;
3789 if (l_start != NULL &&
3793 exclude_groups = unhashed_rollup->
numGroups;
3800 dNumGroups - exclude_groups);
3807 if (hashsize > hash_mem_limit && gd->
rollups)
3836 foreach(lc, sets_data)
3845 empty_sets_data =
lappend(empty_sets_data, gs);
3860 new_rollups =
lappend(new_rollups, rollup);
3868 if (new_rollups ==
NIL)
3875 Assert(!unhashed_rollup || !empty_sets);
3877 if (unhashed_rollup)
3879 new_rollups =
lappend(new_rollups, unhashed_rollup);
3882 else if (empty_sets)
3888 rollup->
gsets = empty_sets;
3892 new_rollups =
lappend(new_rollups, rollup);
3925 double availspace = hash_mem_limit;
3941 int *k_weights =
palloc(num_rollups *
sizeof(
int));
3967 scale =
Max(availspace / (20.0 * num_rollups), 1.0);
3968 k_capacity = (int) floor(availspace /
scale);
3992 k_weights[
i] = (int)
Min(floor(sz /
scale),
4022 rollups =
lappend(rollups, rollup);
4026 rollups =
lappend(rollups, rollup);
4031 if (!rollups && hash_sets)
4034 foreach(lc, hash_sets)
4049 rollups =
lcons(rollup, rollups);
4097 bool output_target_parallel_safe,
4099 List *activeWindows)
4154 input_rel, window_rel,
4160 input_rel, window_rel, NULL);
4186 List *activeWindows)
4207 window_target = input_target;
4209 foreach(l, activeWindows)
4212 List *window_pathkeys;
4252 if (
lnext(activeWindows, l))
4276 window_target = output_target;
4293 wc, topwindow ? topqual :
NIL, topwindow);
4343 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4344 errmsg(
"could not implement DISTINCT"),
4345 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
4362 distinct_rel, NULL);
4367 return distinct_rel;
4384 List *distinctExprs;
4385 double numDistinctRows;
4386 Path *cheapest_partial_path;
4396 if (
parse->hasDistinctOn)
4419 cheapest_partial_path->
rows,
4433 partial_distinct_rel,
4451 partial_distinct_rel,
4452 cheapest_partial_path,
4456 parse->distinctClause,
4471 partial_distinct_rel,
4477 input_rel, partial_distinct_rel, NULL);
4490 final_distinct_rel);
4507 double numDistinctRows;
4521 numDistinctRows = cheapest_input_path->
rows;
4528 List *distinctExprs;
4533 cheapest_input_path->
rows,
4554 List *needed_pathkeys;
4556 if (
parse->hasDistinctOn &&
4589 path = cheapest_input_path;
4628 cheapest_input_path,
4632 parse->distinctClause,
4638 return distinct_rel;
4662 bool target_parallel_safe,
4663 double limit_tuples)
4691 Path *sorted_path = input_path;
4696 input_path->
pathkeys, &presorted_keys);
4703 sorted_path, target);
4705 add_path(ordered_rel, sorted_path);
4714 if (input_path == cheapest_input_path)
4728 sorted_path, target);
4730 add_path(ordered_rel, sorted_path);
4744 if (!presorted_keys)
4758 sorted_path, target);
4760 add_path(ordered_rel, sorted_path);
4777 Path *cheapest_partial_path;
4789 double total_groups;
4793 cheapest_partial_path,
4797 total_groups = cheapest_partial_path->
rows *
4831 double total_groups;
4848 if (presorted_keys == 0)
4858 total_groups = input_path->
rows *
4860 sorted_path = (
Path *)
4870 sorted_path, target);
4872 add_path(ordered_rel, sorted_path);
4884 input_rel, ordered_rel,
4890 input_rel, ordered_rel, NULL);
4934 List *non_group_cols;
4935 List *non_group_vars;
4944 non_group_cols =
NIL;
4947 foreach(lc, final_target->
exprs)
4952 if (sgref &&
parse->groupClause &&
4966 non_group_cols =
lappend(non_group_cols, expr);
4975 if (
parse->havingQual)
4976 non_group_cols =
lappend(non_group_cols,
parse->havingQual);
5023 List *non_group_cols;
5024 List *non_group_exprs;
5029 non_group_cols =
NIL;
5032 foreach(lc, grouping_target->
exprs)
5037 if (sgref &&
parse->groupClause &&
5052 non_group_cols =
lappend(non_group_cols, expr);
5062 non_group_cols =
lappend(non_group_cols, havingQual);
5083 foreach(lc, partial_target->
exprs)
5096 memcpy(newaggref, aggref,
sizeof(
Aggref));
5160 foreach(l, new_tlist)
5169 Assert(orig_tlist_item != NULL);
5171 orig_tlist_item =
lnext(orig_tlist, orig_tlist_item);
5173 elog(
ERROR,
"resjunk output columns are not implemented");
5177 if (orig_tlist_item != NULL)
5178 elog(
ERROR,
"resjunk output columns are not implemented");
5198 foreach(lc, windowClause)
5207 actives[nActive].
wc = wc;
5251 for (
int i = 0;
i < nActive;
i++)
5252 result =
lappend(result, actives[
i].wc);
5339 List *activeWindows)
5344 List *flattenable_cols;
5345 List *flattenable_vars;
5356 foreach(lc, activeWindows)
5376 foreach(lc,
parse->groupClause)
5388 flattenable_cols =
NIL;
5391 foreach(lc, final_target->
exprs)
5415 flattenable_cols =
lappend(flattenable_cols, expr);
5458 List *window_pathkeys;
5459 List *window_sortclauses;
5464 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5465 errmsg(
"could not implement window PARTITION BY"),
5466 errdetail(
"Window partitioning columns must be of sortable datatypes.")));
5469 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5470 errmsg(
"could not implement window ORDER BY"),
5471 errdetail(
"Window ordering columns must be of sortable datatypes.")));
5479 return window_pathkeys;
5551 bool *have_postponed_srfs)
5560 bool have_expensive;
5561 bool have_srf_sortcols;
5563 List *postponable_cols;
5564 List *postponable_vars;
5571 *have_postponed_srfs =
false;
5575 col_is_srf = (
bool *)
palloc0(ncols *
sizeof(
bool));
5576 postpone_col = (
bool *)
palloc0(ncols *
sizeof(
bool));
5577 have_srf = have_volatile = have_expensive = have_srf_sortcols =
false;
5580 foreach(lc, final_target->
exprs)
5598 if (
parse->hasTargetSRFs &&
5602 col_is_srf[
i] =
true;
5608 postpone_col[
i] =
true;
5609 have_volatile =
true;
5629 postpone_col[
i] =
true;
5630 have_expensive =
true;
5637 if (!have_srf_sortcols &&
5638 parse->hasTargetSRFs &&
5640 have_srf_sortcols =
true;
5649 postpone_srfs = (have_srf && !have_srf_sortcols);
5654 if (!(postpone_srfs || have_volatile ||
5657 return final_target;
5665 *have_postponed_srfs = postpone_srfs;
5673 postponable_cols =
NIL;
5676 foreach(lc, final_target->
exprs)
5680 if (postpone_col[
i] || (postpone_srfs && col_is_srf[
i]))
5681 postponable_cols =
lappend(postponable_cols, expr);
5726 if (tuple_fraction <= 0.0)
5730 if (tuple_fraction >= 1.0 && best_path->
rows > 0)
5731 tuple_fraction /= best_path->
rows;
5764 List *targets,
List *targets_contain_srfs)
5793 forboth(lc1, targets, lc2, targets_contain_srfs)