aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/initsplan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/initsplan.c')
-rw-r--r--src/backend/optimizer/plan/initsplan.c579
1 files changed, 303 insertions, 276 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 35b3969b702..62ff23f207e 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* initsplan.c--
- * Target list, qualification, joininfo initialization routines
+ * Target list, qualification, joininfo initialization routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.5 1997/04/24 16:04:23 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.6 1997/09/07 04:44:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,370 +33,397 @@
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
-extern int Quiet;
+extern int Quiet;
-static void add_clause_to_rels(Query *root, List *clause);
-static void add_join_clause_info_to_rels(Query *root, CInfo *clauseinfo,
- List *join_relids);
-static void add_vars_to_rels(Query *root, List *vars, List *join_relids);
+static void add_clause_to_rels(Query * root, List * clause);
+static void
+add_join_clause_info_to_rels(Query * root, CInfo * clauseinfo,
+ List * join_relids);
+static void add_vars_to_rels(Query * root, List * vars, List * join_relids);
-static MergeOrder *mergesortop(Expr *clause);
-static Oid hashjoinop(Expr *clause);
+static MergeOrder *mergesortop(Expr * clause);
+static Oid hashjoinop(Expr * clause);
/*****************************************************************************
*
- * TARGET LISTS
+ * TARGET LISTS
*
*****************************************************************************/
-/*
+/*
* initialize_rel_nodes--
- * Creates rel nodes for every relation mentioned in the target list
- * 'tlist' (if a node hasn't already been created) and adds them to
- * *query-relation-list*. Creates targetlist entries for each member of
- * 'tlist' and adds them to the tlist field of the appropriate rel node.
- *
- * Returns nothing.
+ * Creates rel nodes for every relation mentioned in the target list
+ * 'tlist' (if a node hasn't already been created) and adds them to
+ * *query-relation-list*. Creates targetlist entries for each member of
+ * 'tlist' and adds them to the tlist field of the appropriate rel node.
+ *
+ * Returns nothing.
*/
void
-initialize_base_rels_list(Query *root, List *tlist)
+initialize_base_rels_list(Query * root, List * tlist)
{
- List *tlist_vars = NIL;
- List *l = NIL;
- List *tvar = NIL;
-
- foreach (l, tlist) {
- TargetEntry *entry = (TargetEntry *) lfirst(l);
-
- tlist_vars = append(tlist_vars, pull_var_clause(entry->expr));
- }
-
- /* now, the target list only contains Var nodes */
- foreach (tvar, tlist_vars) {
- Var *var;
- Index varno;
- Rel *result;
-
- var = (Var*)lfirst(tvar);
- varno = var->varno;
- result = get_base_rel(root, varno);
-
- add_tl_element(result, var);
- }
+ List *tlist_vars = NIL;
+ List *l = NIL;
+ List *tvar = NIL;
+
+ foreach(l, tlist)
+ {
+ TargetEntry *entry = (TargetEntry *) lfirst(l);
+
+ tlist_vars = append(tlist_vars, pull_var_clause(entry->expr));
+ }
+
+ /* now, the target list only contains Var nodes */
+ foreach(tvar, tlist_vars)
+ {
+ Var *var;
+ Index varno;
+ Rel *result;
+
+ var = (Var *) lfirst(tvar);
+ varno = var->varno;
+ result = get_base_rel(root, varno);
+
+ add_tl_element(result, var);
+ }
}
/*
* add_missing_variables_to_base_rels -
- * If we have range variable(s) in the FROM clause that does not appear
- * in the target list nor qualifications, we add it to the base relation
- * list. For instance, "select f.x from foo f, foo f2" is a join of f and
- * f2. Note that if we have "select foo.x from foo f", it also gets turned
- * into a join.
+ * If we have range variable(s) in the FROM clause that does not appear
+ * in the target list nor qualifications, we add it to the base relation
+ * list. For instance, "select f.x from foo f, foo f2" is a join of f and
+ * f2. Note that if we have "select foo.x from foo f", it also gets turned
+ * into a join.
*/
void
-add_missing_vars_to_base_rels(Query *root, List *tlist)
+add_missing_vars_to_base_rels(Query * root, List * tlist)
{
- List *l;
- int varno;
-
- varno = 1;
- foreach (l, root->rtable) {
- RangeTblEntry *rte = (RangeTblEntry *)lfirst(l);
- List *relids;
- Rel *result;
- Var *var;
-
- relids = lconsi(varno, NIL);
- if (rte->inFromCl &&
- !rel_member(relids, root->base_relation_list_)) {
-
- var = makeVar(varno, -2 , 26, varno, -2);
- /* add it to base_relation_list_ */
- result = get_base_rel(root, varno);
- add_tl_element(result, var);
+ List *l;
+ int varno;
+
+ varno = 1;
+ foreach(l, root->rtable)
+ {
+ RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
+ List *relids;
+ Rel *result;
+ Var *var;
+
+ relids = lconsi(varno, NIL);
+ if (rte->inFromCl &&
+ !rel_member(relids, root->base_relation_list_))
+ {
+
+ var = makeVar(varno, -2, 26, varno, -2);
+ /* add it to base_relation_list_ */
+ result = get_base_rel(root, varno);
+ add_tl_element(result, var);
+ }
+ pfree(relids);
+ varno++;
}
- pfree(relids);
- varno++;
- }
- return;
+ return;
}
/*****************************************************************************
*
- * QUALIFICATIONS
+ * QUALIFICATIONS
*
*****************************************************************************/
-/*
+/*
* initialize-qualification--
- * Initializes ClauseInfo and JoinInfo fields of relation entries for all
- * relations appearing within clauses. Creates new relation entries if
- * necessary, adding them to *query-relation-list*.
- *
- * Returns nothing of interest.
+ * Initializes ClauseInfo and JoinInfo fields of relation entries for all
+ * relations appearing within clauses. Creates new relation entries if
+ * necessary, adding them to *query-relation-list*.
+ *
+ * Returns nothing of interest.
*/
void
-initialize_base_rels_jinfo(Query *root, List *clauses)
+initialize_base_rels_jinfo(Query * root, List * clauses)
{
- List *clause;
+ List *clause;
- foreach (clause, clauses) {
- add_clause_to_rels(root, lfirst(clause));
- }
- return;
+ foreach(clause, clauses)
+ {
+ add_clause_to_rels(root, lfirst(clause));
+ }
+ return;
}
-/*
+/*
* add-clause-to-rels--
- * Add clause information to either the 'ClauseInfo' or 'JoinInfo' field
- * of a relation entry(depending on whether or not the clause is a join)
- * by creating a new ClauseInfo node and setting appropriate fields
- * within the nodes.
- *
- * Returns nothing of interest.
+ * Add clause information to either the 'ClauseInfo' or 'JoinInfo' field
+ * of a relation entry(depending on whether or not the clause is a join)
+ * by creating a new ClauseInfo node and setting appropriate fields
+ * within the nodes.
+ *
+ * Returns nothing of interest.
*/
static void
-add_clause_to_rels(Query *root, List *clause)
+add_clause_to_rels(Query * root, List * clause)
{
- List *relids;
- List *vars;
- CInfo *clauseinfo = makeNode(CInfo);
+ List *relids;
+ List *vars;
+ CInfo *clauseinfo = makeNode(CInfo);
- /*
- * Retrieve all relids and vars contained within the clause.
- */
- clause_relids_vars((Node*)clause, &relids, &vars);
+ /*
+ * Retrieve all relids and vars contained within the clause.
+ */
+ clause_relids_vars((Node *) clause, &relids, &vars);
- clauseinfo->clause = (Expr*)clause;
- clauseinfo->notclause = contains_not((Node*)clause);
- clauseinfo->selectivity = 0;
- clauseinfo->indexids = NIL;
- clauseinfo->mergesortorder = (MergeOrder*)NULL;
- clauseinfo->hashjoinoperator = (Oid)0;
-
+ clauseinfo->clause = (Expr *) clause;
+ clauseinfo->notclause = contains_not((Node *) clause);
+ clauseinfo->selectivity = 0;
+ clauseinfo->indexids = NIL;
+ clauseinfo->mergesortorder = (MergeOrder *) NULL;
+ clauseinfo->hashjoinoperator = (Oid) 0;
- if(length(relids) == 1) {
- Rel *rel = get_base_rel(root, lfirsti(relids));
-
- /*
- * There is only one relation participating in 'clause',
- * so 'clause' must be a restriction clause.
- */
- /* the selectivity of the clause must be computed
- regardless of whether it's a restriction or a join clause */
- if (is_funcclause((Node*)clause))
- {
+ if (length(relids) == 1)
+ {
+ Rel *rel = get_base_rel(root, lfirsti(relids));
+
/*
- * XXX If we have a func clause set selectivity to 1/3,
- * really need a true selectivity function.
+ * There is only one relation participating in 'clause', so
+ * 'clause' must be a restriction clause.
*/
- clauseinfo->selectivity = (Cost)0.3333333;
- }
- else
- {
- clauseinfo->selectivity =
- compute_clause_selec(root, (Node*)clause,
- NIL);
- }
- rel->clauseinfo = lcons(clauseinfo,
- rel->clauseinfo);
- } else {
- /*
- * 'clause' is a join clause, since there is more than one
- * atom in the relid list.
- */
-
- if (is_funcclause((Node*)clause))
- {
+
/*
- * XXX If we have a func clause set selectivity to 1/3,
- * really need a true selectivity function.
+ * the selectivity of the clause must be computed regardless of
+ * whether it's a restriction or a join clause
*/
- clauseinfo->selectivity = (Cost)0.3333333;
- }
+ if (is_funcclause((Node *) clause))
+ {
+
+ /*
+ * XXX If we have a func clause set selectivity to 1/3, really
+ * need a true selectivity function.
+ */
+ clauseinfo->selectivity = (Cost) 0.3333333;
+ }
+ else
+ {
+ clauseinfo->selectivity =
+ compute_clause_selec(root, (Node *) clause,
+ NIL);
+ }
+ rel->clauseinfo = lcons(clauseinfo,
+ rel->clauseinfo);
+ }
else
- {
- clauseinfo->selectivity =
- compute_clause_selec(root, (Node*)clause,
- NIL);
- }
- add_join_clause_info_to_rels(root, clauseinfo, relids);
- add_vars_to_rels(root,vars, relids);
- }
+ {
+
+ /*
+ * 'clause' is a join clause, since there is more than one atom in
+ * the relid list.
+ */
+
+ if (is_funcclause((Node *) clause))
+ {
+
+ /*
+ * XXX If we have a func clause set selectivity to 1/3, really
+ * need a true selectivity function.
+ */
+ clauseinfo->selectivity = (Cost) 0.3333333;
+ }
+ else
+ {
+ clauseinfo->selectivity =
+ compute_clause_selec(root, (Node *) clause,
+ NIL);
+ }
+ add_join_clause_info_to_rels(root, clauseinfo, relids);
+ add_vars_to_rels(root, vars, relids);
+ }
}
-/*
+/*
* add-join-clause-info-to-rels--
- * For every relation participating in a join clause, add 'clauseinfo' to
- * the appropriate joininfo node(creating a new one and adding it to the
- * appropriate rel node if necessary).
- *
+ * For every relation participating in a join clause, add 'clauseinfo' to
+ * the appropriate joininfo node(creating a new one and adding it to the
+ * appropriate rel node if necessary).
+ *
* 'clauseinfo' describes the join clause
* 'join-relids' is the list of relations participating in the join clause
- *
+ *
* Returns nothing.
- *
+ *
*/
static void
-add_join_clause_info_to_rels(Query *root, CInfo *clauseinfo, List *join_relids)
+add_join_clause_info_to_rels(Query * root, CInfo * clauseinfo, List * join_relids)
{
- List *join_relid;
-
- foreach (join_relid, join_relids) {
- JInfo *joininfo;
- List *other_rels = NIL;
- List *rel;
-
- foreach (rel, join_relids)
- {
- if ( lfirsti(rel) != lfirsti(join_relid) )
- other_rels = lappendi (other_rels, lfirsti(rel));
- }
-
- joininfo =
- find_joininfo_node(get_base_rel(root, lfirsti(join_relid)),
- other_rels);
- joininfo->jinfoclauseinfo =
- lcons(copyObject((void*)clauseinfo), joininfo->jinfoclauseinfo);
-
- }
+ List *join_relid;
+
+ foreach(join_relid, join_relids)
+ {
+ JInfo *joininfo;
+ List *other_rels = NIL;
+ List *rel;
+
+ foreach(rel, join_relids)
+ {
+ if (lfirsti(rel) != lfirsti(join_relid))
+ other_rels = lappendi(other_rels, lfirsti(rel));
+ }
+
+ joininfo =
+ find_joininfo_node(get_base_rel(root, lfirsti(join_relid)),
+ other_rels);
+ joininfo->jinfoclauseinfo =
+ lcons(copyObject((void *) clauseinfo), joininfo->jinfoclauseinfo);
+
+ }
}
-/*
+/*
* add-vars-to-rels--
- * For each variable appearing in a clause,
- * (1) If a targetlist entry for the variable is not already present in
- * the appropriate relation's target list, add one.
- * (2) If a targetlist entry is already present, but the var is part of a
- * join clause, add the relids of the join relations to the JoinList
- * entry of the targetlist entry.
- *
- * 'vars' is the list of var nodes
- * 'join-relids' is the list of relids appearing in the join clause
- * (if this is a join clause)
- *
- * Returns nothing.
+ * For each variable appearing in a clause,
+ * (1) If a targetlist entry for the variable is not already present in
+ * the appropriate relation's target list, add one.
+ * (2) If a targetlist entry is already present, but the var is part of a
+ * join clause, add the relids of the join relations to the JoinList
+ * entry of the targetlist entry.
+ *
+ * 'vars' is the list of var nodes
+ * 'join-relids' is the list of relids appearing in the join clause
+ * (if this is a join clause)
+ *
+ * Returns nothing.
*/
static void
-add_vars_to_rels(Query *root, List *vars, List *join_relids)
+add_vars_to_rels(Query * root, List * vars, List * join_relids)
{
- Var *var;
- List *temp = NIL;
- Rel *rel = (Rel*)NULL;
- TargetEntry *tlistentry;
-
- foreach (temp, vars) {
- var = (Var*)lfirst(temp);
- rel = get_base_rel(root, var->varno);
- tlistentry = tlistentry_member(var, rel->targetlist);
- if(tlistentry==NULL)
- /* add a new entry */
- add_tl_element(rel, var);
- }
+ Var *var;
+ List *temp = NIL;
+ Rel *rel = (Rel *) NULL;
+ TargetEntry *tlistentry;
+
+ foreach(temp, vars)
+ {
+ var = (Var *) lfirst(temp);
+ rel = get_base_rel(root, var->varno);
+ tlistentry = tlistentry_member(var, rel->targetlist);
+ if (tlistentry == NULL)
+ /* add a new entry */
+ add_tl_element(rel, var);
+ }
}
/*****************************************************************************
*
- * JOININFO
+ * JOININFO
*
*****************************************************************************/
-/*
+/*
* initialize-join-clause-info--
- * Set the MergeSortable or HashJoinable field for every joininfo node
- * (within a rel node) and the MergeSortOrder or HashJoinOp field for
- * each clauseinfo node(within a joininfo node) for all relations in a
- * query.
- *
- * Returns nothing.
+ * Set the MergeSortable or HashJoinable field for every joininfo node
+ * (within a rel node) and the MergeSortOrder or HashJoinOp field for
+ * each clauseinfo node(within a joininfo node) for all relations in a
+ * query.
+ *
+ * Returns nothing.
*/
void
-initialize_join_clause_info(List *rel_list)
+initialize_join_clause_info(List * rel_list)
{
- List *x, *y, *z;
- Rel *rel;
- JInfo *joininfo;
- CInfo *clauseinfo;
- Expr *clause;
-
- foreach (x, rel_list) {
- rel = (Rel*)lfirst(x);
- foreach (y, rel->joininfo) {
- joininfo = (JInfo*)lfirst(y);
- foreach (z, joininfo->jinfoclauseinfo) {
- clauseinfo = (CInfo*)lfirst(z);
- clause = clauseinfo->clause;
- if(join_clause_p((Node*)clause)) {
- MergeOrder *sortop = (MergeOrder*)NULL;
- Oid hashop = (Oid)NULL;
-
- if (_enable_mergesort_)
- sortop = mergesortop(clause);
- if (_enable_hashjoin_)
- hashop = hashjoinop(clause);
-
- if (sortop) {
- clauseinfo->mergesortorder = sortop;
- joininfo->mergesortable = true;
- }
- if (hashop) {
- clauseinfo->hashjoinoperator = hashop;
- joininfo->hashjoinable = true;
- }
+ List *x,
+ *y,
+ *z;
+ Rel *rel;
+ JInfo *joininfo;
+ CInfo *clauseinfo;
+ Expr *clause;
+
+ foreach(x, rel_list)
+ {
+ rel = (Rel *) lfirst(x);
+ foreach(y, rel->joininfo)
+ {
+ joininfo = (JInfo *) lfirst(y);
+ foreach(z, joininfo->jinfoclauseinfo)
+ {
+ clauseinfo = (CInfo *) lfirst(z);
+ clause = clauseinfo->clause;
+ if (join_clause_p((Node *) clause))
+ {
+ MergeOrder *sortop = (MergeOrder *) NULL;
+ Oid hashop = (Oid) NULL;
+
+ if (_enable_mergesort_)
+ sortop = mergesortop(clause);
+ if (_enable_hashjoin_)
+ hashop = hashjoinop(clause);
+
+ if (sortop)
+ {
+ clauseinfo->mergesortorder = sortop;
+ joininfo->mergesortable = true;
+ }
+ if (hashop)
+ {
+ clauseinfo->hashjoinoperator = hashop;
+ joininfo->hashjoinable = true;
+ }
+ }
+ }
}
- }
}
- }
}
-/*
+/*
* mergesortop--
- * Returns the mergesort operator of an operator iff 'clause' is
- * mergesortable, i.e., both operands are single vars and the operator is
- * a mergesortable operator.
+ * Returns the mergesort operator of an operator iff 'clause' is
+ * mergesortable, i.e., both operands are single vars and the operator is
+ * a mergesortable operator.
*/
static MergeOrder *
-mergesortop(Expr *clause)
+mergesortop(Expr * clause)
{
- Oid leftOp, rightOp;
- bool sortable;
-
- sortable = op_mergesortable(((Oper*)clause->oper)->opno,
- (get_leftop(clause))->vartype,
- (get_rightop(clause))->vartype,
- &leftOp,
- &rightOp);
-
- if (sortable) {
- MergeOrder *morder = makeNode(MergeOrder);
-
- morder->join_operator = ((Oper*)clause->oper)->opno;
- morder->left_operator = leftOp;
- morder->right_operator = rightOp;
- morder->left_type = (get_leftop(clause))->vartype;
- morder->right_type = (get_rightop(clause))->vartype;
- return (morder);
- } else
- return(NULL);
+ Oid leftOp,
+ rightOp;
+ bool sortable;
+
+ sortable = op_mergesortable(((Oper *) clause->oper)->opno,
+ (get_leftop(clause))->vartype,
+ (get_rightop(clause))->vartype,
+ &leftOp,
+ &rightOp);
+
+ if (sortable)
+ {
+ MergeOrder *morder = makeNode(MergeOrder);
+
+ morder->join_operator = ((Oper *) clause->oper)->opno;
+ morder->left_operator = leftOp;
+ morder->right_operator = rightOp;
+ morder->left_type = (get_leftop(clause))->vartype;
+ morder->right_type = (get_rightop(clause))->vartype;
+ return (morder);
+ }
+ else
+ return (NULL);
}
-/*
+/*
* hashjoinop--
- * Returns the hashjoin operator of an operator iff 'clause' is
- * hashjoinable, i.e., both operands are single vars and the operator is
- * a hashjoinable operator.
+ * Returns the hashjoin operator of an operator iff 'clause' is
+ * hashjoinable, i.e., both operands are single vars and the operator is
+ * a hashjoinable operator.
*/
-static Oid
-hashjoinop(Expr *clause)
+static Oid
+hashjoinop(Expr * clause)
{
- return(op_hashjoinable(((Oper*)clause->oper)->opno,
- (get_leftop(clause))->vartype,
- (get_rightop(clause))->vartype));
+ return (op_hashjoinable(((Oper *) clause->oper)->opno,
+ (get_leftop(clause))->vartype,
+ (get_rightop(clause))->vartype));
}