1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-30 21:42:05 +03:00

Ye-old pgindent run. Same 4-space tabs.

This commit is contained in:
Bruce Momjian
2000-04-12 17:17:23 +00:00
parent db4518729d
commit 52f77df613
434 changed files with 24799 additions and 21246 deletions

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.88 2000/04/04 01:21:47 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.89 2000/04/12 17:15:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -32,15 +32,15 @@
static List *switch_outer(List *clauses);
static int set_tlist_sort_info(List *tlist, List *pathkeys);
static int set_tlist_sort_info(List *tlist, List *pathkeys);
static Scan *create_scan_node(Query *root, Path *best_path, List *tlist);
static Join *create_join_node(Query *root, JoinPath *best_path, List *tlist);
static SeqScan *create_seqscan_node(Path *best_path, List *tlist,
List *scan_clauses);
static IndexScan *create_indexscan_node(Query *root, IndexPath *best_path,
List *tlist, List *scan_clauses);
List *tlist, List *scan_clauses);
static TidScan *create_tidscan_node(TidPath *best_path, List *tlist,
List *scan_clauses);
List *scan_clauses);
static NestLoop *create_nestloop_node(NestPath *best_path, List *tlist,
List *clauses, Plan *outer_node, List *outer_tlist,
Plan *inner_node, List *inner_tlist);
@ -52,16 +52,16 @@ static HashJoin *create_hashjoin_node(HashPath *best_path, List *tlist,
Plan *inner_node, List *inner_tlist);
static List *fix_indxqual_references(List *indexquals, IndexPath *index_path);
static List *fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam,
Form_pg_index index);
Form_pg_index index);
static Node *fix_indxqual_operand(Node *node, int baserelid,
Form_pg_index index,
Oid *opclass);
Form_pg_index index,
Oid *opclass);
static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
List *indxid, List *indxqual,
List *indxqualorig,
ScanDirection indexscandir);
List *indxid, List *indxqual,
List *indxqualorig,
ScanDirection indexscandir);
static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
List *tideval);
List *tideval);
static NestLoop *make_nestloop(List *qptlist, List *qpqual, Plan *lefttree,
Plan *righttree);
static HashJoin *make_hashjoin(List *tlist, List *qpqual,
@ -166,8 +166,8 @@ create_scan_node(Query *root, Path *best_path, List *tlist)
case T_TidScan:
node = (Scan *) create_tidscan_node((TidPath *) best_path,
tlist,
scan_clauses);
tlist,
scan_clauses);
break;
default:
@ -242,6 +242,7 @@ create_join_node(Query *root, JoinPath *best_path, List *tlist)
}
#ifdef NOT_USED
/*
* * Expensive function pullups may have pulled local predicates *
* into this path node. Put them in the qpqual of the plan node. *
@ -250,7 +251,7 @@ create_join_node(Query *root, JoinPath *best_path, List *tlist)
if (get_loc_restrictinfo(best_path) != NIL)
set_qpqual((Plan) retval,
nconc(get_qpqual((Plan) retval),
get_actual_clauses(get_loc_restrictinfo(best_path))));
get_actual_clauses(get_loc_restrictinfo(best_path))));
#endif
return retval;
@ -345,17 +346,17 @@ create_indexscan_node(Query *root,
* for lossy indices the indxqual predicates need to be double-checked
* after the index fetches the best-guess tuples.
*
* Since the indexquals were generated from the restriction clauses
* given by scan_clauses, there will normally be some duplications
* between the lists. We get rid of the duplicates, then add back
* if lossy.
* Since the indexquals were generated from the restriction clauses given
* by scan_clauses, there will normally be some duplications between
* the lists. We get rid of the duplicates, then add back if lossy.
*/
if (length(indxqual) > 1)
{
/*
* Build an expression representation of the indexqual, expanding
* the implicit OR and AND semantics of the first- and second-level
* lists.
* the implicit OR and AND semantics of the first- and
* second-level lists.
*/
List *orclauses = NIL;
List *orclause;
@ -374,8 +375,11 @@ create_indexscan_node(Query *root,
}
else if (indxqual != NIL)
{
/* Here, we can simply treat the first sublist as an independent
* set of qual expressions, since there is no top-level OR behavior.
/*
* Here, we can simply treat the first sublist as an independent
* set of qual expressions, since there is no top-level OR
* behavior.
*/
List *indxqual_list = lfirst(indxqual);
@ -387,8 +391,9 @@ create_indexscan_node(Query *root,
else
qpqual = scan_clauses;
/* The executor needs a copy with the indexkey on the left of each clause
* and with index attr numbers substituted for table ones.
/*
* The executor needs a copy with the indexkey on the left of each
* clause and with index attr numbers substituted for table ones.
*/
fixed_indxqual = fix_indxqual_references(indxqual, best_path);
@ -410,11 +415,11 @@ create_indexscan_node(Query *root,
static TidScan *
make_tidscan(List *qptlist,
List *qpqual,
Index scanrelid,
Index scanrelid,
List *tideval)
{
TidScan *node = makeNode(TidScan);
Plan *plan = &node->scan.plan;
TidScan *node = makeNode(TidScan);
Plan *plan = &node->scan.plan;
/* cost should be inserted by caller */
plan->state = (EState *) NULL;
@ -423,7 +428,8 @@ make_tidscan(List *qptlist,
plan->lefttree = NULL;
plan->righttree = NULL;
node->scan.scanrelid = scanrelid;
node->tideval = copyObject(tideval); /* XXX do we really need a copy? */
node->tideval = copyObject(tideval); /* XXX do we really need a
* copy? */
node->needRescan = false;
node->scan.scanstate = (CommonScanState *) NULL;
@ -438,8 +444,8 @@ make_tidscan(List *qptlist,
static TidScan *
create_tidscan_node(TidPath *best_path, List *tlist, List *scan_clauses)
{
TidScan *scan_node;
Index scan_relid;
TidScan *scan_node;
Index scan_relid;
/* there should be exactly one base rel involved... */
Assert(length(best_path->path.parent->relids) == 1);
@ -452,7 +458,7 @@ create_tidscan_node(TidPath *best_path, List *tlist, List *scan_clauses)
best_path->tideval);
if (best_path->unjoined_relids)
scan_node->needRescan = true;
scan_node->needRescan = true;
copy_path_costsize(&scan_node->scan.plan, &best_path->path);
@ -467,7 +473,7 @@ create_tidscan_node(TidPath *best_path, List *tlist, List *scan_clauses)
* once we have changed a Var node to refer to a subplan output rather than
* the original relation, it is no longer equal() to an unmodified Var node
* for the same var. So, we cannot easily compare reference-adjusted qual
* clauses to clauses that have not been adjusted. Fortunately, that
* clauses to clauses that have not been adjusted. Fortunately, that
* doesn't seem to be necessary; all the decisions are made before we do
* the reference adjustments.
*
@ -493,6 +499,7 @@ create_nestloop_node(NestPath *best_path,
if (IsA(inner_node, IndexScan))
{
/*
* An index is being used to reduce the number of tuples scanned
* in the inner relation. If there are join clauses being used
@ -522,12 +529,13 @@ create_nestloop_node(NestPath *best_path,
{
Index innerrel = innerscan->scan.scanrelid;
/* Remove redundant tests from my clauses, if possible.
* Note we must compare against indxqualorig not the "fixed"
* indxqual (which has index attnos instead of relation attnos,
* and may have been commuted as well).
/*
* Remove redundant tests from my clauses, if possible. Note
* we must compare against indxqualorig not the "fixed"
* indxqual (which has index attnos instead of relation
* attnos, and may have been commuted as well).
*/
if (length(indxqualorig) == 1) /* single indexscan? */
if (length(indxqualorig) == 1) /* single indexscan? */
clauses = set_difference(clauses, lfirst(indxqualorig));
/* only refs to outer vars get changed in the inner indexqual */
@ -549,17 +557,20 @@ create_nestloop_node(NestPath *best_path,
}
else if (IsA(inner_node, TidScan))
{
List *inner_tideval = ((TidScan *) inner_node)->tideval;
TidScan *innerscan = (TidScan *) inner_node;
List *inner_tideval = ((TidScan *) inner_node)->tideval;
TidScan *innerscan = (TidScan *) inner_node;
((TidScan *) inner_node)->tideval = join_references(inner_tideval, outer_tlist, inner_tlist, innerscan->scan.scanrelid);
}
}
else if (IsA_Join(inner_node))
{
/*
* Materialize the inner join for speed reasons.
*
* XXX It is probably *not* always fastest to materialize an inner
* join --- how can we estimate whether this is a good thing to do?
* join --- how can we estimate whether this is a good thing to
* do?
*/
inner_node = (Plan *) make_noname(inner_tlist,
NIL,
@ -595,9 +606,9 @@ create_mergejoin_node(MergePath *best_path,
mergeclauses = get_actual_clauses(best_path->path_mergeclauses);
/*
* Remove the mergeclauses from the list of join qual clauses,
* leaving the list of quals that must be checked as qpquals.
* Set those clauses to contain INNER/OUTER var references.
* Remove the mergeclauses from the list of join qual clauses, leaving
* the list of quals that must be checked as qpquals. Set those
* clauses to contain INNER/OUTER var references.
*/
qpqual = join_references(set_difference(clauses, mergeclauses),
outer_tlist,
@ -655,16 +666,16 @@ create_hashjoin_node(HashPath *best_path,
/*
* NOTE: there will always be exactly one hashclause in the list
* best_path->path_hashclauses (cf. hash_inner_and_outer()).
* We represent it as a list anyway, for convenience with routines
* that want to work on lists of clauses.
* best_path->path_hashclauses (cf. hash_inner_and_outer()). We
* represent it as a list anyway, for convenience with routines that
* want to work on lists of clauses.
*/
hashclauses = get_actual_clauses(best_path->path_hashclauses);
/*
* Remove the hashclauses from the list of join qual clauses,
* leaving the list of quals that must be checked as qpquals.
* Set those clauses to contain INNER/OUTER var references.
* Remove the hashclauses from the list of join qual clauses, leaving
* the list of quals that must be checked as qpquals. Set those
* clauses to contain INNER/OUTER var references.
*/
qpqual = join_references(set_difference(clauses, hashclauses),
outer_tlist,
@ -779,7 +790,7 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path)
*
* For each qual clause, commute if needed to put the indexkey operand on the
* left, and then change its varno. (We do not need to change the other side
* of the clause.) Also change the operator if necessary.
* of the clause.) Also change the operator if necessary.
*/
static List *
fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam,
@ -803,14 +814,16 @@ fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam,
length(clause->args) != 2)
elog(ERROR, "fix_indxqual_sublist: indexqual clause is not binary opclause");
/* Which side is the indexkey on?
/*
* Which side is the indexkey on?
*
* get_relattval sets flag&SEL_RIGHT if the indexkey is on the LEFT.
*/
get_relattval((Node *) clause, baserelid,
&relid, &attno, &constval, &flag);
/* Make a copy that will become the fixed clause.
/*
* Make a copy that will become the fixed clause.
*
* We used to try to do a shallow copy here, but that fails if there
* is a subplan in the arguments of the opclause. So just do a
@ -822,18 +835,19 @@ fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam,
if ((flag & SEL_RIGHT) == 0)
CommuteClause(newclause);
/* Now, determine which index attribute this is,
* change the indexkey operand as needed,
* and get the index opclass.
/*
* Now, determine which index attribute this is, change the
* indexkey operand as needed, and get the index opclass.
*/
lfirst(newclause->args) = fix_indxqual_operand(lfirst(newclause->args),
baserelid,
index,
&opclass);
/* Substitute the appropriate operator if the expression operator
* is merely binary-compatible with the index. This shouldn't fail,
* since indxpath.c found it before...
/*
* Substitute the appropriate operator if the expression operator
* is merely binary-compatible with the index. This shouldn't
* fail, since indxpath.c found it before...
*/
newopno = indexable_operator(newclause, opclass, relam, true);
if (newopno == InvalidOid)
@ -861,12 +875,14 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index,
if (index->indkey[pos] == varatt)
{
Node *newnode = copyObject(node);
((Var *) newnode)->varattno = pos + 1;
*opclass = index->indclass[pos];
return newnode;
}
}
}
/*
* Oops, this Var isn't the indexkey!
*/
@ -876,13 +892,13 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index,
/*
* Else, it must be a func expression representing a functional index.
*
* Currently, there is no need for us to do anything here for
* functional indexes. If nodeIndexscan.c sees a func clause as the left
* or right-hand toplevel operand of an indexqual, it assumes that that is
* a reference to the functional index's value and makes the appropriate
* substitution. (It would be cleaner to make the substitution here, I
* think --- suspect this issue if a join clause involving a function call
* misbehaves...)
* Currently, there is no need for us to do anything here for functional
* indexes. If nodeIndexscan.c sees a func clause as the left or
* right-hand toplevel operand of an indexqual, it assumes that that
* is a reference to the functional index's value and makes the
* appropriate substitution. (It would be cleaner to make the
* substitution here, I think --- suspect this issue if a join clause
* involving a function call misbehaves...)
*/
/* indclass[0] is the only class of a functional index */
@ -915,6 +931,7 @@ switch_outer(List *clauses)
Assert(op && IsA(op, Var));
if (var_is_outer(op))
{
/*
* Duplicate just enough of the structure to allow commuting
* the clause without changing the original list. Could use
@ -954,21 +971,21 @@ set_tlist_sort_info(List *tlist, List *pathkeys)
foreach(i, pathkeys)
{
List *keysublist = (List *) lfirst(i);
PathKeyItem *pathkey = NULL;
Resdom *resdom = NULL;
List *j;
List *keysublist = (List *) lfirst(i);
PathKeyItem *pathkey = NULL;
Resdom *resdom = NULL;
List *j;
/*
* We can sort by any one of the sort key items listed in this
* sublist. For now, we take the first one that corresponds to
* an available Var in the tlist.
* sublist. For now, we take the first one that corresponds to an
* available Var in the tlist.
*
* XXX if we have a choice, is there any way of figuring out which
* might be cheapest to execute? (For example, int4lt is likely
* much cheaper to execute than numericlt, but both might appear in
* the same pathkey sublist...) Not clear that we ever will have
* a choice in practice, so it may not matter.
* much cheaper to execute than numericlt, but both might appear
* in the same pathkey sublist...) Not clear that we ever will
* have a choice in practice, so it may not matter.
*/
foreach(j, keysublist)
{
@ -982,12 +999,12 @@ set_tlist_sort_info(List *tlist, List *pathkeys)
elog(ERROR, "set_tlist_sort_info: cannot find tlist item to sort");
/*
* The resdom might be already marked as a sort key, if the pathkeys
* contain duplicate entries. (This can happen in scenarios where
* multiple mergejoinable clauses mention the same var, for example.)
* In that case the current pathkey is essentially a no-op, because
* only one value can be seen within any subgroup where it would be
* consulted. We can ignore it.
* The resdom might be already marked as a sort key, if the
* pathkeys contain duplicate entries. (This can happen in
* scenarios where multiple mergejoinable clauses mention the same
* var, for example.) In that case the current pathkey is
* essentially a no-op, because only one value can be seen within
* any subgroup where it would be consulted. We can ignore it.
*/
if (resdom->reskey == 0)
{
@ -1195,7 +1212,9 @@ make_hash(List *tlist, Var *hashkey, Plan *lefttree)
Plan *plan = &node->plan;
copy_plan_costsize(plan, lefttree);
/* For plausibility, make startup & total costs equal total cost of
/*
* 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;
@ -1237,7 +1256,7 @@ make_sort(List *tlist, Oid nonameid, Plan *lefttree, int keycount)
Plan *plan = &node->plan;
Path sort_path; /* dummy for result of cost_sort */
copy_plan_costsize(plan, lefttree); /* only care about copying size */
copy_plan_costsize(plan, lefttree); /* only care about copying size */
cost_sort(&sort_path, NIL, lefttree->plan_rows, lefttree->plan_width);
plan->startup_cost = sort_path.startup_cost + lefttree->total_cost;
plan->total_cost = sort_path.total_cost + lefttree->total_cost;
@ -1262,9 +1281,11 @@ make_material(List *tlist,
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.
* XXX shouldn't we charge some additional cost for materialization?
/*
* For plausibility, make startup & total costs equal total cost of
* input plan; this only affects EXPLAIN display not decisions. XXX
* shouldn't we charge some additional cost for materialization?
*/
plan->startup_cost = plan->total_cost;
plan->state = (EState *) NULL;
@ -1285,18 +1306,21 @@ make_agg(List *tlist, List *qual, Plan *lefttree)
Plan *plan = &node->plan;
copy_plan_costsize(plan, lefttree);
/*
* Charge one cpu_operator_cost per aggregate function per input tuple.
* Charge one cpu_operator_cost per aggregate function per input
* tuple.
*/
plan->total_cost += cpu_operator_cost * plan->plan_rows *
(length(pull_agg_clause((Node *) tlist)) +
length(pull_agg_clause((Node *) qual)));
/*
* We will produce a single output tuple if the input is not a Group,
* and a tuple per group otherwise. For now, estimate the number of
* groups as 10% of the number of tuples --- bogus, but how to do better?
* (Note we assume the input Group node is in "tuplePerGroup" mode,
* so it didn't reduce its row count already.)
* groups as 10% of the number of tuples --- bogus, but how to do
* better? (Note we assume the input Group node is in "tuplePerGroup"
* mode, so it didn't reduce its row count already.)
*/
if (IsA(lefttree, Group))
plan->plan_rows *= 0.1;
@ -1326,19 +1350,21 @@ make_group(List *tlist,
Plan *plan = &node->plan;
copy_plan_costsize(plan, lefttree);
/*
* Charge one cpu_operator_cost per comparison per input tuple.
* We assume all columns get compared at most of the tuples.
* Charge one cpu_operator_cost per comparison per input tuple. We
* assume all columns get compared at most of the tuples.
*/
plan->total_cost += cpu_operator_cost * plan->plan_rows * ngrp;
/*
* If tuplePerGroup (which is named exactly backwards) is true,
* we will return all the input tuples, so the input node's row count
* is OK. Otherwise, we'll return only one tuple from each group.
* For now, estimate the number of groups as 10% of the number of
* tuples --- bogus, but how to do better?
* If tuplePerGroup (which is named exactly backwards) is true, we
* will return all the input tuples, so the input node's row count is
* OK. Otherwise, we'll return only one tuple from each group. For
* now, estimate the number of groups as 10% of the number of tuples
* --- bogus, but how to do better?
*/
if (! tuplePerGroup)
if (!tuplePerGroup)
plan->plan_rows *= 0.1;
plan->state = (EState *) NULL;
@ -1369,11 +1395,13 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList)
List *slitem;
copy_plan_costsize(plan, lefttree);
/*
* Charge one cpu_operator_cost per comparison per input tuple.
* We assume all columns get compared at most of the tuples.
* Charge one cpu_operator_cost per comparison per input tuple. We
* assume all columns get compared at most of the tuples.
*/
plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols;
/*
* As for Group, we make the unsupported assumption that there will be
* 10% as many tuples out as in.
@ -1388,14 +1416,17 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList)
node->nonameid = _NONAME_RELATION_ID_;
node->keycount = 0;
/* convert SortClause list into array of attr indexes, as wanted by exec */
/*
* convert SortClause list into array of attr indexes, as wanted by
* exec
*/
Assert(numCols > 0);
uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
foreach(slitem, distinctList)
{
SortClause *sortcl = (SortClause *) lfirst(slitem);
TargetEntry *tle = get_sortgroupclause_tle(sortcl, tlist);
SortClause *sortcl = (SortClause *) lfirst(slitem);
TargetEntry *tle = get_sortgroupclause_tle(sortcl, tlist);
uniqColIdx[keyno++] = tle->resdom->resno;
}