aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/geqo/geqo_eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/geqo/geqo_eval.c')
-rw-r--r--src/backend/optimizer/geqo/geqo_eval.c985
1 files changed, 522 insertions, 463 deletions
diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c
index 7ec449f2e94..ba34d8f3e02 100644
--- a/src/backend/optimizer/geqo/geqo_eval.c
+++ b/src/backend/optimizer/geqo/geqo_eval.c
@@ -1,20 +1,20 @@
/*------------------------------------------------------------------------
*
* geqo_eval.c--
- * Routines to evaluate query trees
+ * Routines to evaluate query trees
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_eval.c,v 1.12 1997/08/12 22:53:07 momjian Exp $
+ * $Id: geqo_eval.c,v 1.13 1997/09/07 04:43:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
@@ -22,13 +22,13 @@
#include <math.h>
#ifdef HAVE_LIMITS_H
-# include <limits.h>
-# ifndef MAXINT
-# define MAXINT INT_MAX
-# endif
+#include <limits.h>
+#ifndef MAXINT
+#define MAXINT INT_MAX
+#endif
#else
-# include <values.h>
-#endif
+#include <values.h>
+#endif
#include "nodes/pg_list.h"
#include "nodes/relation.h"
@@ -50,548 +50,598 @@
#include "optimizer/geqo_paths.h"
-static List *gimme_clause_joins(Query *root, Rel *outer_rel, Rel *inner_rel);
-static Rel *gimme_clauseless_join(Rel *outer_rel, Rel *inner_rel);
-static Rel *init_join_rel(Rel *outer_rel, Rel *inner_rel, JInfo *joininfo);
-static List *new_join_tlist(List *tlist, List *other_relids, int first_resdomno);
-static List *new_joininfo_list(List *joininfo_list, List *join_relids);
-static void geqo_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel);
-static Rel *geqo_nth(int stop, List *rels);
+static List *gimme_clause_joins(Query * root, Rel * outer_rel, Rel * inner_rel);
+static Rel *gimme_clauseless_join(Rel * outer_rel, Rel * inner_rel);
+static Rel *init_join_rel(Rel * outer_rel, Rel * inner_rel, JInfo * joininfo);
+static List *new_join_tlist(List * tlist, List * other_relids, int first_resdomno);
+static List *new_joininfo_list(List * joininfo_list, List * join_relids);
+static void geqo_joinrel_size(Rel * joinrel, Rel * outer_rel, Rel * inner_rel);
+static Rel *geqo_nth(int stop, List * rels);
-/*
+/*
* geqo_eval--
- *
+ *
* Returns cost of a query tree as an individual of the population.
*/
Cost
-geqo_eval (Query *root, Gene *tour, int num_gene)
+geqo_eval(Query * root, Gene * tour, int num_gene)
{
- Rel *joinrel;
- Cost fitness;
- List *temp;
+ Rel *joinrel;
+ Cost fitness;
+ List *temp;
/* remember root->join_relation_list_ ... */
/* because root->join_relation_list_ will be changed during the following */
- temp = listCopy(root->join_relation_list_);
+ temp = listCopy(root->join_relation_list_);
/* joinrel is readily processed query tree -- left-sided ! */
- joinrel = gimme_tree(root, tour, 0, num_gene, NULL);
+ joinrel = gimme_tree(root, tour, 0, num_gene, NULL);
/* compute fitness */
- fitness = (Cost) joinrel->cheapestpath->path_cost;
+ fitness = (Cost) joinrel->cheapestpath->path_cost;
- root->join_relation_list_ = listCopy(temp);
+ root->join_relation_list_ = listCopy(temp);
- pfree(joinrel);
- freeList(temp);
+ pfree(joinrel);
+ freeList(temp);
- return(fitness);
+ return (fitness);
}
-/*
+/*
* gimme-tree --
- * this program presumes that only LEFT-SIDED TREES are considered!
- *
+ * this program presumes that only LEFT-SIDED TREES are considered!
+ *
* 'outer_rel' is the preceeding join
- *
+ *
* Returns a new join relation incorporating all joins in a left-sided tree.
*/
-Rel *
-gimme_tree (Query *root, Gene *tour, int rel_count, int num_gene, Rel *outer_rel)
+Rel *
+gimme_tree(Query * root, Gene * tour, int rel_count, int num_gene, Rel * outer_rel)
{
- Rel *inner_rel; /* current relation */
- int base_rel_index;
+ Rel *inner_rel; /* current relation */
+ int base_rel_index;
- List *new_rels = NIL;
- Rel *new_rel = NULL;
+ List *new_rels = NIL;
+ Rel *new_rel = NULL;
- if (rel_count < num_gene ) { /* tree not yet finished */
+ if (rel_count < num_gene)
+ { /* tree not yet finished */
- /* tour[0] = 3; tour[1] = 1; tour[2] = 2 */
- base_rel_index = (int) tour[rel_count];
+ /* tour[0] = 3; tour[1] = 1; tour[2] = 2 */
+ base_rel_index = (int) tour[rel_count];
- inner_rel = (Rel *) geqo_nth(base_rel_index,root->base_relation_list_);
+ inner_rel = (Rel *) geqo_nth(base_rel_index, root->base_relation_list_);
- if (rel_count == 0) { /* processing first join with base_rel_index = (int) tour[0] */
- rel_count++;
- return gimme_tree(root, tour, rel_count, num_gene, inner_rel);
+ if (rel_count == 0)
+ { /* processing first join with
+ * base_rel_index = (int) tour[0] */
+ rel_count++;
+ return gimme_tree(root, tour, rel_count, num_gene, inner_rel);
}
- else { /* tree main part */
-
- if(!(new_rels = gimme_clause_joins(root, outer_rel,inner_rel))) {
- if (BushyPlanFlag) {
- new_rels = lcons(gimme_clauseless_join(outer_rel,outer_rel),NIL); /* ??? MAU */
+ else
+ { /* tree main part */
+
+ if (!(new_rels = gimme_clause_joins(root, outer_rel, inner_rel)))
+ {
+ if (BushyPlanFlag)
+ {
+ new_rels = lcons(gimme_clauseless_join(outer_rel, outer_rel), NIL); /* ??? MAU */
}
- else {
- new_rels = lcons(gimme_clauseless_join(outer_rel,inner_rel),NIL);
+ else
+ {
+ new_rels = lcons(gimme_clauseless_join(outer_rel, inner_rel), NIL);
}
}
- /* process new_rel->pathlist */
- find_all_join_paths(root, new_rels);
+ /* process new_rel->pathlist */
+ find_all_join_paths(root, new_rels);
- /* prune new_rels */
- /* MAU: is this necessary? */
- /* what's the matter if more than one new rel is left till now? */
- /* joinrels in newrels with different ordering of relids are not possible */
- if (length(new_rels) > 1) new_rels = geqo_prune_rels(new_rels);
+ /* prune new_rels */
+ /* MAU: is this necessary? */
- if (length(new_rels) > 1) { /* should never be reached ... */
- elog(DEBUG,"gimme_tree: still %d relations left", length(new_rels));
+ /*
+ * what's the matter if more than one new rel is left till
+ * now?
+ */
+
+ /*
+ * joinrels in newrels with different ordering of relids are
+ * not possible
+ */
+ if (length(new_rels) > 1)
+ new_rels = geqo_prune_rels(new_rels);
+
+ if (length(new_rels) > 1)
+ { /* should never be reached ... */
+ elog(DEBUG, "gimme_tree: still %d relations left", length(new_rels));
}
- /* get essential new relation */
- new_rel = (Rel *) lfirst(new_rels);
- rel_count++;
+ /* get essential new relation */
+ new_rel = (Rel *) lfirst(new_rels);
+ rel_count++;
- /* process new_rel->cheapestpath, new_rel->unorderedpath */
- geqo_rel_paths(new_rel);
+ /* process new_rel->cheapestpath, new_rel->unorderedpath */
+ geqo_rel_paths(new_rel);
- /* processing of other new_rel attributes */
- if ( new_rel->size <= 0 )
- new_rel->size = compute_rel_size(new_rel);
- new_rel->width = compute_rel_width(new_rel);
+ /* processing of other new_rel attributes */
+ if (new_rel->size <= 0)
+ new_rel->size = compute_rel_size(new_rel);
+ new_rel->width = compute_rel_width(new_rel);
- root->join_relation_list_ = lcons(new_rel, NIL);
+ root->join_relation_list_ = lcons(new_rel, NIL);
- return gimme_tree(root, tour, rel_count, num_gene, new_rel);
+ return gimme_tree(root, tour, rel_count, num_gene, new_rel);
}
}
- return (outer_rel); /* tree finished ... */
+ return (outer_rel); /* tree finished ... */
}
-/*
+/*
* gimme-clause-joins--
*
* 'outer-rel' is the relation entry for the outer relation
* 'inner-rel' is the relation entry for the inner relation
- *
+ *
* Returns a list of new join relations.
*/
-static List *
-gimme_clause_joins(Query *root, Rel *outer_rel, Rel *inner_rel)
+static List *
+gimme_clause_joins(Query * root, Rel * outer_rel, Rel * inner_rel)
{
- List *join_list = NIL;
- List *i = NIL;
- List *joininfo_list = (List *) outer_rel->joininfo;
-
- foreach (i, joininfo_list) {
- JInfo *joininfo = (JInfo*)lfirst(i);
- Rel *rel = NULL;
-
- if(!joininfo->inactive) {
- List *other_rels = (List *)joininfo->otherrels;
-
- if(other_rels != NIL) {
- if( (length(other_rels) == 1) ) {
-
- if( same(other_rels, inner_rel->relids) ) { /* look if inner_rel is it...*/
- rel = init_join_rel(outer_rel, inner_rel, joininfo);
+ List *join_list = NIL;
+ List *i = NIL;
+ List *joininfo_list = (List *) outer_rel->joininfo;
+
+ foreach(i, joininfo_list)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(i);
+ Rel *rel = NULL;
+
+ if (!joininfo->inactive)
+ {
+ List *other_rels = (List *) joininfo->otherrels;
+
+ if (other_rels != NIL)
+ {
+ if ((length(other_rels) == 1))
+ {
+
+ if (same(other_rels, inner_rel->relids))
+ { /* look if inner_rel is it... */
+ rel = init_join_rel(outer_rel, inner_rel, joininfo);
}
}
- else if (BushyPlanFlag) { /* ?!? MAU */
- rel = init_join_rel(outer_rel, get_join_rel(root, other_rels), joininfo);
- }
- else {
- rel = NULL;
- }
+ else if (BushyPlanFlag)
+ { /* ?!? MAU */
+ rel = init_join_rel(outer_rel, get_join_rel(root, other_rels), joininfo);
+ }
+ else
+ {
+ rel = NULL;
+ }
- if (rel != NULL)
- join_list = lappend(join_list, rel);
+ if (rel != NULL)
+ join_list = lappend(join_list, rel);
}
}
}
- return(join_list);
+ return (join_list);
}
-/*
+/*
* gimme-clauseless-join--
- * Given an outer relation 'outer-rel' and an inner relation
- * 'inner-rel', create a join relation between 'outer-rel' and 'inner-rel'
- *
+ * Given an outer relation 'outer-rel' and an inner relation
+ * 'inner-rel', create a join relation between 'outer-rel' and 'inner-rel'
+ *
* Returns a new join relation.
*/
-static Rel *
-gimme_clauseless_join(Rel *outer_rel, Rel *inner_rel)
+static Rel *
+gimme_clauseless_join(Rel * outer_rel, Rel * inner_rel)
{
- return(init_join_rel(outer_rel, inner_rel, (JInfo*)NULL));
+ return (init_join_rel(outer_rel, inner_rel, (JInfo *) NULL));
}
-/*
+/*
* init-join-rel--
- * Creates and initializes a new join relation.
- *
+ * Creates and initializes a new join relation.
+ *
* 'outer-rel' and 'inner-rel' are relation nodes for the relations to be
- * joined
+ * joined
* 'joininfo' is the joininfo node(join clause) containing both
- * 'outer-rel' and 'inner-rel', if any exists
- *
+ * 'outer-rel' and 'inner-rel', if any exists
+ *
* Returns the new join relation node.
*/
-static Rel *
-init_join_rel(Rel *outer_rel, Rel *inner_rel, JInfo *joininfo)
+static Rel *
+init_join_rel(Rel * outer_rel, Rel * inner_rel, JInfo * joininfo)
{
- Rel *joinrel = makeNode(Rel);
- List *joinrel_joininfo_list = NIL;
- List *new_outer_tlist;
- List *new_inner_tlist;
-
- /*
- * Create a new tlist by removing irrelevant elements from both
- * tlists of the outer and inner join relations and then merging
- * the results together.
- */
- new_outer_tlist =
- new_join_tlist(outer_rel->targetlist, /* XXX 1-based attnos */
- inner_rel->relids, 1);
- new_inner_tlist =
- new_join_tlist(inner_rel->targetlist, /* XXX 1-based attnos */
- outer_rel->relids,
- length(new_outer_tlist) + 1);
-
- joinrel->relids = NIL;
- joinrel->indexed = false;
- joinrel->pages = 0;
- joinrel->tuples = 0;
- joinrel->width = 0;
-/* joinrel->targetlist = NIL;*/
- joinrel->pathlist = NIL;
- joinrel->unorderedpath = (Path *)NULL;
- joinrel->cheapestpath = (Path *)NULL;
- joinrel->pruneable = true;
- joinrel->classlist = NULL;
- joinrel->relam = InvalidOid;
- joinrel->ordering = NULL;
- joinrel->clauseinfo = NIL;
- joinrel->joininfo = NULL;
- joinrel->innerjoin = NIL;
- joinrel->superrels = NIL;
-
- joinrel->relids = lcons(outer_rel->relids, lcons(inner_rel->relids, NIL));
-
- new_outer_tlist = nconc(new_outer_tlist,new_inner_tlist);
- joinrel->targetlist = new_outer_tlist;
-
- if (joininfo) {
- joinrel->clauseinfo = joininfo->jinfoclauseinfo;
- if (BushyPlanFlag) joininfo->inactive = true;
- }
-
- joinrel_joininfo_list =
- new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
- intAppend(outer_rel->relids, inner_rel->relids));
-
- joinrel->joininfo = joinrel_joininfo_list;
-
- geqo_joinrel_size(joinrel, outer_rel, inner_rel);
-
- return(joinrel);
+ Rel *joinrel = makeNode(Rel);
+ List *joinrel_joininfo_list = NIL;
+ List *new_outer_tlist;
+ List *new_inner_tlist;
+
+ /*
+ * Create a new tlist by removing irrelevant elements from both tlists
+ * of the outer and inner join relations and then merging the results
+ * together.
+ */
+ new_outer_tlist =
+ new_join_tlist(outer_rel->targetlist, /* XXX 1-based attnos */
+ inner_rel->relids, 1);
+ new_inner_tlist =
+ new_join_tlist(inner_rel->targetlist, /* XXX 1-based attnos */
+ outer_rel->relids,
+ length(new_outer_tlist) + 1);
+
+ joinrel->relids = NIL;
+ joinrel->indexed = false;
+ joinrel->pages = 0;
+ joinrel->tuples = 0;
+ joinrel->width = 0;
+/* joinrel->targetlist = NIL;*/
+ joinrel->pathlist = NIL;
+ joinrel->unorderedpath = (Path *) NULL;
+ joinrel->cheapestpath = (Path *) NULL;
+ joinrel->pruneable = true;
+ joinrel->classlist = NULL;
+ joinrel->relam = InvalidOid;
+ joinrel->ordering = NULL;
+ joinrel->clauseinfo = NIL;
+ joinrel->joininfo = NULL;
+ joinrel->innerjoin = NIL;
+ joinrel->superrels = NIL;
+
+ joinrel->relids = lcons(outer_rel->relids, lcons(inner_rel->relids, NIL));
+
+ new_outer_tlist = nconc(new_outer_tlist, new_inner_tlist);
+ joinrel->targetlist = new_outer_tlist;
+
+ if (joininfo)
+ {
+ joinrel->clauseinfo = joininfo->jinfoclauseinfo;
+ if (BushyPlanFlag)
+ joininfo->inactive = true;
+ }
+
+ joinrel_joininfo_list =
+ new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
+ intAppend(outer_rel->relids, inner_rel->relids));
+
+ joinrel->joininfo = joinrel_joininfo_list;
+
+ geqo_joinrel_size(joinrel, outer_rel, inner_rel);
+
+ return (joinrel);
}
-/*
+/*
* new-join-tlist--
- * Builds a join relations's target list by keeping those elements that
- * will be in the final target list and any other elements that are still
- * needed for future joins. For a target list entry to still be needed
- * for future joins, its 'joinlist' field must not be empty after removal
- * of all relids in 'other-relids'.
- *
+ * Builds a join relations's target list by keeping those elements that
+ * will be in the final target list and any other elements that are still
+ * needed for future joins. For a target list entry to still be needed
+ * for future joins, its 'joinlist' field must not be empty after removal
+ * of all relids in 'other-relids'.
+ *
* 'tlist' is the target list of one of the join relations
* 'other-relids' is a list of relids contained within the other
- * join relation
+ * join relation
* 'first-resdomno' is the resdom number to use for the first created
- * target list entry
- *
+ * target list entry
+ *
* Returns the new target list.
*/
-static List *
-new_join_tlist(List *tlist,
- List *other_relids,
- int first_resdomno)
+static List *
+new_join_tlist(List * tlist,
+ List * other_relids,
+ int first_resdomno)
{
- int resdomno = first_resdomno - 1;
- TargetEntry *xtl = NULL;
- List *temp_node = NIL;
- List *t_list = NIL;
- List *i = NIL;
- List *join_list = NIL;
- bool in_final_tlist =false;
-
-
- foreach(i,tlist) {
- xtl= lfirst(i);
- in_final_tlist = (join_list==NIL);
- if( in_final_tlist) {
- resdomno += 1;
- temp_node =
- lcons(create_tl_element(get_expr(xtl),
- resdomno),
- NIL);
- t_list = nconc(t_list,temp_node);
- }
- }
-
- return(t_list);
+ int resdomno = first_resdomno - 1;
+ TargetEntry *xtl = NULL;
+ List *temp_node = NIL;
+ List *t_list = NIL;
+ List *i = NIL;
+ List *join_list = NIL;
+ bool in_final_tlist = false;
+
+
+ foreach(i, tlist)
+ {
+ xtl = lfirst(i);
+ in_final_tlist = (join_list == NIL);
+ if (in_final_tlist)
+ {
+ resdomno += 1;
+ temp_node =
+ lcons(create_tl_element(get_expr(xtl),
+ resdomno),
+ NIL);
+ t_list = nconc(t_list, temp_node);
+ }
+ }
+
+ return (t_list);
}
-/*
+/*
* new-joininfo-list--
- * Builds a join relation's joininfo list by checking for join clauses
- * which still need to used in future joins involving this relation. A
- * join clause is still needed if there are still relations in the clause
- * not contained in the list of relations comprising this join relation.
- * New joininfo nodes are only created and added to
- * 'current-joininfo-list' if a node for a particular join hasn't already
- * been created.
+ * Builds a join relation's joininfo list by checking for join clauses
+ * which still need to used in future joins involving this relation. A
+ * join clause is still needed if there are still relations in the clause
+ * not contained in the list of relations comprising this join relation.
+ * New joininfo nodes are only created and added to
+ * 'current-joininfo-list' if a node for a particular join hasn't already
+ * been created.
*
- * 'current-joininfo-list' contains a list of those joininfo nodes that
- * have already been built
+ * 'current-joininfo-list' contains a list of those joininfo nodes that
+ * have already been built
* 'joininfo-list' is the list of join clauses involving this relation
- * 'join-relids' is a list of relids corresponding to the relations
- * currently being joined
- *
+ * 'join-relids' is a list of relids corresponding to the relations
+ * currently being joined
+ *
* Returns a list of joininfo nodes, new and old.
*/
-static List *
-new_joininfo_list(List *joininfo_list, List *join_relids)
+static List *
+new_joininfo_list(List * joininfo_list, List * join_relids)
{
- List *current_joininfo_list = NIL;
- List *new_otherrels = NIL;
- JInfo *other_joininfo = (JInfo*)NULL;
- List *xjoininfo = NIL;
-
- foreach (xjoininfo, joininfo_list) {
- List *or;
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
-
- new_otherrels = joininfo->otherrels;
- foreach (or, new_otherrels)
- {
- if ( intMember (lfirsti(or), join_relids) )
- new_otherrels = lremove ((void*)lfirst(or), new_otherrels);
- }
- joininfo->otherrels = new_otherrels;
- if ( new_otherrels != NIL )
+ List *current_joininfo_list = NIL;
+ List *new_otherrels = NIL;
+ JInfo *other_joininfo = (JInfo *) NULL;
+ List *xjoininfo = NIL;
+
+ foreach(xjoininfo, joininfo_list)
{
- other_joininfo = joininfo_member(new_otherrels,
- current_joininfo_list);
- if(other_joininfo) {
- other_joininfo->jinfoclauseinfo =
- (List*)LispUnion(joininfo->jinfoclauseinfo,
- other_joininfo->jinfoclauseinfo);
- }else {
- other_joininfo = makeNode(JInfo);
-
- other_joininfo->otherrels =
- joininfo->otherrels;
- other_joininfo->jinfoclauseinfo =
- joininfo->jinfoclauseinfo;
- other_joininfo->mergesortable =
- joininfo->mergesortable;
- other_joininfo->hashjoinable =
- joininfo->hashjoinable;
- other_joininfo->inactive = false;
-
- current_joininfo_list = lcons(other_joininfo,
- current_joininfo_list);
- }
+ List *or;
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ new_otherrels = joininfo->otherrels;
+ foreach(or, new_otherrels)
+ {
+ if (intMember(lfirsti(or), join_relids))
+ new_otherrels = lremove((void *) lfirst(or), new_otherrels);
+ }
+ joininfo->otherrels = new_otherrels;
+ if (new_otherrels != NIL)
+ {
+ other_joininfo = joininfo_member(new_otherrels,
+ current_joininfo_list);
+ if (other_joininfo)
+ {
+ other_joininfo->jinfoclauseinfo =
+ (List *) LispUnion(joininfo->jinfoclauseinfo,
+ other_joininfo->jinfoclauseinfo);
+ }
+ else
+ {
+ other_joininfo = makeNode(JInfo);
+
+ other_joininfo->otherrels =
+ joininfo->otherrels;
+ other_joininfo->jinfoclauseinfo =
+ joininfo->jinfoclauseinfo;
+ other_joininfo->mergesortable =
+ joininfo->mergesortable;
+ other_joininfo->hashjoinable =
+ joininfo->hashjoinable;
+ other_joininfo->inactive = false;
+
+ current_joininfo_list = lcons(other_joininfo,
+ current_joininfo_list);
+ }
+ }
}
- }
- return(current_joininfo_list);
+ return (current_joininfo_list);
}
#ifdef NOTUSED
/*
* add-new-joininfos--
- * For each new join relation, create new joininfos that
- * use the join relation as inner relation, and add
- * the new joininfos to those rel nodes that still
- * have joins with the join relation.
+ * For each new join relation, create new joininfos that
+ * use the join relation as inner relation, and add
+ * the new joininfos to those rel nodes that still
+ * have joins with the join relation.
*
* 'joinrels' is a list of join relations.
*
* Modifies the joininfo field of appropriate rel nodes.
*/
static void
-geqo_add_new_joininfos(Query *root, List *joinrels, List *outerrels)
+geqo_add_new_joininfos(Query * root, List * joinrels, List * outerrels)
{
- List *xjoinrel = NIL;
- List *xrelid = NIL;
- List *xrel = NIL;
- List *xjoininfo = NIL;
-
- Rel *rel;
- List *relids;
-
- List *super_rels;
- List *xsuper_rel = NIL;
- JInfo *new_joininfo;
-
- foreach(xjoinrel, joinrels) {
- Rel *joinrel = (Rel *)lfirst(xjoinrel);
- foreach(xrelid, joinrel->relids) {
- /* length(joinrel->relids) should always be greater that 1, because of *JOIN* */
- /* ! BUG BUG !
- Relid relid = (Relid)lfirst(xrelid);
- Rel *rel = get_join_rel(root, relid);
- */
-
- /*
- if ( (root->join_relation_list_) != NIL ) {
- rel = get_join_rel(root, xrelid);
- }
- else {
- rel = get_base_rel(root, lfirsti(xrelid));
- }
- */
-
- /* NOTE: STILL BUGGY FOR CLAUSE-JOINS: */
- /*
- relids = lconsi(lfirsti(xrelid), NIL);
- rel = rel_member(relids, outerrels);
- */
+ List *xjoinrel = NIL;
+ List *xrelid = NIL;
+ List *xrel = NIL;
+ List *xjoininfo = NIL;
+
+ Rel *rel;
+ List *relids;
+
+ List *super_rels;
+ List *xsuper_rel = NIL;
+ JInfo *new_joininfo;
+
+ foreach(xjoinrel, joinrels)
+ {
+ Rel *joinrel = (Rel *) lfirst(xjoinrel);
+
+ foreach(xrelid, joinrel->relids)
+ {
+
+ /*
+ * length(joinrel->relids) should always be greater that 1,
+ * because of *JOIN*
+ */
+
+ /*
+ * ! BUG BUG ! Relid relid = (Relid)lfirst(xrelid); Rel *rel =
+ * get_join_rel(root, relid);
+ */
- relids = lconsi(lfirsti(xrelid), NIL);
- rel = rel_member(relids, root->base_relation_list_);
+ /*
+ * if ( (root->join_relation_list_) != NIL ) { rel =
+ * get_join_rel(root, xrelid); } else { rel =
+ * get_base_rel(root, lfirsti(xrelid)); }
+ */
- add_superrels(rel,joinrel);
+ /* NOTE: STILL BUGGY FOR CLAUSE-JOINS: */
+
+ /*
+ * relids = lconsi(lfirsti(xrelid), NIL); rel =
+ * rel_member(relids, outerrels);
+ */
+
+ relids = lconsi(lfirsti(xrelid), NIL);
+ rel = rel_member(relids, root->base_relation_list_);
+
+ add_superrels(rel, joinrel);
+ }
}
- }
- foreach(xjoinrel, joinrels) {
- Rel *joinrel = (Rel *)lfirst(xjoinrel);
-
- foreach(xjoininfo, joinrel->joininfo) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
- List *other_rels = joininfo->otherrels;
- List *clause_info = joininfo->jinfoclauseinfo;
- bool mergesortable = joininfo->mergesortable;
- bool hashjoinable = joininfo->hashjoinable;
-
- foreach(xrelid, other_rels) {
- /* ! BUG BUG !
- Relid relid = (Relid)lfirst(xrelid);
- Rel *rel = get_join_rel(root, relid);
- */
-
- /*
- if ( (root->join_relation_list_) != NIL ) {
- rel = get_join_rel(root, xrelid);
- }
- else {
- rel = get_base_rel(root, lfirsti(xrelid));
- }
- */
-
- /* NOTE: STILL BUGGY FOR CLAUSE-JOINS: */
- /*
- relids = lconsi(lfirsti(xrelid), NIL);
- rel = rel_member(relids, outerrels);
- */
-
- relids = lconsi(lfirsti(xrelid), NIL);
- rel = rel_member(relids, root->base_relation_list_);
-
- super_rels = rel->superrels;
- new_joininfo = makeNode(JInfo);
-
- new_joininfo->otherrels = joinrel->relids;
- new_joininfo->jinfoclauseinfo = clause_info;
- new_joininfo->mergesortable = mergesortable;
- new_joininfo->hashjoinable = hashjoinable;
- new_joininfo->inactive = false;
- rel->joininfo =
- lappend(rel->joininfo, new_joininfo);
-
- foreach(xsuper_rel, super_rels) {
- Rel *super_rel = (Rel *)lfirst(xsuper_rel);
-
- if( nonoverlap_rels(super_rel,joinrel) ) {
- List *new_relids = super_rel->relids;
- JInfo *other_joininfo =
- joininfo_member(new_relids,
- joinrel->joininfo);
-
- if (other_joininfo) {
- other_joininfo->jinfoclauseinfo =
- (List*)LispUnion(clause_info,
- other_joininfo->jinfoclauseinfo);
- } else {
- JInfo *new_joininfo = makeNode(JInfo);
-
- new_joininfo->otherrels = new_relids;
- new_joininfo->jinfoclauseinfo = clause_info;
- new_joininfo->mergesortable = mergesortable;
- new_joininfo->hashjoinable = hashjoinable;
- new_joininfo->inactive = false;
- joinrel->joininfo =
- lappend(joinrel->joininfo,
- new_joininfo);
+ foreach(xjoinrel, joinrels)
+ {
+ Rel *joinrel = (Rel *) lfirst(xjoinrel);
+
+ foreach(xjoininfo, joinrel->joininfo)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+ List *other_rels = joininfo->otherrels;
+ List *clause_info = joininfo->jinfoclauseinfo;
+ bool mergesortable = joininfo->mergesortable;
+ bool hashjoinable = joininfo->hashjoinable;
+
+ foreach(xrelid, other_rels)
+ {
+
+ /*
+ * ! BUG BUG ! Relid relid = (Relid)lfirst(xrelid); Rel
+ * *rel = get_join_rel(root, relid);
+ */
+
+ /*
+ * if ( (root->join_relation_list_) != NIL ) { rel =
+ * get_join_rel(root, xrelid); } else { rel =
+ * get_base_rel(root, lfirsti(xrelid)); }
+ */
+
+ /* NOTE: STILL BUGGY FOR CLAUSE-JOINS: */
+
+ /*
+ * relids = lconsi(lfirsti(xrelid), NIL); rel =
+ * rel_member(relids, outerrels);
+ */
+
+ relids = lconsi(lfirsti(xrelid), NIL);
+ rel = rel_member(relids, root->base_relation_list_);
+
+ super_rels = rel->superrels;
+ new_joininfo = makeNode(JInfo);
+
+ new_joininfo->otherrels = joinrel->relids;
+ new_joininfo->jinfoclauseinfo = clause_info;
+ new_joininfo->mergesortable = mergesortable;
+ new_joininfo->hashjoinable = hashjoinable;
+ new_joininfo->inactive = false;
+ rel->joininfo =
+ lappend(rel->joininfo, new_joininfo);
+
+ foreach(xsuper_rel, super_rels)
+ {
+ Rel *super_rel = (Rel *) lfirst(xsuper_rel);
+
+ if (nonoverlap_rels(super_rel, joinrel))
+ {
+ List *new_relids = super_rel->relids;
+ JInfo *other_joininfo =
+ joininfo_member(new_relids,
+ joinrel->joininfo);
+
+ if (other_joininfo)
+ {
+ other_joininfo->jinfoclauseinfo =
+ (List *) LispUnion(clause_info,
+ other_joininfo->jinfoclauseinfo);
+ }
+ else
+ {
+ JInfo *new_joininfo = makeNode(JInfo);
+
+ new_joininfo->otherrels = new_relids;
+ new_joininfo->jinfoclauseinfo = clause_info;
+ new_joininfo->mergesortable = mergesortable;
+ new_joininfo->hashjoinable = hashjoinable;
+ new_joininfo->inactive = false;
+ joinrel->joininfo =
+ lappend(joinrel->joininfo,
+ new_joininfo);
+ }
+ }
+ }
}
- }
}
- }
}
- }
- foreach(xrel, outerrels) {
- rel = (Rel *)lfirst(xrel);
- rel->superrels = NIL;
- }
+ foreach(xrel, outerrels)
+ {
+ rel = (Rel *) lfirst(xrel);
+ rel->superrels = NIL;
+ }
}
/*
* final-join-rels--
- * Find the join relation that includes all the original
- * relations, i.e. the final join result.
+ * Find the join relation that includes all the original
+ * relations, i.e. the final join result.
*
* 'join-rel-list' is a list of join relations.
*
* Returns the list of final join relations.
*/
-static List *
-geqo_final_join_rels(List *join_rel_list)
+static List *
+geqo_final_join_rels(List * join_rel_list)
{
- List *xrel = NIL;
- List *temp = NIL;
- List *t_list = NIL;
-
- /*
- * find the relations that has no further joins,
- * i.e., its joininfos all have otherrels nil.
- */
- foreach(xrel,join_rel_list) {
- Rel *rel = (Rel *)lfirst(xrel);
- List *xjoininfo = NIL;
- bool final = true;
-
- foreach (xjoininfo, rel->joininfo) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
-
- if (joininfo->otherrels != NIL) {
- final = false;
- break;
- }
- }
- if (final) {
- temp = lcons(rel, NIL);
- t_list = nconc(t_list, temp);
+ List *xrel = NIL;
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ /*
+ * find the relations that has no further joins, i.e., its joininfos
+ * all have otherrels nil.
+ */
+ foreach(xrel, join_rel_list)
+ {
+ Rel *rel = (Rel *) lfirst(xrel);
+ List *xjoininfo = NIL;
+ bool final = true;
+
+ foreach(xjoininfo, rel->joininfo)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ if (joininfo->otherrels != NIL)
+ {
+ final = false;
+ break;
+ }
+ }
+ if (final)
+ {
+ temp = lcons(rel, NIL);
+ t_list = nconc(t_list, temp);
+ }
}
- }
- return(t_list);
+ return (t_list);
}
/*
* add_superrels--
- * add rel to the temporary property list superrels.
+ * add rel to the temporary property list superrels.
*
* 'rel' a rel node
* 'super-rel' rel node of a join relation that includes rel
@@ -599,65 +649,72 @@ geqo_final_join_rels(List *join_rel_list)
* Modifies the superrels field of rel
*/
static void
-add_superrels(Rel *rel, Rel *super_rel)
+add_superrels(Rel * rel, Rel * super_rel)
{
- rel->superrels = lappend(rel->superrels, super_rel);
+ rel->superrels = lappend(rel->superrels, super_rel);
}
/*
* nonoverlap-rels--
- * test if two join relations overlap, i.e., includes the same
- * relation.
+ * test if two join relations overlap, i.e., includes the same
+ * relation.
*
* 'rel1' and 'rel2' are two join relations
*
* Returns non-nil if rel1 and rel2 do not overlap.
*/
-static bool
-nonoverlap_rels(Rel *rel1, Rel *rel2)
+static bool
+nonoverlap_rels(Rel * rel1, Rel * rel2)
{
- return(nonoverlap_sets(rel1->relids, rel2->relids));
+ return (nonoverlap_sets(rel1->relids, rel2->relids));
}
-static bool
-nonoverlap_sets(List *s1, List *s2)
+static bool
+nonoverlap_sets(List * s1, List * s2)
{
- List *x = NIL;
-
- foreach(x,s1) {
- int e = lfirsti(x);
- if(intMember(e,s2))
- return(false);
- }
- return(true);
+ List *x = NIL;
+
+ foreach(x, s1)
+ {
+ int e = lfirsti(x);
+
+ if (intMember(e, s2))
+ return (false);
+ }
+ return (true);
}
-#endif /* NOTUSED */
+
+#endif /* NOTUSED */
/*
* geqo_joinrel_size--
- * compute estimate for join relation tuples, even for
- * long join queries; so get logarithm of size when MAXINT overflow;
+ * compute estimate for join relation tuples, even for
+ * long join queries; so get logarithm of size when MAXINT overflow;
*/
static void
-geqo_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel)
+geqo_joinrel_size(Rel * joinrel, Rel * outer_rel, Rel * inner_rel)
{
- Cost temp;
- int ntuples;
-
+ Cost temp;
+ int ntuples;
+
temp = (Cost) inner_rel->tuples * (Cost) outer_rel->tuples; /* cartesian product */
- if (joinrel->clauseinfo) {
+ if (joinrel->clauseinfo)
+ {
temp = temp * product_selec(joinrel->clauseinfo);
- }
-
- if (temp >= (MAXINT -1)) {
- ntuples = ceil( geqo_log((double)temp, (double) GEQO_LOG_BASE) );
- }
- else {
- ntuples = ceil((double)temp);
- }
+ }
- if (ntuples < 1) ntuples = 1; /* make the best case 1 instead of 0 */
+ if (temp >= (MAXINT - 1))
+ {
+ ntuples = ceil(geqo_log((double) temp, (double) GEQO_LOG_BASE));
+ }
+ else
+ {
+ ntuples = ceil((double) temp);
+ }
+
+ if (ntuples < 1)
+ ntuples = 1; /* make the best case 1 instead of 0 */
joinrel->tuples = ntuples;
}
@@ -665,19 +722,21 @@ geqo_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel)
double
geqo_log(double x, double b)
{
- return(log(x)/log(b));
+ return (log(x) / log(b));
}
-static Rel *
-geqo_nth(int stop, List *rels)
+static Rel *
+geqo_nth(int stop, List * rels)
{
- List *r;
- int i=1;
+ List *r;
+ int i = 1;
- foreach(r, rels) {
- if (i == stop) return lfirst(r);
+ foreach(r, rels)
+ {
+ if (i == stop)
+ return lfirst(r);
i++;
- }
- elog(WARN,"geqo_nth: Internal error - ran off end of list");
- return NULL; /* to keep compiler happy */
+ }
+ elog(WARN, "geqo_nth: Internal error - ran off end of list");
+ return NULL; /* to keep compiler happy */
}