📄 createplan.c
字号:
dest->plan_rows = 0; dest->plan_width = 0; }}/* * Copy cost and size info from a lower plan node to an inserted node. * This is not critical, since the decisions have already been made, * but it helps produce more reasonable-looking EXPLAIN output. * (Some callers alter the info after copying it.) */static voidcopy_plan_costsize(Plan *dest, Plan *src){ if (src) { dest->startup_cost = src->startup_cost; dest->total_cost = src->total_cost; dest->plan_rows = src->plan_rows; dest->plan_width = src->plan_width; } else { dest->startup_cost = 0; dest->total_cost = 0; dest->plan_rows = 0; dest->plan_width = 0; }}/***************************************************************************** * * PLAN NODE BUILDING ROUTINES * * Some of these are exported because they are called to build plan nodes * in contexts where we're not deriving the plan node from a path node. * *****************************************************************************/static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid){ SeqScan *node = makeNode(SeqScan); Plan *plan = &node->plan; /* cost should be inserted by caller */ plan->targetlist = qptlist; plan->qual = qpqual; plan->lefttree = NULL; plan->righttree = NULL; node->scanrelid = scanrelid; return node;}static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid, Oid indexid, List *indexqual, List *indexqualorig, List *indexstrategy, List *indexsubtype, ScanDirection indexscandir){ IndexScan *node = makeNode(IndexScan); Plan *plan = &node->scan.plan; /* cost should be inserted by caller */ plan->targetlist = qptlist; plan->qual = qpqual; plan->lefttree = NULL; plan->righttree = NULL; node->scan.scanrelid = scanrelid; node->indexid = indexid; node->indexqual = indexqual; node->indexqualorig = indexqualorig; node->indexstrategy = indexstrategy; node->indexsubtype = indexsubtype; node->indexorderdir = indexscandir; return node;}static BitmapIndexScan *make_bitmap_indexscan(Index scanrelid, Oid indexid, List *indexqual, List *indexqualorig, List *indexstrategy, List *indexsubtype){ BitmapIndexScan *node = makeNode(BitmapIndexScan); Plan *plan = &node->scan.plan; /* cost should be inserted by caller */ plan->targetlist = NIL; /* not used */ plan->qual = NIL; /* not used */ plan->lefttree = NULL; plan->righttree = NULL; node->scan.scanrelid = scanrelid; node->indexid = indexid; node->indexqual = indexqual; node->indexqualorig = indexqualorig; node->indexstrategy = indexstrategy; node->indexsubtype = indexsubtype; return node;}static BitmapHeapScan *make_bitmap_heapscan(List *qptlist, List *qpqual, Plan *lefttree, List *bitmapqualorig, Index scanrelid){ BitmapHeapScan *node = makeNode(BitmapHeapScan); Plan *plan = &node->scan.plan; /* cost should be inserted by caller */ plan->targetlist = qptlist; plan->qual = qpqual; plan->lefttree = lefttree; plan->righttree = NULL; node->scan.scanrelid = scanrelid; node->bitmapqualorig = bitmapqualorig; return node;}static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid, List *tideval){ TidScan *node = makeNode(TidScan); Plan *plan = &node->scan.plan; /* cost should be inserted by caller */ plan->targetlist = qptlist; plan->qual = qpqual; plan->lefttree = NULL; plan->righttree = NULL; node->scan.scanrelid = scanrelid; node->tideval = tideval; return node;}SubqueryScan *make_subqueryscan(List *qptlist, List *qpqual, Index scanrelid, Plan *subplan){ SubqueryScan *node = makeNode(SubqueryScan); Plan *plan = &node->scan.plan; /* * Cost is figured here for the convenience of prepunion.c. Note this is * only correct for the case where qpqual is empty; otherwise caller * should overwrite cost with a better estimate. */ copy_plan_costsize(plan, subplan); plan->total_cost += cpu_tuple_cost * subplan->plan_rows; plan->targetlist = qptlist; plan->qual = qpqual; plan->lefttree = NULL; plan->righttree = NULL; node->scan.scanrelid = scanrelid; node->subplan = subplan; return node;}static FunctionScan *make_functionscan(List *qptlist, List *qpqual, Index scanrelid){ FunctionScan *node = makeNode(FunctionScan); Plan *plan = &node->scan.plan; /* cost should be inserted by caller */ plan->targetlist = qptlist; plan->qual = qpqual; plan->lefttree = NULL; plan->righttree = NULL; node->scan.scanrelid = scanrelid; return node;}Append *make_append(List *appendplans, bool isTarget, List *tlist){ Append *node = makeNode(Append); Plan *plan = &node->plan; ListCell *subnode; /* * Compute cost as sum of subplan costs. We charge nothing extra for the * Append itself, which perhaps is too optimistic, but since it doesn't do * any selection or projection, it is a pretty cheap node. */ plan->startup_cost = 0; plan->total_cost = 0; plan->plan_rows = 0; plan->plan_width = 0; foreach(subnode, appendplans) { Plan *subplan = (Plan *) lfirst(subnode); if (subnode == list_head(appendplans)) /* first node? */ plan->startup_cost = subplan->startup_cost; plan->total_cost += subplan->total_cost; plan->plan_rows += subplan->plan_rows; if (plan->plan_width < subplan->plan_width) plan->plan_width = subplan->plan_width; } plan->targetlist = tlist; plan->qual = NIL; plan->lefttree = NULL; plan->righttree = NULL; node->appendplans = appendplans; node->isTarget = isTarget; return node;}static BitmapAnd *make_bitmap_and(List *bitmapplans){ BitmapAnd *node = makeNode(BitmapAnd); Plan *plan = &node->plan; /* cost should be inserted by caller */ plan->targetlist = NIL; plan->qual = NIL; plan->lefttree = NULL; plan->righttree = NULL; node->bitmapplans = bitmapplans; return node;}static BitmapOr *make_bitmap_or(List *bitmapplans){ BitmapOr *node = makeNode(BitmapOr); Plan *plan = &node->plan; /* cost should be inserted by caller */ plan->targetlist = NIL; plan->qual = NIL; plan->lefttree = NULL; plan->righttree = NULL; node->bitmapplans = bitmapplans; return node;}static NestLoop *make_nestloop(List *tlist, List *joinclauses, List *otherclauses, Plan *lefttree, Plan *righttree, JoinType jointype){ NestLoop *node = makeNode(NestLoop); Plan *plan = &node->join.plan; /* cost should be inserted by caller */ plan->targetlist = tlist; plan->qual = otherclauses; plan->lefttree = lefttree; plan->righttree = righttree; node->join.jointype = jointype; node->join.joinqual = joinclauses; return node;}static HashJoin *make_hashjoin(List *tlist, List *joinclauses, List *otherclauses, List *hashclauses, Plan *lefttree, Plan *righttree, JoinType jointype){ HashJoin *node = makeNode(HashJoin); Plan *plan = &node->join.plan; /* cost should be inserted by caller */ plan->targetlist = tlist; plan->qual = otherclauses; plan->lefttree = lefttree; plan->righttree = righttree; node->hashclauses = hashclauses; node->join.jointype = jointype; node->join.joinqual = joinclauses; return node;}static Hash *make_hash(Plan *lefttree){ Hash *node = makeNode(Hash); Plan *plan = &node->plan; copy_plan_costsize(plan, lefttree); /* * For plausibility, make startup & total costs equal total cost of input * plan; this only affects EXPLAIN display not decisions. */ plan->startup_cost = plan->total_cost; plan->targetlist = copyObject(lefttree->targetlist); plan->qual = NIL; plan->lefttree = lefttree; plan->righttree = NULL; return node;}static MergeJoin *make_mergejoin(List *tlist, List *joinclauses, List *otherclauses, List *mergeclauses, Plan *lefttree, Plan *righttree, JoinType jointype){ MergeJoin *node = makeNode(MergeJoin); Plan *plan = &node->join.plan; /* cost should be inserted by caller */ plan->targetlist = tlist; plan->qual = otherclauses; plan->lefttree = lefttree; plan->righttree = righttree; node->mergeclauses = mergeclauses; node->join.jointype = jointype; node->join.joinqual = joinclauses; return node;}/* * make_sort --- basic routine to build a Sort plan node * * Caller must have built the sortColIdx and sortOperators arrays already. */static Sort *make_sort(PlannerInfo *root, Plan *lefttree, int numCols, AttrNumber *sortColIdx, Oid *sortOperators){ Sort *node = makeNode(Sort); Plan *plan = &node->plan; Path sort_path; /* dummy for result of cost_sort */ copy_plan_costsize(plan, lefttree); /* only care about copying size */ cost_sort(&sort_path, root, NIL, lefttree->total_cost, lefttree->plan_rows, lefttree->plan_width); plan->startup_cost = sort_path.startup_cost; plan->total_cost = sort_path.total_cost; plan->targetlist = copyObject(lefttree->targetlist); plan->qual = NIL; plan->lefttree = lefttree; plan->righttree = NULL; node->numCols = numCols; node->sortColIdx = sortColIdx; node->sortOperators = sortOperators; return node;}/* * add_sort_column --- utility subroutine for building sort info arrays * * We need this routine because the same column might be selected more than * once as a sort key column; if so, the extra mentions are redundant. * * Caller is assumed to have allocated the arrays large enough for the * max possible number of columns. Return value is the new column count. */static intadd_sort_column(AttrNumber colIdx, Oid sortOp, int numCols, AttrNumber *sortColIdx, Oid *sortOperators){ int i; for (i = 0; i < numCols; i++) { if (sortColIdx[i] == colIdx) { /* Already sorting by this col, so extra sort key is useless */ return numCols; } } /* Add the column */ sortColIdx[numCols] = colIdx; sortOperators[numCols] = sortOp; return numCols + 1;}/* * make_sort_from_pathkeys * Create sort plan to sort according to given pathkeys * * 'lefttree' is the node which yields input tuples * 'pathkeys' is the list of pathkeys by which the result is to be sorted * * We must convert the pathkey information into arrays of sort key column * numbers and sort operator OIDs. * * If the pathkeys include expressions that aren't simple Vars, we will * usually need to add resjunk items to the input plan's targetlist to * compute these expressions (since the Sort node itself won't do it). * If the input plan type isn't one that can do projections, this means * adding a Result node just to do the projection. */static Sort *make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys){ List *tlist = lefttree->targetlist; ListCell *i; int numsortkeys; AttrNumber *sortColIdx; Oid *sortOperators; /* * We will need at most list_length(pathkeys
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -