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/clauseinfo.c259
-rw-r--r--src/backend/optimizer/util/clauses.c1026
-rw-r--r--src/backend/optimizer/util/indexnode.c113
-rw-r--r--src/backend/optimizer/util/internal.c48
-rw-r--r--src/backend/optimizer/util/joininfo.c132
-rw-r--r--src/backend/optimizer/util/keys.c261
-rw-r--r--src/backend/optimizer/util/ordering.c154
-rw-r--r--src/backend/optimizer/util/pathnode.c867
-rw-r--r--src/backend/optimizer/util/plancat.c969
-rw-r--r--src/backend/optimizer/util/relnode.c182
-rw-r--r--src/backend/optimizer/util/tlist.c834
-rw-r--r--src/backend/optimizer/util/var.c308
12 files changed, 2690 insertions, 2463 deletions
diff --git a/src/backend/optimizer/util/clauseinfo.c b/src/backend/optimizer/util/clauseinfo.c
index 2d648eb3605..e5fd2b7e5bb 100644
--- a/src/backend/optimizer/util/clauseinfo.c
+++ b/src/backend/optimizer/util/clauseinfo.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* clauseinfo.c--
- * ClauseInfo node manipulation routines.
+ * ClauseInfo node manipulation routines.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/clauseinfo.c,v 1.3 1996/07/31 18:47:06 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/clauseinfo.c,v 1.4 1997/09/07 04:44:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,167 +20,172 @@
#include "optimizer/clauses.h"
#include "optimizer/clauseinfo.h"
-/*
+/*
* valid-or-clause--
- *
+ *
* Returns t iff the clauseinfo node contains a 'normal' 'or' clause.
- *
+ *
*/
bool
-valid_or_clause(CInfo *clauseinfo)
+valid_or_clause(CInfo * clauseinfo)
{
- if (clauseinfo != NULL &&
- !single_node((Node*)clauseinfo->clause) &&
- !clauseinfo->notclause &&
- or_clause((Node*)clauseinfo->clause))
- return(true);
- else
- return(false);
+ if (clauseinfo != NULL &&
+ !single_node((Node *) clauseinfo->clause) &&
+ !clauseinfo->notclause &&
+ or_clause((Node *) clauseinfo->clause))
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* get-actual-clauses--
- *
+ *
* Returns a list containing the clauses from 'clauseinfo-list'.
- *
+ *
*/
-List *
-get_actual_clauses(List *clauseinfo_list)
+List *
+get_actual_clauses(List * clauseinfo_list)
{
- List *temp = NIL;
- List *result = NIL;
- CInfo *clause = (CInfo *)NULL;
-
- foreach(temp,clauseinfo_list) {
- clause = (CInfo *)lfirst(temp);
- result = lappend(result,clause->clause);
- }
- return(result);
+ List *temp = NIL;
+ List *result = NIL;
+ CInfo *clause = (CInfo *) NULL;
+
+ foreach(temp, clauseinfo_list)
+ {
+ clause = (CInfo *) lfirst(temp);
+ result = lappend(result, clause->clause);
+ }
+ return (result);
}
-/*
+/*
* XXX NOTE:
- * The following routines must return their contents in the same order
- * (e.g., the first clause's info should be first, and so on) or else
- * get_index_sel() won't work.
- *
+ * The following routines must return their contents in the same order
+ * (e.g., the first clause's info should be first, and so on) or else
+ * get_index_sel() won't work.
+ *
*/
-/*
+/*
* get_relattvals--
- * For each member of a list of clauseinfo nodes to be used with an
- * index, create a vectori-long specifying:
- * the attnos,
- * the values of the clause constants, and
- * flags indicating the type and location of the constant within
- * each clause.
- * Each clause is of the form (op var some_type_of_constant), thus the
- * flag indicating whether the constant is on the left or right should
- * always be *SELEC-CONSTANT-RIGHT*.
- *
+ * For each member of a list of clauseinfo nodes to be used with an
+ * index, create a vectori-long specifying:
+ * the attnos,
+ * the values of the clause constants, and
+ * flags indicating the type and location of the constant within
+ * each clause.
+ * Each clause is of the form (op var some_type_of_constant), thus the
+ * flag indicating whether the constant is on the left or right should
+ * always be *SELEC-CONSTANT-RIGHT*.
+ *
* 'clauseinfo-list' is a list of clauseinfo nodes
- *
+ *
* Returns a list of vectori-longs.
- *
+ *
*/
void
-get_relattvals(List *clauseinfo_list,
- List **attnos,
- List **values,
- List **flags)
+get_relattvals(List * clauseinfo_list,
+ List ** attnos,
+ List ** values,
+ List ** flags)
{
- List *result1 = NIL;
- List *result2 = NIL;
- List *result3 = NIL;
- CInfo *temp = (CInfo *)NULL;
- List *i = NIL;
-
- foreach (i,clauseinfo_list) {
- int dummy;
- AttrNumber attno;
- Datum constval;
- int flag;
-
- temp = (CInfo *)lfirst(i);
- get_relattval((Node*)temp->clause, &dummy, &attno, &constval, &flag);
- result1 = lappendi(result1, (int)attno);
- result2 = lappendi(result2, constval);
- result3 = lappendi(result3, flag);
- }
+ List *result1 = NIL;
+ List *result2 = NIL;
+ List *result3 = NIL;
+ CInfo *temp = (CInfo *) NULL;
+ List *i = NIL;
+
+ foreach(i, clauseinfo_list)
+ {
+ int dummy;
+ AttrNumber attno;
+ Datum constval;
+ int flag;
+
+ temp = (CInfo *) lfirst(i);
+ get_relattval((Node *) temp->clause, &dummy, &attno, &constval, &flag);
+ result1 = lappendi(result1, (int) attno);
+ result2 = lappendi(result2, constval);
+ result3 = lappendi(result3, flag);
+ }
- *attnos = result1;
- *values = result2;
- *flags = result3;
- return;
+ *attnos = result1;
+ *values = result2;
+ *flags = result3;
+ return;
}
-/*
+/*
* get_joinvars --
- * Given a list of join clauseinfo nodes to be used with the index
- * of an inner join relation, return three lists consisting of:
- * the attributes corresponding to the inner join relation
- * the value of the inner var clause (always "")
- * whether the attribute appears on the left or right side of
- * the operator.
- *
+ * Given a list of join clauseinfo nodes to be used with the index
+ * of an inner join relation, return three lists consisting of:
+ * the attributes corresponding to the inner join relation
+ * the value of the inner var clause (always "")
+ * whether the attribute appears on the left or right side of
+ * the operator.
+ *
* 'relid' is the inner join relation
* 'clauseinfo-list' is a list of qualification clauses to be used with
- * 'rel'
- *
+ * 'rel'
+ *
*/
void
get_joinvars(Oid relid,
- List *clauseinfo_list,
- List **attnos,
- List **values,
- List **flags)
+ List * clauseinfo_list,
+ List ** attnos,
+ List ** values,
+ List ** flags)
{
- List *result1 = NIL;
- List *result2 = NIL;
- List *result3 = NIL;
- List *temp;
-
- foreach(temp, clauseinfo_list) {
- CInfo *clauseinfo = lfirst(temp);
- Expr *clause = clauseinfo->clause;
-
- if( IsA (get_leftop(clause),Var) &&
- (relid == (get_leftop(clause))->varno)) {
- result1 = lappendi(result1, (int4)(get_leftop(clause))->varattno);
- result2 = lappend(result2, "");
- result3 = lappendi(result3, _SELEC_CONSTANT_RIGHT_);
- } else {
- result1 = lappendi(result1, (int4)(get_rightop(clause))->varattno);
- result2 = lappend(result2, "");
- result3 = lappendi(result3, _SELEC_CONSTANT_LEFT_);
+ List *result1 = NIL;
+ List *result2 = NIL;
+ List *result3 = NIL;
+ List *temp;
+
+ foreach(temp, clauseinfo_list)
+ {
+ CInfo *clauseinfo = lfirst(temp);
+ Expr *clause = clauseinfo->clause;
+
+ if (IsA(get_leftop(clause), Var) &&
+ (relid == (get_leftop(clause))->varno))
+ {
+ result1 = lappendi(result1, (int4) (get_leftop(clause))->varattno);
+ result2 = lappend(result2, "");
+ result3 = lappendi(result3, _SELEC_CONSTANT_RIGHT_);
+ }
+ else
+ {
+ result1 = lappendi(result1, (int4) (get_rightop(clause))->varattno);
+ result2 = lappend(result2, "");
+ result3 = lappendi(result3, _SELEC_CONSTANT_LEFT_);
+ }
}
- }
- *attnos = result1;
- *values = result2;
- *flags = result3;
- return;
+ *attnos = result1;
+ *values = result2;
+ *flags = result3;
+ return;
}
-/*
+/*
* get_opnos--
- * Create and return a list containing the clause operators of each member
- * of a list of clauseinfo nodes to be used with an index.
- *
+ * Create and return a list containing the clause operators of each member
+ * of a list of clauseinfo nodes to be used with an index.
+ *
*/
-List *
-get_opnos(List *clauseinfo_list)
+List *
+get_opnos(List * clauseinfo_list)
{
- CInfo *temp = (CInfo *)NULL;
- List *result = NIL;
- List *i = NIL;
-
- foreach(i,clauseinfo_list) {
- temp = (CInfo *)lfirst(i);
- result =
- lappendi(result,
- (((Oper*)temp->clause->oper)->opno));
- }
- return(result);
+ CInfo *temp = (CInfo *) NULL;
+ List *result = NIL;
+ List *i = NIL;
+
+ foreach(i, clauseinfo_list)
+ {
+ temp = (CInfo *) lfirst(i);
+ result =
+ lappendi(result,
+ (((Oper *) temp->clause->oper)->opno));
+ }
+ return (result);
}
-
-
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 153c11f9f42..03e0856ef09 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* clauses.c--
- * routines to manipulate qualification clauses
+ * routines to manipulate qualification clauses
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.7 1997/08/19 21:31:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.8 1997/09/07 04:44:20 momjian Exp $
*
* HISTORY
- * AUTHOR DATE MAJOR EVENT
- * Andrew Yu Nov 3, 1994 clause.c and clauses.c combined
+ * AUTHOR DATE MAJOR EVENT
+ * Andrew Yu Nov 3, 1994 clause.c and clauses.c combined
*
*-------------------------------------------------------------------------
*/
@@ -34,533 +34,556 @@
#include "optimizer/internal.h"
#include "optimizer/var.h"
-static bool agg_clause(Node *clause);
+static bool agg_clause(Node * clause);
-Expr *
-make_clause(int type, Node *oper, List *args)
+Expr *
+make_clause(int type, Node * oper, List * args)
{
- if (type == AND_EXPR || type == OR_EXPR || type == NOT_EXPR ||
- type == OP_EXPR || type == FUNC_EXPR) {
- Expr *expr = makeNode(Expr);
-
- /*
- * assume type checking already done and we don't need the type of
- * the expr any more.
- */
- expr->typeOid = InvalidOid;
- expr->opType = type;
- expr->oper = oper; /* ignored for AND, OR, NOT */
- expr->args = args;
- return expr;
- }else {
- /* will this ever happen? translated from lispy C code - ay 10/94 */
- return((Expr*)args);
- }
+ if (type == AND_EXPR || type == OR_EXPR || type == NOT_EXPR ||
+ type == OP_EXPR || type == FUNC_EXPR)
+ {
+ Expr *expr = makeNode(Expr);
+
+ /*
+ * assume type checking already done and we don't need the type of
+ * the expr any more.
+ */
+ expr->typeOid = InvalidOid;
+ expr->opType = type;
+ expr->oper = oper; /* ignored for AND, OR, NOT */
+ expr->args = args;
+ return expr;
+ }
+ else
+ {
+ /* will this ever happen? translated from lispy C code - ay 10/94 */
+ return ((Expr *) args);
+ }
}
/*****************************************************************************
- * OPERATOR clause functions
+ * OPERATOR clause functions
*****************************************************************************/
-/*
+/*
* is_opclause--
- *
+ *
* Returns t iff the clause is an operator clause:
- * (op expr expr) or (op expr).
+ * (op expr expr) or (op expr).
*
* [historical note: is_clause has the exact functionality and is used
- * throughout the code. They're renamed to is_opclause for clarity.
- * - ay 10/94.]
+ * throughout the code. They're renamed to is_opclause for clarity.
+ * - ay 10/94.]
*/
bool
-is_opclause(Node *clause)
+is_opclause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType==OP_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == OP_EXPR);
}
-/*
+/*
* make_opclause--
- * Creates a clause given its operator left operand and right
- * operand (if it is non-null).
- *
+ * Creates a clause given its operator left operand and right
+ * operand (if it is non-null).
+ *
*/
-Expr *
-make_opclause(Oper *op, Var *leftop, Var *rightop)
+Expr *
+make_opclause(Oper * op, Var * leftop, Var * rightop)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = OP_EXPR;
- expr->oper = (Node*)op;
- expr->args = makeList(leftop, rightop, -1);
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = OP_EXPR;
+ expr->oper = (Node *) op;
+ expr->args = makeList(leftop, rightop, -1);
+ return expr;
}
-/*
+/*
* get_leftop--
- *
+ *
* Returns the left operand of a clause of the form (op expr expr)
- * or (op expr)
- * NB: it is assumed (for now) that all expr must be Var nodes
+ * or (op expr)
+ * NB: it is assumed (for now) that all expr must be Var nodes
*/
-Var *
-get_leftop(Expr *clause)
+Var *
+get_leftop(Expr * clause)
{
- if (clause->args!=NULL)
- return(lfirst(clause->args));
- else
- return NULL;
+ if (clause->args != NULL)
+ return (lfirst(clause->args));
+ else
+ return NULL;
}
-/*
+/*
* get_rightop
- *
+ *
* Returns the right operand in a clause of the form (op expr expr).
- *
+ *
*/
-Var *
-get_rightop(Expr *clause)
+Var *
+get_rightop(Expr * clause)
{
- if (clause->args!=NULL && lnext(clause->args)!=NULL)
- return (lfirst(lnext(clause->args)));
- else
- return NULL;
+ if (clause->args != NULL && lnext(clause->args) != NULL)
+ return (lfirst(lnext(clause->args)));
+ else
+ return NULL;
}
/*****************************************************************************
- * AGG clause functions
+ * AGG clause functions
*****************************************************************************/
-static bool
-agg_clause(Node *clause)
+static bool
+agg_clause(Node * clause)
{
- return
- (clause!=NULL && nodeTag(clause)==T_Aggreg);
+ return
+ (clause != NULL && nodeTag(clause) == T_Aggreg);
}
/*****************************************************************************
- * FUNC clause functions
+ * FUNC clause functions
*****************************************************************************/
-/*
+/*
* is_funcclause--
- *
+ *
* Returns t iff the clause is a function clause: (func { expr }).
- *
+ *
*/
bool
-is_funcclause(Node *clause)
+is_funcclause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType==FUNC_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == FUNC_EXPR);
}
-/*
+/*
* make_funcclause--
- *
+ *
* Creates a function clause given the FUNC node and the functional
* arguments.
- *
+ *
*/
-Expr *
-make_funcclause(Func *func, List *funcargs)
+Expr *
+make_funcclause(Func * func, List * funcargs)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = FUNC_EXPR;
- expr->oper = (Node*)func;
- expr->args = funcargs;
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = FUNC_EXPR;
+ expr->oper = (Node *) func;
+ expr->args = funcargs;
+ return expr;
}
/*****************************************************************************
- * OR clause functions
+ * OR clause functions
*****************************************************************************/
-/*
+/*
* or_clause--
- *
+ *
* Returns t iff the clause is an 'or' clause: (OR { expr }).
- *
+ *
*/
bool
-or_clause(Node *clause)
+or_clause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType==OR_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == OR_EXPR);
}
-/*
+/*
* make_orclause--
- *
+ *
* Creates an 'or' clause given a list of its subclauses.
- *
+ *
*/
-Expr *
-make_orclause(List *orclauses)
+Expr *
+make_orclause(List * orclauses)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = OR_EXPR;
- expr->oper = NULL;
- expr->args = orclauses;
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = OR_EXPR;
+ expr->oper = NULL;
+ expr->args = orclauses;
+ return expr;
}
/*****************************************************************************
- * NOT clause functions
+ * NOT clause functions
*****************************************************************************/
-/*
+/*
* not_clause--
- *
+ *
* Returns t iff this is a 'not' clause: (NOT expr).
- *
+ *
*/
bool
-not_clause(Node *clause)
+not_clause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType == NOT_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == NOT_EXPR);
}
-/*
+/*
* make_notclause--
- *
+ *
* Create a 'not' clause given the expression to be negated.
- *
+ *
*/
-Expr *
-make_notclause(Expr *notclause)
+Expr *
+make_notclause(Expr * notclause)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = NOT_EXPR;
- expr->oper = NULL;
- expr->args = lcons(notclause, NIL);
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = NOT_EXPR;
+ expr->oper = NULL;
+ expr->args = lcons(notclause, NIL);
+ return expr;
}
-/*
+/*
* get_notclausearg--
- *
+ *
* Retrieve the clause within a 'not' clause
- *
+ *
*/
-Expr *
-get_notclausearg(Expr *notclause)
+Expr *
+get_notclausearg(Expr * notclause)
{
- return(lfirst(notclause->args));
+ return (lfirst(notclause->args));
}
/*****************************************************************************
- * AND clause functions
+ * AND clause functions
*****************************************************************************/
-/*
+/*
* and_clause--
- *
+ *
* Returns t iff its argument is an 'and' clause: (AND { expr }).
- *
+ *
*/
bool
-and_clause(Node *clause)
+and_clause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType == AND_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == AND_EXPR);
}
-/*
+
+/*
* make_andclause--
- *
+ *
* Create an 'and' clause given its arguments in a list.
- *
+ *
*/
-Expr *
-make_andclause(List *andclauses)
+Expr *
+make_andclause(List * andclauses)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = AND_EXPR;
- expr->oper = NULL;
- expr->args = andclauses;
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = AND_EXPR;
+ expr->oper = NULL;
+ expr->args = andclauses;
+ return expr;
}
/*****************************************************************************
- * *
- * *
- * *
+ * *
+ * *
+ * *
*****************************************************************************/
-/*
+/*
* pull-constant-clauses--
- * Scans through a list of qualifications and find those that
- * contain no variables.
- *
+ * Scans through a list of qualifications and find those that
+ * contain no variables.
+ *
* Returns a list of the constant clauses in constantQual and the remaining
* quals as the return value.
- *
+ *
*/
-List *
-pull_constant_clauses(List *quals, List **constantQual)
+List *
+pull_constant_clauses(List * quals, List ** constantQual)
{
- List *q;
- List *constqual=NIL;
- List *restqual=NIL;
-
- foreach(q, quals) {
- if (!contain_var_clause(lfirst(q))) {
- constqual = lcons(lfirst(q), constqual);
- }else {
- restqual = lcons(lfirst(q), restqual);
+ List *q;
+ List *constqual = NIL;
+ List *restqual = NIL;
+
+ foreach(q, quals)
+ {
+ if (!contain_var_clause(lfirst(q)))
+ {
+ constqual = lcons(lfirst(q), constqual);
+ }
+ else
+ {
+ restqual = lcons(lfirst(q), restqual);
+ }
}
- }
- freeList(quals);
- *constantQual = constqual;
- return restqual;
+ freeList(quals);
+ *constantQual = constqual;
+ return restqual;
}
-/*
+/*
* clause-relids-vars--
- * Retrieves relids and vars appearing within a clause.
- * Returns ((relid1 relid2 ... relidn) (var1 var2 ... varm)) where
- * vars appear in the clause this is done by recursively searching
- * through the left and right operands of a clause.
- *
+ * Retrieves relids and vars appearing within a clause.
+ * Returns ((relid1 relid2 ... relidn) (var1 var2 ... varm)) where
+ * vars appear in the clause this is done by recursively searching
+ * through the left and right operands of a clause.
+ *
* Returns the list of relids and vars.
- *
+ *
* XXX take the nreverse's out later
- *
+ *
*/
void
-clause_relids_vars(Node *clause, List **relids, List **vars)
+clause_relids_vars(Node * clause, List ** relids, List ** vars)
{
- List *clvars = pull_var_clause(clause);
- List *var_list = NIL;
- List *varno_list = NIL;
- List *i = NIL;
+ List *clvars = pull_var_clause(clause);
+ List *var_list = NIL;
+ List *varno_list = NIL;
+ List *i = NIL;
- foreach (i, clvars) {
- Var *var = (Var *)lfirst(i);
- List *vi;
-
- if (!intMember(var->varno, varno_list)) {
- varno_list = lappendi(varno_list, var->varno);
- }
- foreach (vi, var_list)
+ foreach(i, clvars)
{
- Var *in_list = (Var *)lfirst(vi);
-
- if ( in_list->varno == var->varno &&
- in_list->varattno == var->varattno )
- break;
+ Var *var = (Var *) lfirst(i);
+ List *vi;
+
+ if (!intMember(var->varno, varno_list))
+ {
+ varno_list = lappendi(varno_list, var->varno);
+ }
+ foreach(vi, var_list)
+ {
+ Var *in_list = (Var *) lfirst(vi);
+
+ if (in_list->varno == var->varno &&
+ in_list->varattno == var->varattno)
+ break;
+ }
+ if (vi == NIL)
+ var_list = lappend(var_list, var);
}
- if ( vi == NIL )
- var_list = lappend(var_list, var);
- }
- *relids = varno_list;
- *vars = var_list;
- return;
+ *relids = varno_list;
+ *vars = var_list;
+ return;
}
-/*
+/*
* NumRelids--
- * (formerly clause-relids)
- *
+ * (formerly clause-relids)
+ *
* Returns the number of different relations referenced in 'clause'.
*/
int
-NumRelids(Node *clause)
+NumRelids(Node * clause)
{
- List *vars = pull_var_clause(clause);
- List *i = NIL;
- List *var_list = NIL;
+ List *vars = pull_var_clause(clause);
+ List *i = NIL;
+ List *var_list = NIL;
- foreach (i, vars) {
- Var *var = (Var *)lfirst(i);
+ foreach(i, vars)
+ {
+ Var *var = (Var *) lfirst(i);
- if (!intMember(var->varno, var_list)) {
- var_list = lconsi(var->varno, var_list);
+ if (!intMember(var->varno, var_list))
+ {
+ var_list = lconsi(var->varno, var_list);
+ }
}
- }
- return(length(var_list));
+ return (length(var_list));
}
-/*
+/*
* contains-not--
*
* Returns t iff the clause is a 'not' clause or if any of the
* subclauses within an 'or' clause contain 'not's.
- *
+ *
*/
bool
-contains_not(Node *clause)
+contains_not(Node * clause)
{
- if (single_node(clause))
- return (false);
-
- if (not_clause(clause))
- return (true);
+ if (single_node(clause))
+ return (false);
- if (or_clause(clause)) {
- List *a;
- foreach(a, ((Expr*)clause)->args) {
- if (contains_not(lfirst(a)))
+ if (not_clause(clause))
return (true);
+
+ if (or_clause(clause))
+ {
+ List *a;
+
+ foreach(a, ((Expr *) clause)->args)
+ {
+ if (contains_not(lfirst(a)))
+ return (true);
+ }
}
- }
-
- return(false);
+
+ return (false);
}
-/*
+/*
* join-clause-p--
- *
+ *
* Returns t iff 'clause' is a valid join clause.
- *
+ *
*/
bool
-join_clause_p(Node *clause)
+join_clause_p(Node * clause)
{
- Node *leftop, *rightop;
+ Node *leftop,
+ *rightop;
- if (!is_opclause(clause))
- return false;
+ if (!is_opclause(clause))
+ return false;
- leftop = (Node*)get_leftop((Expr*)clause);
- rightop = (Node*)get_rightop((Expr*)clause);
+ leftop = (Node *) get_leftop((Expr *) clause);
+ rightop = (Node *) get_rightop((Expr *) clause);
- /*
- * One side of the clause (i.e. left or right operands)
- * must either be a var node ...
- */
- if (IsA(leftop,Var) || IsA(rightop,Var))
- return true;
+ /*
+ * One side of the clause (i.e. left or right operands) must either be
+ * a var node ...
+ */
+ if (IsA(leftop, Var) || IsA(rightop, Var))
+ return true;
- /*
- * ... or a func node.
- */
- if (is_funcclause(leftop) || is_funcclause(rightop))
- return(true);
+ /*
+ * ... or a func node.
+ */
+ if (is_funcclause(leftop) || is_funcclause(rightop))
+ return (true);
- return(false);
+ return (false);
}
-/*
+/*
* qual-clause-p--
- *
+ *
* Returns t iff 'clause' is a valid qualification clause.
- *
+ *
*/
bool
-qual_clause_p(Node *clause)
+qual_clause_p(Node * clause)
{
- if (!is_opclause(clause))
- return false;
+ if (!is_opclause(clause))
+ return false;
- if (IsA (get_leftop((Expr*)clause),Var) &&
- IsA (get_rightop((Expr*)clause),Const))
+ if (IsA(get_leftop((Expr *) clause), Var) &&
+ IsA(get_rightop((Expr *) clause), Const))
{
- return(true);
+ return (true);
}
- else if (IsA (get_rightop((Expr*)clause),Var) &&
- IsA (get_leftop((Expr*)clause),Const))
+ else if (IsA(get_rightop((Expr *) clause), Var) &&
+ IsA(get_leftop((Expr *) clause), Const))
{
- return(true);
+ return (true);
}
- return(false);
+ return (false);
}
-/*
+/*
* fix-opid--
- * Calculate the opfid from the opno...
- *
+ * Calculate the opfid from the opno...
+ *
* Returns nothing.
- *
+ *
*/
void
-fix_opid(Node *clause)
+fix_opid(Node * clause)
{
- if (clause==NULL || single_node(clause)) {
- ;
- }
- else if (or_clause (clause)) {
- fix_opids(((Expr*)clause)->args);
- }
- else if (is_funcclause (clause)) {
- fix_opids(((Expr*)clause)->args);
- }
- else if (IsA(clause,ArrayRef)) {
- ArrayRef *aref = (ArrayRef *)clause;
-
- fix_opids(aref->refupperindexpr);
- fix_opids(aref->reflowerindexpr);
- fix_opid(aref->refexpr);
- fix_opid(aref->refassgnexpr);
- }
- else if (not_clause(clause)) {
- fix_opid((Node*)get_notclausearg((Expr*)clause));
- }
- else if (is_opclause (clause)) {
- replace_opid((Oper*)((Expr*)clause)->oper);
- fix_opid((Node*)get_leftop((Expr*)clause));
- fix_opid((Node*)get_rightop((Expr*)clause));
- }
- else if (agg_clause (clause)) {
- fix_opid (((Aggreg*)clause)->target);
- }
+ if (clause == NULL || single_node(clause))
+ {
+ ;
+ }
+ else if (or_clause(clause))
+ {
+ fix_opids(((Expr *) clause)->args);
+ }
+ else if (is_funcclause(clause))
+ {
+ fix_opids(((Expr *) clause)->args);
+ }
+ else if (IsA(clause, ArrayRef))
+ {
+ ArrayRef *aref = (ArrayRef *) clause;
+
+ fix_opids(aref->refupperindexpr);
+ fix_opids(aref->reflowerindexpr);
+ fix_opid(aref->refexpr);
+ fix_opid(aref->refassgnexpr);
+ }
+ else if (not_clause(clause))
+ {
+ fix_opid((Node *) get_notclausearg((Expr *) clause));
+ }
+ else if (is_opclause(clause))
+ {
+ replace_opid((Oper *) ((Expr *) clause)->oper);
+ fix_opid((Node *) get_leftop((Expr *) clause));
+ fix_opid((Node *) get_rightop((Expr *) clause));
+ }
+ else if (agg_clause(clause))
+ {
+ fix_opid(((Aggreg *) clause)->target);
+ }
}
-/*
+/*
* fix-opids--
- * Calculate the opfid from the opno for all the clauses...
- *
+ * Calculate the opfid from the opno for all the clauses...
+ *
* Returns its argument.
- *
+ *
*/
-List *
-fix_opids(List *clauses)
+List *
+fix_opids(List * clauses)
{
- List *clause;
+ List *clause;
- foreach(clause, clauses)
- fix_opid(lfirst(clause));
+ foreach(clause, clauses)
+ fix_opid(lfirst(clause));
- return(clauses);
+ return (clauses);
}
-/*
+/*
* get_relattval--
- * For a non-join clause, returns a list consisting of the
- * relid,
- * attno,
- * value of the CONST node (if any), and a
- * flag indicating whether the value appears on the left or right
- * of the operator and whether the value varied.
+ * For a non-join clause, returns a list consisting of the
+ * relid,
+ * attno,
+ * value of the CONST node (if any), and a
+ * flag indicating whether the value appears on the left or right
+ * of the operator and whether the value varied.
*
* OLD OBSOLETE COMMENT FOLLOWS:
- * If 'clause' is not of the format (op var node) or (op node var),
- * or if the var refers to a nested attribute, then -1's are returned for
- * everything but the value a blank string "" (pointer to \0) is
- * returned for the value if it is unknown or null.
+ * If 'clause' is not of the format (op var node) or (op node var),
+ * or if the var refers to a nested attribute, then -1's are returned for
+ * everything but the value a blank string "" (pointer to \0) is
+ * returned for the value if it is unknown or null.
* END OF OLD OBSOLETE COMMENT.
* NEW COMMENT:
* when defining rules one of the attibutes of the operator can
@@ -569,198 +592,223 @@ fix_opids(List *clauses)
* this routine used to return "" as value, which made 'compute_selec'
* to bomb (because it was expecting a lisp integer and got back a lisp
* string). Now the code returns a plain old good "lispInteger(0)".
- *
+ *
*/
void
-get_relattval(Node *clause,
- int *relid,
- AttrNumber *attno,
- Datum *constval,
- int *flag)
+get_relattval(Node * clause,
+ int *relid,
+ AttrNumber * attno,
+ Datum * constval,
+ int *flag)
{
- Var *left = get_leftop((Expr*)clause);
- Var *right = get_rightop((Expr*)clause);
-
- if(is_opclause(clause) && IsA(left,Var) &&
- IsA(right,Const)) {
-
- if(right!=NULL) {
-
- *relid = left->varno;
- *attno = left->varattno;
- *constval = ((Const *)right)->constvalue;
- *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
-
- } else {
-
- *relid = left->varno;
- *attno = left->varattno;
- *constval = 0;
- *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_NOT_CONSTANT_);
-
- }
+ Var *left = get_leftop((Expr *) clause);
+ Var *right = get_rightop((Expr *) clause);
+
+ if (is_opclause(clause) && IsA(left, Var) &&
+ IsA(right, Const))
+ {
+
+ if (right != NULL)
+ {
+
+ *relid = left->varno;
+ *attno = left->varattno;
+ *constval = ((Const *) right)->constvalue;
+ *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
+
+ }
+ else
+ {
+
+ *relid = left->varno;
+ *attno = left->varattno;
+ *constval = 0;
+ *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_NOT_CONSTANT_);
+
+ }
#ifdef INDEXSCAN_PATCH
- } else if (is_opclause(clause) && IsA(left,Var) && IsA(right,Param)) {
- /* Function parameter used as index scan arg. DZ - 27-8-1996 */
- *relid = left->varno;
- *attno = left->varattno;
- *constval = 0;
- *flag = (_SELEC_NOT_CONSTANT_);
+ }
+ else if (is_opclause(clause) && IsA(left, Var) && IsA(right, Param))
+ {
+ /* Function parameter used as index scan arg. DZ - 27-8-1996 */
+ *relid = left->varno;
+ *attno = left->varattno;
+ *constval = 0;
+ *flag = (_SELEC_NOT_CONSTANT_);
#endif
- }else if (is_opclause(clause) &&
- is_funcclause((Node*)left) &&
- IsA(right,Const)) {
- List *args = ((Expr*)left)->args;
+ }
+ else if (is_opclause(clause) &&
+ is_funcclause((Node *) left) &&
+ IsA(right, Const))
+ {
+ List *args = ((Expr *) left)->args;
+
+
+ *relid = ((Var *) lfirst(args))->varno;
+ *attno = InvalidAttrNumber;
+ *constval = ((Const *) right)->constvalue;
+ *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
+
+ /*
+ * XXX both of these func clause handling if's seem wrong to me.
+ * they assume that the first argument is the Var. It could not
+ * handle (for example) f(1, emp.name). I think I may have been
+ * assuming no constants in functional index scans when I
+ * implemented this originally (still currently true). -mer 10 Aug
+ * 1992
+ */
+ }
+ else if (is_opclause(clause) &&
+ is_funcclause((Node *) right) &&
+ IsA(left, Const))
+ {
+ List *args = ((Expr *) right)->args;
+ *relid = ((Var *) lfirst(args))->varno;
+ *attno = InvalidAttrNumber;
+ *constval = ((Const *) left)->constvalue;
+ *flag = (_SELEC_IS_CONSTANT_);
- *relid = ((Var*)lfirst(args))->varno;
- *attno = InvalidAttrNumber;
- *constval = ((Const*)right)->constvalue;
- *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
-
- /*
- * XXX both of these func clause handling if's seem wrong to me.
- * they assume that the first argument is the Var. It could
- * not handle (for example) f(1, emp.name). I think I may have
- * been assuming no constants in functional index scans when I
- * implemented this originally (still currently true).
- * -mer 10 Aug 1992
- */
- } else if (is_opclause(clause) &&
- is_funcclause((Node*)right) &&
- IsA(left,Const)) {
- List *args = ((Expr*)right)->args;
-
- *relid = ((Var*)lfirst(args))->varno;
- *attno = InvalidAttrNumber;
- *constval = ((Const*)left)->constvalue;
- *flag = ( _SELEC_IS_CONSTANT_);
-
- } else if (is_opclause (clause) && IsA (right,Var) &&
- IsA (left,Const)) {
- if (left!=NULL) {
-
- *relid = right->varno;
- *attno = right->varattno;
- *constval = ((Const*)left)->constvalue;
- *flag = (_SELEC_IS_CONSTANT_);
- } else {
-
- *relid = right->varno;
- *attno = right->varattno;
- *constval = 0;
- *flag = (_SELEC_NOT_CONSTANT_);
- }
+ }
+ else if (is_opclause(clause) && IsA(right, Var) &&
+ IsA(left, Const))
+ {
+ if (left != NULL)
+ {
+
+ *relid = right->varno;
+ *attno = right->varattno;
+ *constval = ((Const *) left)->constvalue;
+ *flag = (_SELEC_IS_CONSTANT_);
+ }
+ else
+ {
+
+ *relid = right->varno;
+ *attno = right->varattno;
+ *constval = 0;
+ *flag = (_SELEC_NOT_CONSTANT_);
+ }
#ifdef INDEXSCAN_PATCH
- } else if (is_opclause(clause) && IsA(right,Var) && IsA(left,Param)) {
- /* ...And here... - vadim 01/22/97 */
- *relid = right->varno;
- *attno = right->varattno;
- *constval = 0;
- *flag = (_SELEC_NOT_CONSTANT_);
+ }
+ else if (is_opclause(clause) && IsA(right, Var) && IsA(left, Param))
+ {
+ /* ...And here... - vadim 01/22/97 */
+ *relid = right->varno;
+ *attno = right->varattno;
+ *constval = 0;
+ *flag = (_SELEC_NOT_CONSTANT_);
#endif
- } else {
- /* One or more of the operands are expressions
- * (e.g., oper clauses)
- */
- *relid = _SELEC_VALUE_UNKNOWN_;
- *attno = _SELEC_VALUE_UNKNOWN_;
- *constval = 0;
- *flag = (_SELEC_NOT_CONSTANT_);
- }
+ }
+ else
+ {
+
+ /*
+ * One or more of the operands are expressions (e.g., oper
+ * clauses)
+ */
+ *relid = _SELEC_VALUE_UNKNOWN_;
+ *attno = _SELEC_VALUE_UNKNOWN_;
+ *constval = 0;
+ *flag = (_SELEC_NOT_CONSTANT_);
+ }
}
-/*
+/*
* get_relsatts--
- *
- * Returns a list
- * ( relid1 attno1 relid2 attno2 )
- * for a joinclause.
- *
+ *
+ * Returns a list
+ * ( relid1 attno1 relid2 attno2 )
+ * for a joinclause.
+ *
* If the clause is not of the form (op var var) or if any of the vars
* refer to nested attributes, then -1's are returned.
- *
+ *
*/
void
-get_rels_atts(Node *clause,
- int *relid1,
- AttrNumber *attno1,
- int *relid2,
- AttrNumber *attno2)
+get_rels_atts(Node * clause,
+ int *relid1,
+ AttrNumber * attno1,
+ int *relid2,
+ AttrNumber * attno2)
{
- Var *left = get_leftop((Expr*)clause);
- Var *right = get_rightop((Expr*)clause);
- bool var_left = (IsA(left,Var));
- bool var_right = (IsA(right,Var));
- bool varexpr_left = (bool)((IsA(left,Func) || IsA (left,Oper)) &&
- contain_var_clause((Node*)left));
- bool varexpr_right = (bool)(( IsA(right,Func) || IsA (right,Oper)) &&
- contain_var_clause((Node*)right));
-
- if (is_opclause(clause)) {
- if(var_left && var_right) {
-
- *relid1 = left->varno;
- *attno1 = left->varoattno;
- *relid2 = right->varno;
- *attno2 = right->varoattno;
- return;
- } else if (var_left && varexpr_right ) {
-
- *relid1 = left->varno;
- *attno1 = left->varoattno;
- *relid2 = _SELEC_VALUE_UNKNOWN_;
- *attno2 = _SELEC_VALUE_UNKNOWN_;
- return;
- } else if (varexpr_left && var_right) {
-
- *relid1 = _SELEC_VALUE_UNKNOWN_;
- *attno1 = _SELEC_VALUE_UNKNOWN_;
- *relid2 = right->varno;
- *attno2 = right->varoattno;
- return;
+ Var *left = get_leftop((Expr *) clause);
+ Var *right = get_rightop((Expr *) clause);
+ bool var_left = (IsA(left, Var));
+ bool var_right = (IsA(right, Var));
+ bool varexpr_left = (bool) ((IsA(left, Func) || IsA(left, Oper)) &&
+ contain_var_clause((Node *) left));
+ bool varexpr_right = (bool) ((IsA(right, Func) || IsA(right, Oper)) &&
+ contain_var_clause((Node *) right));
+
+ if (is_opclause(clause))
+ {
+ if (var_left && var_right)
+ {
+
+ *relid1 = left->varno;
+ *attno1 = left->varoattno;
+ *relid2 = right->varno;
+ *attno2 = right->varoattno;
+ return;
+ }
+ else if (var_left && varexpr_right)
+ {
+
+ *relid1 = left->varno;
+ *attno1 = left->varoattno;
+ *relid2 = _SELEC_VALUE_UNKNOWN_;
+ *attno2 = _SELEC_VALUE_UNKNOWN_;
+ return;
+ }
+ else if (varexpr_left && var_right)
+ {
+
+ *relid1 = _SELEC_VALUE_UNKNOWN_;
+ *attno1 = _SELEC_VALUE_UNKNOWN_;
+ *relid2 = right->varno;
+ *attno2 = right->varoattno;
+ return;
+ }
}
- }
- *relid1 = _SELEC_VALUE_UNKNOWN_;
- *attno1 = _SELEC_VALUE_UNKNOWN_;
- *relid2 = _SELEC_VALUE_UNKNOWN_;
- *attno2 = _SELEC_VALUE_UNKNOWN_;
- return;
+ *relid1 = _SELEC_VALUE_UNKNOWN_;
+ *attno1 = _SELEC_VALUE_UNKNOWN_;
+ *relid2 = _SELEC_VALUE_UNKNOWN_;
+ *attno2 = _SELEC_VALUE_UNKNOWN_;
+ return;
}
void
-CommuteClause(Node *clause)
+CommuteClause(Node * clause)
{
- Node *temp;
- Oper *commu;
- OperatorTupleForm commuTup;
- HeapTuple heapTup;
+ Node *temp;
+ Oper *commu;
+ OperatorTupleForm commuTup;
+ HeapTuple heapTup;
- if (!is_opclause(clause))
- return;
+ if (!is_opclause(clause))
+ return;
- heapTup = (HeapTuple)
- get_operator_tuple(get_commutator(((Oper*)((Expr*)clause)->oper)->opno));
+ heapTup = (HeapTuple)
+ get_operator_tuple(get_commutator(((Oper *) ((Expr *) clause)->oper)->opno));
- if (heapTup == (HeapTuple)NULL)
- return;
+ if (heapTup == (HeapTuple) NULL)
+ return;
- commuTup = (OperatorTupleForm)GETSTRUCT(heapTup);
-
- commu = makeOper(heapTup->t_oid,
- InvalidOid,
- commuTup->oprresult,
- ((Oper*)((Expr*)clause)->oper)->opsize,
- NULL);
-
- /*
- * reform the clause -> (operator func/var constant)
- */
- ((Expr*)clause)->oper = (Node*)commu;
- temp = lfirst(((Expr*)clause)->args);
- lfirst(((Expr*)clause)->args) = lsecond(((Expr*)clause)->args);
- lsecond(((Expr*)clause)->args) = temp;
-}
+ commuTup = (OperatorTupleForm) GETSTRUCT(heapTup);
+ commu = makeOper(heapTup->t_oid,
+ InvalidOid,
+ commuTup->oprresult,
+ ((Oper *) ((Expr *) clause)->oper)->opsize,
+ NULL);
+ /*
+ * reform the clause -> (operator func/var constant)
+ */
+ ((Expr *) clause)->oper = (Node *) commu;
+ temp = lfirst(((Expr *) clause)->args);
+ lfirst(((Expr *) clause)->args) = lsecond(((Expr *) clause)->args);
+ lsecond(((Expr *) clause)->args) = temp;
+}
diff --git a/src/backend/optimizer/util/indexnode.c b/src/backend/optimizer/util/indexnode.c
index 8e9237e6845..e6a1902f8b9 100644
--- a/src/backend/optimizer/util/indexnode.c
+++ b/src/backend/optimizer/util/indexnode.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* indexnode.c--
- * Routines to find all indices on a relation
+ * Routines to find all indices on a relation
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/indexnode.c,v 1.2 1996/10/31 10:59:37 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/indexnode.c,v 1.3 1997/09/07 04:44:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,74 +21,77 @@
#include "optimizer/internal.h"
#include "optimizer/plancat.h"
-#include "optimizer/pathnode.h" /* where the decls go */
+#include "optimizer/pathnode.h" /* where the decls go */
-static List *find_secondary_index(Query *root, Oid relid);
+static List *find_secondary_index(Query * root, Oid relid);
-/*
+/*
* find-relation-indices--
- * Returns a list of index nodes containing appropriate information for
- * each (secondary) index defined on a relation.
- *
+ * Returns a list of index nodes containing appropriate information for
+ * each (secondary) index defined on a relation.
+ *
*/
-List *
-find_relation_indices(Query *root, Rel *rel)
+List *
+find_relation_indices(Query * root, Rel * rel)
{
- if (rel->indexed) {
- return (find_secondary_index(root, lfirsti(rel->relids)));
- } else {
- return (NIL);
- }
+ if (rel->indexed)
+ {
+ return (find_secondary_index(root, lfirsti(rel->relids)));
+ }
+ else
+ {
+ return (NIL);
+ }
}
-/*
+/*
* find-secondary-index--
- * Creates a list of index path nodes containing information for each
- * secondary index defined on a relation by searching through the index
- * catalog.
- *
+ * Creates a list of index path nodes containing information for each
+ * secondary index defined on a relation by searching through the index
+ * catalog.
+ *
* 'relid' is the OID of the relation for which indices are being located
- *
+ *
* Returns a list of new index nodes.
- *
+ *
*/
-static List *
-find_secondary_index(Query *root, Oid relid)
+static List *
+find_secondary_index(Query * root, Oid relid)
{
- IdxInfoRetval indexinfo;
- List *indexes = NIL;
- bool first = TRUE;
+ IdxInfoRetval indexinfo;
+ List *indexes = NIL;
+ bool first = TRUE;
- while (index_info(root, first, relid,&indexinfo)) {
- Rel *indexnode = makeNode(Rel);
+ while (index_info(root, first, relid, &indexinfo))
+ {
+ Rel *indexnode = makeNode(Rel);
- indexnode->relids = lconsi(indexinfo.relid,NIL);
- indexnode->relam = indexinfo.relam;
- indexnode->pages = indexinfo.pages;
- indexnode->tuples = indexinfo.tuples;
- indexnode->indexkeys = indexinfo.indexkeys;
- indexnode->ordering = indexinfo.orderOprs;
- indexnode->classlist = indexinfo.classlist;
- indexnode->indproc= indexinfo.indproc;
- indexnode->indpred = (List*)indexinfo.indpred;
-
- indexnode->indexed= false; /* not indexed itself */
- indexnode->size = 0;
- indexnode->width= 0;
- indexnode->targetlist= NIL;
- indexnode->pathlist= NIL;
- indexnode->unorderedpath= NULL;
- indexnode->cheapestpath= NULL;
- indexnode->pruneable= true;
- indexnode->clauseinfo= NIL;
- indexnode->joininfo= NIL;
- indexnode->innerjoin= NIL;
+ indexnode->relids = lconsi(indexinfo.relid, NIL);
+ indexnode->relam = indexinfo.relam;
+ indexnode->pages = indexinfo.pages;
+ indexnode->tuples = indexinfo.tuples;
+ indexnode->indexkeys = indexinfo.indexkeys;
+ indexnode->ordering = indexinfo.orderOprs;
+ indexnode->classlist = indexinfo.classlist;
+ indexnode->indproc = indexinfo.indproc;
+ indexnode->indpred = (List *) indexinfo.indpred;
- indexes = lcons(indexnode, indexes);
- first = FALSE;
- }
+ indexnode->indexed = false; /* not indexed itself */
+ indexnode->size = 0;
+ indexnode->width = 0;
+ indexnode->targetlist = NIL;
+ indexnode->pathlist = NIL;
+ indexnode->unorderedpath = NULL;
+ indexnode->cheapestpath = NULL;
+ indexnode->pruneable = true;
+ indexnode->clauseinfo = NIL;
+ indexnode->joininfo = NIL;
+ indexnode->innerjoin = NIL;
- return indexes;
-}
+ indexes = lcons(indexnode, indexes);
+ first = FALSE;
+ }
+ return indexes;
+}
diff --git a/src/backend/optimizer/util/internal.c b/src/backend/optimizer/util/internal.c
index 8b2dfd43bcb..d1af2062fce 100644
--- a/src/backend/optimizer/util/internal.c
+++ b/src/backend/optimizer/util/internal.c
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* internal.c--
- * Definitions required throughout the query optimizer.
+ * Definitions required throughout the query optimizer.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/internal.c,v 1.3 1997/08/20 14:53:37 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/internal.c,v 1.4 1997/09/07 04:44:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-/*
- * ---------- SHARED MACROS
- *
- * Macros common to modules for creating, accessing, and modifying
- * query tree and query plan components.
- * Shared with the executor.
- *
+/*
+ * ---------- SHARED MACROS
+ *
+ * Macros common to modules for creating, accessing, and modifying
+ * query tree and query plan components.
+ * Shared with the executor.
+ *
*/
#include <sys/types.h>
@@ -31,32 +31,30 @@
#include "nodes/primnodes.h"
#include "utils/palloc.h"
-#ifdef NOT_USED
+#ifdef NOT_USED
/*****************************************************************************
*
*****************************************************************************/
/* the following should probably be moved elsewhere -ay */
-TargetEntry *
-MakeTLE(Resdom *resdom, Node *expr)
+TargetEntry *
+MakeTLE(Resdom * resdom, Node * expr)
{
- TargetEntry *rt = makeNode(TargetEntry);
- rt->resdom = resdom;
- rt->expr = expr;
- return rt;
+ TargetEntry *rt = makeNode(TargetEntry);
+
+ rt->resdom = resdom;
+ rt->expr = expr;
+ return rt;
}
-Var *
-get_expr(TargetEntry *tle)
+Var *
+get_expr(TargetEntry * tle)
{
- Assert(tle!=NULL);
- Assert(tle->expr!=NULL);
+ Assert(tle != NULL);
+ Assert(tle->expr != NULL);
- return ((Var *)tle->expr);
+ return ((Var *) tle->expr);
}
-#endif /* 0 */
-
-
-
+#endif /* 0 */
diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c
index a4fd6913752..cf206d80094 100644
--- a/src/backend/optimizer/util/joininfo.c
+++ b/src/backend/optimizer/util/joininfo.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* joininfo.c--
- * JoinInfo node manipulation routines
+ * JoinInfo node manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/joininfo.c,v 1.2 1996/11/10 03:01:00 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/joininfo.c,v 1.3 1997/09/07 04:44:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,88 +21,96 @@
#include "optimizer/clauses.h"
-/*
+/*
* joininfo-member--
- * Determines whether a node has already been created for a join
- * between a set of join relations and the relation described by
- * 'joininfo-list'.
- *
+ * Determines whether a node has already been created for a join
+ * between a set of join relations and the relation described by
+ * 'joininfo-list'.
+ *
* 'join-relids' is a list of relids corresponding to the join relation
- * 'joininfo-list' is the list of joininfo nodes against which this is
- * checked
- *
+ * 'joininfo-list' is the list of joininfo nodes against which this is
+ * checked
+ *
* Returns the corresponding node in 'joininfo-list' if such a node
* exists.
- *
+ *
*/
-JInfo *
-joininfo_member(List *join_relids, List *joininfo_list)
+JInfo *
+joininfo_member(List * join_relids, List * joininfo_list)
{
- List *i = NIL;
- List *other_rels = NIL;
+ List *i = NIL;
+ List *other_rels = NIL;
- foreach(i,joininfo_list) {
- other_rels = lfirst(i);
- if(same(join_relids, ((JInfo*)other_rels)->otherrels))
- return((JInfo*)other_rels);
- }
- return((JInfo*)NULL);
+ foreach(i, joininfo_list)
+ {
+ other_rels = lfirst(i);
+ if (same(join_relids, ((JInfo *) other_rels)->otherrels))
+ return ((JInfo *) other_rels);
+ }
+ return ((JInfo *) NULL);
}
-/*
+/*
* find-joininfo-node--
- * Find the joininfo node within a relation entry corresponding
- * to a join between 'this_rel' and the relations in 'join-relids'. A
- * new node is created and added to the relation entry's joininfo
- * field if the desired one can't be found.
- *
+ * Find the joininfo node within a relation entry corresponding
+ * to a join between 'this_rel' and the relations in 'join-relids'. A
+ * new node is created and added to the relation entry's joininfo
+ * field if the desired one can't be found.
+ *
* Returns a joininfo node.
- *
+ *
*/
-JInfo *
-find_joininfo_node(Rel *this_rel, List *join_relids)
+JInfo *
+find_joininfo_node(Rel * this_rel, List * join_relids)
{
- JInfo *joininfo = joininfo_member(join_relids,
- this_rel->joininfo);
- if( joininfo == NULL ) {
- joininfo = makeNode(JInfo);
- joininfo->otherrels = join_relids;
- joininfo->jinfoclauseinfo = NIL;
- joininfo->mergesortable = false;
- joininfo->hashjoinable = false;
- joininfo->inactive = false;
- this_rel->joininfo = lcons(joininfo, this_rel->joininfo);
- }
- return(joininfo);
+ JInfo *joininfo = joininfo_member(join_relids,
+ this_rel->joininfo);
+
+ if (joininfo == NULL)
+ {
+ joininfo = makeNode(JInfo);
+ joininfo->otherrels = join_relids;
+ joininfo->jinfoclauseinfo = NIL;
+ joininfo->mergesortable = false;
+ joininfo->hashjoinable = false;
+ joininfo->inactive = false;
+ this_rel->joininfo = lcons(joininfo, this_rel->joininfo);
+ }
+ return (joininfo);
}
-/*
+/*
* other-join-clause-var--
- * Determines whether a var node is contained within a joinclause
- * of the form(op var var).
- *
+ * Determines whether a var node is contained within a joinclause
+ * of the form(op var var).
+ *
* Returns the other var node in the joinclause if it is, nil if not.
- *
+ *
*/
-Var *
-other_join_clause_var(Var *var, Expr *clause)
+Var *
+other_join_clause_var(Var * var, Expr * clause)
{
- Var *retval;
- Var *l, *r;
+ Var *retval;
+ Var *l,
+ *r;
- retval = (Var*) NULL;
+ retval = (Var *) NULL;
- if( var != NULL && join_clause_p((Node*)clause)) {
- l = (Var *) get_leftop(clause);
- r = (Var *) get_rightop(clause);
+ if (var != NULL && join_clause_p((Node *) clause))
+ {
+ l = (Var *) get_leftop(clause);
+ r = (Var *) get_rightop(clause);
- if(var_equal(var, l)) {
- retval = r;
- } else if(var_equal(var, r)) {
- retval = l;
- }
- }
+ if (var_equal(var, l))
+ {
+ retval = r;
+ }
+ else if (var_equal(var, r))
+ {
+ retval = l;
+ }
+ }
- return(retval);
+ return (retval);
}
diff --git a/src/backend/optimizer/util/keys.c b/src/backend/optimizer/util/keys.c
index 4296deb7e98..0c3a3569eb5 100644
--- a/src/backend/optimizer/util/keys.c
+++ b/src/backend/optimizer/util/keys.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* keys.c--
- * Key manipulation routines
+ * Key manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.2 1997/08/19 21:32:03 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.3 1997/09/07 04:44:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,173 +22,180 @@
#include "optimizer/tlist.h"
-static Expr *matching2_tlvar(int var, List *tlist, bool (*test)());
-static bool equal_indexkey_var(int index_key, Var *var);
+static Expr *matching2_tlvar(int var, List * tlist, bool(*test) ());
+static bool equal_indexkey_var(int index_key, Var * var);
-/*
+/*
* 1. index key
- * one of:
- * attnum
- * (attnum arrayindex)
+ * one of:
+ * attnum
+ * (attnum arrayindex)
* 2. path key
- * (subkey1 ... subkeyN)
- * where subkeyI is a var node
- * note that the 'Keys field is a list of these
+ * (subkey1 ... subkeyN)
+ * where subkeyI is a var node
+ * note that the 'Keys field is a list of these
* 3. join key
- * (outer-subkey inner-subkey)
- * where each subkey is a var node
+ * (outer-subkey inner-subkey)
+ * where each subkey is a var node
* 4. sort key
- * one of:
- * SortKey node
- * number
- * nil
- * (may also refer to the 'SortKey field of a SortKey node,
- * which looks exactly like an index key)
- *
+ * one of:
+ * SortKey node
+ * number
+ * nil
+ * (may also refer to the 'SortKey field of a SortKey node,
+ * which looks exactly like an index key)
+ *
*/
-/*
+/*
* match-indexkey-operand--
- * Returns t iff an index key 'index-key' matches the given clause
- * operand.
- *
+ * Returns t iff an index key 'index-key' matches the given clause
+ * operand.
+ *
*/
bool
-match_indexkey_operand(int indexkey, Var *operand, Rel *rel)
+match_indexkey_operand(int indexkey, Var * operand, Rel * rel)
{
- if (IsA (operand,Var) &&
- (lfirsti(rel->relids) == operand->varno) &&
- equal_indexkey_var(indexkey,operand))
- return(true);
- else
- return(false);
+ if (IsA(operand, Var) &&
+ (lfirsti(rel->relids) == operand->varno) &&
+ equal_indexkey_var(indexkey, operand))
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* equal_indexkey_var--
- * Returns t iff an index key 'index-key' matches the corresponding
- * fields of var node 'var'.
- *
+ * Returns t iff an index key 'index-key' matches the corresponding
+ * fields of var node 'var'.
+ *
*/
-static bool
-equal_indexkey_var(int index_key, Var *var)
+static bool
+equal_indexkey_var(int index_key, Var * var)
{
- if (index_key == var->varattno)
- return(true);
- else
- return(false);
+ if (index_key == var->varattno)
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* extract-subkey--
- * Returns the subkey in a join key corresponding to the outer or inner
- * lelation.
- *
+ * Returns the subkey in a join key corresponding to the outer or inner
+ * lelation.
+ *
*/
-Var *
-extract_subkey(JoinKey *jk, int which_subkey)
+Var *
+extract_subkey(JoinKey * jk, int which_subkey)
{
- Var *retval;
-
- switch (which_subkey) {
- case OUTER:
- retval = jk->outer;
- break;
- case INNER:
- retval = jk->inner;
- break;
- default: /* do nothing */
- elog(DEBUG,"extract_subkey with neither INNER or OUTER");
- retval = NULL;
- }
- return(retval);
+ Var *retval;
+
+ switch (which_subkey)
+ {
+ case OUTER:
+ retval = jk->outer;
+ break;
+ case INNER:
+ retval = jk->inner;
+ break;
+ default: /* do nothing */
+ elog(DEBUG, "extract_subkey with neither INNER or OUTER");
+ retval = NULL;
+ }
+ return (retval);
}
-/*
+/*
* samekeys--
- * Returns t iff two sets of path keys are equivalent. They are
- * equivalent if the first subkey (var node) within each sublist of
- * list 'keys1' is contained within the corresponding sublist of 'keys2'.
- *
- * XXX It isn't necessary to check that each sublist exactly contain
- * the same elements because if the routine that built these
- * sublists together is correct, having one element in common
- * implies having all elements in common.
- *
+ * Returns t iff two sets of path keys are equivalent. They are
+ * equivalent if the first subkey (var node) within each sublist of
+ * list 'keys1' is contained within the corresponding sublist of 'keys2'.
+ *
+ * XXX It isn't necessary to check that each sublist exactly contain
+ * the same elements because if the routine that built these
+ * sublists together is correct, having one element in common
+ * implies having all elements in common.
+ *
*/
bool
-samekeys(List *keys1, List *keys2)
+samekeys(List * keys1, List * keys2)
{
- bool allmember = true;
- List *key1, *key2;
-
- for(key1=keys1,key2=keys2 ; key1 != NIL && key2 !=NIL ;
- key1=lnext(key1), key2=lnext(key2))
- if (!member(lfirst(key1), lfirst(key2)))
- allmember = false;
-
- if ( (length (keys2) >= length (keys1)) && allmember)
- return(true);
- else
- return(false);
+ bool allmember = true;
+ List *key1,
+ *key2;
+
+ for (key1 = keys1, key2 = keys2; key1 != NIL && key2 != NIL;
+ key1 = lnext(key1), key2 = lnext(key2))
+ if (!member(lfirst(key1), lfirst(key2)))
+ allmember = false;
+
+ if ((length(keys2) >= length(keys1)) && allmember)
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* collect-index-pathkeys--
- * Creates a list of subkeys by retrieving var nodes corresponding to
- * each index key in 'index-keys' from the relation's target list
- * 'tlist'. If the key is not in the target list, the key is irrelevant
- * and is thrown away. The returned subkey list is of the form:
- * ((var1) (var2) ... (varn))
- *
+ * Creates a list of subkeys by retrieving var nodes corresponding to
+ * each index key in 'index-keys' from the relation's target list
+ * 'tlist'. If the key is not in the target list, the key is irrelevant
+ * and is thrown away. The returned subkey list is of the form:
+ * ((var1) (var2) ... (varn))
+ *
* 'index-keys' is a list of index keys
* 'tlist' is a relation target list
- *
+ *
* Returns the list of cons'd subkeys.
- *
+ *
*/
/* This function is identical to matching_tlvar and tlistentry_member.
* They should be merged.
*/
-static Expr *
-matching2_tlvar(int var, List *tlist, bool (*test)())
+static Expr *
+matching2_tlvar(int var, List * tlist, bool(*test) ())
{
- TargetEntry *tlentry = NULL;
-
- if (var) {
- List *temp;
- foreach (temp,tlist) {
- if ((*test)(var, get_expr(lfirst(temp)))) {
- tlentry = lfirst(temp);
- break;
- }
+ TargetEntry *tlentry = NULL;
+
+ if (var)
+ {
+ List *temp;
+
+ foreach(temp, tlist)
+ {
+ if ((*test) (var, get_expr(lfirst(temp))))
+ {
+ tlentry = lfirst(temp);
+ break;
+ }
+ }
}
- }
- if (tlentry)
- return((Expr*)get_expr(tlentry));
- else
- return((Expr*)NULL);
+ if (tlentry)
+ return ((Expr *) get_expr(tlentry));
+ else
+ return ((Expr *) NULL);
}
-List *
-collect_index_pathkeys(int *index_keys, List *tlist)
+List *
+collect_index_pathkeys(int *index_keys, List * tlist)
{
- List *retval = NIL;
-
- Assert (index_keys != NULL);
-
- while(index_keys[0] != 0) {
- Expr *mvar;
- mvar = matching2_tlvar(index_keys[0],
- tlist,
- equal_indexkey_var);
- if (mvar)
- retval = nconc(retval,lcons(lcons(mvar,NIL),
- NIL));
- index_keys++;
- }
- return(retval);
-}
+ List *retval = NIL;
+
+ Assert(index_keys != NULL);
+
+ while (index_keys[0] != 0)
+ {
+ Expr *mvar;
+ mvar = matching2_tlvar(index_keys[0],
+ tlist,
+ equal_indexkey_var);
+ if (mvar)
+ retval = nconc(retval, lcons(lcons(mvar, NIL),
+ NIL));
+ index_keys++;
+ }
+ return (retval);
+}
diff --git a/src/backend/optimizer/util/ordering.c b/src/backend/optimizer/util/ordering.c
index 40699e81e0b..504d48bdce5 100644
--- a/src/backend/optimizer/util/ordering.c
+++ b/src/backend/optimizer/util/ordering.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* ordering.c--
- * Routines to manipulate and compare merge and path orderings
+ * Routines to manipulate and compare merge and path orderings
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/ordering.c,v 1.3 1997/08/19 21:32:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/ordering.c,v 1.4 1997/09/07 04:44:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,81 +18,88 @@
#include "optimizer/internal.h"
#include "optimizer/ordering.h"
-static bool equal_sortops_order(Oid *ordering1, Oid *ordering2);
+static bool equal_sortops_order(Oid * ordering1, Oid * ordering2);
-/*
+/*
* equal-path-path-ordering--
- * Returns t iff two path orderings are equal.
- *
+ * Returns t iff two path orderings are equal.
+ *
*/
bool
-equal_path_path_ordering(PathOrder *path_ordering1,
- PathOrder *path_ordering2)
+equal_path_path_ordering(PathOrder * path_ordering1,
+ PathOrder * path_ordering2)
{
- if (path_ordering1 == path_ordering2)
- return true;
-
- if (!path_ordering1 || !path_ordering2)
- return false;
-
- if (path_ordering1->ordtype == MERGE_ORDER &&
- path_ordering2->ordtype == MERGE_ORDER) {
-
- return equal(path_ordering1->ord.merge, path_ordering2->ord.merge);
-
- } else if (path_ordering1->ordtype == SORTOP_ORDER &&
- path_ordering2->ordtype == SORTOP_ORDER) {
-
- return
- (equal_sortops_order(path_ordering1->ord.sortop,
- path_ordering2->ord.sortop));
- } else if (path_ordering1->ordtype == MERGE_ORDER &&
- path_ordering2->ordtype == SORTOP_ORDER) {
-
- return (path_ordering2->ord.sortop &&
- (path_ordering1->ord.merge->left_operator ==
- path_ordering2->ord.sortop[0]));
- } else {
-
- return (path_ordering1->ord.sortop &&
- (path_ordering1->ord.sortop[0] ==
- path_ordering2->ord.merge->left_operator));
- }
+ if (path_ordering1 == path_ordering2)
+ return true;
+
+ if (!path_ordering1 || !path_ordering2)
+ return false;
+
+ if (path_ordering1->ordtype == MERGE_ORDER &&
+ path_ordering2->ordtype == MERGE_ORDER)
+ {
+
+ return equal(path_ordering1->ord.merge, path_ordering2->ord.merge);
+
+ }
+ else if (path_ordering1->ordtype == SORTOP_ORDER &&
+ path_ordering2->ordtype == SORTOP_ORDER)
+ {
+
+ return
+ (equal_sortops_order(path_ordering1->ord.sortop,
+ path_ordering2->ord.sortop));
+ }
+ else if (path_ordering1->ordtype == MERGE_ORDER &&
+ path_ordering2->ordtype == SORTOP_ORDER)
+ {
+
+ return (path_ordering2->ord.sortop &&
+ (path_ordering1->ord.merge->left_operator ==
+ path_ordering2->ord.sortop[0]));
+ }
+ else
+ {
+
+ return (path_ordering1->ord.sortop &&
+ (path_ordering1->ord.sortop[0] ==
+ path_ordering2->ord.merge->left_operator));
+ }
}
-/*
+/*
* equal-path-merge-ordering--
- * Returns t iff a path ordering is usable for ordering a merge join.
+ * Returns t iff a path ordering is usable for ordering a merge join.
*
* XXX Presently, this means that the first sortop of the path matches
- * either of the merge sortops. Is there a "right" and "wrong"
- * sortop to match?
- *
+ * either of the merge sortops. Is there a "right" and "wrong"
+ * sortop to match?
+ *
*/
bool
-equal_path_merge_ordering(Oid *path_ordering,
- MergeOrder *merge_ordering)
+equal_path_merge_ordering(Oid * path_ordering,
+ MergeOrder * merge_ordering)
{
- if (path_ordering == NULL || merge_ordering == NULL)
- return(false);
-
- if (path_ordering[0] == merge_ordering->left_operator ||
- path_ordering[0] == merge_ordering->right_operator)
- return(true);
- else
- return(false);
+ if (path_ordering == NULL || merge_ordering == NULL)
+ return (false);
+
+ if (path_ordering[0] == merge_ordering->left_operator ||
+ path_ordering[0] == merge_ordering->right_operator)
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* equal-merge-merge-ordering--
- * Returns t iff two merge orderings are equal.
- *
+ * Returns t iff two merge orderings are equal.
+ *
*/
bool
-equal_merge_merge_ordering(MergeOrder *merge_ordering1,
- MergeOrder *merge_ordering2)
+equal_merge_merge_ordering(MergeOrder * merge_ordering1,
+ MergeOrder * merge_ordering2)
{
- return (equal(merge_ordering1, merge_ordering2));
+ return (equal(merge_ordering1, merge_ordering2));
}
/*****************************************************************************
@@ -101,21 +108,22 @@ equal_merge_merge_ordering(MergeOrder *merge_ordering1,
/*
* equal_sort_ops_order -
- * Returns true iff the sort operators are in the same order.
+ * Returns true iff the sort operators are in the same order.
*/
-static bool
-equal_sortops_order(Oid *ordering1, Oid *ordering2)
+static bool
+equal_sortops_order(Oid * ordering1, Oid * ordering2)
{
- int i = 0;
-
- if (ordering1 == NULL || ordering2 == NULL)
- return (ordering1==ordering2);
-
- while (ordering1[i]!=0 && ordering2[i]!=0) {
- if (ordering1[i] != ordering2[i])
- break;
- i++;
- }
-
- return (ordering1[i]==0 && ordering2[i]==0);
+ int i = 0;
+
+ if (ordering1 == NULL || ordering2 == NULL)
+ return (ordering1 == ordering2);
+
+ while (ordering1[i] != 0 && ordering2[i] != 0)
+ {
+ if (ordering1[i] != ordering2[i])
+ break;
+ i++;
+ }
+
+ return (ordering1[i] == 0 && ordering2[i] == 0);
}
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index d79788b0e6e..6b37d2f36d4 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* pathnode.c--
- * Routines to manipulate pathlists and create path nodes
+ * Routines to manipulate pathlists and create path nodes
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.3 1997/09/05 18:10:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.4 1997/09/07 04:44:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,418 +27,459 @@
#include "optimizer/xfunc.h"
#include "optimizer/ordering.h"
-#include "parser/parsetree.h" /* for getrelid() */
+#include "parser/parsetree.h" /* for getrelid() */
-static Path *better_path(Path *new_path, List *unique_paths, bool *noOther);
+static Path *better_path(Path * new_path, List * unique_paths, bool * noOther);
/*****************************************************************************
- * MISC. PATH UTILITIES
+ * MISC. PATH UTILITIES
*****************************************************************************/
-/*
+/*
* path-is-cheaper--
- * Returns t iff 'path1' is cheaper than 'path2'.
- *
+ * Returns t iff 'path1' is cheaper than 'path2'.
+ *
*/
bool
-path_is_cheaper(Path *path1, Path *path2)
+path_is_cheaper(Path * path1, Path * path2)
{
- Cost cost1 = path1->path_cost;
- Cost cost2 = path2->path_cost;
+ Cost cost1 = path1->path_cost;
+ Cost cost2 = path2->path_cost;
- return((bool)(cost1 < cost2));
+ return ((bool) (cost1 < cost2));
}
-/*
+/*
* set_cheapest--
- * Finds the minimum cost path from among a relation's paths.
- *
+ * Finds the minimum cost path from among a relation's paths.
+ *
* 'parent-rel' is the parent relation
* 'pathlist' is a list of path nodes corresponding to 'parent-rel'
- *
- * Returns and sets the relation entry field with the pathnode that
+ *
+ * Returns and sets the relation entry field with the pathnode that
* is minimum.
- *
+ *
*/
-Path *
-set_cheapest(Rel *parent_rel, List *pathlist)
+Path *
+set_cheapest(Rel * parent_rel, List * pathlist)
{
- List *p;
- Path *cheapest_so_far;
+ List *p;
+ Path *cheapest_so_far;
- Assert(pathlist!=NIL);
- Assert(IsA(parent_rel,Rel));
+ Assert(pathlist != NIL);
+ Assert(IsA(parent_rel, Rel));
- cheapest_so_far = (Path*)lfirst(pathlist);
+ cheapest_so_far = (Path *) lfirst(pathlist);
- foreach (p, lnext(pathlist)) {
- Path *path = (Path*)lfirst(p);
+ foreach(p, lnext(pathlist))
+ {
+ Path *path = (Path *) lfirst(p);
- if (path_is_cheaper(path, cheapest_so_far)) {
- cheapest_so_far = path;
+ if (path_is_cheaper(path, cheapest_so_far))
+ {
+ cheapest_so_far = path;
+ }
}
- }
- parent_rel->cheapestpath = cheapest_so_far;
+ parent_rel->cheapestpath = cheapest_so_far;
- return(cheapest_so_far);
+ return (cheapest_so_far);
}
-/*
+/*
* add_pathlist--
- * For each path in the list 'new-paths', add to the list 'unique-paths'
- * only those paths that are unique (i.e., unique ordering and ordering
- * keys). Should a conflict arise, the more expensive path is thrown out,
- * thereby pruning the plan space. But we don't prune if xfunc
- * told us not to.
- *
+ * For each path in the list 'new-paths', add to the list 'unique-paths'
+ * only those paths that are unique (i.e., unique ordering and ordering
+ * keys). Should a conflict arise, the more expensive path is thrown out,
+ * thereby pruning the plan space. But we don't prune if xfunc
+ * told us not to.
+ *
* 'parent-rel' is the relation entry to which these paths correspond.
- *
+ *
* Returns the list of unique pathnodes.
- *
+ *
*/
-List *
-add_pathlist(Rel *parent_rel, List *unique_paths, List *new_paths)
+List *
+add_pathlist(Rel * parent_rel, List * unique_paths, List * new_paths)
{
- List *x;
- Path *new_path;
- Path *old_path;
- bool noOther;
-
- foreach (x, new_paths) {
- new_path = (Path*)lfirst(x);
- if (member(new_path, unique_paths))
- continue;
- old_path = better_path(new_path,unique_paths,&noOther);
-
- if (noOther) {
- /* Is a brand new path. */
- new_path->parent = parent_rel;
- unique_paths = lcons(new_path, unique_paths);
- } else if (old_path==NULL) {
- ; /* do nothing if path is not cheaper */
- } else if (old_path != NULL) { /* (IsA(old_path,Path)) { */
- new_path->parent = parent_rel;
- if (!parent_rel->pruneable) {
- unique_paths = lcons(new_path, unique_paths);
- }else
- unique_paths = lcons(new_path,
- LispRemove(old_path,unique_paths));
+ List *x;
+ Path *new_path;
+ Path *old_path;
+ bool noOther;
+
+ foreach(x, new_paths)
+ {
+ new_path = (Path *) lfirst(x);
+ if (member(new_path, unique_paths))
+ continue;
+ old_path = better_path(new_path, unique_paths, &noOther);
+
+ if (noOther)
+ {
+ /* Is a brand new path. */
+ new_path->parent = parent_rel;
+ unique_paths = lcons(new_path, unique_paths);
+ }
+ else if (old_path == NULL)
+ {
+ ; /* do nothing if path is not cheaper */
+ }
+ else if (old_path != NULL)
+ { /* (IsA(old_path,Path)) { */
+ new_path->parent = parent_rel;
+ if (!parent_rel->pruneable)
+ {
+ unique_paths = lcons(new_path, unique_paths);
+ }
+ else
+ unique_paths = lcons(new_path,
+ LispRemove(old_path, unique_paths));
+ }
}
- }
- return(unique_paths);
+ return (unique_paths);
}
-/*
+/*
* better_path--
- * Determines whether 'new-path' has the same ordering and keys as some
- * path in the list 'unique-paths'. If there is a redundant path,
- * eliminate the more expensive path.
- *
+ * Determines whether 'new-path' has the same ordering and keys as some
+ * path in the list 'unique-paths'. If there is a redundant path,
+ * eliminate the more expensive path.
+ *
* Returns:
- * The old path - if 'new-path' matches some path in 'unique-paths' and is
- * cheaper
- * nil - if 'new-path' matches but isn't cheaper
- * t - if there is no path in the list with the same ordering and keys
- *
+ * The old path - if 'new-path' matches some path in 'unique-paths' and is
+ * cheaper
+ * nil - if 'new-path' matches but isn't cheaper
+ * t - if there is no path in the list with the same ordering and keys
+ *
*/
-static Path *
-better_path(Path *new_path, List *unique_paths, bool *noOther)
+static Path *
+better_path(Path * new_path, List * unique_paths, bool * noOther)
{
- Path *old_path = (Path*)NULL;
- Path *path = (Path*)NULL;
- List *temp = NIL;
- Path *retval = NULL;
-
- /* XXX - added the following two lines which weren't int
- * the lisp planner, but otherwise, doesn't seem to work
- * for the case where new_path is 'nil
- */
- foreach (temp,unique_paths) {
- path = (Path*) lfirst(temp);
-
- if ((equal_path_path_ordering(&new_path->p_ordering,
- &path->p_ordering) &&
- samekeys(new_path->keys, path->keys))) {
- old_path = path;
- break;
+ Path *old_path = (Path *) NULL;
+ Path *path = (Path *) NULL;
+ List *temp = NIL;
+ Path *retval = NULL;
+
+ /*
+ * XXX - added the following two lines which weren't int the lisp
+ * planner, but otherwise, doesn't seem to work for the case where
+ * new_path is 'nil
+ */
+ foreach(temp, unique_paths)
+ {
+ path = (Path *) lfirst(temp);
+
+ if ((equal_path_path_ordering(&new_path->p_ordering,
+ &path->p_ordering) &&
+ samekeys(new_path->keys, path->keys)))
+ {
+ old_path = path;
+ break;
+ }
}
- }
-
- if (old_path==NULL) {
- *noOther = true;
- } else {
- *noOther = false;
- if (path_is_cheaper(new_path,old_path)) {
- retval = old_path;
+
+ if (old_path == NULL)
+ {
+ *noOther = true;
+ }
+ else
+ {
+ *noOther = false;
+ if (path_is_cheaper(new_path, old_path))
+ {
+ retval = old_path;
+ }
}
- }
-
- return(retval);
+
+ return (retval);
}
/*****************************************************************************
- * PATH NODE CREATION ROUTINES
+ * PATH NODE CREATION ROUTINES
*****************************************************************************/
-/*
+/*
* create_seqscan_path--
- * Creates a path corresponding to a sequential scan, returning the
- * pathnode.
- *
+ * Creates a path corresponding to a sequential scan, returning the
+ * pathnode.
+ *
*/
-Path *
-create_seqscan_path(Rel *rel)
+Path *
+create_seqscan_path(Rel * rel)
{
- int relid=0;
-
- Path *pathnode = makeNode(Path);
-
- pathnode->pathtype = T_SeqScan;
- pathnode->parent = rel;
- pathnode->path_cost = 0.0;
- pathnode->p_ordering.ordtype = SORTOP_ORDER;
- pathnode->p_ordering.ord.sortop = NULL;
- pathnode->keys = NIL;
- /* copy clauseinfo list into path for expensive function processing
- * -- JMH, 7/7/92
- */
- pathnode->locclauseinfo=
- (List*)copyObject((Node*)rel->clauseinfo);
-
- if (rel->relids !=NULL)
- relid = lfirsti(rel->relids);
-
- pathnode->path_cost = cost_seqscan (relid,
- rel->pages, rel->tuples);
- /* add in expensive functions cost! -- JMH, 7/7/92 */
+ int relid = 0;
+
+ Path *pathnode = makeNode(Path);
+
+ pathnode->pathtype = T_SeqScan;
+ pathnode->parent = rel;
+ pathnode->path_cost = 0.0;
+ pathnode->p_ordering.ordtype = SORTOP_ORDER;
+ pathnode->p_ordering.ord.sortop = NULL;
+ pathnode->keys = NIL;
+
+ /*
+ * copy clauseinfo list into path for expensive function processing --
+ * JMH, 7/7/92
+ */
+ pathnode->locclauseinfo =
+ (List *) copyObject((Node *) rel->clauseinfo);
+
+ if (rel->relids != NULL)
+ relid = lfirsti(rel->relids);
+
+ pathnode->path_cost = cost_seqscan(relid,
+ rel->pages, rel->tuples);
+ /* add in expensive functions cost! -- JMH, 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost +=
- xfunc_get_path_cost(pathnode);
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost +=
+ xfunc_get_path_cost(pathnode);
+ }
#endif
- return (pathnode);
+ return (pathnode);
}
-/*
+/*
* create_index_path--
- * Creates a single path node for an index scan.
- *
+ * Creates a single path node for an index scan.
+ *
* 'rel' is the parent rel
* 'index' is the pathnode for the index on 'rel'
* 'restriction-clauses' is a list of restriction clause nodes.
* 'is-join-scan' is a flag indicating whether or not the index is being
- * considered because of its sort order.
- *
+ * considered because of its sort order.
+ *
* Returns the new path node.
- *
+ *
*/
-IndexPath *
-create_index_path(Query *root,
- Rel *rel,
- Rel *index,
- List *restriction_clauses,
- bool is_join_scan)
+IndexPath *
+create_index_path(Query * root,
+ Rel * rel,
+ Rel * index,
+ List * restriction_clauses,
+ bool is_join_scan)
{
- IndexPath *pathnode = makeNode(IndexPath);
-
- pathnode->path.pathtype = T_IndexScan;
- pathnode->path.parent = rel;
- pathnode->path.p_ordering.ordtype = SORTOP_ORDER;
- pathnode->path.p_ordering.ord.sortop = index->ordering;
-
- pathnode->indexid = index->relids;
- pathnode->indexkeys = index->indexkeys;
- pathnode->indexqual = NIL;
-
- /* copy clauseinfo list into path for expensive function processing
- * -- JMH, 7/7/92
- */
- pathnode->path.locclauseinfo =
- set_difference((List*) copyObject((Node*)rel->clauseinfo),
- (List*) restriction_clauses);
-
- /*
- * The index must have an ordering for the path to have (ordering) keys,
- * and vice versa.
- */
- if (pathnode->path.p_ordering.ord.sortop) {
- pathnode->path.keys = collect_index_pathkeys(index->indexkeys,
- rel->targetlist);
+ IndexPath *pathnode = makeNode(IndexPath);
+
+ pathnode->path.pathtype = T_IndexScan;
+ pathnode->path.parent = rel;
+ pathnode->path.p_ordering.ordtype = SORTOP_ORDER;
+ pathnode->path.p_ordering.ord.sortop = index->ordering;
+
+ pathnode->indexid = index->relids;
+ pathnode->indexkeys = index->indexkeys;
+ pathnode->indexqual = NIL;
+
/*
- * Check that the keys haven't 'disappeared', since they may
- * no longer be in the target list (i.e., index keys that are not
- * relevant to the scan are not applied to the scan path node,
- * so if no index keys were found, we can't order the path).
+ * copy clauseinfo list into path for expensive function processing --
+ * JMH, 7/7/92
*/
- if (pathnode->path.keys==NULL) {
- pathnode->path.p_ordering.ord.sortop = NULL;
- }
- } else {
- pathnode->path.keys = NULL;
- }
+ pathnode->path.locclauseinfo =
+ set_difference((List *) copyObject((Node *) rel->clauseinfo),
+ (List *) restriction_clauses);
- if (is_join_scan || restriction_clauses==NULL) {
/*
- * Indices used for joins or sorting result nodes don't
- * restrict the result at all, they simply order it,
- * so compute the scan cost
- * accordingly -- use a selectivity of 1.0.
+ * The index must have an ordering for the path to have (ordering)
+ * keys, and vice versa.
*/
-/* is the statement above really true? what about IndexScan as the
+ if (pathnode->path.p_ordering.ord.sortop)
+ {
+ pathnode->path.keys = collect_index_pathkeys(index->indexkeys,
+ rel->targetlist);
+
+ /*
+ * Check that the keys haven't 'disappeared', since they may no
+ * longer be in the target list (i.e., index keys that are not
+ * relevant to the scan are not applied to the scan path node, so
+ * if no index keys were found, we can't order the path).
+ */
+ if (pathnode->path.keys == NULL)
+ {
+ pathnode->path.p_ordering.ord.sortop = NULL;
+ }
+ }
+ else
+ {
+ pathnode->path.keys = NULL;
+ }
+
+ if (is_join_scan || restriction_clauses == NULL)
+ {
+
+ /*
+ * Indices used for joins or sorting result nodes don't restrict
+ * the result at all, they simply order it, so compute the scan
+ * cost accordingly -- use a selectivity of 1.0.
+ */
+/* is the statement above really true? what about IndexScan as the
inner of a join? */
- pathnode->path.path_cost =
- cost_index (lfirsti(index->relids),
- index->pages,
- 1.0,
- rel->pages,
- rel->tuples,
- index->pages,
- index->tuples,
- false);
- /* add in expensive functions cost! -- JMH, 7/7/92 */
+ pathnode->path.path_cost =
+ cost_index(lfirsti(index->relids),
+ index->pages,
+ 1.0,
+ rel->pages,
+ rel->tuples,
+ index->pages,
+ index->tuples,
+ false);
+ /* add in expensive functions cost! -- JMH, 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost =
- (pathnode->path_cost +
- xfunc_get_path_cost((Path*)pathnode));
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost =
+ (pathnode->path_cost +
+ xfunc_get_path_cost((Path *) pathnode));
+ }
#endif
- } else {
- /*
- * Compute scan cost for the case when 'index' is used with a
- * restriction clause.
- */
- List *attnos;
- List *values;
- List *flags;
- float npages;
- float selec;
- Cost clausesel;
-
- get_relattvals(restriction_clauses,
- &attnos,
- &values,
- &flags);
- index_selectivity(lfirsti(index->relids),
- index->classlist,
- get_opnos(restriction_clauses),
- getrelid(lfirsti(rel->relids),
- root->rtable),
- attnos,
- values,
- flags,
- length(restriction_clauses),
- &npages,
- &selec);
- /* each clause gets an equal selectivity */
- clausesel =
- pow(selec,
- 1.0 / (double) length(restriction_clauses));
-
- pathnode->indexqual = restriction_clauses;
- pathnode->path.path_cost =
- cost_index (lfirsti(index->relids),
- (int)npages,
- selec,
- rel->pages,
- rel->tuples,
- index->pages,
- index->tuples,
- false);
+ }
+ else
+ {
+
+ /*
+ * Compute scan cost for the case when 'index' is used with a
+ * restriction clause.
+ */
+ List *attnos;
+ List *values;
+ List *flags;
+ float npages;
+ float selec;
+ Cost clausesel;
+
+ get_relattvals(restriction_clauses,
+ &attnos,
+ &values,
+ &flags);
+ index_selectivity(lfirsti(index->relids),
+ index->classlist,
+ get_opnos(restriction_clauses),
+ getrelid(lfirsti(rel->relids),
+ root->rtable),
+ attnos,
+ values,
+ flags,
+ length(restriction_clauses),
+ &npages,
+ &selec);
+ /* each clause gets an equal selectivity */
+ clausesel =
+ pow(selec,
+ 1.0 / (double) length(restriction_clauses));
+
+ pathnode->indexqual = restriction_clauses;
+ pathnode->path.path_cost =
+ cost_index(lfirsti(index->relids),
+ (int) npages,
+ selec,
+ rel->pages,
+ rel->tuples,
+ index->pages,
+ index->tuples,
+ false);
#if 0
- /* add in expensive functions cost! -- JMH, 7/7/92 */
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost +=
- xfunc_get_path_cost((Path*)pathnode);
- }
+ /* add in expensive functions cost! -- JMH, 7/7/92 */
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost +=
+ xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- /* Set selectivities of clauses used with index to the selectivity
- * of this index, subdividing the selectivity equally over each of
- * the clauses.
- */
- /* XXX Can this divide the selectivities in a better way? */
- set_clause_selectivities(restriction_clauses, clausesel);
- }
- return(pathnode);
+ /*
+ * Set selectivities of clauses used with index to the selectivity
+ * of this index, subdividing the selectivity equally over each of
+ * the clauses.
+ */
+
+ /* XXX Can this divide the selectivities in a better way? */
+ set_clause_selectivities(restriction_clauses, clausesel);
+ }
+ return (pathnode);
}
-/*
+/*
* create_nestloop_path--
- * Creates a pathnode corresponding to a nestloop join between two
- * relations.
- *
+ * Creates a pathnode corresponding to a nestloop join between two
+ * relations.
+ *
* 'joinrel' is the join relation.
* 'outer_rel' is the outer join relation
* 'outer_path' is the outer join path.
* 'inner_path' is the inner join path.
* 'keys' are the keys of the path
- *
+ *
* Returns the resulting path node.
- *
+ *
*/
-JoinPath *
-create_nestloop_path(Rel *joinrel,
- Rel *outer_rel,
- Path *outer_path,
- Path *inner_path,
- List *keys)
+JoinPath *
+create_nestloop_path(Rel * joinrel,
+ Rel * outer_rel,
+ Path * outer_path,
+ Path * inner_path,
+ List * keys)
{
- JoinPath *pathnode = makeNode(JoinPath);
-
- pathnode->path.pathtype = T_NestLoop;
- pathnode->path.parent = joinrel;
- pathnode->outerjoinpath = outer_path;
- pathnode->innerjoinpath = inner_path;
- pathnode->pathclauseinfo = joinrel->clauseinfo;
- pathnode->path.keys = keys;
- pathnode->path.joinid = NIL;
- pathnode->path.outerjoincost = (Cost)0.0;
- pathnode->path.locclauseinfo = NIL;
-
- if (keys) {
- pathnode->path.p_ordering.ordtype =
- outer_path->p_ordering.ordtype;
- if (outer_path->p_ordering.ordtype == SORTOP_ORDER) {
- pathnode->path.p_ordering.ord.sortop =
- outer_path->p_ordering.ord.sortop;
- } else {
- pathnode->path.p_ordering.ord.merge =
- outer_path->p_ordering.ord.merge;
+ JoinPath *pathnode = makeNode(JoinPath);
+
+ pathnode->path.pathtype = T_NestLoop;
+ pathnode->path.parent = joinrel;
+ pathnode->outerjoinpath = outer_path;
+ pathnode->innerjoinpath = inner_path;
+ pathnode->pathclauseinfo = joinrel->clauseinfo;
+ pathnode->path.keys = keys;
+ pathnode->path.joinid = NIL;
+ pathnode->path.outerjoincost = (Cost) 0.0;
+ pathnode->path.locclauseinfo = NIL;
+
+ if (keys)
+ {
+ pathnode->path.p_ordering.ordtype =
+ outer_path->p_ordering.ordtype;
+ if (outer_path->p_ordering.ordtype == SORTOP_ORDER)
+ {
+ pathnode->path.p_ordering.ord.sortop =
+ outer_path->p_ordering.ord.sortop;
+ }
+ else
+ {
+ pathnode->path.p_ordering.ord.merge =
+ outer_path->p_ordering.ord.merge;
+ }
}
- } else {
- pathnode->path.p_ordering.ordtype = SORTOP_ORDER;
- pathnode->path.p_ordering.ord.sortop = NULL;
- }
-
- pathnode->path.path_cost =
- cost_nestloop(outer_path->path_cost,
- inner_path->path_cost,
- outer_rel->size,
- inner_path->parent->size,
- page_size(outer_rel->size,
- outer_rel->width),
- IsA(inner_path,IndexPath));
- /* add in expensive function costs -- JMH 7/7/92 */
+ else
+ {
+ pathnode->path.p_ordering.ordtype = SORTOP_ORDER;
+ pathnode->path.p_ordering.ord.sortop = NULL;
+ }
+
+ pathnode->path.path_cost =
+ cost_nestloop(outer_path->path_cost,
+ inner_path->path_cost,
+ outer_rel->size,
+ inner_path->parent->size,
+ page_size(outer_rel->size,
+ outer_rel->width),
+ IsA(inner_path, IndexPath));
+ /* add in expensive function costs -- JMH 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost += xfunc_get_path_cost((Path*)pathnode);
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost += xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- return(pathnode);
+ return (pathnode);
}
-/*
+/*
* create_mergesort_path--
- * Creates a pathnode corresponding to a mergesort join between
- * two relations
- *
+ * Creates a pathnode corresponding to a mergesort join between
+ * two relations
+ *
* 'joinrel' is the join relation
* 'outersize' is the number of tuples in the outer relation
* 'innersize' is the number of tuples in the inner relation
@@ -451,59 +492,60 @@ create_nestloop_path(Rel *joinrel,
* 'mergeclauses' are the applicable join/restriction clauses
* 'outersortkeys' are the sort varkeys for the outer relation
* 'innersortkeys' are the sort varkeys for the inner relation
- *
+ *
*/
-MergePath *
-create_mergesort_path(Rel *joinrel,
- int outersize,
- int innersize,
- int outerwidth,
- int innerwidth,
- Path *outer_path,
- Path *inner_path,
- List *keys,
- MergeOrder *order,
- List *mergeclauses,
- List *outersortkeys,
- List *innersortkeys)
+MergePath *
+create_mergesort_path(Rel * joinrel,
+ int outersize,
+ int innersize,
+ int outerwidth,
+ int innerwidth,
+ Path * outer_path,
+ Path * inner_path,
+ List * keys,
+ MergeOrder * order,
+ List * mergeclauses,
+ List * outersortkeys,
+ List * innersortkeys)
{
- MergePath *pathnode = makeNode(MergePath);
-
- pathnode->jpath.path.pathtype = T_MergeJoin;
- pathnode->jpath.path.parent = joinrel;
- pathnode->jpath.outerjoinpath = outer_path;
- pathnode->jpath.innerjoinpath = inner_path;
- pathnode->jpath.pathclauseinfo = joinrel->clauseinfo;
- pathnode->jpath.path.keys = keys;
- pathnode->jpath.path.p_ordering.ordtype = MERGE_ORDER;
- pathnode->jpath.path.p_ordering.ord.merge = order;
- pathnode->path_mergeclauses = mergeclauses;
- pathnode->jpath.path.locclauseinfo = NIL;
- pathnode->outersortkeys = outersortkeys;
- pathnode->innersortkeys = innersortkeys;
- pathnode->jpath.path.path_cost =
- cost_mergesort(outer_path->path_cost,
- inner_path->path_cost,
- outersortkeys,
- innersortkeys,
- outersize,
- innersize,
- outerwidth,
- innerwidth);
- /* add in expensive function costs -- JMH 7/7/92 */
+ MergePath *pathnode = makeNode(MergePath);
+
+ pathnode->jpath.path.pathtype = T_MergeJoin;
+ pathnode->jpath.path.parent = joinrel;
+ pathnode->jpath.outerjoinpath = outer_path;
+ pathnode->jpath.innerjoinpath = inner_path;
+ pathnode->jpath.pathclauseinfo = joinrel->clauseinfo;
+ pathnode->jpath.path.keys = keys;
+ pathnode->jpath.path.p_ordering.ordtype = MERGE_ORDER;
+ pathnode->jpath.path.p_ordering.ord.merge = order;
+ pathnode->path_mergeclauses = mergeclauses;
+ pathnode->jpath.path.locclauseinfo = NIL;
+ pathnode->outersortkeys = outersortkeys;
+ pathnode->innersortkeys = innersortkeys;
+ pathnode->jpath.path.path_cost =
+ cost_mergesort(outer_path->path_cost,
+ inner_path->path_cost,
+ outersortkeys,
+ innersortkeys,
+ outersize,
+ innersize,
+ outerwidth,
+ innerwidth);
+ /* add in expensive function costs -- JMH 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost +=
- xfunc_get_path_cost((Path*)pathnode);
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost +=
+ xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- return(pathnode);
+ return (pathnode);
}
-/*
- * create_hashjoin_path-- XXX HASH
- * Creates a pathnode corresponding to a hash join between two relations.
- *
+/*
+ * create_hashjoin_path-- XXX HASH
+ * Creates a pathnode corresponding to a hash join between two relations.
+ *
* 'joinrel' is the join relation
* 'outersize' is the number of tuples in the outer relation
* 'innersize' is the number of tuples in the inner relation
@@ -516,52 +558,53 @@ create_mergesort_path(Rel *joinrel,
* 'hashclauses' are the applicable join/restriction clauses
* 'outerkeys' are the sort varkeys for the outer relation
* 'innerkeys' are the sort varkeys for the inner relation
- *
+ *
*/
-HashPath *
-create_hashjoin_path(Rel *joinrel,
- int outersize,
- int innersize,
- int outerwidth,
- int innerwidth,
- Path *outer_path,
- Path *inner_path,
- List *keys,
- Oid operator,
- List *hashclauses,
- List *outerkeys,
- List *innerkeys)
+HashPath *
+create_hashjoin_path(Rel * joinrel,
+ int outersize,
+ int innersize,
+ int outerwidth,
+ int innerwidth,
+ Path * outer_path,
+ Path * inner_path,
+ List * keys,
+ Oid operator,
+ List * hashclauses,
+ List * outerkeys,
+ List * innerkeys)
{
- HashPath *pathnode = makeNode(HashPath);
-
- pathnode->jpath.path.pathtype = T_HashJoin;
- pathnode->jpath.path.parent = joinrel;
- pathnode->jpath.outerjoinpath = outer_path;
- pathnode->jpath.innerjoinpath = inner_path;
- pathnode->jpath.pathclauseinfo = joinrel->clauseinfo;
- pathnode->jpath.path.locclauseinfo = NIL;
- pathnode->jpath.path.keys = keys;
- pathnode->jpath.path.p_ordering.ordtype = SORTOP_ORDER;
- pathnode->jpath.path.p_ordering.ord.sortop = NULL;
- pathnode->jpath.path.outerjoincost = (Cost)0.0;
- pathnode->jpath.path.joinid = (Relid)NULL;
- /* pathnode->hashjoinoperator = operator; */
- pathnode->path_hashclauses = hashclauses;
- pathnode->outerhashkeys = outerkeys;
- pathnode->innerhashkeys = innerkeys;
- pathnode->jpath.path.path_cost =
- cost_hashjoin(outer_path->path_cost,
- inner_path->path_cost,
- outerkeys,
- innerkeys,
- outersize,innersize,
- outerwidth,innerwidth);
- /* add in expensive function costs -- JMH 7/7/92 */
+ HashPath *pathnode = makeNode(HashPath);
+
+ pathnode->jpath.path.pathtype = T_HashJoin;
+ pathnode->jpath.path.parent = joinrel;
+ pathnode->jpath.outerjoinpath = outer_path;
+ pathnode->jpath.innerjoinpath = inner_path;
+ pathnode->jpath.pathclauseinfo = joinrel->clauseinfo;
+ pathnode->jpath.path.locclauseinfo = NIL;
+ pathnode->jpath.path.keys = keys;
+ pathnode->jpath.path.p_ordering.ordtype = SORTOP_ORDER;
+ pathnode->jpath.path.p_ordering.ord.sortop = NULL;
+ pathnode->jpath.path.outerjoincost = (Cost) 0.0;
+ pathnode->jpath.path.joinid = (Relid) NULL;
+ /* pathnode->hashjoinoperator = operator; */
+ pathnode->path_hashclauses = hashclauses;
+ pathnode->outerhashkeys = outerkeys;
+ pathnode->innerhashkeys = innerkeys;
+ pathnode->jpath.path.path_cost =
+ cost_hashjoin(outer_path->path_cost,
+ inner_path->path_cost,
+ outerkeys,
+ innerkeys,
+ outersize, innersize,
+ outerwidth, innerwidth);
+ /* add in expensive function costs -- JMH 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost +=
- xfunc_get_path_cost((Path*)pathnode);
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost +=
+ xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- return(pathnode);
+ return (pathnode);
}
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index abe764aa4e0..0e88a72c4eb 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* plancat.c--
- * routines for accessing the system catalogs
+ * routines for accessing the system catalogs
*
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.6 1997/04/24 16:07:14 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.7 1997/09/07 04:44:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,7 +26,7 @@
#include "catalog/pg_inherits.h"
#include "catalog/pg_version.h"
-#include "parser/parsetree.h" /* for getrelid() */
+#include "parser/parsetree.h" /* for getrelid() */
#include "fmgr.h"
#include "optimizer/internal.h"
@@ -34,193 +34,203 @@
#include "utils/syscache.h"
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static void IndexSelectivity(Oid indexrelid, Oid indrelid, int32 nIndexKeys,
- Oid AccessMethodOperatorClasses[], Oid operatorObjectIds[],
+static void
+IndexSelectivity(Oid indexrelid, Oid indrelid, int32 nIndexKeys,
+ Oid AccessMethodOperatorClasses[], Oid operatorObjectIds[],
int32 varAttributeNumbers[], char *constValues[], int32 constFlags[],
- float *idxPages, float *idxSelec);
+ float *idxPages, float *idxSelec);
/*
* relation-info -
- * Retrieves catalog information for a given relation. Given the oid of
- * the relation, return the following information:
- * whether the relation has secondary indices
- * number of pages
- * number of tuples
+ * Retrieves catalog information for a given relation. Given the oid of
+ * the relation, return the following information:
+ * whether the relation has secondary indices
+ * number of pages
+ * number of tuples
*/
void
-relation_info(Query *root, Index relid,
- bool *hasindex, int *pages, int *tuples)
+relation_info(Query * root, Index relid,
+ bool * hasindex, int *pages, int *tuples)
{
- HeapTuple relationTuple;
- Form_pg_class relation;
- Oid relationObjectId;
-
- relationObjectId = getrelid(relid, root->rtable);
- relationTuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relationObjectId),
- 0,0,0);
- if (HeapTupleIsValid(relationTuple)) {
- relation = (Form_pg_class)GETSTRUCT(relationTuple);
-
- *hasindex = (relation->relhasindex) ? TRUE : FALSE;
- *pages = relation->relpages;
- *tuples = relation->reltuples;
- } else {
- elog(WARN, "RelationCatalogInformation: Relation %d not found",
- relationObjectId);
- }
-
- return;
+ HeapTuple relationTuple;
+ Form_pg_class relation;
+ Oid relationObjectId;
+
+ relationObjectId = getrelid(relid, root->rtable);
+ relationTuple = SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(relationObjectId),
+ 0, 0, 0);
+ if (HeapTupleIsValid(relationTuple))
+ {
+ relation = (Form_pg_class) GETSTRUCT(relationTuple);
+
+ *hasindex = (relation->relhasindex) ? TRUE : FALSE;
+ *pages = relation->relpages;
+ *tuples = relation->reltuples;
+ }
+ else
+ {
+ elog(WARN, "RelationCatalogInformation: Relation %d not found",
+ relationObjectId);
+ }
+
+ return;
}
-/*
+/*
* index-info--
- * Retrieves catalog information on an index on a given relation.
- *
- * The index relation is opened on the first invocation. The current
- * retrieves the next index relation within the catalog that has not
- * already been retrieved by a previous call. The index catalog
- * is closed when no more indices for 'relid' can be found.
- *
- * 'first' is 1 if this is the first call
- *
+ * Retrieves catalog information on an index on a given relation.
+ *
+ * The index relation is opened on the first invocation. The current
+ * retrieves the next index relation within the catalog that has not
+ * already been retrieved by a previous call. The index catalog
+ * is closed when no more indices for 'relid' can be found.
+ *
+ * 'first' is 1 if this is the first call
+ *
* Returns true if successful and false otherwise. Index info is returned
* via the transient data structure 'info'.
- *
+ *
*/
bool
-index_info(Query *root, bool first, int relid, IdxInfoRetval *info)
+index_info(Query * root, bool first, int relid, IdxInfoRetval * info)
{
- register i;
- HeapTuple indexTuple, amopTuple;
- IndexTupleForm index;
- Relation indexRelation;
- uint16 amstrategy;
- Oid relam;
- Oid indrelid;
-
- static Relation relation = (Relation) NULL;
- static HeapScanDesc scan = (HeapScanDesc) NULL;
- static ScanKeyData indexKey;
-
-
- /* find the oid of the indexed relation */
- indrelid = getrelid(relid, root->rtable);
-
- memset(info, 0, sizeof(IdxInfoRetval));
-
- /*
- * the maximum number of elements in each of the following arrays is
- * 8. We allocate one more for a terminating 0 to indicate the end
- * of the array.
- */
- info->indexkeys = (int *)palloc(sizeof(int)*9);
- memset(info->indexkeys, 0, sizeof(int)*9);
- info->orderOprs = (Oid *)palloc(sizeof(Oid)*9);
- memset(info->orderOprs, 0, sizeof(Oid)*9);
- info->classlist = (Oid *)palloc(sizeof(Oid)*9);
- memset(info->classlist, 0, sizeof(Oid)*9);
-
- /* Find an index on the given relation */
- if (first) {
- if (RelationIsValid(relation))
- heap_close(relation);
- if (HeapScanIsValid(scan))
- heap_endscan(scan);
-
- ScanKeyEntryInitialize(&indexKey, 0,
- Anum_pg_index_indrelid,
- F_OIDEQ,
- ObjectIdGetDatum(indrelid));
-
- relation = heap_openr(IndexRelationName);
- scan = heap_beginscan(relation, 0, NowTimeQual,
- 1, &indexKey);
- }
- if (!HeapScanIsValid(scan))
- elog(WARN, "index_info: scan not started");
- indexTuple = heap_getnext(scan, 0, (Buffer *) NULL);
- if (!HeapTupleIsValid(indexTuple)) {
- heap_endscan(scan);
- heap_close(relation);
- scan = (HeapScanDesc) NULL;
- relation = (Relation) NULL;
- return(0);
- }
-
- /* Extract info from the index tuple */
- index = (IndexTupleForm)GETSTRUCT(indexTuple);
- info->relid = index->indexrelid; /* index relation */
- for (i = 0; i < 8; i++)
- info->indexkeys[i] = index->indkey[i];
- for (i = 0; i < 8; i++)
- info->classlist[i] = index->indclass[i];
-
- info->indproc = index->indproc; /* functional index ?? */
-
- /* partial index ?? */
- if (VARSIZE(&index->indpred) != 0) {
+ register i;
+ HeapTuple indexTuple,
+ amopTuple;
+ IndexTupleForm index;
+ Relation indexRelation;
+ uint16 amstrategy;
+ Oid relam;
+ Oid indrelid;
+
+ static Relation relation = (Relation) NULL;
+ static HeapScanDesc scan = (HeapScanDesc) NULL;
+ static ScanKeyData indexKey;
+
+
+ /* find the oid of the indexed relation */
+ indrelid = getrelid(relid, root->rtable);
+
+ memset(info, 0, sizeof(IdxInfoRetval));
+
/*
- * The memory allocated here for the predicate (in lispReadString)
- * only needs to stay around until it's used in find_index_paths,
- * which is all within a command, so the automatic pfree at end
- * of transaction should be ok.
+ * the maximum number of elements in each of the following arrays is
+ * 8. We allocate one more for a terminating 0 to indicate the end of
+ * the array.
*/
- char *predString;
+ info->indexkeys = (int *) palloc(sizeof(int) * 9);
+ memset(info->indexkeys, 0, sizeof(int) * 9);
+ info->orderOprs = (Oid *) palloc(sizeof(Oid) * 9);
+ memset(info->orderOprs, 0, sizeof(Oid) * 9);
+ info->classlist = (Oid *) palloc(sizeof(Oid) * 9);
+ memset(info->classlist, 0, sizeof(Oid) * 9);
+
+ /* Find an index on the given relation */
+ if (first)
+ {
+ if (RelationIsValid(relation))
+ heap_close(relation);
+ if (HeapScanIsValid(scan))
+ heap_endscan(scan);
+
+ ScanKeyEntryInitialize(&indexKey, 0,
+ Anum_pg_index_indrelid,
+ F_OIDEQ,
+ ObjectIdGetDatum(indrelid));
+
+ relation = heap_openr(IndexRelationName);
+ scan = heap_beginscan(relation, 0, NowTimeQual,
+ 1, &indexKey);
+ }
+ if (!HeapScanIsValid(scan))
+ elog(WARN, "index_info: scan not started");
+ indexTuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(indexTuple))
+ {
+ heap_endscan(scan);
+ heap_close(relation);
+ scan = (HeapScanDesc) NULL;
+ relation = (Relation) NULL;
+ return (0);
+ }
+
+ /* Extract info from the index tuple */
+ index = (IndexTupleForm) GETSTRUCT(indexTuple);
+ info->relid = index->indexrelid; /* index relation */
+ for (i = 0; i < 8; i++)
+ info->indexkeys[i] = index->indkey[i];
+ for (i = 0; i < 8; i++)
+ info->classlist[i] = index->indclass[i];
- predString = fmgr(F_TEXTOUT, &index->indpred);
- info->indpred = (Node*)stringToNode(predString);
- pfree(predString);
- }
+ info->indproc = index->indproc; /* functional index ?? */
- /* Extract info from the relation descriptor for the index */
- indexRelation = index_open(index->indexrelid);
+ /* partial index ?? */
+ if (VARSIZE(&index->indpred) != 0)
+ {
+
+ /*
+ * The memory allocated here for the predicate (in lispReadString)
+ * only needs to stay around until it's used in find_index_paths,
+ * which is all within a command, so the automatic pfree at end of
+ * transaction should be ok.
+ */
+ char *predString;
+
+ predString = fmgr(F_TEXTOUT, &index->indpred);
+ info->indpred = (Node *) stringToNode(predString);
+ pfree(predString);
+ }
+
+ /* Extract info from the relation descriptor for the index */
+ indexRelation = index_open(index->indexrelid);
#ifdef notdef
- /* XXX should iterate through strategies -- but how? use #1 for now */
- amstrategy = indexRelation->rd_am->amstrategies;
-#endif /* notdef */
- amstrategy = 1;
- relam = indexRelation->rd_rel->relam;
- info->relam = relam;
- info->pages = indexRelation->rd_rel->relpages;
- info->tuples = indexRelation->rd_rel->reltuples;
- heap_close(indexRelation);
-
- /*
- * Find the index ordering keys
- *
- * Must use indclass to know when to stop looking since with
- * functional indices there could be several keys (args) for
- * one opclass. -mer 27 Sept 1991
- */
- for (i = 0; i < 8 && index->indclass[i]; ++i) {
- amopTuple = SearchSysCacheTuple(AMOPSTRATEGY,
- ObjectIdGetDatum(relam),
- ObjectIdGetDatum(index->indclass[i]),
- UInt16GetDatum(amstrategy),
- 0);
- if (!HeapTupleIsValid(amopTuple))
- elog(WARN, "index_info: no amop %d %d %d",
- relam, index->indclass[i], amstrategy);
- info->orderOprs[i] =
- ((Form_pg_amop)GETSTRUCT(amopTuple))->amopopr;
- }
- return(TRUE);
+ /* XXX should iterate through strategies -- but how? use #1 for now */
+ amstrategy = indexRelation->rd_am->amstrategies;
+#endif /* notdef */
+ amstrategy = 1;
+ relam = indexRelation->rd_rel->relam;
+ info->relam = relam;
+ info->pages = indexRelation->rd_rel->relpages;
+ info->tuples = indexRelation->rd_rel->reltuples;
+ heap_close(indexRelation);
+
+ /*
+ * Find the index ordering keys
+ *
+ * Must use indclass to know when to stop looking since with functional
+ * indices there could be several keys (args) for one opclass. -mer 27
+ * Sept 1991
+ */
+ for (i = 0; i < 8 && index->indclass[i]; ++i)
+ {
+ amopTuple = SearchSysCacheTuple(AMOPSTRATEGY,
+ ObjectIdGetDatum(relam),
+ ObjectIdGetDatum(index->indclass[i]),
+ UInt16GetDatum(amstrategy),
+ 0);
+ if (!HeapTupleIsValid(amopTuple))
+ elog(WARN, "index_info: no amop %d %d %d",
+ relam, index->indclass[i], amstrategy);
+ info->orderOprs[i] =
+ ((Form_pg_amop) GETSTRUCT(amopTuple))->amopopr;
+ }
+ return (TRUE);
}
-/*
+/*
* index-selectivity--
- *
- * Call util/plancat.c:IndexSelectivity with the indicated arguments.
- *
+ *
+ * Call util/plancat.c:IndexSelectivity with the indicated arguments.
+ *
* 'indid' is the index OID
* 'classes' is a list of index key classes
* 'opnos' is a list of index key operator OIDs
@@ -229,153 +239,162 @@ index_info(Query *root, bool first, int relid, IdxInfoRetval *info)
* 'values' is a list of the values of the clause's constants
* 'flags' is a list of fixnums which describe the constants
* 'nkeys' is the number of index keys
- *
+ *
* Returns two floats: index pages and index selectivity in 'idxPages' and
- * 'idxSelec'.
- *
+ * 'idxSelec'.
+ *
*/
void
index_selectivity(Oid indid,
- Oid *classes,
- List *opnos,
- Oid relid,
- List *attnos,
- List *values,
- List *flags,
- int32 nkeys,
- float *idxPages,
- float *idxSelec)
+ Oid * classes,
+ List * opnos,
+ Oid relid,
+ List * attnos,
+ List * values,
+ List * flags,
+ int32 nkeys,
+ float *idxPages,
+ float *idxSelec)
{
- Oid *opno_array;
- int *attno_array, *flag_array;
- char **value_array;
- int i = 0;
- List *xopno, *xattno, *value, *flag;
+ Oid *opno_array;
+ int *attno_array,
+ *flag_array;
+ char **value_array;
+ int i = 0;
+ List *xopno,
+ *xattno,
+ *value,
+ *flag;
+
+ if (length(opnos) != nkeys || length(attnos) != nkeys ||
+ length(values) != nkeys || length(flags) != nkeys)
+ {
+
+ *idxPages = 0.0;
+ *idxSelec = 1.0;
+ return;
+ }
- if (length(opnos)!=nkeys || length(attnos)!=nkeys ||
- length(values)!=nkeys || length(flags)!=nkeys) {
+ opno_array = (Oid *) palloc(nkeys * sizeof(Oid));
+ attno_array = (int *) palloc(nkeys * sizeof(int32));
+ value_array = (char **) palloc(nkeys * sizeof(char *));
+ flag_array = (int *) palloc(nkeys * sizeof(int32));
- *idxPages = 0.0;
- *idxSelec = 1.0;
+ i = 0;
+ foreach(xopno, opnos)
+ {
+ opno_array[i++] = lfirsti(xopno);
+ }
+
+ i = 0;
+ foreach(xattno, attnos)
+ {
+ attno_array[i++] = lfirsti(xattno);
+ }
+
+ i = 0;
+ foreach(value, values)
+ {
+ value_array[i++] = (char *) lfirst(value);
+ }
+
+ i = 0;
+ foreach(flag, flags)
+ {
+ flag_array[i++] = lfirsti(flag);
+ }
+
+ IndexSelectivity(indid,
+ relid,
+ nkeys,
+ classes, /* not used */
+ opno_array,
+ attno_array,
+ value_array,
+ flag_array,
+ idxPages,
+ idxSelec);
return;
- }
-
- opno_array = (Oid *)palloc(nkeys*sizeof(Oid));
- attno_array = (int *)palloc(nkeys*sizeof(int32));
- value_array = (char **)palloc(nkeys*sizeof(char *));
- flag_array = (int *)palloc(nkeys*sizeof(int32));
-
- i = 0;
- foreach(xopno, opnos) {
- opno_array[i++] = lfirsti(xopno);
- }
-
- i = 0;
- foreach(xattno,attnos) {
- attno_array[i++] = lfirsti(xattno);
- }
-
- i = 0;
- foreach(value, values) {
- value_array[i++] = (char *)lfirst(value);
- }
-
- i = 0;
- foreach(flag,flags) {
- flag_array[i++] = lfirsti(flag);
- }
-
- IndexSelectivity(indid,
- relid,
- nkeys,
- classes, /* not used */
- opno_array,
- attno_array,
- value_array,
- flag_array,
- idxPages,
- idxSelec);
- return;
}
/*
* restriction_selectivity in lisp system.--
*
- * NOTE: The routine is now merged with RestrictionClauseSelectivity
- * as defined in plancat.c
+ * NOTE: The routine is now merged with RestrictionClauseSelectivity
+ * as defined in plancat.c
*
* Returns the selectivity of a specified operator.
* This code executes registered procedures stored in the
* operator relation, by calling the function manager.
*
* XXX The assumption in the selectivity procedures is that if the
- * relation OIDs or attribute numbers are -1, then the clause
- * isn't of the form (op var const).
+ * relation OIDs or attribute numbers are -1, then the clause
+ * isn't of the form (op var const).
*/
Cost
restriction_selectivity(Oid functionObjectId,
- Oid operatorObjectId,
- Oid relationObjectId,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag)
+ Oid operatorObjectId,
+ Oid relationObjectId,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag)
{
- float64 result;
-
- result = (float64) fmgr(functionObjectId,
- (char *) operatorObjectId,
- (char *) relationObjectId,
- (char *) (int)attributeNumber,
- (char *) constValue,
- (char *) constFlag,
- NULL);
- if (!PointerIsValid(result))
- elog(WARN, "RestrictionClauseSelectivity: bad pointer");
-
- if (*result < 0.0 || *result > 1.0)
- elog(WARN, "RestrictionClauseSelectivity: bad value %lf",
- *result);
-
- return ((Cost)*result);
+ float64 result;
+
+ result = (float64) fmgr(functionObjectId,
+ (char *) operatorObjectId,
+ (char *) relationObjectId,
+ (char *) (int) attributeNumber,
+ (char *) constValue,
+ (char *) constFlag,
+ NULL);
+ if (!PointerIsValid(result))
+ elog(WARN, "RestrictionClauseSelectivity: bad pointer");
+
+ if (*result < 0.0 || *result > 1.0)
+ elog(WARN, "RestrictionClauseSelectivity: bad value %lf",
+ *result);
+
+ return ((Cost) * result);
}
/*
* join_selectivity--
- * Similarly, this routine is merged with JoinClauseSelectivity in
- * plancat.c
+ * Similarly, this routine is merged with JoinClauseSelectivity in
+ * plancat.c
*
- * Returns the selectivity of an operator, given the join clause
- * information.
+ * Returns the selectivity of an operator, given the join clause
+ * information.
*
* XXX The assumption in the selectivity procedures is that if the
- * relation OIDs or attribute numbers are -1, then the clause
- * isn't of the form (op var var).
+ * relation OIDs or attribute numbers are -1, then the clause
+ * isn't of the form (op var var).
*/
Cost
-join_selectivity (Oid functionObjectId,
- Oid operatorObjectId,
- Oid relationObjectId1,
- AttrNumber attributeNumber1,
- Oid relationObjectId2,
- AttrNumber attributeNumber2)
+join_selectivity(Oid functionObjectId,
+ Oid operatorObjectId,
+ Oid relationObjectId1,
+ AttrNumber attributeNumber1,
+ Oid relationObjectId2,
+ AttrNumber attributeNumber2)
{
- float64 result;
-
- result = (float64) fmgr(functionObjectId,
- (char *) operatorObjectId,
- (char *) relationObjectId1,
- (char *) (int)attributeNumber1,
- (char *) relationObjectId2,
- (char *) (int)attributeNumber2,
- NULL);
- if (!PointerIsValid(result))
- elog(WARN, "JoinClauseSelectivity: bad pointer");
-
- if (*result < 0.0 || *result > 1.0)
- elog(WARN, "JoinClauseSelectivity: bad value %lf",
- *result);
-
- return((Cost)*result);
+ float64 result;
+
+ result = (float64) fmgr(functionObjectId,
+ (char *) operatorObjectId,
+ (char *) relationObjectId1,
+ (char *) (int) attributeNumber1,
+ (char *) relationObjectId2,
+ (char *) (int) attributeNumber2,
+ NULL);
+ if (!PointerIsValid(result))
+ elog(WARN, "JoinClauseSelectivity: bad pointer");
+
+ if (*result < 0.0 || *result > 1.0)
+ elog(WARN, "JoinClauseSelectivity: bad value %lf",
+ *result);
+
+ return ((Cost) * result);
}
/*
@@ -384,33 +403,34 @@ join_selectivity (Oid functionObjectId,
* Returns a LISP list containing the OIDs of all relations which
* inherits from the relation with OID 'inhparent'.
*/
-List *
+List *
find_inheritance_children(Oid inhparent)
{
- static ScanKeyData key[1] = {
- { 0, Anum_pg_inherits_inhparent, F_OIDEQ }
- };
-
- HeapTuple inheritsTuple;
- Relation relation;
- HeapScanDesc scan;
- List *list = NIL;
- Oid inhrelid;
-
- fmgr_info(F_OIDEQ, &key[0].sk_func, &key[0].sk_nargs);
-
- key[0].sk_argument = ObjectIdGetDatum((Oid)inhparent);
- relation = heap_openr(InheritsRelationName);
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
- while (HeapTupleIsValid(inheritsTuple =
- heap_getnext(scan, 0,
- (Buffer *) NULL))) {
- inhrelid = ((InheritsTupleForm)GETSTRUCT(inheritsTuple))->inhrel;
- list = lappendi(list, inhrelid);
- }
- heap_endscan(scan);
- heap_close(relation);
- return(list);
+ static ScanKeyData key[1] = {
+ {0, Anum_pg_inherits_inhparent, F_OIDEQ}
+ };
+
+ HeapTuple inheritsTuple;
+ Relation relation;
+ HeapScanDesc scan;
+ List *list = NIL;
+ Oid inhrelid;
+
+ fmgr_info(F_OIDEQ, &key[0].sk_func, &key[0].sk_nargs);
+
+ key[0].sk_argument = ObjectIdGetDatum((Oid) inhparent);
+ relation = heap_openr(InheritsRelationName);
+ scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
+ while (HeapTupleIsValid(inheritsTuple =
+ heap_getnext(scan, 0,
+ (Buffer *) NULL)))
+ {
+ inhrelid = ((InheritsTupleForm) GETSTRUCT(inheritsTuple))->inhrel;
+ list = lappendi(list, inhrelid);
+ }
+ heap_endscan(scan);
+ heap_close(relation);
+ return (list);
}
/*
@@ -419,39 +439,40 @@ find_inheritance_children(Oid inhparent)
* Returns a LISP list containing the OIDs of all relations which are
* base relations of the relation with OID 'verrelid'.
*/
-List *
+List *
VersionGetParents(Oid verrelid)
{
- static ScanKeyData key[1] = {
- { 0, Anum_pg_version_verrelid, F_OIDEQ }
- };
-
- HeapTuple versionTuple;
- Relation relation;
- HeapScanDesc scan;
- Oid verbaseid;
- List *list= NIL;
-
- fmgr_info(F_OIDEQ, &key[0].sk_func, &key[0].sk_nargs);
- relation = heap_openr(VersionRelationName);
- key[0].sk_argument = ObjectIdGetDatum(verrelid);
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
- for (;;) {
- versionTuple = heap_getnext(scan, 0,
- (Buffer *) NULL);
- if (!HeapTupleIsValid(versionTuple))
- break;
- verbaseid = ((VersionTupleForm)
- GETSTRUCT(versionTuple))->verbaseid;
-
- list = lconsi(verbaseid, list);
-
- key[0].sk_argument = ObjectIdGetDatum(verbaseid);
- heap_rescan(scan, 0, key);
- }
- heap_endscan(scan);
- heap_close(relation);
- return(list);
+ static ScanKeyData key[1] = {
+ {0, Anum_pg_version_verrelid, F_OIDEQ}
+ };
+
+ HeapTuple versionTuple;
+ Relation relation;
+ HeapScanDesc scan;
+ Oid verbaseid;
+ List *list = NIL;
+
+ fmgr_info(F_OIDEQ, &key[0].sk_func, &key[0].sk_nargs);
+ relation = heap_openr(VersionRelationName);
+ key[0].sk_argument = ObjectIdGetDatum(verrelid);
+ scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
+ for (;;)
+ {
+ versionTuple = heap_getnext(scan, 0,
+ (Buffer *) NULL);
+ if (!HeapTupleIsValid(versionTuple))
+ break;
+ verbaseid = ((VersionTupleForm)
+ GETSTRUCT(versionTuple))->verbaseid;
+
+ list = lconsi(verbaseid, list);
+
+ key[0].sk_argument = ObjectIdGetDatum(verbaseid);
+ heap_rescan(scan, 0, key);
+ }
+ heap_endscan(scan);
+ heap_close(relation);
+ return (list);
}
/*****************************************************************************
@@ -461,14 +482,14 @@ VersionGetParents(Oid verrelid)
/*
* IdexSelectivity--
*
- * Retrieves the 'amopnpages' and 'amopselect' parameters for each
- * AM operator when a given index (specified by 'indexrelid') is used.
- * These two parameters are returned by copying them to into an array of
- * floats.
+ * Retrieves the 'amopnpages' and 'amopselect' parameters for each
+ * AM operator when a given index (specified by 'indexrelid') is used.
+ * These two parameters are returned by copying them to into an array of
+ * floats.
*
- * Assumption: the attribute numbers and operator ObjectIds are in order
- * WRT to each other (otherwise, you have no way of knowing which
- * AM operator class or attribute number corresponds to which operator.
+ * Assumption: the attribute numbers and operator ObjectIds are in order
+ * WRT to each other (otherwise, you have no way of knowing which
+ * AM operator class or attribute number corresponds to which operator.
*
* 'varAttributeNumbers' contains attribute numbers for variables
* 'constValues' contains the constant values
@@ -481,144 +502,154 @@ VersionGetParents(Oid verrelid)
*/
static void
IndexSelectivity(Oid indexrelid,
- Oid indrelid,
- int32 nIndexKeys,
- Oid AccessMethodOperatorClasses[], /* XXX not used? */
- Oid operatorObjectIds[],
- int32 varAttributeNumbers[],
- char *constValues[],
- int32 constFlags[],
- float *idxPages,
- float *idxSelec)
+ Oid indrelid,
+ int32 nIndexKeys,
+ Oid AccessMethodOperatorClasses[], /* XXX not used? */
+ Oid operatorObjectIds[],
+ int32 varAttributeNumbers[],
+ char *constValues[],
+ int32 constFlags[],
+ float *idxPages,
+ float *idxSelec)
{
- register i, n;
- HeapTuple indexTuple, amopTuple, indRel;
- IndexTupleForm index;
- Form_pg_amop amop;
- Oid indclass;
- float64data npages, select;
- float64 amopnpages, amopselect;
- Oid relam;
- bool nphack = false;
- float64data fattr_select = 1.0;
-
- indRel = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexrelid),
- 0,0,0);
- if (!HeapTupleIsValid(indRel))
- elog(WARN, "IndexSelectivity: index %d not found",
- indexrelid);
- relam = ((Form_pg_class)GETSTRUCT(indRel))->relam;
-
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexrelid),
- 0,0,0);
- if (!HeapTupleIsValid(indexTuple))
- elog(WARN, "IndexSelectivity: index %d not found",
- indexrelid);
- index = (IndexTupleForm)GETSTRUCT(indexTuple);
-
- /*
- * Hack for non-functional btree npages estimation:
- * npages = index_pages * selectivity_of_1st_attr_clause(s)
- * - vadim 04/24/97
- */
- if ( relam == BTREE_AM_OID &&
- varAttributeNumbers[0] != InvalidAttrNumber )
- nphack = true;
-
- npages = 0.0;
- select = 1.0;
- for (n = 0; n < nIndexKeys; ++n) {
- /*
- * Find the AM class for this key.
- *
- * If the first attribute number is invalid then we have a
- * functional index, and AM class is the first one defined
- * since functional indices have exactly one key.
+ register i,
+ n;
+ HeapTuple indexTuple,
+ amopTuple,
+ indRel;
+ IndexTupleForm index;
+ Form_pg_amop amop;
+ Oid indclass;
+ float64data npages,
+ select;
+ float64 amopnpages,
+ amopselect;
+ Oid relam;
+ bool nphack = false;
+ float64data fattr_select = 1.0;
+
+ indRel = SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(indexrelid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(indRel))
+ elog(WARN, "IndexSelectivity: index %d not found",
+ indexrelid);
+ relam = ((Form_pg_class) GETSTRUCT(indRel))->relam;
+
+ indexTuple = SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(indexrelid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(indexTuple))
+ elog(WARN, "IndexSelectivity: index %d not found",
+ indexrelid);
+ index = (IndexTupleForm) GETSTRUCT(indexTuple);
+
+ /*
+ * Hack for non-functional btree npages estimation: npages =
+ * index_pages * selectivity_of_1st_attr_clause(s) - vadim 04/24/97
*/
- indclass = (varAttributeNumbers[0] == InvalidAttrNumber) ?
- index->indclass[0] : InvalidOid;
- i = 0;
- while ((i < nIndexKeys) && (indclass == InvalidOid)) {
- if (varAttributeNumbers[n] == index->indkey[i]) {
- indclass = index->indclass[i];
- break;
- }
- i++;
- }
- if (!OidIsValid(indclass)) {
- /*
- * Presumably this means that we are using a functional
- * index clause and so had no variable to match to
- * the index key ... if not we are in trouble.
- */
- elog(NOTICE, "IndexSelectivity: no key %d in index %d",
- varAttributeNumbers[n], indexrelid);
- continue;
- }
+ if (relam == BTREE_AM_OID &&
+ varAttributeNumbers[0] != InvalidAttrNumber)
+ nphack = true;
- amopTuple = SearchSysCacheTuple(AMOPOPID,
- ObjectIdGetDatum(indclass),
- ObjectIdGetDatum(operatorObjectIds[n]),
- ObjectIdGetDatum(relam),
- 0);
- if (!HeapTupleIsValid(amopTuple))
- elog(WARN, "IndexSelectivity: no amop %d %d",
- indclass, operatorObjectIds[n]);
- amop = (Form_pg_amop)GETSTRUCT(amopTuple);
-
- if ( !nphack )
+ npages = 0.0;
+ select = 1.0;
+ for (n = 0; n < nIndexKeys; ++n)
{
- amopnpages = (float64) fmgr(amop->amopnpages,
- (char *) operatorObjectIds[n],
- (char *) indrelid,
- (char *) varAttributeNumbers[n],
- (char *) constValues[n],
- (char *) constFlags[n],
- (char *) nIndexKeys,
- (char *) indexrelid);
-#if 0
-/*
+
+ /*
+ * Find the AM class for this key.
+ *
+ * If the first attribute number is invalid then we have a functional
+ * index, and AM class is the first one defined since functional
+ * indices have exactly one key.
+ */
+ indclass = (varAttributeNumbers[0] == InvalidAttrNumber) ?
+ index->indclass[0] : InvalidOid;
+ i = 0;
+ while ((i < nIndexKeys) && (indclass == InvalidOid))
+ {
+ if (varAttributeNumbers[n] == index->indkey[i])
+ {
+ indclass = index->indclass[i];
+ break;
+ }
+ i++;
+ }
+ if (!OidIsValid(indclass))
+ {
+
+ /*
+ * Presumably this means that we are using a functional index
+ * clause and so had no variable to match to the index key ...
+ * if not we are in trouble.
+ */
+ elog(NOTICE, "IndexSelectivity: no key %d in index %d",
+ varAttributeNumbers[n], indexrelid);
+ continue;
+ }
+
+ amopTuple = SearchSysCacheTuple(AMOPOPID,
+ ObjectIdGetDatum(indclass),
+ ObjectIdGetDatum(operatorObjectIds[n]),
+ ObjectIdGetDatum(relam),
+ 0);
+ if (!HeapTupleIsValid(amopTuple))
+ elog(WARN, "IndexSelectivity: no amop %d %d",
+ indclass, operatorObjectIds[n]);
+ amop = (Form_pg_amop) GETSTRUCT(amopTuple);
+
+ if (!nphack)
+ {
+ amopnpages = (float64) fmgr(amop->amopnpages,
+ (char *) operatorObjectIds[n],
+ (char *) indrelid,
+ (char *) varAttributeNumbers[n],
+ (char *) constValues[n],
+ (char *) constFlags[n],
+ (char *) nIndexKeys,
+ (char *) indexrelid);
+#if 0
+/*
* So cool guys! Npages for x > 10 and x < 20 is twice as
* npages for x > 10! - vadim 04/09/97
*/
- npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0;
- if ((i = npages) < npages) /* ceil(npages)? */
- npages += 1.0;
+ npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0;
+ if ((i = npages) < npages) /* ceil(npages)? */
+ npages += 1.0;
#endif
- npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0;
+ npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0;
+ }
+
+ amopselect = (float64) fmgr(amop->amopselect,
+ (char *) operatorObjectIds[n],
+ (char *) indrelid,
+ (char *) varAttributeNumbers[n],
+ (char *) constValues[n],
+ (char *) constFlags[n],
+ (char *) nIndexKeys,
+ (char *) indexrelid);
+
+ if (nphack && varAttributeNumbers[n] == index->indkey[0])
+ fattr_select *= PointerIsValid(amopselect) ? *amopselect : 1.0;
+
+ select *= PointerIsValid(amopselect) ? *amopselect : 1.0;
}
-
- amopselect = (float64) fmgr(amop->amopselect,
- (char *) operatorObjectIds[n],
- (char *) indrelid,
- (char *) varAttributeNumbers[n],
- (char *) constValues[n],
- (char *) constFlags[n],
- (char *) nIndexKeys,
- (char *) indexrelid);
-
- if ( nphack && varAttributeNumbers[n] == index->indkey[0] )
- fattr_select *= PointerIsValid(amopselect) ? *amopselect : 1.0;
-
- select *= PointerIsValid(amopselect) ? *amopselect : 1.0;
- }
- /*
- * Estimation of npages below is hack of course, but it's
- * better than it was before. - vadim 04/09/97
- */
- if ( nphack )
- {
- npages = fattr_select * ((Form_pg_class)GETSTRUCT(indRel))->relpages;
- *idxPages = ceil ((double)npages);
- }
- else
- {
- if ( nIndexKeys > 1 )
- npages = npages / (1.0 + nIndexKeys);
- *idxPages = ceil ((double)(npages/nIndexKeys));
- }
- *idxSelec = select;
-}
+ /*
+ * Estimation of npages below is hack of course, but it's better than
+ * it was before. - vadim 04/09/97
+ */
+ if (nphack)
+ {
+ npages = fattr_select * ((Form_pg_class) GETSTRUCT(indRel))->relpages;
+ *idxPages = ceil((double) npages);
+ }
+ else
+ {
+ if (nIndexKeys > 1)
+ npages = npages / (1.0 + nIndexKeys);
+ *idxPages = ceil((double) (npages / nIndexKeys));
+ }
+ *idxSelec = select;
+}
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 351fb182107..229dff98092 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* relnode.c--
- * Relation manipulation routines
+ * Relation manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.1.1.1 1996/07/09 06:21:39 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.2 1997/09/07 04:44:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,108 +16,118 @@
#include "nodes/relation.h"
#include "optimizer/internal.h"
-#include "optimizer/pathnode.h" /* where the decls go */
+#include "optimizer/pathnode.h" /* where the decls go */
#include "optimizer/plancat.h"
-/*
+/*
* get_base_rel--
- * Returns relation entry corresponding to 'relid', creating a new one if
- * necessary. This is for base relations.
- *
+ * Returns relation entry corresponding to 'relid', creating a new one if
+ * necessary. This is for base relations.
+ *
*/
-Rel *get_base_rel(Query* root, int relid)
+Rel *
+get_base_rel(Query * root, int relid)
{
- List *relids;
- Rel *rel;
+ List *relids;
+ Rel *rel;
+
+ relids = lconsi(relid, NIL);
+ rel = rel_member(relids, root->base_relation_list_);
+ if (rel == NULL)
+ {
+ rel = makeNode(Rel);
+ rel->relids = relids;
+ rel->indexed = false;
+ rel->pages = 0;
+ rel->tuples = 0;
+ rel->width = 0;
+ rel->targetlist = NIL;
+ rel->pathlist = NIL;
+ rel->unorderedpath = (Path *) NULL;
+ rel->cheapestpath = (Path *) NULL;
+ rel->pruneable = true;
+ rel->classlist = NULL;
+ rel->ordering = NULL;
+ rel->relam = InvalidOid;
+ rel->clauseinfo = NIL;
+ rel->joininfo = NIL;
+ rel->innerjoin = NIL;
+ rel->superrels = NIL;
+
+ root->base_relation_list_ = lcons(rel,
+ root->base_relation_list_);
+
+ /*
+ * ??? the old lispy C code (get_rel) do a listp(relid) here but
+ * that can never happen since we already established relid is not
+ * a list. -ay 10/94
+ */
+ if (relid < 0)
+ {
+
+ /*
+ * If the relation is a materialized relation, assume
+ * constants for sizes.
+ */
+ rel->pages = _TEMP_RELATION_PAGES_;
+ rel->tuples = _TEMP_RELATION_TUPLES_;
+
+ }
+ else
+ {
+ bool hasindex;
+ int pages,
+ tuples;
- relids = lconsi(relid, NIL);
- rel = rel_member(relids, root->base_relation_list_);
- if (rel==NULL) {
- rel = makeNode(Rel);
- rel->relids = relids;
- rel->indexed = false;
- rel->pages = 0;
- rel->tuples = 0;
- rel->width = 0;
- rel->targetlist = NIL;
- rel->pathlist = NIL;
- rel->unorderedpath = (Path *)NULL;
- rel->cheapestpath = (Path *)NULL;
- rel->pruneable = true;
- rel->classlist = NULL;
- rel->ordering = NULL;
- rel->relam = InvalidOid;
- rel->clauseinfo = NIL;
- rel->joininfo = NIL;
- rel->innerjoin = NIL;
- rel->superrels = NIL;
-
- root->base_relation_list_ = lcons(rel,
- root->base_relation_list_);
-
- /*
- * ??? the old lispy C code (get_rel) do a listp(relid) here but
- * that can never happen since we already established relid is not
- * a list. -ay 10/94
- */
- if(relid < 0) {
- /*
- * If the relation is a materialized relation, assume
- * constants for sizes.
- */
- rel->pages = _TEMP_RELATION_PAGES_;
- rel->tuples = _TEMP_RELATION_TUPLES_;
-
- } else {
- bool hasindex;
- int pages, tuples;
-
- /*
- * Otherwise, retrieve relation characteristics from the
- * system catalogs.
- */
- relation_info(root, relid, &hasindex, &pages, &tuples);
- rel->indexed = hasindex;
- rel->pages = pages;
- rel->tuples = tuples;
- }
- }
- return rel;
+ /*
+ * Otherwise, retrieve relation characteristics from the
+ * system catalogs.
+ */
+ relation_info(root, relid, &hasindex, &pages, &tuples);
+ rel->indexed = hasindex;
+ rel->pages = pages;
+ rel->tuples = tuples;
+ }
+ }
+ return rel;
}
-/*
+/*
* get_join_rel--
- * Returns relation entry corresponding to 'relid' (a list of relids),
- * creating a new one if necessary. This is for join relations.
- *
+ * Returns relation entry corresponding to 'relid' (a list of relids),
+ * creating a new one if necessary. This is for join relations.
+ *
*/
-Rel *get_join_rel(Query *root, List *relid)
+Rel *
+get_join_rel(Query * root, List * relid)
{
- return rel_member(relid, root->join_relation_list_);
+ return rel_member(relid, root->join_relation_list_);
}
-/*
+/*
* rel-member--
- * Determines whether a relation of id 'relid' is contained within a list
- * 'rels'.
- *
+ * Determines whether a relation of id 'relid' is contained within a list
+ * 'rels'.
+ *
* Returns the corresponding entry in 'rels' if it is there.
- *
+ *
*/
-Rel *
-rel_member(List *relid, List *rels)
+Rel *
+rel_member(List * relid, List * rels)
{
- List *temp = NIL;
- List *temprelid = NIL;
-
- if (relid!=NIL && rels!=NIL) {
- foreach(temp,rels) {
- temprelid = ((Rel*)lfirst(temp))->relids;
- if(same(temprelid, relid))
- return((Rel*)(lfirst(temp)));
+ List *temp = NIL;
+ List *temprelid = NIL;
+
+ if (relid != NIL && rels != NIL)
+ {
+ foreach(temp, rels)
+ {
+ temprelid = ((Rel *) lfirst(temp))->relids;
+ if (same(temprelid, relid))
+ return ((Rel *) (lfirst(temp)));
+ }
}
- }
- return(NULL);
+ return (NULL);
}
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index c0f11ff3293..7e8563d31ab 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* tlist.c--
- * Target list manipulation routines
+ * Target list manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.4 1997/08/20 14:53:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.5 1997/09/07 04:44:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,498 +28,538 @@
#include "nodes/makefuncs.h"
#include "parser/catalog_utils.h"
-static Node *flatten_tlistentry(Node *tlistentry, List *flat_tlist);
+static Node *flatten_tlistentry(Node * tlistentry, List * flat_tlist);
/*****************************************************************************
- * ---------- RELATION node target list routines ----------
+ * ---------- RELATION node target list routines ----------
*****************************************************************************/
-/*
+/*
* tlistentry-member--
- *
+ *
* RETURNS: the leftmost member of sequence "targetlist" that satisfies
- * the predicate "var_equal"
+ * the predicate "var_equal"
* MODIFIES: nothing
* REQUIRES: test = function which can operate on a lispval union
- * var = valid var-node
- * targetlist = valid sequence
+ * var = valid var-node
+ * targetlist = valid sequence
*/
-TargetEntry *
-tlistentry_member(Var *var, List *targetlist)
+TargetEntry *
+tlistentry_member(Var * var, List * targetlist)
{
- if (var) {
- List *temp = NIL;
-
- foreach (temp,targetlist) {
- if (var_equal(var,
- get_expr(lfirst(temp))))
- return((TargetEntry*)lfirst(temp));
+ if (var)
+ {
+ List *temp = NIL;
+
+ foreach(temp, targetlist)
+ {
+ if (var_equal(var,
+ get_expr(lfirst(temp))))
+ return ((TargetEntry *) lfirst(temp));
+ }
}
- }
- return (NULL);
+ return (NULL);
}
-/*
+/*
* matching_tlvar--
- *
+ *
* RETURNS: var node in a target list which is var_equal to 'var',
- * if one exists.
+ * if one exists.
* REQUIRES: "test" operates on lispval unions,
- *
+ *
*/
-Expr *
-matching_tlvar(Var *var, List *targetlist)
+Expr *
+matching_tlvar(Var * var, List * targetlist)
{
- TargetEntry *tlentry;
+ TargetEntry *tlentry;
- tlentry = tlistentry_member(var,targetlist);
- if (tlentry)
- return((Expr*)get_expr (tlentry) );
+ tlentry = tlistentry_member(var, targetlist);
+ if (tlentry)
+ return ((Expr *) get_expr(tlentry));
- return((Expr*) NULL);
+ return ((Expr *) NULL);
}
-/*
+/*
* add_tl_element--
- * Creates a targetlist entry corresponding to the supplied var node
+ * Creates a targetlist entry corresponding to the supplied var node
*
* 'var' and adds the new targetlist entry to the targetlist field of
- * 'rel'
- *
+ * 'rel'
+ *
* RETURNS: nothing
* MODIFIES: vartype and varid fields of leftmost varnode that matches
- * argument "var" (sometimes).
+ * argument "var" (sometimes).
* CREATES: new var-node iff no matching var-node exists in targetlist
*/
void
-add_tl_element(Rel *rel, Var *var)
+add_tl_element(Rel * rel, Var * var)
{
- Expr *oldvar = (Expr *)NULL;
-
- oldvar = matching_tlvar(var, rel->targetlist);
-
- /*
- * If 'var' is not already in 'rel's target list, add a new node.
- */
- if (oldvar==NULL) {
- List *tlist = rel->targetlist;
- Var *newvar = makeVar(var->varno,
- var->varattno,
- var->vartype,
- var->varno,
- var->varoattno);
-
- rel->targetlist =
- lappend (tlist,
- create_tl_element(newvar,
- length(tlist) + 1));
-
- }
+ Expr *oldvar = (Expr *) NULL;
+
+ oldvar = matching_tlvar(var, rel->targetlist);
+
+ /*
+ * If 'var' is not already in 'rel's target list, add a new node.
+ */
+ if (oldvar == NULL)
+ {
+ List *tlist = rel->targetlist;
+ Var *newvar = makeVar(var->varno,
+ var->varattno,
+ var->vartype,
+ var->varno,
+ var->varoattno);
+
+ rel->targetlist =
+ lappend(tlist,
+ create_tl_element(newvar,
+ length(tlist) + 1));
+
+ }
}
-/*
+/*
* create_tl_element--
- * Creates a target list entry node and its associated (resdom var) pair
- * with its resdom number equal to 'resdomno' and the joinlist field set
- * to 'joinlist'.
- *
+ * Creates a target list entry node and its associated (resdom var) pair
+ * with its resdom number equal to 'resdomno' and the joinlist field set
+ * to 'joinlist'.
+ *
* RETURNS: newly created tlist-entry
* CREATES: new targetlist entry (always).
*/
-TargetEntry*
-create_tl_element(Var *var, int resdomno)
+TargetEntry *
+create_tl_element(Var * var, int resdomno)
{
- TargetEntry *tlelement= makeNode(TargetEntry);
-
- tlelement->resdom =
- makeResdom(resdomno,
- var->vartype,
- get_typlen(var->vartype),
- NULL,
- (Index)0,
- (Oid)0,
- 0);
- tlelement->expr = (Node*)var;
-
- return(tlelement);
+ TargetEntry *tlelement = makeNode(TargetEntry);
+
+ tlelement->resdom =
+ makeResdom(resdomno,
+ var->vartype,
+ get_typlen(var->vartype),
+ NULL,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ tlelement->expr = (Node *) var;
+
+ return (tlelement);
}
-/*
+/*
* get-actual-tlist--
- * Returns the targetlist elements from a relation tlist.
- *
+ * Returns the targetlist elements from a relation tlist.
+ *
*/
-List *
-get_actual_tlist(List *tlist)
+List *
+get_actual_tlist(List * tlist)
{
- /*
- * this function is not making sense. - ay 10/94
- */
-#if 0
- List *element = NIL;
- List *result = NIL;
-
- if (tlist==NULL) {
- elog(DEBUG,"calling get_actual_tlist with empty tlist");
- return(NIL);
- }
- /* XXX - it is unclear to me what exactly get_entry
- should be doing, as it is unclear to me the exact
- relationship between "TL" "TLE" and joinlists */
-
- foreach(element,tlist)
- result = lappend(result, lfirst((List*)lfirst(element)));
-
- return(result);
+
+ /*
+ * this function is not making sense. - ay 10/94
+ */
+#if 0
+ List *element = NIL;
+ List *result = NIL;
+
+ if (tlist == NULL)
+ {
+ elog(DEBUG, "calling get_actual_tlist with empty tlist");
+ return (NIL);
+ }
+
+ /*
+ * XXX - it is unclear to me what exactly get_entry should be doing,
+ * as it is unclear to me the exact relationship between "TL" "TLE"
+ * and joinlists
+ */
+
+ foreach(element, tlist)
+ result = lappend(result, lfirst((List *) lfirst(element)));
+
+ return (result);
#endif
- return tlist;
+ return tlist;
}
/*****************************************************************************
- * ---------- GENERAL target list routines ----------
+ * ---------- GENERAL target list routines ----------
*****************************************************************************/
-/*
+/*
* tlist-member--
- * Determines whether a var node is already contained within a
- * target list.
- *
+ * Determines whether a var node is already contained within a
+ * target list.
+ *
* 'var' is the var node
* 'tlist' is the target list
* 'dots' is t if we must match dotfields to determine uniqueness
- *
+ *
* Returns the resdom entry of the matching var node.
- *
+ *
*/
-Resdom *
-tlist_member(Var *var, List *tlist)
+Resdom *
+tlist_member(Var * var, List * tlist)
{
- List *i = NIL;
- TargetEntry *temp_tle = (TargetEntry *)NULL;
- TargetEntry *tl_elt = (TargetEntry *)NULL;
-
- if (var) {
- foreach (i,tlist) {
- temp_tle = (TargetEntry *)lfirst(i);
- if (var_equal(var, get_expr(temp_tle))) {
- tl_elt = temp_tle;
- break;
- }
+ List *i = NIL;
+ TargetEntry *temp_tle = (TargetEntry *) NULL;
+ TargetEntry *tl_elt = (TargetEntry *) NULL;
+
+ if (var)
+ {
+ foreach(i, tlist)
+ {
+ temp_tle = (TargetEntry *) lfirst(i);
+ if (var_equal(var, get_expr(temp_tle)))
+ {
+ tl_elt = temp_tle;
+ break;
+ }
+ }
+
+ if (tl_elt != NULL)
+ return (tl_elt->resdom);
+ else
+ return ((Resdom *) NULL);
}
-
- if (tl_elt != NULL)
- return(tl_elt->resdom);
- else
- return((Resdom*)NULL);
- }
- return ((Resdom*)NULL);
+ return ((Resdom *) NULL);
}
/*
- * Routine to get the resdom out of a targetlist.
+ * Routine to get the resdom out of a targetlist.
*/
-Resdom *
-tlist_resdom(List *tlist, Resdom *resnode)
+Resdom *
+tlist_resdom(List * tlist, Resdom * resnode)
{
- Resdom *resdom = (Resdom*)NULL;
- List *i = NIL;
- TargetEntry *temp_tle = (TargetEntry *)NULL;
-
- foreach(i,tlist) {
- temp_tle = (TargetEntry *)lfirst(i);
- resdom = temp_tle->resdom;
- /* Since resnos are supposed to be unique */
- if (resnode->resno == resdom->resno)
- return(resdom);
- }
- return((Resdom*)NULL);
+ Resdom *resdom = (Resdom *) NULL;
+ List *i = NIL;
+ TargetEntry *temp_tle = (TargetEntry *) NULL;
+
+ foreach(i, tlist)
+ {
+ temp_tle = (TargetEntry *) lfirst(i);
+ resdom = temp_tle->resdom;
+ /* Since resnos are supposed to be unique */
+ if (resnode->resno == resdom->resno)
+ return (resdom);
+ }
+ return ((Resdom *) NULL);
}
-/*
+/*
* match_varid--
- * Searches a target list for an entry with some desired varid.
- *
+ * Searches a target list for an entry with some desired varid.
+ *
* 'varid' is the desired id
* 'tlist' is the target list that is searched
- *
+ *
* Returns the target list entry (resdom var) of the matching var.
*
* Now checks to make sure array references (in addition to range
* table indices) are identical - retrieve (a.b[1],a.b[2]) should
* not be turned into retrieve (a.b[1],a.b[1]).
- *
+ *
* [what used to be varid is now broken up into two fields varnoold and
- * varoattno. Also, nested attnos are long gone. - ay 2/95]
+ * varoattno. Also, nested attnos are long gone. - ay 2/95]
*/
-TargetEntry *
-match_varid(Var *test_var, List *tlist)
+TargetEntry *
+match_varid(Var * test_var, List * tlist)
{
- List *tl;
- Oid type_var;
+ List *tl;
+ Oid type_var;
- type_var = (Oid) test_var->vartype;
+ type_var = (Oid) test_var->vartype;
- foreach (tl, tlist) {
- TargetEntry *entry;
- Var *tlvar;
+ foreach(tl, tlist)
+ {
+ TargetEntry *entry;
+ Var *tlvar;
- entry = lfirst(tl);
- tlvar = get_expr(entry);
-
- if ( !IsA (tlvar, Var) )
- continue;
+ entry = lfirst(tl);
+ tlvar = get_expr(entry);
- /*
- * we test the original varno (instead of varno which might
- * be changed to INNER/OUTER.
- */
- if (tlvar->varnoold == test_var->varnoold &&
- tlvar->varoattno == test_var->varoattno) {
+ if (!IsA(tlvar, Var))
+ continue;
+
+ /*
+ * we test the original varno (instead of varno which might be
+ * changed to INNER/OUTER.
+ */
+ if (tlvar->varnoold == test_var->varnoold &&
+ tlvar->varoattno == test_var->varoattno)
+ {
- if (tlvar->vartype == type_var)
- return(entry);
+ if (tlvar->vartype == type_var)
+ return (entry);
+ }
}
- }
- return (NULL);
+ return (NULL);
}
-/*
+/*
* new-unsorted-tlist--
- * Creates a copy of a target list by creating new resdom nodes
- * without sort information.
- *
+ * Creates a copy of a target list by creating new resdom nodes
+ * without sort information.
+ *
* 'targetlist' is the target list to be copied.
- *
+ *
* Returns the resulting target list.
- *
+ *
*/
-List *
-new_unsorted_tlist(List *targetlist)
+List *
+new_unsorted_tlist(List * targetlist)
{
- List *new_targetlist = (List*)copyObject ((Node*)targetlist);
- List *x = NIL;
-
- foreach (x, new_targetlist) {
- TargetEntry *tle = (TargetEntry *)lfirst(x);
- tle->resdom->reskey = 0;
- tle->resdom->reskeyop = (Oid)0;
- }
- return(new_targetlist);
+ List *new_targetlist = (List *) copyObject((Node *) targetlist);
+ List *x = NIL;
+
+ foreach(x, new_targetlist)
+ {
+ TargetEntry *tle = (TargetEntry *) lfirst(x);
+
+ tle->resdom->reskey = 0;
+ tle->resdom->reskeyop = (Oid) 0;
+ }
+ return (new_targetlist);
}
-/*
+/*
* copy-vars--
- * Replaces the var nodes in the first target list with those from
- * the second target list. The two target lists are assumed to be
- * identical except their actual resdoms and vars are different.
- *
+ * Replaces the var nodes in the first target list with those from
+ * the second target list. The two target lists are assumed to be
+ * identical except their actual resdoms and vars are different.
+ *
* 'target' is the target list to be replaced
* 'source' is the target list to be copied
- *
+ *
* Returns a new target list.
- *
+ *
*/
-List *
-copy_vars(List *target, List *source)
+List *
+copy_vars(List * target, List * source)
{
- List *result = NIL;
- List *src = NIL;
- List *dest = NIL;
-
- for ( src = source, dest = target; src != NIL &&
- dest != NIL; src = lnext(src), dest = lnext(dest)) {
- TargetEntry *temp = MakeTLE(((TargetEntry *)lfirst(dest))->resdom,
- (Node*)get_expr(lfirst(src)));
- result = lappend(result,temp);
- }
- return(result);
+ List *result = NIL;
+ List *src = NIL;
+ List *dest = NIL;
+
+ for (src = source, dest = target; src != NIL &&
+ dest != NIL; src = lnext(src), dest = lnext(dest))
+ {
+ TargetEntry *temp = MakeTLE(((TargetEntry *) lfirst(dest))->resdom,
+ (Node *) get_expr(lfirst(src)));
+
+ result = lappend(result, temp);
+ }
+ return (result);
}
-/*
+/*
* flatten-tlist--
- * Create a target list that only contains unique variables.
+ * Create a target list that only contains unique variables.
*
*
* 'tlist' is the current target list
- *
+ *
* Returns the "flattened" new target list.
- *
+ *
*/
-List *
-flatten_tlist(List *tlist)
+List *
+flatten_tlist(List * tlist)
{
- int last_resdomno = 1;
- List *new_tlist = NIL;
- List *tlist_vars = NIL;
- List *temp;
-
- foreach (temp, tlist) {
- TargetEntry *temp_entry = NULL;
- List *vars;
-
- temp_entry = lfirst(temp);
- vars = pull_var_clause((Node*)get_expr(temp_entry));
- if(vars != NULL) {
- tlist_vars = nconc(tlist_vars, vars);
+ int last_resdomno = 1;
+ List *new_tlist = NIL;
+ List *tlist_vars = NIL;
+ List *temp;
+
+ foreach(temp, tlist)
+ {
+ TargetEntry *temp_entry = NULL;
+ List *vars;
+
+ temp_entry = lfirst(temp);
+ vars = pull_var_clause((Node *) get_expr(temp_entry));
+ if (vars != NULL)
+ {
+ tlist_vars = nconc(tlist_vars, vars);
+ }
}
- }
-
- foreach (temp, tlist_vars) {
- Var *var = lfirst(temp);
- if (!(tlist_member(var, new_tlist))) {
- Resdom *r;
-
- r = makeResdom(last_resdomno,
- var->vartype,
- get_typlen(var->vartype),
- NULL,
- (Index)0,
- (Oid)0,
- 0);
- last_resdomno++;
- new_tlist = lappend(new_tlist, MakeTLE (r, (Node*)var));
+
+ foreach(temp, tlist_vars)
+ {
+ Var *var = lfirst(temp);
+
+ if (!(tlist_member(var, new_tlist)))
+ {
+ Resdom *r;
+
+ r = makeResdom(last_resdomno,
+ var->vartype,
+ get_typlen(var->vartype),
+ NULL,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ last_resdomno++;
+ new_tlist = lappend(new_tlist, MakeTLE(r, (Node *) var));
+ }
}
- }
- return new_tlist;
+ return new_tlist;
}
-/*
+/*
* flatten-tlist-vars--
- * Redoes the target list of a query with no nested attributes by
- * replacing vars within computational expressions with vars from
- * the 'flattened' target list of the query.
- *
+ * Redoes the target list of a query with no nested attributes by
+ * replacing vars within computational expressions with vars from
+ * the 'flattened' target list of the query.
+ *
* 'full-tlist' is the actual target list
* 'flat-tlist' is the flattened (var-only) target list
- *
+ *
* Returns the modified actual target list.
- *
+ *
*/
-List *
-flatten_tlist_vars(List *full_tlist, List *flat_tlist)
+List *
+flatten_tlist_vars(List * full_tlist, List * flat_tlist)
{
- List *x = NIL;
- List *result = NIL;
-
- foreach(x,full_tlist) {
- TargetEntry *tle= lfirst(x);
- result =
- lappend(result,
- MakeTLE(tle->resdom,
- flatten_tlistentry((Node*)get_expr(tle),
- flat_tlist)));
- }
-
- return(result);
+ List *x = NIL;
+ List *result = NIL;
+
+ foreach(x, full_tlist)
+ {
+ TargetEntry *tle = lfirst(x);
+
+ result =
+ lappend(result,
+ MakeTLE(tle->resdom,
+ flatten_tlistentry((Node *) get_expr(tle),
+ flat_tlist)));
+ }
+
+ return (result);
}
-/*
+/*
* flatten-tlistentry--
- * Replaces vars within a target list entry with vars from a flattened
- * target list.
- *
+ * Replaces vars within a target list entry with vars from a flattened
+ * target list.
+ *
* 'tlistentry' is the target list entry to be modified
* 'flat-tlist' is the flattened target list
- *
+ *
* Returns the (modified) target_list entry from the target list.
- *
+ *
*/
-static Node *
-flatten_tlistentry(Node *tlistentry, List *flat_tlist)
+static Node *
+flatten_tlistentry(Node * tlistentry, List * flat_tlist)
{
- if (tlistentry==NULL) {
-
- return NULL;
-
- } else if (IsA (tlistentry,Var)) {
-
- return
- ((Node *)get_expr(match_varid((Var*)tlistentry,
- flat_tlist)));
- } else if (IsA (tlistentry,Iter)) {
-
- ((Iter*)tlistentry)->iterexpr =
- flatten_tlistentry((Node*)((Iter*)tlistentry)->iterexpr,
- flat_tlist);
- return tlistentry;
-
- } else if (single_node(tlistentry)) {
-
- return tlistentry;
-
- } else if (is_funcclause (tlistentry)) {
- Expr *expr = (Expr*)tlistentry;
- List *temp_result = NIL;
- List *elt = NIL;
-
- foreach(elt, expr->args)
- temp_result = lappend(temp_result,
- flatten_tlistentry(lfirst(elt),flat_tlist));
-
- return
- ((Node *)make_funcclause((Func*)expr->oper, temp_result));
-
- } else if (IsA(tlistentry,Aggreg)) {
-
- return tlistentry;
-
- } else if (IsA(tlistentry,ArrayRef)) {
- ArrayRef *aref = (ArrayRef *)tlistentry;
- List *temp = NIL;
- List *elt = NIL;
-
- foreach(elt, aref->refupperindexpr)
- temp = lappend(temp, flatten_tlistentry(lfirst(elt), flat_tlist));
- aref->refupperindexpr = temp;
-
- temp = NIL;
- foreach(elt, aref->reflowerindexpr)
- temp = lappend(temp, flatten_tlistentry(lfirst(elt), flat_tlist));
- aref->reflowerindexpr = temp;
-
- aref->refexpr =
- flatten_tlistentry(aref->refexpr, flat_tlist);
-
- aref->refassgnexpr =
- flatten_tlistentry(aref->refassgnexpr, flat_tlist);
-
- return tlistentry;
- } else {
- Expr *expr = (Expr*)tlistentry;
- Var *left =
- (Var*)flatten_tlistentry((Node*)get_leftop(expr),
- flat_tlist);
- Var *right =
- (Var*)flatten_tlistentry((Node*)get_rightop(expr),
- flat_tlist);
-
- return((Node *)
- make_opclause((Oper*)expr->oper, left, right));
- }
+ if (tlistentry == NULL)
+ {
+
+ return NULL;
+
+ }
+ else if (IsA(tlistentry, Var))
+ {
+
+ return
+ ((Node *) get_expr(match_varid((Var *) tlistentry,
+ flat_tlist)));
+ }
+ else if (IsA(tlistentry, Iter))
+ {
+
+ ((Iter *) tlistentry)->iterexpr =
+ flatten_tlistentry((Node *) ((Iter *) tlistentry)->iterexpr,
+ flat_tlist);
+ return tlistentry;
+
+ }
+ else if (single_node(tlistentry))
+ {
+
+ return tlistentry;
+
+ }
+ else if (is_funcclause(tlistentry))
+ {
+ Expr *expr = (Expr *) tlistentry;
+ List *temp_result = NIL;
+ List *elt = NIL;
+
+ foreach(elt, expr->args)
+ temp_result = lappend(temp_result,
+ flatten_tlistentry(lfirst(elt), flat_tlist));
+
+ return
+ ((Node *) make_funcclause((Func *) expr->oper, temp_result));
+
+ }
+ else if (IsA(tlistentry, Aggreg))
+ {
+
+ return tlistentry;
+
+ }
+ else if (IsA(tlistentry, ArrayRef))
+ {
+ ArrayRef *aref = (ArrayRef *) tlistentry;
+ List *temp = NIL;
+ List *elt = NIL;
+
+ foreach(elt, aref->refupperindexpr)
+ temp = lappend(temp, flatten_tlistentry(lfirst(elt), flat_tlist));
+ aref->refupperindexpr = temp;
+
+ temp = NIL;
+ foreach(elt, aref->reflowerindexpr)
+ temp = lappend(temp, flatten_tlistentry(lfirst(elt), flat_tlist));
+ aref->reflowerindexpr = temp;
+
+ aref->refexpr =
+ flatten_tlistentry(aref->refexpr, flat_tlist);
+
+ aref->refassgnexpr =
+ flatten_tlistentry(aref->refassgnexpr, flat_tlist);
+
+ return tlistentry;
+ }
+ else
+ {
+ Expr *expr = (Expr *) tlistentry;
+ Var *left =
+ (Var *) flatten_tlistentry((Node *) get_leftop(expr),
+ flat_tlist);
+ Var *right =
+ (Var *) flatten_tlistentry((Node *) get_rightop(expr),
+ flat_tlist);
+
+ return ((Node *)
+ make_opclause((Oper *) expr->oper, left, right));
+ }
}
-TargetEntry *
-MakeTLE(Resdom *resdom, Node *expr)
+TargetEntry *
+MakeTLE(Resdom * resdom, Node * expr)
{
- TargetEntry *rt = makeNode(TargetEntry);
+ TargetEntry *rt = makeNode(TargetEntry);
- rt->resdom = resdom;
- rt->expr = expr;
- return rt;
+ rt->resdom = resdom;
+ rt->expr = expr;
+ return rt;
}
-Var *
-get_expr(TargetEntry *tle)
+Var *
+get_expr(TargetEntry * tle)
{
- Assert(tle!=NULL);
- Assert(tle->expr!=NULL);
+ Assert(tle != NULL);
+ Assert(tle->expr != NULL);
- return ((Var *)tle->expr);
+ return ((Var *) tle->expr);
}
@@ -529,54 +569,56 @@ get_expr(TargetEntry *tle)
/*
* AddGroupAttrToTlist -
- * append the group attribute to the target list if it's not already
- * in there.
+ * append the group attribute to the target list if it's not already
+ * in there.
*/
#ifdef NOT_USED
void
-AddGroupAttrToTlist(List *tlist, List *grpCl)
+AddGroupAttrToTlist(List * tlist, List * grpCl)
{
- List *gl;
- int last_resdomno = length(tlist) + 1;
-
- foreach (gl, grpCl) {
- GroupClause *gc = (GroupClause*)lfirst(gl);
- Var *var = gc->grpAttr;
-
- if (!(tlist_member(var, tlist))) {
- Resdom *r;
-
- r = makeResdom(last_resdomno,
- var->vartype,
- get_typlen(var->vartype),
- NULL,
- (Index)0,
- (Oid)0,
- 0);
- last_resdomno++;
- tlist = lappend(tlist, MakeTLE(r, (Node*)var));
+ List *gl;
+ int last_resdomno = length(tlist) + 1;
+
+ foreach(gl, grpCl)
+ {
+ GroupClause *gc = (GroupClause *) lfirst(gl);
+ Var *var = gc->grpAttr;
+
+ if (!(tlist_member(var, tlist)))
+ {
+ Resdom *r;
+
+ r = makeResdom(last_resdomno,
+ var->vartype,
+ get_typlen(var->vartype),
+ NULL,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ last_resdomno++;
+ tlist = lappend(tlist, MakeTLE(r, (Node *) var));
+ }
}
- }
}
+
#endif
-/* was ExecTargetListLength() in execQual.c,
+/* was ExecTargetListLength() in execQual.c,
moved here to reduce dependencies on the executor module */
int
-exec_tlist_length(List *targetlist)
+exec_tlist_length(List * targetlist)
{
- int len;
- List *tl;
- TargetEntry *curTle;
-
- len = 0;
- foreach (tl, targetlist) {
- curTle = lfirst(tl);
-
- if (curTle->resdom != NULL)
- len++;
- }
- return len;
-}
+ int len;
+ List *tl;
+ TargetEntry *curTle;
+ len = 0;
+ foreach(tl, targetlist)
+ {
+ curTle = lfirst(tl);
+ if (curTle->resdom != NULL)
+ len++;
+ }
+ return len;
+}
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 3eb0787e3ef..40abf5f80cb 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* var.c--
- * Var node manipulation routines
+ * Var node manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.3 1996/11/06 09:29:26 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.4 1997/09/07 04:44:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,169 +27,193 @@
#include "parser/parsetree.h"
/*
- * find_varnos
+ * find_varnos
*
- * Descends down part of a parsetree (qual or tlist),
+ * Descends down part of a parsetree (qual or tlist),
*
- * XXX assumes varno's are always integers, which shouldn't be true...
- * (though it currently is, see primnodes.h)
+ * XXX assumes varno's are always integers, which shouldn't be true...
+ * (though it currently is, see primnodes.h)
*/
-List *
-pull_varnos(Node *me)
+List *
+pull_varnos(Node * me)
{
- List *i, *result = NIL;
-
- if (me == NULL)
- return (NIL);
-
- switch (nodeTag(me)) {
- case T_List:
- foreach (i, (List*)me) {
- result = nconc(result, pull_varnos(lfirst(i)));
+ List *i,
+ *result = NIL;
+
+ if (me == NULL)
+ return (NIL);
+
+ switch (nodeTag(me))
+ {
+ case T_List:
+ foreach(i, (List *) me)
+ {
+ result = nconc(result, pull_varnos(lfirst(i)));
+ }
+ break;
+ case T_ArrayRef:
+ foreach(i, ((ArrayRef *) me)->refupperindexpr)
+ result = nconc(result, pull_varnos(lfirst(i)));
+ foreach(i, ((ArrayRef *) me)->reflowerindexpr)
+ result = nconc(result, pull_varnos(lfirst(i)));
+ result = nconc(result, pull_varnos(((ArrayRef *) me)->refassgnexpr));
+ break;
+ case T_Var:
+ result = lconsi(((Var *) me)->varno, NIL);
+ break;
+ default:
+ break;
}
- break;
- case T_ArrayRef:
- foreach (i, ((ArrayRef*) me)->refupperindexpr)
- result = nconc(result, pull_varnos(lfirst(i)));
- foreach (i, ((ArrayRef*) me)->reflowerindexpr)
- result = nconc(result, pull_varnos(lfirst(i)));
- result = nconc(result, pull_varnos(((ArrayRef*) me)->refassgnexpr));
- break;
- case T_Var:
- result = lconsi(((Var*) me)->varno, NIL);
- break;
- default:
- break;
- }
- return(result);
+ return (result);
}
-/*
+/*
* contain_var_clause--
- * Recursively find var nodes from a clause by pulling vars from the
- * left and right operands of the clause.
- *
- * Returns true if any varnode found.
+ * Recursively find var nodes from a clause by pulling vars from the
+ * left and right operands of the clause.
+ *
+ * Returns true if any varnode found.
*/
-bool contain_var_clause(Node *clause)
+bool
+contain_var_clause(Node * clause)
{
- if (clause==NULL)
- return FALSE;
- else if (IsA(clause,Var))
- return TRUE;
- else if (IsA(clause,Iter))
- return contain_var_clause(((Iter*)clause)->iterexpr);
- else if (single_node(clause))
- return FALSE;
- else if (or_clause(clause)) {
- List *temp;
-
- foreach (temp, ((Expr*)clause)->args) {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
- }
- return FALSE;
- } else if (is_funcclause (clause)) {
- List *temp;
-
- foreach(temp, ((Expr *)clause)->args) {
- if (contain_var_clause(lfirst(temp)))
+ if (clause == NULL)
+ return FALSE;
+ else if (IsA(clause, Var))
return TRUE;
+ else if (IsA(clause, Iter))
+ return contain_var_clause(((Iter *) clause)->iterexpr);
+ else if (single_node(clause))
+ return FALSE;
+ else if (or_clause(clause))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) clause)->args)
+ {
+ if (contain_var_clause(lfirst(temp)))
+ return TRUE;
+ }
+ return FALSE;
}
- return FALSE;
- } else if (IsA(clause,ArrayRef)) {
- List *temp;
-
- foreach(temp, ((ArrayRef*)clause)->refupperindexpr) {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
+ else if (is_funcclause(clause))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) clause)->args)
+ {
+ if (contain_var_clause(lfirst(temp)))
+ return TRUE;
+ }
+ return FALSE;
}
- foreach(temp, ((ArrayRef*)clause)->reflowerindexpr) {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
+ else if (IsA(clause, ArrayRef))
+ {
+ List *temp;
+
+ foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
+ {
+ if (contain_var_clause(lfirst(temp)))
+ return TRUE;
+ }
+ foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
+ {
+ if (contain_var_clause(lfirst(temp)))
+ return TRUE;
+ }
+ if (contain_var_clause(((ArrayRef *) clause)->refexpr))
+ return TRUE;
+ if (contain_var_clause(((ArrayRef *) clause)->refassgnexpr))
+ return TRUE;
+ return FALSE;
}
- if (contain_var_clause(((ArrayRef*)clause)->refexpr))
- return TRUE;
- if (contain_var_clause(((ArrayRef*)clause)->refassgnexpr))
- return TRUE;
- return FALSE;
- } else if (not_clause(clause))
- return contain_var_clause((Node*)get_notclausearg((Expr*)clause));
- else if (is_opclause(clause))
- return (contain_var_clause((Node*)get_leftop((Expr*)clause)) ||
- contain_var_clause((Node*)get_rightop((Expr*)clause)));
+ else if (not_clause(clause))
+ return contain_var_clause((Node *) get_notclausearg((Expr *) clause));
+ else if (is_opclause(clause))
+ return (contain_var_clause((Node *) get_leftop((Expr *) clause)) ||
+ contain_var_clause((Node *) get_rightop((Expr *) clause)));
- return FALSE;
+ return FALSE;
}
-/*
+/*
* pull_var_clause--
- * Recursively pulls all var nodes from a clause by pulling vars from the
- * left and right operands of the clause.
- *
- * Returns list of varnodes found.
+ * Recursively pulls all var nodes from a clause by pulling vars from the
+ * left and right operands of the clause.
+ *
+ * Returns list of varnodes found.
*/
-List *
-pull_var_clause(Node *clause)
+List *
+pull_var_clause(Node * clause)
{
- List *retval = NIL;
-
- if (clause==NULL)
- return(NIL);
- else if (IsA(clause,Var))
- retval = lcons(clause,NIL);
- else if (IsA(clause,Iter))
- retval = pull_var_clause(((Iter*)clause)->iterexpr);
- else if (single_node(clause))
- retval = NIL;
- else if (or_clause(clause)) {
- List *temp;
-
- foreach (temp, ((Expr*)clause)->args)
- retval = nconc(retval, pull_var_clause(lfirst(temp)));
- } else if (is_funcclause (clause)) {
- List *temp;
-
- foreach(temp, ((Expr *)clause)->args)
- retval = nconc (retval,pull_var_clause(lfirst(temp)));
- } else if (IsA(clause,Aggreg)) {
- retval = pull_var_clause(((Aggreg*)clause)->target);
- } else if (IsA(clause,ArrayRef)) {
- List *temp;
-
- foreach(temp, ((ArrayRef*)clause)->refupperindexpr)
- retval = nconc (retval,pull_var_clause(lfirst(temp)));
- foreach(temp, ((ArrayRef*)clause)->reflowerindexpr)
- retval = nconc (retval,pull_var_clause(lfirst(temp)));
- retval = nconc(retval,
- pull_var_clause(((ArrayRef*)clause)->refexpr));
- retval = nconc(retval,
- pull_var_clause(((ArrayRef*)clause)->refassgnexpr));
- } else if (not_clause(clause))
- retval = pull_var_clause((Node*)get_notclausearg((Expr*)clause));
- else if (is_opclause(clause))
- retval = nconc(pull_var_clause((Node*)get_leftop((Expr*)clause)),
- pull_var_clause((Node*)get_rightop((Expr*)clause)));
- else
- retval = NIL;
-
- return (retval);
+ List *retval = NIL;
+
+ if (clause == NULL)
+ return (NIL);
+ else if (IsA(clause, Var))
+ retval = lcons(clause, NIL);
+ else if (IsA(clause, Iter))
+ retval = pull_var_clause(((Iter *) clause)->iterexpr);
+ else if (single_node(clause))
+ retval = NIL;
+ else if (or_clause(clause))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) clause)->args)
+ retval = nconc(retval, pull_var_clause(lfirst(temp)));
+ }
+ else if (is_funcclause(clause))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) clause)->args)
+ retval = nconc(retval, pull_var_clause(lfirst(temp)));
+ }
+ else if (IsA(clause, Aggreg))
+ {
+ retval = pull_var_clause(((Aggreg *) clause)->target);
+ }
+ else if (IsA(clause, ArrayRef))
+ {
+ List *temp;
+
+ foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
+ retval = nconc(retval, pull_var_clause(lfirst(temp)));
+ foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
+ retval = nconc(retval, pull_var_clause(lfirst(temp)));
+ retval = nconc(retval,
+ pull_var_clause(((ArrayRef *) clause)->refexpr));
+ retval = nconc(retval,
+ pull_var_clause(((ArrayRef *) clause)->refassgnexpr));
+ }
+ else if (not_clause(clause))
+ retval = pull_var_clause((Node *) get_notclausearg((Expr *) clause));
+ else if (is_opclause(clause))
+ retval = nconc(pull_var_clause((Node *) get_leftop((Expr *) clause)),
+ pull_var_clause((Node *) get_rightop((Expr *) clause)));
+ else
+ retval = NIL;
+
+ return (retval);
}
-/*
- * var_equal
- *
- * Returns t iff two var nodes correspond to the same attribute.
+/*
+ * var_equal
+ *
+ * Returns t iff two var nodes correspond to the same attribute.
*/
bool
-var_equal(Var *var1, Var *var2)
+var_equal(Var * var1, Var * var2)
{
- if (IsA (var1,Var) && IsA (var2,Var) &&
- (((Var*)var1)->varno == ((Var*)var2)->varno) &&
- (((Var*)var1)->vartype == ((Var*)var2)->vartype) &&
- (((Var*)var1)->varattno == ((Var*)var2)->varattno)) {
-
- return(true);
- } else
- return(false);
+ if (IsA(var1, Var) && IsA(var2, Var) &&
+ (((Var *) var1)->varno == ((Var *) var2)->varno) &&
+ (((Var *) var1)->vartype == ((Var *) var2)->vartype) &&
+ (((Var *) var1)->varattno == ((Var *) var2)->varattno))
+ {
+
+ return (true);
+ }
+ else
+ return (false);
}