aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/clauses.c521
-rw-r--r--src/backend/optimizer/util/pathnode.c65
-rw-r--r--src/backend/optimizer/util/plancat.c42
-rw-r--r--src/backend/optimizer/util/relnode.c81
-rw-r--r--src/backend/optimizer/util/tlist.c14
-rw-r--r--src/backend/optimizer/util/var.c17
6 files changed, 412 insertions, 328 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index d429db93a03..7ddbe4190cc 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.64 2000/04/04 01:21:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.65 2000/04/12 17:15:24 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -46,9 +46,9 @@ static bool pull_agg_clause_walker(Node *node, List **listptr);
static bool contain_subplans_walker(Node *node, void *context);
static bool pull_subplans_walker(Node *node, List **listptr);
static bool check_subplans_for_ungrouped_vars_walker(Node *node,
- Query *context);
-static int is_single_func(Node *node);
-static Node *eval_const_expressions_mutator (Node *node, void *context);
+ Query *context);
+static int is_single_func(Node *node);
+static Node *eval_const_expressions_mutator(Node *node, void *context);
static Expr *simplify_op_or_func(Expr *expr, List *args);
@@ -340,18 +340,19 @@ make_ands_explicit(List *andclauses)
List *
make_ands_implicit(Expr *clause)
{
+
/*
* NB: because the parser sets the qual field to NULL in a query that
* has no WHERE clause, we must consider a NULL input clause as TRUE,
- * even though one might more reasonably think it FALSE. Grumble.
- * If this causes trouble, consider changing the parser's behavior.
+ * even though one might more reasonably think it FALSE. Grumble. If
+ * this causes trouble, consider changing the parser's behavior.
*/
if (clause == NULL)
return NIL; /* NULL -> NIL list == TRUE */
else if (and_clause((Node *) clause))
return clause->args;
else if (IsA(clause, Const) &&
- ! ((Const *) clause)->constisnull &&
+ !((Const *) clause)->constisnull &&
DatumGetInt32(((Const *) clause)->constvalue))
return NIL; /* constant TRUE input -> NIL list */
else
@@ -381,7 +382,8 @@ contain_agg_clause_walker(Node *node, void *context)
if (node == NULL)
return false;
if (IsA(node, Aggref))
- return true; /* abort the tree traversal and return true */
+ return true; /* abort the tree traversal and return
+ * true */
return expression_tree_walker(node, contain_agg_clause_walker, context);
}
@@ -411,12 +413,14 @@ pull_agg_clause_walker(Node *node, List **listptr)
if (IsA(node, Aggref))
{
*listptr = lappend(*listptr, node);
+
/*
* Complain if the aggregate's argument contains any aggregates;
* nested agg functions are semantically nonsensical.
*/
if (contain_agg_clause(((Aggref *) node)->target))
elog(ERROR, "Aggregate function calls may not be nested");
+
/*
* Having checked that, we need not recurse into the argument.
*/
@@ -454,7 +458,8 @@ contain_subplans_walker(Node *node, void *context)
if (node == NULL)
return false;
if (is_subplan(node) || IsA(node, SubLink))
- return true; /* abort the tree traversal and return true */
+ return true; /* abort the tree traversal and return
+ * true */
return expression_tree_walker(node, contain_subplans_walker, context);
}
@@ -462,7 +467,7 @@ contain_subplans_walker(Node *node, void *context)
* pull_subplans
* Recursively pulls all subplans from an expression tree.
*
- * Returns list of subplan nodes found. Note the nodes themselves are not
+ * Returns list of subplan nodes found. Note the nodes themselves are not
* copied, only referenced.
*/
List *
@@ -507,7 +512,11 @@ void
check_subplans_for_ungrouped_vars(Node *clause,
Query *query)
{
- /* No special setup needed; context for walker is just the Query pointer */
+
+ /*
+ * No special setup needed; context for walker is just the Query
+ * pointer
+ */
check_subplans_for_ungrouped_vars_walker(clause, query);
}
@@ -517,17 +526,19 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
{
if (node == NULL)
return false;
+
/*
- * We can ignore Vars other than in subplan args lists,
- * since the parser already checked 'em.
+ * We can ignore Vars other than in subplan args lists, since the
+ * parser already checked 'em.
*/
if (is_subplan(node))
{
+
/*
* The args list of the subplan node represents attributes from
* outside passed into the sublink.
*/
- List *t;
+ List *t;
foreach(t, ((Expr *) node)->args)
{
@@ -539,10 +550,10 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
/*
* We do not care about args that are not local variables;
* params or outer-level vars are not our responsibility to
- * check. (The outer-level query passing them to us needs
- * to worry, instead.)
+ * check. (The outer-level query passing them to us needs to
+ * worry, instead.)
*/
- if (! IsA(thisarg, Var))
+ if (!IsA(thisarg, Var))
continue;
var = (Var *) thisarg;
if (var->varlevelsup > 0)
@@ -554,8 +565,8 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
contained_in_group_clause = false;
foreach(gl, context->groupClause)
{
- GroupClause *gcl = lfirst(gl);
- Node *groupexpr;
+ GroupClause *gcl = lfirst(gl);
+ Node *groupexpr;
groupexpr = get_sortgroupclause_expr(gcl,
context->targetList);
@@ -569,14 +580,14 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
if (!contained_in_group_clause)
{
/* Found an ungrouped argument. Complain. */
- RangeTblEntry *rte;
- char *attname;
+ RangeTblEntry *rte;
+ char *attname;
Assert(var->varno > 0 &&
var->varno <= length(context->rtable));
rte = rt_fetch(var->varno, context->rtable);
attname = get_attname(rte->relid, var->varattno);
- if (! attname)
+ if (!attname)
elog(ERROR, "cache lookup of attribute %d in relation %u failed",
var->varattno, rte->relid);
elog(ERROR, "Sub-SELECT uses un-GROUPed attribute %s.%s from outer query",
@@ -585,7 +596,7 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
}
}
return expression_tree_walker(node,
- check_subplans_for_ungrouped_vars_walker,
+ check_subplans_for_ungrouped_vars_walker,
(void *) context);
}
@@ -697,7 +708,7 @@ NumRelids(Node *clause)
* is referenced in the clause). The routine checks that the
* expression is of the form (var op something) or (something op var)
* where the var is an attribute of the specified relation, or
- * a function of a var of the specified relation. If so, it
+ * a function of a var of the specified relation. If so, it
* returns the following info:
* the found relation number (same as targetrelid unless that is 0)
* the found var number (or InvalidAttrNumber if a function)
@@ -707,7 +718,7 @@ NumRelids(Node *clause)
* specifically 0 for the relid and attno, 0 for the constant value.
*
* Note that negative attno values are *not* invalid, but represent
- * system attributes such as OID. It's sufficient to check for relid=0
+ * system attributes such as OID. It's sufficient to check for relid=0
* to determine whether the routine succeeded.
*/
void
@@ -785,15 +796,13 @@ default_results:
*flag |= SEL_CONSTANT;
}
else
- {
*constval = 0;
- }
}
/*
* is_single_func
- * If the given expression is a function of a single relation,
- * return the relation number; else return 0
+ * If the given expression is a function of a single relation,
+ * return the relation number; else return 0
*/
static int
is_single_func(Node *node)
@@ -804,7 +813,7 @@ is_single_func(Node *node)
if (length(varnos) == 1)
{
- int funcvarno = lfirsti(varnos);
+ int funcvarno = lfirsti(varnos);
freeList(varnos);
return funcvarno;
@@ -922,7 +931,7 @@ CommuteClause(Expr *clause)
* expression tree, for example "2 + 2" => "4". More interestingly,
* we can reduce certain boolean expressions even when they contain
* non-constant subexpressions: "x OR true" => "true" no matter what
- * the subexpression x is. (XXX We assume that no such subexpression
+ * the subexpression x is. (XXX We assume that no such subexpression
* will have important side-effects, which is not necessarily a good
* assumption in the presence of user-defined functions; do we need a
* pg_proc flag that prevents discarding the execution of a function?)
@@ -954,7 +963,7 @@ eval_const_expressions(Node *node)
}
static Node *
-eval_const_expressions_mutator (Node *node, void *context)
+eval_const_expressions_mutator(Node *node, void *context)
{
if (node == NULL)
return NULL;
@@ -963,21 +972,22 @@ eval_const_expressions_mutator (Node *node, void *context)
Expr *expr = (Expr *) node;
List *args;
Const *const_input;
- Expr *newexpr;
+ Expr *newexpr;
/*
* Reduce constants in the Expr's arguments. We know args is
- * either NIL or a List node, so we can call expression_tree_mutator
- * directly rather than recursing to self.
+ * either NIL or a List node, so we can call
+ * expression_tree_mutator directly rather than recursing to self.
*/
args = (List *) expression_tree_mutator((Node *) expr->args,
- eval_const_expressions_mutator,
+ eval_const_expressions_mutator,
(void *) context);
switch (expr->opType)
{
case OP_EXPR:
case FUNC_EXPR:
+
/*
* Code for op/func case is pretty bulky, so split it out
* as a separate function.
@@ -985,123 +995,131 @@ eval_const_expressions_mutator (Node *node, void *context)
newexpr = simplify_op_or_func(expr, args);
if (newexpr) /* successfully simplified it */
return (Node *) newexpr;
- /* else fall out to build new Expr node with simplified args */
- break;
- case OR_EXPR:
- {
+
/*
- * OR arguments are handled as follows:
- * non constant: keep
- * FALSE: drop (does not affect result)
- * TRUE: force result to TRUE
- * NULL: keep only one
- * We keep one NULL input because ExecEvalOr returns
- * NULL when no input is TRUE and at least one is NULL.
+ * else fall out to build new Expr node with simplified
+ * args
*/
- List *newargs = NIL;
- List *arg;
- bool haveNull = false;
- bool forceTrue = false;
-
- foreach(arg, args)
+ break;
+ case OR_EXPR:
{
- if (! IsA(lfirst(arg), Const))
+
+ /*
+ * OR arguments are handled as follows: non constant:
+ * keep FALSE: drop (does not affect result) TRUE:
+ * force result to TRUE NULL: keep only one We keep
+ * one NULL input because ExecEvalOr returns NULL when
+ * no input is TRUE and at least one is NULL.
+ */
+ List *newargs = NIL;
+ List *arg;
+ bool haveNull = false;
+ bool forceTrue = false;
+
+ foreach(arg, args)
{
- newargs = lappend(newargs, lfirst(arg));
- continue;
+ if (!IsA(lfirst(arg), Const))
+ {
+ newargs = lappend(newargs, lfirst(arg));
+ continue;
+ }
+ const_input = (Const *) lfirst(arg);
+ if (const_input->constisnull)
+ haveNull = true;
+ else if (DatumGetInt32(const_input->constvalue))
+ forceTrue = true;
+ /* otherwise, we can drop the constant-false input */
}
- const_input = (Const *) lfirst(arg);
- if (const_input->constisnull)
- haveNull = true;
- else if (DatumGetInt32(const_input->constvalue))
- forceTrue = true;
- /* otherwise, we can drop the constant-false input */
+
+ /*
+ * We could return TRUE before falling out of the
+ * loop, but this coding method will be easier to
+ * adapt if we ever add a notion of non-removable
+ * functions. We'd need to check all the inputs for
+ * non-removability.
+ */
+ if (forceTrue)
+ return MAKEBOOLCONST(true, false);
+ if (haveNull)
+ newargs = lappend(newargs, MAKEBOOLCONST(false, true));
+ /* If all the inputs are FALSE, result is FALSE */
+ if (newargs == NIL)
+ return MAKEBOOLCONST(false, false);
+ /* If only one nonconst-or-NULL input, it's the result */
+ if (lnext(newargs) == NIL)
+ return (Node *) lfirst(newargs);
+ /* Else we still need an OR node */
+ return (Node *) make_orclause(newargs);
}
- /*
- * We could return TRUE before falling out of the loop,
- * but this coding method will be easier to adapt if
- * we ever add a notion of non-removable functions.
- * We'd need to check all the inputs for non-removability.
- */
- if (forceTrue)
- return MAKEBOOLCONST(true, false);
- if (haveNull)
- newargs = lappend(newargs, MAKEBOOLCONST(false, true));
- /* If all the inputs are FALSE, result is FALSE */
- if (newargs == NIL)
- return MAKEBOOLCONST(false, false);
- /* If only one nonconst-or-NULL input, it's the result */
- if (lnext(newargs) == NIL)
- return (Node *) lfirst(newargs);
- /* Else we still need an OR node */
- return (Node *) make_orclause(newargs);
- }
case AND_EXPR:
- {
- /*
- * AND arguments are handled as follows:
- * non constant: keep
- * TRUE: drop (does not affect result)
- * FALSE: force result to FALSE
- * NULL: keep only one
- * We keep one NULL input because ExecEvalAnd returns
- * NULL when no input is FALSE and at least one is NULL.
- */
- List *newargs = NIL;
- List *arg;
- bool haveNull = false;
- bool forceFalse = false;
-
- foreach(arg, args)
{
- if (! IsA(lfirst(arg), Const))
+
+ /*
+ * AND arguments are handled as follows: non constant:
+ * keep TRUE: drop (does not affect result) FALSE:
+ * force result to FALSE NULL: keep only one We keep
+ * one NULL input because ExecEvalAnd returns NULL
+ * when no input is FALSE and at least one is NULL.
+ */
+ List *newargs = NIL;
+ List *arg;
+ bool haveNull = false;
+ bool forceFalse = false;
+
+ foreach(arg, args)
{
- newargs = lappend(newargs, lfirst(arg));
- continue;
+ if (!IsA(lfirst(arg), Const))
+ {
+ newargs = lappend(newargs, lfirst(arg));
+ continue;
+ }
+ const_input = (Const *) lfirst(arg);
+ if (const_input->constisnull)
+ haveNull = true;
+ else if (!DatumGetInt32(const_input->constvalue))
+ forceFalse = true;
+ /* otherwise, we can drop the constant-true input */
}
- const_input = (Const *) lfirst(arg);
- if (const_input->constisnull)
- haveNull = true;
- else if (! DatumGetInt32(const_input->constvalue))
- forceFalse = true;
- /* otherwise, we can drop the constant-true input */
+
+ /*
+ * We could return FALSE before falling out of the
+ * loop, but this coding method will be easier to
+ * adapt if we ever add a notion of non-removable
+ * functions. We'd need to check all the inputs for
+ * non-removability.
+ */
+ if (forceFalse)
+ return MAKEBOOLCONST(false, false);
+ if (haveNull)
+ newargs = lappend(newargs, MAKEBOOLCONST(false, true));
+ /* If all the inputs are TRUE, result is TRUE */
+ if (newargs == NIL)
+ return MAKEBOOLCONST(true, false);
+ /* If only one nonconst-or-NULL input, it's the result */
+ if (lnext(newargs) == NIL)
+ return (Node *) lfirst(newargs);
+ /* Else we still need an AND node */
+ return (Node *) make_andclause(newargs);
}
- /*
- * We could return FALSE before falling out of the loop,
- * but this coding method will be easier to adapt if
- * we ever add a notion of non-removable functions.
- * We'd need to check all the inputs for non-removability.
- */
- if (forceFalse)
- return MAKEBOOLCONST(false, false);
- if (haveNull)
- newargs = lappend(newargs, MAKEBOOLCONST(false, true));
- /* If all the inputs are TRUE, result is TRUE */
- if (newargs == NIL)
- return MAKEBOOLCONST(true, false);
- /* If only one nonconst-or-NULL input, it's the result */
- if (lnext(newargs) == NIL)
- return (Node *) lfirst(newargs);
- /* Else we still need an AND node */
- return (Node *) make_andclause(newargs);
- }
case NOT_EXPR:
Assert(length(args) == 1);
- if (! IsA(lfirst(args), Const))
+ if (!IsA(lfirst(args), Const))
break;
const_input = (Const *) lfirst(args);
/* NOT NULL => NULL */
if (const_input->constisnull)
return MAKEBOOLCONST(false, true);
/* otherwise pretty easy */
- return MAKEBOOLCONST(! DatumGetInt32(const_input->constvalue),
+ return MAKEBOOLCONST(!DatumGetInt32(const_input->constvalue),
false);
case SUBPLAN_EXPR:
+
/*
* Safety measure per notes at head of this routine:
- * return a SubPlan unchanged. Too late to do anything
+ * return a SubPlan unchanged. Too late to do anything
* with it. The arglist simplification above was wasted
- * work (the list probably only contains Var nodes anyway).
+ * work (the list probably only contains Var nodes
+ * anyway).
*/
return (Node *) expr;
default:
@@ -1112,25 +1130,26 @@ eval_const_expressions_mutator (Node *node, void *context)
/*
* If we break out of the above switch on opType, then the
- * expression cannot be simplified any further, so build
- * and return a replacement Expr node using the
- * possibly-simplified arguments and the original oper node.
- * Can't use make_clause() here because we want to be sure
- * the typeOid field is preserved...
+ * expression cannot be simplified any further, so build and
+ * return a replacement Expr node using the possibly-simplified
+ * arguments and the original oper node. Can't use make_clause()
+ * here because we want to be sure the typeOid field is
+ * preserved...
*/
newexpr = makeNode(Expr);
- newexpr->typeOid = expr->typeOid;
- newexpr->opType = expr->opType;
- newexpr->oper = expr->oper;
- newexpr->args = args;
- return (Node *) newexpr;
+ newexpr->typeOid = expr->typeOid;
+ newexpr->opType = expr->opType;
+ newexpr->oper = expr->oper;
+ newexpr->args = args;
+ return (Node *) newexpr;
}
if (IsA(node, RelabelType))
{
+
/*
* If we can simplify the input to a constant, then we don't need
- * the RelabelType node anymore: just change the type field of
- * the Const node. Otherwise, copy the RelabelType node.
+ * the RelabelType node anymore: just change the type field of the
+ * Const node. Otherwise, copy the RelabelType node.
*/
RelabelType *relabel = (RelabelType *) node;
Node *arg;
@@ -1138,13 +1157,15 @@ eval_const_expressions_mutator (Node *node, void *context)
arg = eval_const_expressions_mutator(relabel->arg, context);
if (arg && IsA(arg, Const))
{
- Const *con = (Const *) arg;
+ Const *con = (Const *) arg;
con->consttype = relabel->resulttype;
+
/*
* relabel's resulttypmod is discarded, which is OK for now;
* if the type actually needs a runtime length coercion then
- * there should be a function call to do it just above this node.
+ * there should be a function call to do it just above this
+ * node.
*/
return (Node *) con;
}
@@ -1160,15 +1181,15 @@ eval_const_expressions_mutator (Node *node, void *context)
}
if (IsA(node, CaseExpr))
{
+
/*
- * CASE expressions can be simplified if there are constant condition
- * clauses:
- * FALSE (or NULL): drop the alternative
- * TRUE: drop all remaining alternatives
- * If the first non-FALSE alternative is a constant TRUE, we can
- * simplify the entire CASE to that alternative's expression.
- * If there are no non-FALSE alternatives, we simplify the entire
- * CASE to the default result (ELSE result).
+ * CASE expressions can be simplified if there are constant
+ * condition clauses: FALSE (or NULL): drop the alternative TRUE:
+ * drop all remaining alternatives If the first non-FALSE
+ * alternative is a constant TRUE, we can simplify the entire CASE
+ * to that alternative's expression. If there are no non-FALSE
+ * alternatives, we simplify the entire CASE to the default result
+ * (ELSE result).
*/
CaseExpr *caseexpr = (CaseExpr *) node;
CaseExpr *newcase;
@@ -1181,26 +1202,29 @@ eval_const_expressions_mutator (Node *node, void *context)
{
/* Simplify this alternative's condition and result */
CaseWhen *casewhen = (CaseWhen *)
- expression_tree_mutator((Node *) lfirst(arg),
- eval_const_expressions_mutator,
- (void *) context);
+ expression_tree_mutator((Node *) lfirst(arg),
+ eval_const_expressions_mutator,
+ (void *) context);
+
Assert(IsA(casewhen, CaseWhen));
if (casewhen->expr == NULL ||
- ! IsA(casewhen->expr, Const))
+ !IsA(casewhen->expr, Const))
{
newargs = lappend(newargs, casewhen);
continue;
}
const_input = (Const *) casewhen->expr;
if (const_input->constisnull ||
- ! DatumGetInt32(const_input->constvalue))
+ !DatumGetInt32(const_input->constvalue))
continue; /* drop alternative with FALSE condition */
+
/*
- * Found a TRUE condition. If it's the first (un-dropped)
+ * Found a TRUE condition. If it's the first (un-dropped)
* alternative, the CASE reduces to just this alternative.
*/
if (newargs == NIL)
return casewhen->result;
+
/*
* Otherwise, add it to the list, and drop all the rest.
*/
@@ -1211,7 +1235,11 @@ eval_const_expressions_mutator (Node *node, void *context)
/* Simplify the default result */
defresult = eval_const_expressions_mutator(caseexpr->defresult,
context);
- /* If no non-FALSE alternatives, CASE reduces to the default result */
+
+ /*
+ * If no non-FALSE alternatives, CASE reduces to the default
+ * result
+ */
if (newargs == NIL)
return defresult;
/* Otherwise we need a new CASE node */
@@ -1224,21 +1252,21 @@ eval_const_expressions_mutator (Node *node, void *context)
}
if (IsA(node, Iter))
{
+
/*
- * The argument of an Iter is normally a function call.
- * We must not try to eliminate the function, but we
- * can try to simplify its arguments. If, by chance,
- * the arg is NOT a function then we go ahead and try to
- * simplify it (by falling into expression_tree_mutator).
- * Is that the right thing?
+ * The argument of an Iter is normally a function call. We must
+ * not try to eliminate the function, but we can try to simplify
+ * its arguments. If, by chance, the arg is NOT a function then
+ * we go ahead and try to simplify it (by falling into
+ * expression_tree_mutator). Is that the right thing?
*/
Iter *iter = (Iter *) node;
if (is_funcclause(iter->iterexpr))
{
- Expr *func = (Expr *) iter->iterexpr;
- Expr *newfunc;
- Iter *newiter;
+ Expr *func = (Expr *) iter->iterexpr;
+ Expr *newfunc;
+ Iter *newiter;
newfunc = makeNode(Expr);
newfunc->typeOid = func->typeOid;
@@ -1254,12 +1282,13 @@ eval_const_expressions_mutator (Node *node, void *context)
return (Node *) newiter;
}
}
+
/*
* For any node type not handled above, we recurse using
- * expression_tree_mutator, which will copy the node unchanged
- * but try to simplify its arguments (if any) using this routine.
- * For example: we cannot eliminate an ArrayRef node, but we
- * might be able to simplify constant expressions in its subscripts.
+ * expression_tree_mutator, which will copy the node unchanged but try
+ * to simplify its arguments (if any) using this routine. For example:
+ * we cannot eliminate an ArrayRef node, but we might be able to
+ * simplify constant expressions in its subscripts.
*/
return expression_tree_mutator(node, eval_const_expressions_mutator,
(void *) context);
@@ -1289,31 +1318,32 @@ simplify_op_or_func(Expr *expr, List *args)
HeapTuple func_tuple;
Form_pg_proc funcform;
Type resultType;
- Expr *newexpr;
+ Expr *newexpr;
Datum const_val;
bool const_is_null;
bool isDone;
/*
- * For an operator or function, we cannot simplify unless all the inputs
- * are constants. (XXX possible future improvement: if the op/func is
- * strict and at least one input is NULL, we could simplify to NULL.
- * But we do not currently have any way to know if the op/func is strict
- * or not. For now, a NULL input is treated the same as any other
- * constant node.)
+ * For an operator or function, we cannot simplify unless all the
+ * inputs are constants. (XXX possible future improvement: if the
+ * op/func is strict and at least one input is NULL, we could simplify
+ * to NULL. But we do not currently have any way to know if the
+ * op/func is strict or not. For now, a NULL input is treated the
+ * same as any other constant node.)
*/
foreach(arg, args)
{
- if (! IsA(lfirst(arg), Const))
+ if (!IsA(lfirst(arg), Const))
return NULL;
}
+
/*
- * Get the function procedure's OID and look to see
- * whether it is marked proiscachable.
+ * Get the function procedure's OID and look to see whether it is
+ * marked proiscachable.
*/
if (expr->opType == OP_EXPR)
{
- Oper *oper = (Oper *) expr->oper;
+ Oper *oper = (Oper *) expr->oper;
replace_opid(oper); /* OK to scribble on input to this extent */
funcid = oper->opid;
@@ -1321,7 +1351,7 @@ simplify_op_or_func(Expr *expr, List *args)
}
else
{
- Func *func = (Func *) expr->oper;
+ Func *func = (Func *) expr->oper;
funcid = func->funcid;
result_typeid = func->functype;
@@ -1333,21 +1363,23 @@ simplify_op_or_func(Expr *expr, List *args)
if (!HeapTupleIsValid(func_tuple))
elog(ERROR, "Function OID %u does not exist", funcid);
funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
- if (! funcform->proiscachable)
+ if (!funcform->proiscachable)
return NULL;
+
/*
* Also check to make sure it doesn't return a set.
*/
if (funcform->proretset)
return NULL;
+
/*
* OK, looks like we can simplify this operator/function.
*
* We use the executor's routine ExecEvalExpr() to avoid duplication of
* code and ensure we get the same result as the executor would get.
*
- * Build a new Expr node containing the already-simplified arguments.
- * The only other setup needed here is the replace_opid() that we already
+ * Build a new Expr node containing the already-simplified arguments. The
+ * only other setup needed here is the replace_opid() that we already
* did for the OP_EXPR case.
*/
newexpr = makeNode(Expr);
@@ -1355,21 +1387,23 @@ simplify_op_or_func(Expr *expr, List *args)
newexpr->opType = expr->opType;
newexpr->oper = expr->oper;
newexpr->args = args;
+
/*
* It is OK to pass econtext = NULL because none of the ExecEvalExpr()
* code used in this situation will use econtext. That might seem
- * fortuitous, but it's not so unreasonable --- a constant expression does
- * not depend on context, by definition, n'est ce pas?
+ * fortuitous, but it's not so unreasonable --- a constant expression
+ * does not depend on context, by definition, n'est ce pas?
*/
const_val = ExecEvalExpr((Node *) newexpr, NULL,
&const_is_null, &isDone);
Assert(isDone); /* if this isn't set, we blew it... */
pfree(newexpr);
+
/*
* Make the constant result node.
*
- * XXX would it be better to take the result type from the
- * pg_proc tuple, rather than the Oper or Func node?
+ * XXX would it be better to take the result type from the pg_proc tuple,
+ * rather than the Oper or Func node?
*/
resultType = typeidType(result_typeid);
return (Expr *) makeConst(result_typeid, typeLen(resultType),
@@ -1426,8 +1460,8 @@ simplify_op_or_func(Expr *expr, List *args)
*
* The walker routine should return "false" to continue the tree walk, or
* "true" to abort the walk and immediately return "true" to the top-level
- * caller. This can be used to short-circuit the traversal if the walker
- * has found what it came for. "false" is returned to the top-level caller
+ * caller. This can be used to short-circuit the traversal if the walker
+ * has found what it came for. "false" is returned to the top-level caller
* iff no invocation of the walker returned "true".
*
* The node types handled by expression_tree_walker include all those
@@ -1454,16 +1488,16 @@ simplify_op_or_func(Expr *expr, List *args)
*/
bool
-expression_tree_walker(Node *node, bool (*walker) (), void *context)
+ expression_tree_walker(Node *node, bool (*walker) (), void *context)
{
List *temp;
/*
- * The walker has already visited the current node,
- * and so we need only recurse into any sub-nodes it has.
+ * The walker has already visited the current node, and so we need
+ * only recurse into any sub-nodes it has.
*
- * We assume that the walker is not interested in List nodes per se,
- * so when we expect a List we just recurse directly to self without
+ * We assume that the walker is not interested in List nodes per se, so
+ * when we expect a List we just recurse directly to self without
* bothering to call the walker.
*/
if (node == NULL)
@@ -1478,7 +1512,7 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context)
break;
case T_Expr:
{
- Expr *expr = (Expr *) node;
+ Expr *expr = (Expr *) node;
if (expr->opType == SUBPLAN_EXPR)
{
@@ -1500,6 +1534,7 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context)
case T_ArrayRef:
{
ArrayRef *aref = (ArrayRef *) node;
+
/* recurse directly for upper/lower array index lists */
if (expression_tree_walker((Node *) aref->refupperindexpr,
walker, context))
@@ -1519,10 +1554,12 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context)
case T_CaseExpr:
{
CaseExpr *caseexpr = (CaseExpr *) node;
+
/* we assume walker doesn't care about CaseWhens, either */
foreach(temp, caseexpr->args)
{
CaseWhen *when = (CaseWhen *) lfirst(temp);
+
Assert(IsA(when, CaseWhen));
if (walker(when->expr, context))
return true;
@@ -1538,12 +1575,14 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context)
break;
case T_SubLink:
{
- SubLink *sublink = (SubLink *) node;
+ SubLink *sublink = (SubLink *) node;
- /* If the SubLink has already been processed by subselect.c,
- * it will have lefthand=NIL, and we only need to look at
- * the oper list. Otherwise we only need to look at lefthand
- * (the Oper nodes in the oper list are deemed uninteresting).
+ /*
+ * If the SubLink has already been processed by
+ * subselect.c, it will have lefthand=NIL, and we only
+ * need to look at the oper list. Otherwise we only need
+ * to look at lefthand (the Oper nodes in the oper list
+ * are deemed uninteresting).
*/
if (sublink->lefthand)
return walker((Node *) sublink->lefthand, context);
@@ -1628,18 +1667,19 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context)
*/
Node *
-expression_tree_mutator(Node *node, Node * (*mutator) (), void *context)
+ expression_tree_mutator(Node *node, Node *(*mutator) (), void *context)
{
+
/*
- * The mutator has already decided not to modify the current node,
- * but we must call the mutator for any sub-nodes.
+ * The mutator has already decided not to modify the current node, but
+ * we must call the mutator for any sub-nodes.
*/
#define FLATCOPY(newnode, node, nodetype) \
( (newnode) = makeNode(nodetype), \
memcpy((newnode), (node), sizeof(nodetype)) )
-#define CHECKFLATCOPY(newnode, node, nodetype) \
+#define CHECKFLATCOPY(newnode, node, nodetype) \
( AssertMacro(IsA((node), nodetype)), \
(newnode) = makeNode(nodetype), \
memcpy((newnode), (node), sizeof(nodetype)) )
@@ -1659,31 +1699,41 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context)
return (Node *) copyObject(node);
case T_Expr:
{
- Expr *expr = (Expr *) node;
- Expr *newnode;
+ Expr *expr = (Expr *) node;
+ Expr *newnode;
FLATCOPY(newnode, expr, Expr);
if (expr->opType == SUBPLAN_EXPR)
{
- SubLink *oldsublink = ((SubPlan *) expr->oper)->sublink;
- SubPlan *newsubplan;
+ SubLink *oldsublink = ((SubPlan *) expr->oper)->sublink;
+ SubPlan *newsubplan;
/* flat-copy the oper node, which is a SubPlan */
CHECKFLATCOPY(newsubplan, expr->oper, SubPlan);
newnode->oper = (Node *) newsubplan;
/* likewise its SubLink node */
CHECKFLATCOPY(newsubplan->sublink, oldsublink, SubLink);
- /* transform args list (params to be passed to subplan) */
+
+ /*
+ * transform args list (params to be passed to
+ * subplan)
+ */
MUTATE(newnode->args, expr->args, List *);
/* transform sublink's oper list as well */
- MUTATE(newsubplan->sublink->oper, oldsublink->oper, List*);
- /* but not the subplan itself, which is referenced as-is */
+ MUTATE(newsubplan->sublink->oper, oldsublink->oper, List *);
+
+ /*
+ * but not the subplan itself, which is referenced
+ * as-is
+ */
}
else
{
- /* for other Expr node types, just transform args list,
- * linking to original oper node (OK?)
+
+ /*
+ * for other Expr node types, just transform args
+ * list, linking to original oper node (OK?)
*/
MUTATE(newnode->args, expr->args, List *);
}
@@ -1692,8 +1742,8 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context)
break;
case T_Aggref:
{
- Aggref *aggref = (Aggref *) node;
- Aggref *newnode;
+ Aggref *aggref = (Aggref *) node;
+ Aggref *newnode;
FLATCOPY(newnode, aggref, Aggref);
MUTATE(newnode->target, aggref->target, Node *);
@@ -1702,8 +1752,8 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context)
break;
case T_Iter:
{
- Iter *iter = (Iter *) node;
- Iter *newnode;
+ Iter *iter = (Iter *) node;
+ Iter *newnode;
FLATCOPY(newnode, iter, Iter);
MUTATE(newnode->iterexpr, iter->iterexpr, Node *);
@@ -1763,12 +1813,14 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context)
break;
case T_SubLink:
{
- /* A "bare" SubLink (note we will not come here if we found
- * a SUBPLAN_EXPR node above it). Transform the lefthand side,
- * but not the oper list nor the subquery.
+
+ /*
+ * A "bare" SubLink (note we will not come here if we
+ * found a SUBPLAN_EXPR node above it). Transform the
+ * lefthand side, but not the oper list nor the subquery.
*/
- SubLink *sublink = (SubLink *) node;
- SubLink *newnode;
+ SubLink *sublink = (SubLink *) node;
+ SubLink *newnode;
FLATCOPY(newnode, sublink, SubLink);
MUTATE(newnode->lefthand, sublink->lefthand, List *);
@@ -1777,9 +1829,12 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context)
break;
case T_List:
{
- /* We assume the mutator isn't interested in the list nodes
- * per se, so just invoke it on each list element.
- * NOTE: this would fail badly on a list with integer elements!
+
+ /*
+ * We assume the mutator isn't interested in the list
+ * nodes per se, so just invoke it on each list element.
+ * NOTE: this would fail badly on a list with integer
+ * elements!
*/
List *resultlist = NIL;
List *temp;
@@ -1795,9 +1850,13 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context)
break;
case T_TargetEntry:
{
- /* We mutate the expression, but not the resdom, by default. */
- TargetEntry *targetentry = (TargetEntry *) node;
- TargetEntry *newnode;
+
+ /*
+ * We mutate the expression, but not the resdom, by
+ * default.
+ */
+ TargetEntry *targetentry = (TargetEntry *) node;
+ TargetEntry *newnode;
FLATCOPY(newnode, targetentry, TargetEntry);
MUTATE(newnode->expr, targetentry->expr, Node *);
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 400c813125c..69a28138d8a 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.62 2000/03/22 22:08:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.63 2000/04/12 17:15:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,6 +42,7 @@ compare_path_costs(Path *path1, Path *path2, CostSelector criterion)
return -1;
if (path1->startup_cost > path2->startup_cost)
return +1;
+
/*
* If paths have the same startup cost (not at all unlikely),
* order them by total cost.
@@ -57,6 +58,7 @@ compare_path_costs(Path *path1, Path *path2, CostSelector criterion)
return -1;
if (path1->total_cost > path2->total_cost)
return +1;
+
/*
* If paths have the same total cost, order them by startup cost.
*/
@@ -172,7 +174,8 @@ set_cheapest(RelOptInfo *parent_rel)
void
add_path(RelOptInfo *parent_rel, Path *new_path)
{
- bool accept_new = true; /* unless we find a superior old path */
+ bool accept_new = true; /* unless we find a superior old
+ * path */
List *p1_prev = NIL;
List *p1;
@@ -184,36 +187,39 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
foreach(p1, parent_rel->pathlist)
{
Path *old_path = (Path *) lfirst(p1);
- bool remove_old = false; /* unless new proves superior */
+ bool remove_old = false; /* unless new proves superior */
int costcmp;
costcmp = compare_path_costs(new_path, old_path, TOTAL_COST);
+
/*
- * If the two paths compare differently for startup and total cost,
- * then we want to keep both, and we can skip the (much slower)
- * comparison of pathkeys. If they compare the same, proceed with
- * the pathkeys comparison. Note this test relies on the fact that
- * compare_path_costs will only return 0 if both costs are equal
- * (and, therefore, there's no need to call it twice in that case).
+ * If the two paths compare differently for startup and total
+ * cost, then we want to keep both, and we can skip the (much
+ * slower) comparison of pathkeys. If they compare the same,
+ * proceed with the pathkeys comparison. Note this test relies on
+ * the fact that compare_path_costs will only return 0 if both
+ * costs are equal (and, therefore, there's no need to call it
+ * twice in that case).
*/
if (costcmp == 0 ||
- costcmp == compare_path_costs(new_path, old_path, STARTUP_COST))
+ costcmp == compare_path_costs(new_path, old_path, STARTUP_COST))
{
switch (compare_pathkeys(new_path->pathkeys, old_path->pathkeys))
{
case PATHKEYS_EQUAL:
if (costcmp < 0)
- remove_old = true; /* new dominates old */
+ remove_old = true; /* new dominates old */
else
- accept_new = false; /* old equals or dominates new */
+ accept_new = false; /* old equals or dominates
+ * new */
break;
case PATHKEYS_BETTER1:
if (costcmp <= 0)
- remove_old = true; /* new dominates old */
+ remove_old = true; /* new dominates old */
break;
case PATHKEYS_BETTER2:
if (costcmp >= 0)
- accept_new = false; /* old dominates new */
+ accept_new = false; /* old dominates new */
break;
case PATHKEYS_DIFFERENT:
/* keep both paths, since they have different ordering */
@@ -241,7 +247,7 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
* scanning the pathlist; we will not add new_path, and we assume
* new_path cannot dominate any other elements of the pathlist.
*/
- if (! accept_new)
+ if (!accept_new)
break;
}
@@ -315,12 +321,14 @@ create_index_path(Query *root,
if (pathnode->path.pathkeys == NIL)
{
/* No ordering available from index, is that OK? */
- if (! ScanDirectionIsNoMovement(indexscandir))
+ if (!ScanDirectionIsNoMovement(indexscandir))
elog(ERROR, "create_index_path: failed to create ordered index scan");
}
else
{
- /* The index is ordered, and build_index_pathkeys defaulted to
+
+ /*
+ * The index is ordered, and build_index_pathkeys defaulted to
* forward scan, so make sure we mark the pathnode properly.
*/
if (ScanDirectionIsNoMovement(indexscandir))
@@ -341,11 +349,11 @@ create_index_path(Query *root,
pathnode->indexscandir = indexscandir;
/*
- * This routine is only used to generate "standalone" indexpaths,
- * not nestloop inner indexpaths. So joinrelids is always NIL
- * and the number of rows is the same as the parent rel's estimate.
+ * This routine is only used to generate "standalone" indexpaths, not
+ * nestloop inner indexpaths. So joinrelids is always NIL and the
+ * number of rows is the same as the parent rel's estimate.
*/
- pathnode->joinrelids = NIL; /* no join clauses here */
+ pathnode->joinrelids = NIL; /* no join clauses here */
pathnode->rows = rel->rows;
cost_index(&pathnode->path, root, rel, index, indexquals, false);
@@ -359,20 +367,23 @@ create_index_path(Query *root,
* pathnode.
*
*/
-TidPath *
+TidPath *
create_tidscan_path(RelOptInfo *rel, List *tideval)
{
- TidPath *pathnode = makeNode(TidPath);
+ TidPath *pathnode = makeNode(TidPath);
pathnode->path.pathtype = T_TidScan;
pathnode->path.parent = rel;
pathnode->path.pathkeys = NIL;
- pathnode->tideval = copyObject(tideval); /* is copy really necessary? */
+ pathnode->tideval = copyObject(tideval); /* is copy really
+ * necessary? */
pathnode->unjoined_relids = NIL;
cost_tidscan(&pathnode->path, rel, tideval);
- /* divide selectivity for each clause to get an equal selectivity
- * as IndexScan does OK ?
+
+ /*
+ * divide selectivity for each clause to get an equal selectivity as
+ * IndexScan does OK ?
*/
return pathnode;
@@ -485,7 +496,7 @@ create_mergejoin_path(RelOptInfo *joinrel,
* 'innerdisbursion' is an estimate of the disbursion of the inner hash key
*
*/
-HashPath *
+HashPath *
create_hashjoin_path(RelOptInfo *joinrel,
Path *outer_path,
Path *inner_path,
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 716c31ab0f1..e9d7690e00c 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.49 2000/02/18 09:30:09 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.50 2000/04/12 17:15:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,7 +50,7 @@ relation_info(Query *root, Index relid,
Form_pg_class relation;
relationTuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relationObjectId),
+ ObjectIdGetDatum(relationObjectId),
0, 0, 0);
if (!HeapTupleIsValid(relationTuple))
elog(ERROR, "relation_info: Relation %u not found",
@@ -81,7 +81,7 @@ find_secondary_indexes(Query *root, Index relid)
Oid indrelid = getrelid(relid, root->rtable);
Relation relation;
HeapScanDesc scan;
- ScanKeyData indexKey;
+ ScanKeyData indexKey;
HeapTuple indexTuple;
/* Scan pg_index for tuples describing indexes of this rel */
@@ -97,27 +97,28 @@ find_secondary_indexes(Query *root, Index relid)
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
{
- Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple);
- IndexOptInfo *info = makeNode(IndexOptInfo);
- int i;
- Relation indexRelation;
- Oid relam;
- uint16 amorderstrategy;
+ Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple);
+ IndexOptInfo *info = makeNode(IndexOptInfo);
+ int i;
+ Relation indexRelation;
+ Oid relam;
+ uint16 amorderstrategy;
/*
* Need to make these arrays large enough to be sure there is a
* terminating 0 at the end of each one.
*/
- info->classlist = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS+1));
- info->indexkeys = (int *) palloc(sizeof(int) * (INDEX_MAX_KEYS+1));
- info->ordering = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS+1));
+ info->classlist = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1));
+ info->indexkeys = (int *) palloc(sizeof(int) * (INDEX_MAX_KEYS + 1));
+ info->ordering = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1));
/* Extract info from the pg_index tuple */
info->indexoid = index->indexrelid;
- info->indproc = index->indproc; /* functional index ?? */
- if (VARSIZE(&index->indpred) != 0) /* partial index ?? */
+ info->indproc = index->indproc; /* functional index ?? */
+ if (VARSIZE(&index->indpred) != 0) /* partial index ?? */
{
char *predString = fmgr(F_TEXTOUT, &index->indpred);
+
info->indpred = (List *) stringToNode(predString);
pfree(predString);
}
@@ -143,26 +144,25 @@ find_secondary_indexes(Query *root, Index relid)
index_close(indexRelation);
/*
- * Fetch the ordering operators associated with the index,
- * if any.
+ * Fetch the ordering operators associated with the index, if any.
*/
- MemSet(info->ordering, 0, sizeof(Oid) * (INDEX_MAX_KEYS+1));
+ MemSet(info->ordering, 0, sizeof(Oid) * (INDEX_MAX_KEYS + 1));
if (amorderstrategy != 0)
{
for (i = 0; i < INDEX_MAX_KEYS && index->indclass[i]; i++)
{
- HeapTuple amopTuple;
- Form_pg_amop amop;
+ HeapTuple amopTuple;
+ Form_pg_amop amop;
amopTuple =
SearchSysCacheTuple(AMOPSTRATEGY,
ObjectIdGetDatum(relam),
- ObjectIdGetDatum(index->indclass[i]),
+ ObjectIdGetDatum(index->indclass[i]),
UInt16GetDatum(amorderstrategy),
0);
if (!HeapTupleIsValid(amopTuple))
elog(ERROR, "find_secondary_indexes: no amop %u %u %d",
- relam, index->indclass[i], (int) amorderstrategy);
+ relam, index->indclass[i], (int) amorderstrategy);
amop = (Form_pg_amop) GETSTRUCT(amopTuple);
info->ordering[i] = amop->amopopr;
}
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 694a1b905e1..da7059ce915 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.25 2000/02/18 23:47:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.26 2000/04/12 17:15:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,15 +24,15 @@
static List *new_join_tlist(List *tlist, int first_resdomno);
static List *build_joinrel_restrictlist(RelOptInfo *joinrel,
- RelOptInfo *outer_rel,
- RelOptInfo *inner_rel);
+ RelOptInfo *outer_rel,
+ RelOptInfo *inner_rel);
static void build_joinrel_joinlist(RelOptInfo *joinrel,
- RelOptInfo *outer_rel,
- RelOptInfo *inner_rel);
+ RelOptInfo *outer_rel,
+ RelOptInfo *inner_rel);
static List *subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
- List *joininfo_list);
+ List *joininfo_list);
static void subbuild_joinrel_joinlist(RelOptInfo *joinrel,
- List *joininfo_list);
+ List *joininfo_list);
/*
@@ -50,7 +50,10 @@ get_base_rel(Query *root, int relid)
{
rel = (RelOptInfo *) lfirst(baserels);
- /* We know length(rel->relids) == 1 for all members of base_rel_list */
+ /*
+ * We know length(rel->relids) == 1 for all members of
+ * base_rel_list
+ */
if (lfirsti(rel->relids) == relid)
return rel;
}
@@ -75,18 +78,20 @@ get_base_rel(Query *root, int relid)
if (relid < 0)
{
+
/*
- * If the relation is a materialized relation, assume
- * constants for sizes.
+ * If the relation is a materialized relation, assume constants
+ * for sizes.
*/
rel->pages = _NONAME_RELATION_PAGES_;
rel->tuples = _NONAME_RELATION_TUPLES_;
}
else
{
+
/*
- * Otherwise, retrieve relation statistics from the
- * system catalogs.
+ * Otherwise, retrieve relation statistics from the system
+ * catalogs.
*/
relation_info(root, relid,
&rel->indexed, &rel->pages, &rel->tuples);
@@ -162,6 +167,7 @@ get_join_rel(Query *root,
if (joinrel)
{
+
/*
* Yes, so we only need to figure the restrictlist for this
* particular pair of component relations.
@@ -198,13 +204,13 @@ get_join_rel(Query *root,
* of the outer and inner join relations and then merging the results
* together.
*
- * NOTE: the tlist order for a join rel will depend on which pair
- * of outer and inner rels we first try to build it from. But the
+ * NOTE: the tlist order for a join rel will depend on which pair of
+ * outer and inner rels we first try to build it from. But the
* contents should be the same regardless.
*
- * XXX someday: consider pruning vars from the join's targetlist
- * if they are needed only to evaluate restriction clauses of this
- * join, and will never be accessed at higher levels of the plantree.
+ * XXX someday: consider pruning vars from the join's targetlist if they
+ * are needed only to evaluate restriction clauses of this join, and
+ * will never be accessed at higher levels of the plantree.
*/
new_outer_tlist = new_join_tlist(outer_rel->targetlist, 1);
new_inner_tlist = new_join_tlist(inner_rel->targetlist,
@@ -212,9 +218,9 @@ get_join_rel(Query *root,
joinrel->targetlist = nconc(new_outer_tlist, new_inner_tlist);
/*
- * Construct restrict and join clause lists for the new joinrel.
- * (The caller might or might not need the restrictlist, but
- * I need it anyway for set_joinrel_size_estimates().)
+ * Construct restrict and join clause lists for the new joinrel. (The
+ * caller might or might not need the restrictlist, but I need it
+ * anyway for set_joinrel_size_estimates().)
*/
restrictlist = build_joinrel_restrictlist(joinrel, outer_rel, inner_rel);
if (restrictlist_ptr)
@@ -246,7 +252,7 @@ get_join_rel(Query *root,
*
* XXX the above comment refers to code that is long dead and gone;
* we don't keep track of joinlists for individual targetlist entries
- * anymore. For now, all vars present in either input tlist will be
+ * anymore. For now, all vars present in either input tlist will be
* emitted in the join's tlist.
*
* 'tlist' is the target list of one of the join relations
@@ -286,16 +292,16 @@ new_join_tlist(List *tlist,
* the join lists need only be computed once for any join RelOptInfo.
* The join lists are fully determined by the set of rels making up the
* joinrel, so we should get the same results (up to ordering) from any
- * candidate pair of sub-relations. But the restriction list is whatever
+ * candidate pair of sub-relations. But the restriction list is whatever
* is not handled in the sub-relations, so it depends on which
* sub-relations are considered.
*
* If a join clause from an input relation refers to base rels still not
* present in the joinrel, then it is still a join clause for the joinrel;
- * we put it into an appropriate JoinInfo list for the joinrel. Otherwise,
+ * we put it into an appropriate JoinInfo list for the joinrel. Otherwise,
* the clause is now a restrict clause for the joined relation, and we
* return it to the caller of build_joinrel_restrictlist() to be stored in
- * join paths made from this pair of sub-relations. (It will not need to
+ * join paths made from this pair of sub-relations. (It will not need to
* be considered further up the join tree.)
*
* 'joinrel' is a join relation node
@@ -304,11 +310,11 @@ new_join_tlist(List *tlist,
*
* build_joinrel_restrictlist() returns a list of relevant restrictinfos,
* whereas build_joinrel_joinlist() stores its results in the joinrel's
- * joininfo lists. One or the other must accept each given clause!
+ * joininfo lists. One or the other must accept each given clause!
*
* NB: Formerly, we made deep(!) copies of each input RestrictInfo to pass
* up to the join relation. I believe this is no longer necessary, because
- * RestrictInfo nodes are no longer context-dependent. Instead, just include
+ * RestrictInfo nodes are no longer context-dependent. Instead, just include
* the original nodes in the lists made for the join relation.
*/
static List *
@@ -316,9 +322,10 @@ build_joinrel_restrictlist(RelOptInfo *joinrel,
RelOptInfo *outer_rel,
RelOptInfo *inner_rel)
{
+
/*
- * We must eliminate duplicates, since we will see the
- * same clauses arriving from both input relations...
+ * We must eliminate duplicates, since we will see the same clauses
+ * arriving from both input relations...
*/
return LispUnion(subbuild_joinrel_restrictlist(joinrel,
outer_rel->joininfo),
@@ -348,6 +355,7 @@ subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
if (is_subseti(joininfo->unjoined_relids, joinrel->relids))
{
+
/*
* Clauses in this JoinInfo list become restriction clauses
* for the joinrel, since they refer to no outside rels.
@@ -360,9 +368,10 @@ subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
}
else
{
+
/*
- * These clauses are still join clauses at this level,
- * so we ignore them in this routine.
+ * These clauses are still join clauses at this level, so we
+ * ignore them in this routine.
*/
}
}
@@ -385,18 +394,20 @@ subbuild_joinrel_joinlist(RelOptInfo *joinrel,
joinrel->relids);
if (new_unjoined_relids == NIL)
{
+
/*
* Clauses in this JoinInfo list become restriction clauses
- * for the joinrel, since they refer to no outside rels.
- * So we can ignore them in this routine.
+ * for the joinrel, since they refer to no outside rels. So we
+ * can ignore them in this routine.
*/
}
else
{
+
/*
- * These clauses are still join clauses at this level,
- * so find or make the appropriate JoinInfo item for the joinrel,
- * and add the clauses to it (eliminating duplicates).
+ * These clauses are still join clauses at this level, so find
+ * or make the appropriate JoinInfo item for the joinrel, and
+ * add the clauses to it (eliminating duplicates).
*/
JoinInfo *new_joininfo;
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index b4c745b25f3..d4094dac12a 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.43 2000/01/27 18:11:34 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.44 2000/04/12 17:15:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,7 +27,7 @@
/*
* tlistentry_member
* Finds the (first) member of the given tlist whose expression is
- * equal() to the given expression. Result is NULL if no such member.
+ * equal() to the given expression. Result is NULL if no such member.
*/
TargetEntry *
tlistentry_member(Node *node, List *targetlist)
@@ -36,7 +36,7 @@ tlistentry_member(Node *node, List *targetlist)
foreach(temp, targetlist)
{
- TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
+ TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
if (equal(node, tlentry->expr))
return tlentry;
@@ -87,12 +87,12 @@ tlist_member(Node *node, List *targetlist)
void
add_var_to_tlist(RelOptInfo *rel, Var *var)
{
- if (! tlistentry_member((Node *) var, rel->targetlist))
+ if (!tlistentry_member((Node *) var, rel->targetlist))
{
/* XXX is copyObject necessary here? */
rel->targetlist = lappend(rel->targetlist,
- create_tl_element((Var *) copyObject(var),
- length(rel->targetlist) + 1));
+ create_tl_element((Var *) copyObject(var),
+ length(rel->targetlist) + 1));
}
}
@@ -189,7 +189,7 @@ add_to_flat_tlist(List *tlist, List *vars)
{
Var *var = lfirst(v);
- if (! tlistentry_member((Node *) var, tlist))
+ if (!tlistentry_member((Node *) var, tlist))
{
Resdom *r;
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index f438845cff9..bed7be7f08a 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.25 2000/01/26 05:56:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.26 2000/04/12 17:15:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,8 @@
#include "optimizer/var.h"
-typedef struct {
+typedef struct
+{
List *varlist;
bool includeUpperVars;
} pull_var_clause_context;
@@ -28,7 +29,7 @@ typedef struct {
static bool pull_varnos_walker(Node *node, List **listptr);
static bool contain_var_clause_walker(Node *node, void *context);
static bool pull_var_clause_walker(Node *node,
- pull_var_clause_context *context);
+ pull_var_clause_context *context);
/*
@@ -54,7 +55,8 @@ pull_varnos_walker(Node *node, List **listptr)
return false;
if (IsA(node, Var))
{
- Var *var = (Var *) node;
+ Var *var = (Var *) node;
+
if (var->varlevelsup == 0 && !intMember(var->varno, *listptr))
*listptr = lconsi(var->varno, *listptr);
return false;
@@ -83,7 +85,8 @@ contain_var_clause_walker(Node *node, void *context)
if (IsA(node, Var))
{
if (((Var *) node)->varlevelsup == 0)
- return true; /* abort the tree traversal and return true */
+ return true; /* abort the tree traversal and return
+ * true */
return false;
}
return expression_tree_walker(node, contain_var_clause_walker, context);
@@ -94,7 +97,7 @@ contain_var_clause_walker(Node *node, void *context)
* Recursively pulls all var nodes from an expression clause.
*
* Upper-level vars (with varlevelsup > 0) are included only
- * if includeUpperVars is true. Most callers probably want
+ * if includeUpperVars is true. Most callers probably want
* to ignore upper-level vars.
*
* Returns list of varnodes found. Note the varnodes themselves are not
@@ -103,7 +106,7 @@ contain_var_clause_walker(Node *node, void *context)
List *
pull_var_clause(Node *clause, bool includeUpperVars)
{
- pull_var_clause_context context;
+ pull_var_clause_context context;
context.varlist = NIL;
context.includeUpperVars = includeUpperVars;