74 double dNumGroups,
double dNumOutputRows,
75 const char *construct);
86 List *refnames_tlist);
110 Query *leftmostQuery;
148 leftmostRTE = root->simple_rte_array[((
RangeTblRef *) node)->rtindex];
149 leftmostQuery = leftmostRTE->
subquery;
150 Assert(leftmostQuery != NULL);
170 topop->colTypes, topop->colCollations,
209 List *colTypes,
List *colCollations,
251 elog(
ERROR,
"unexpected outer reference in set operation subquery");
264 *pTargetList = tlist;
310 Path *partial_subpath;
314 partial_path = (
Path *)
364 *pNumGroups = rel->
rows;
427 elog(
ERROR,
"unrecognized node type: %d",
442 List *refnames_tlist,
459 elog(
ERROR,
"only UNION queries can be recursive");
468 setOp->colTypes, setOp->colCollations,
477 setOp->colTypes, setOp->colCollations,
492 *pTargetList = tlist;
515 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
516 errmsg(
"could not implement recursive UNION"),
517 errdetail(
"All column datatypes must be hashable.")));
523 dNumGroups = lpath->
rows + rpath->
rows * 10;
548 List *refnames_tlist,
557 bool partial_paths_valid =
true;
558 bool consider_parallel =
true;
594 tlist_list, refnames_tlist);
596 *pTargetList = tlist;
605 if (consider_parallel)
609 consider_parallel =
false;
610 partial_paths_valid =
false;
613 partial_paths_valid =
false;
615 partial_pathlist =
lappend(partial_pathlist,
631 NIL, NULL, 0,
false, -1);
653 if (partial_paths_valid)
656 int parallel_workers = 0;
659 foreach(lc, partial_pathlist)
663 parallel_workers =
Max(parallel_workers,
666 Assert(parallel_workers > 0);
677 parallel_workers =
Max(parallel_workers,
679 parallel_workers =
Min(parallel_workers,
682 Assert(parallel_workers > 0);
708 List *refnames_tlist,
739 op->colTypes, op->colCollations,
746 op->colTypes, op->colCollations,
765 tlist_list =
list_make2(lpath_tlist, rpath_tlist);
771 tlist_list =
list_make2(rpath_tlist, lpath_tlist);
785 tlist_list, refnames_tlist);
787 *pTargetList = tlist;
798 NIL, NULL, 0,
false, -1);
813 dNumGroups = dLeftGroups;
814 dNumOutputRows = op->
all ? lpath->
rows : dNumGroups;
818 dNumGroups =
Min(dLeftGroups, dRightGroups);
819 dNumOutputRows = op->
all ?
Min(lpath->
rows, rpath->
rows) : dNumGroups;
826 dNumGroups, dNumOutputRows,
829 if (groupList && !use_hash)
850 elog(
ERROR,
"unrecognized set op: %d", (
int) op->
op);
861 use_hash ? firstFlag : -1,
886 List *refnames_tlist,
895 while (pending_rels !=
NIL)
905 if (op->
op == top_union->
op &&
906 (op->
all == top_union->
all || op->
all) &&
907 equal(op->colTypes, top_union->colTypes))
910 pending_rels =
lcons(op->
rarg, pending_rels);
911 pending_rels =
lcons(op->
larg, pending_rels);
928 top_union->colCollations,
933 *tlist_list =
lappend(*tlist_list, child_tlist);
960 dNumGroups = path->
rows;
964 dNumGroups, dNumGroups,
1025 double dNumGroups,
double dNumOutputRows,
1026 const char *construct)
1035 double tuple_fraction;
1040 if (can_hash && can_sort)
1050 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1052 errmsg(
"could not implement %s", construct),
1053 errdetail(
"Some of the datatypes only support hashing, while others only support sorting.")));
1065 if (hashentrysize * dNumGroups > hash_mem_limit)
1080 numGroupCols, dNumGroups,
1083 input_path->
rows, input_path->pathtarget->width);
1093 input_path->
rows, input_path->pathtarget->width,
1095 cost_group(&sorted_p, root, numGroupCols, dNumGroups,
1105 if (tuple_fraction >= 1.0)
1106 tuple_fraction /= dNumOutputRows;
1109 tuple_fraction) < 0)
1133 bool hack_constants,
1135 List *refnames_tlist,
1136 bool *trivial_tlist)
1147 *trivial_tlist =
true;
1149 forfour(ctlc, colTypes, cclc, colCollations,
1150 itlc, input_tlist, rtlc, refnames_tlist)
1159 Assert(!inputtle->resjunk);
1160 Assert(!reftle->resjunk);
1201 "UNION/INTERSECT/EXCEPT");
1202 *trivial_tlist =
false;
1221 *trivial_tlist =
false;
1255 *trivial_tlist =
false;
1282 List *refnames_tlist)
1303 foreach(tlistl, input_tlists)
1310 foreach(subtlistl, subtlist)
1314 if (subtle->resjunk)
1316 Assert(curColType != NULL);
1323 colTypmods[colindex] = subtypmod;
1324 else if (subtypmod != colTypmods[colindex])
1325 colTypmods[colindex] = -1;
1330 colTypmods[colindex] = -1;
1332 curColType =
lnext(colTypes, curColType);
1335 Assert(curColType == NULL);
1342 forthree(curColType, colTypes, curColCollation, colCollations,
1343 ref_tl_item, refnames_tlist)
1346 int32 colTypmod = colTypmods[colindex++];
1351 Assert(!reftle->resjunk);
1414 foreach(lt, targetlist)
1432 lg =
lnext(grouplist, lg);
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
int max_parallel_workers_per_gather
void cost_agg(Path *path, PlannerInfo *root, AggStrategy aggstrategy, const AggClauseCosts *aggcosts, int numGroupCols, double numGroups, List *quals, Cost input_startup_cost, Cost input_total_cost, double input_tuples, double input_width)
void set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel)
bool enable_parallel_append
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)
void cost_group(Path *path, PlannerInfo *root, int numGroupCols, double numGroups, List *quals, Cost input_startup_cost, Cost input_total_cost, double input_tuples)
elog(ERROR, "%s: %s", p2, msg)
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)
#define SizeofMinimalTupleHeader
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
List * list_delete_first(List *list)
List * lcons(void *datum, List *list)
Datum subpath(PG_FUNCTION_ARGS)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
char * pstrdup(const char *in)
void pfree(void *pointer)
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
size_t get_hash_memory_limit(void)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
List * make_pathkeys_for_sortclauses(PlannerInfo *root, List *sortclauses, List *tlist)
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)
ProjectionPath * create_projection_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target)
UpperUniquePath * create_upper_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, int numCols, double numGroups)
GatherPath * create_gather_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, Relids required_outer, double *rows)
void set_cheapest(RelOptInfo *parent_rel)
SubqueryScanPath * create_subqueryscan_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, bool trivial_pathtarget, List *pathkeys, Relids required_outer)
void add_partial_path(RelOptInfo *parent_rel, Path *new_path)
int compare_fractional_path_costs(Path *path1, Path *path2, double fraction)
SetOpPath * create_setop_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, SetOpCmd cmd, SetOpStrategy strategy, List *distinctList, AttrNumber flagColIdx, int firstFlag, double numGroups, double outputRows)
RecursiveUnionPath * create_recursiveunion_path(PlannerInfo *root, RelOptInfo *rel, Path *leftpath, Path *rightpath, PathTarget *target, List *distinctList, int wtParam, double numGroups)
AggPath * create_agg_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, AggStrategy aggstrategy, AggSplit aggsplit, List *groupClause, List *qual, const AggClauseCosts *aggcosts, double numGroups)
void add_path(RelOptInfo *parent_rel, Path *new_path)
Path * apply_projection_to_path(PlannerInfo *root, RelOptInfo *rel, Path *path, PathTarget *target)
static int pg_leftmost_one_pos32(uint32 word)
static int list_length(const List *l)
#define forthree(cell1, list1, cell2, list2, cell3, list3)
static ListCell * list_head(const List *l)
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make2(x1, x2)
PlannerInfo * subquery_planner(PlannerGlobal *glob, Query *parse, PlannerInfo *parent_root, bool hasRecursion, double tuple_fraction)
create_upper_paths_hook_type create_upper_paths_hook
Path * get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction)
void check_stack_depth(void)
static Datum Int32GetDatum(int32 X)
static List * generate_setop_tlist(List *colTypes, List *colCollations, int flag, Index varno, bool hack_constants, List *input_tlist, List *refnames_tlist, bool *trivial_tlist)
static Path * make_union_unique(SetOperationStmt *op, Path *path, List *tlist, PlannerInfo *root)
static List * generate_setop_grouplist(SetOperationStmt *op, List *targetlist)
static RelOptInfo * generate_union_paths(SetOperationStmt *op, PlannerInfo *root, List *refnames_tlist, List **pTargetList)
static List * plan_union_children(PlannerInfo *root, SetOperationStmt *top_union, List *refnames_tlist, List **tlist_list)
static RelOptInfo * generate_nonunion_paths(SetOperationStmt *op, PlannerInfo *root, List *refnames_tlist, List **pTargetList)
static void postprocess_setop_rel(PlannerInfo *root, RelOptInfo *rel)
static bool choose_hashed_setop(PlannerInfo *root, List *groupClauses, Path *input_path, double dNumGroups, double dNumOutputRows, const char *construct)
static List * generate_append_tlist(List *colTypes, List *colCollations, bool flag, List *input_tlists, List *refnames_tlist)
static RelOptInfo * generate_recursion_path(SetOperationStmt *setOp, PlannerInfo *root, List *refnames_tlist, List **pTargetList)
static RelOptInfo * recurse_set_operations(Node *setOp, PlannerInfo *root, List *colTypes, List *colCollations, bool junkOK, int flag, List *refnames_tlist, List **pTargetList, double *pNumGroups)
RelOptInfo * plan_set_operations(PlannerInfo *root)
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
void setup_simple_rel_arrays(PlannerInfo *root)
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)
struct Path * non_recursive_path
Selectivity tuple_fraction
struct PathTarget * reltarget
struct Path * cheapest_total_path
bool tlist_same_collations(List *tlist, List *colCollations, bool junkOK)
List * get_tlist_exprs(List *tlist, bool includeJunk)
bool grouping_is_sortable(List *groupClause)
bool grouping_is_hashable(List *groupClause)
bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
#define create_pathtarget(root, tlist)