From ba2883b264d7bc392604bc9f76abfc30de89f5f8 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 15 Feb 1999 03:22:37 +0000 Subject: [PATCH] Remove duplicate geqo functions, and more optimizer cleanup --- src/backend/nodes/copyfuncs.c | 6 +- src/backend/nodes/equalfuncs.c | 4 +- src/backend/nodes/freefuncs.c | 4 +- src/backend/nodes/outfuncs.c | 4 +- src/backend/optimizer/geqo/Makefile | 4 +- src/backend/optimizer/geqo/geqo_eval.c | 549 +---------------------- src/backend/optimizer/geqo/geqo_params.c | 9 +- src/backend/optimizer/geqo/geqo_paths.c | 104 ----- src/backend/optimizer/path/allpaths.c | 48 +- src/backend/optimizer/path/costsize.c | 18 +- src/backend/optimizer/path/indxpath.c | 16 +- src/backend/optimizer/path/joinpath.c | 3 +- src/backend/optimizer/path/joinrels.c | 97 ++-- src/backend/optimizer/path/mergeutils.c | 3 +- src/backend/optimizer/path/prune.c | 10 +- src/backend/optimizer/plan/initsplan.c | 8 +- src/backend/optimizer/plan/planmain.c | 13 +- src/backend/optimizer/util/joininfo.c | 4 +- src/backend/optimizer/util/pathnode.c | 18 +- src/backend/optimizer/util/relnode.c | 4 +- src/backend/tcop/postgres.c | 8 +- src/include/nodes/relation.h | 4 +- src/include/optimizer/geqo_paths.h | 28 -- src/include/optimizer/internal.h | 4 +- src/include/optimizer/paths.h | 15 +- src/include/storage/proc.h | 13 +- 26 files changed, 188 insertions(+), 810 deletions(-) delete mode 100644 src/backend/optimizer/geqo/geqo_paths.c delete mode 100644 src/include/optimizer/geqo_paths.h diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 41b689126f..ea60d4a7d7 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.70 1999/02/13 23:15:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.71 1999/02/15 03:21:58 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1420,7 +1420,7 @@ _copyMergeInfo(MergeInfo *from) * ---------------- */ static JoinInfo * -_copyJoinInfo(JoinInfo * from) +_copyJoinInfo(JoinInfo *from) { JoinInfo *newnode = makeNode(JoinInfo); @@ -1433,7 +1433,7 @@ _copyJoinInfo(JoinInfo * from) newnode->mergejoinable = from->mergejoinable; newnode->hashjoinable = from->hashjoinable; - newnode->inactive = from->inactive; + newnode->bushy_inactive = from->bushy_inactive; return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 98cf643454..5f24da3f34 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.32 1999/02/13 23:15:55 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.33 1999/02/15 03:21:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -522,7 +522,7 @@ _equalSubPlan(SubPlan *a, SubPlan *b) } static bool -_equalJoinInfo(JoinInfo * a, JoinInfo * b) +_equalJoinInfo(JoinInfo *a, JoinInfo *b) { Assert(IsA(a, JoinInfo)); Assert(IsA(b, JoinInfo)); diff --git a/src/backend/nodes/freefuncs.c b/src/backend/nodes/freefuncs.c index fb96af2a83..b533ee3d71 100644 --- a/src/backend/nodes/freefuncs.c +++ b/src/backend/nodes/freefuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.10 1999/02/13 23:15:56 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.11 1999/02/15 03:21:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1018,7 +1018,7 @@ _freeMergeInfo(MergeInfo *node) * ---------------- */ static void -_freeJoinInfo(JoinInfo * node) +_freeJoinInfo(JoinInfo *node) { /* ---------------- * free remainder of node diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index dda46b1f05..c39d4c6672 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: outfuncs.c,v 1.72 1999/02/13 23:15:59 momjian Exp $ + * $Id: outfuncs.c,v 1.73 1999/02/15 03:21:59 momjian Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -1196,7 +1196,7 @@ _outHashInfo(StringInfo str, HashInfo *node) * JoinInfo is a subclass of Node. */ static void -_outJoinInfo(StringInfo str, JoinInfo * node) +_outJoinInfo(StringInfo str, JoinInfo *node) { appendStringInfo(str, " JINFO :otherrels "); _outIntList(str, node->otherrels); diff --git a/src/backend/optimizer/geqo/Makefile b/src/backend/optimizer/geqo/Makefile index 9a2cef6602..4864300e64 100644 --- a/src/backend/optimizer/geqo/Makefile +++ b/src/backend/optimizer/geqo/Makefile @@ -5,7 +5,7 @@ # # Copyright (c) 1994, Regents of the University of California # -# $Id: Makefile,v 1.10 1998/04/06 00:23:07 momjian Exp $ +# $Id: Makefile,v 1.11 1999/02/15 03:22:00 momjian Exp $ # #------------------------------------------------------------------------- @@ -19,7 +19,7 @@ CFLAGS+= -Wno-error endif OBJS = geqo_copy.o geqo_eval.o geqo_main.o geqo_misc.o \ - geqo_params.o geqo_paths.o geqo_pool.o geqo_recombination.o \ + geqo_params.o geqo_pool.o geqo_recombination.o \ geqo_selection.o \ geqo_erx.o geqo_pmx.o geqo_cx.o geqo_px.o geqo_ox1.o geqo_ox2.o diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c index 00dbffa4ea..a109ecc48e 100644 --- a/src/backend/optimizer/geqo/geqo_eval.c +++ b/src/backend/optimizer/geqo/geqo_eval.c @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: geqo_eval.c,v 1.31 1999/02/15 02:04:58 tgl Exp $ + * $Id: geqo_eval.c,v 1.32 1999/02/15 03:22:00 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -47,15 +47,7 @@ #include "optimizer/geqo_gene.h" #include "optimizer/geqo.h" -#include "optimizer/geqo_paths.h" - -static List *gimme_clause_joins(Query *root, RelOptInfo *outer_rel, RelOptInfo *inner_rel); -static RelOptInfo *gimme_clauseless_join(RelOptInfo *outer_rel, RelOptInfo *inner_rel); -static RelOptInfo *init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * 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(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel); static RelOptInfo *geqo_nth(int stop, List *rels); /* @@ -123,15 +115,18 @@ gimme_tree(Query *root, Gene *tour, int rel_count, int num_gene, RelOptInfo *out } else { /* tree main part */ - - if (!(new_rels = gimme_clause_joins(root, outer_rel, inner_rel))) + if (!(new_rels = make_rels_by_clause_joins(root, outer_rel, + inner_rel->joininfo, + inner_rel->relids))) { +#ifdef NOT_USED if (BushyPlanFlag) - { - new_rels = lcons(gimme_clauseless_join(outer_rel, outer_rel), NIL); /* ??? MAU */ - } + new_rels = make_rels_by_clauseless_joins(outer_rel, + lcons(outer_rel,NIL)); else - new_rels = lcons(gimme_clauseless_join(outer_rel, inner_rel), NIL); +#endif + new_rels = make_rels_by_clauseless_joins(outer_rel, + lcons(inner_rel,NIL)); } /* process new_rel->pathlist */ @@ -150,7 +145,7 @@ gimme_tree(Query *root, Gene *tour, int rel_count, int num_gene, RelOptInfo *out * not possible */ if (length(new_rels) > 1) - new_rels = geqo_prune_rels(new_rels); + merge_rels_with_same_relids(new_rels); if (length(new_rels) > 1) { /* should never be reached ... */ @@ -161,7 +156,7 @@ gimme_tree(Query *root, Gene *tour, int rel_count, int num_gene, RelOptInfo *out new_rel = (RelOptInfo *) lfirst(new_rels); rel_count++; - geqo_set_cheapest(new_rel); + set_cheapest(new_rel, new_rel->pathlist); /* processing of other new_rel attributes */ if (new_rel->size <= 0) @@ -178,526 +173,6 @@ gimme_tree(Query *root, Gene *tour, int rel_count, int num_gene, RelOptInfo *out 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, RelOptInfo *outer_rel, RelOptInfo *inner_rel) -{ - List *join_list = NIL; - List *i = NIL; - List *joininfo_list = (List *) outer_rel->joininfo; - - foreach(i, joininfo_list) - { - JoinInfo *joininfo = (JoinInfo *) lfirst(i); - RelOptInfo *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; - - if (rel != NULL) - join_list = lappend(join_list, rel); - - } - } - } - - 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' - * - * Returns a new join relation. - */ - -static RelOptInfo * -gimme_clauseless_join(RelOptInfo *outer_rel, RelOptInfo *inner_rel) -{ - return init_join_rel(outer_rel, inner_rel, (JoinInfo *) NULL); -} - -/* - * init_join_rel - * Creates and initializes a new join relation. - * - * 'outer_rel' and 'inner_rel' are relation nodes for the relations to be - * joined - * 'joininfo' is the joininfo node(join clause) containing both - * 'outer_rel' and 'inner_rel', if any exists - * - * Returns the new join relation node. - */ -static RelOptInfo * -init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo) -{ - RelOptInfo *joinrel = makeNode(RelOptInfo); - 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->cheapestpath = (Path *) NULL; - joinrel->pruneable = true; - joinrel->classlist = NULL; - joinrel->relam = InvalidOid; - joinrel->ordering = NULL; - joinrel->restrictinfo = 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->restrictinfo = joininfo->jinfo_restrictinfo; - 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'. - * - * 'tlist' is the target list of one of the join relations - * 'other_relids' is a list of relids contained within the other - * join relation - * 'first_resdomno' is the resdom number to use for the first created - * target list entry - * - * Returns the new target list. - */ -static List * -new_join_tlist(List *tlist, - List *other_relids, - int first_resdomno) -{ - int resdomno = first_resdomno - 1; - TargetEntry *xtl = NULL; - List *t_list = NIL; - List *i = NIL; - List *join_list = NIL; - bool in_final_tlist = false; - - foreach(i, tlist) - { - xtl = lfirst(i); - /* XXX surely this is wrong? join_list is never changed? tgl 2/99 */ - in_final_tlist = (join_list == NIL); - if (in_final_tlist) - { - resdomno += 1; - t_list = lappend(t_list, - create_tl_element(get_expr(xtl), resdomno)); - } - } - - 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. - * - * '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 - * - * Returns a list of joininfo nodes, new and old. - */ -static List * -new_joininfo_list(List *joininfo_list, List *join_relids) -{ - List *current_joininfo_list = NIL; - List *new_otherrels = NIL; - JoinInfo *other_joininfo = (JoinInfo *) NULL; - List *xjoininfo = NIL; - - foreach(xjoininfo, joininfo_list) - { - List *or; - JoinInfo *joininfo = (JoinInfo *) 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->jinfo_restrictinfo = - (List *) LispUnion(joininfo->jinfo_restrictinfo, - other_joininfo->jinfo_restrictinfo); - } - else - { - other_joininfo = makeNode(JoinInfo); - - other_joininfo->otherrels = joininfo->otherrels; - other_joininfo->jinfo_restrictinfo = joininfo->jinfo_restrictinfo; - other_joininfo->mergejoinable = joininfo->mergejoinable; - other_joininfo->hashjoinable = joininfo->hashjoinable; - other_joininfo->inactive = false; - - current_joininfo_list = lcons(other_joininfo, - 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. - * - * '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) -{ - List *xjoinrel = NIL; - List *xrelid = NIL; - List *xrel = NIL; - List *xjoininfo = NIL; - - RelOptInfo *rel; - List *relids; - - List *super_rels; - List *xsuper_rel = NIL; - JoinInfo *new_joininfo; - - foreach(xjoinrel, joinrels) - { - RelOptInfo *joinrel = (RelOptInfo *) 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); RelOptInfo - * *rel = get_join_rel(root, relid); - */ - - /* - * if ( (root->join_rel_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_rel_list); - - add_superrels(rel, joinrel); - } - } - foreach(xjoinrel, joinrels) - { - RelOptInfo *joinrel = (RelOptInfo *) lfirst(xjoinrel); - - foreach(xjoininfo, joinrel->joininfo) - { - JoinInfo *joininfo = (JoinInfo *) lfirst(xjoininfo); - List *other_rels = joininfo->otherrels; - List *restrict_info = joininfo->jinfo_restrictinfo; - bool mergejoinable = joininfo->mergejoinable; - bool hashjoinable = joininfo->hashjoinable; - - foreach(xrelid, other_rels) - { - - /* - * ! BUG BUG ! Relid relid = (Relid)lfirst(xrelid); - * RelOptInfo *rel = get_join_rel(root, relid); - */ - - /* - * if ( (root->join_rel_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_rel_list); - - super_rels = rel->superrels; - new_joininfo = makeNode(JoinInfo); - - new_joininfo->otherrels = joinrel->relids; - new_joininfo->jinfo_restrictinfo = restrict_info; - new_joininfo->mergejoinable = mergejoinable; - new_joininfo->hashjoinable = hashjoinable; - new_joininfo->inactive = false; - rel->joininfo = lappend(rel->joininfo, new_joininfo); - - foreach(xsuper_rel, super_rels) - { - RelOptInfo *super_rel = (RelOptInfo *) lfirst(xsuper_rel); - - if (nonoverlap_rels(super_rel, joinrel)) - { - List *new_relids = super_rel->relids; - JoinInfo *other_joininfo = joininfo_member(new_relids, - joinrel->joininfo); - - if (other_joininfo) - { - other_joininfo->jinfo_restrictinfo = - (List *) LispUnion(restrict_info, - other_joininfo->jinfo_restrictinfo); - } - else - { - JoinInfo *new_joininfo = makeNode(JoinInfo); - - new_joininfo->otherrels = new_relids; - new_joininfo->jinfo_restrictinfo = restrict_info; - new_joininfo->mergejoinable = mergejoinable; - new_joininfo->hashjoinable = hashjoinable; - new_joininfo->inactive = false; - joinrel->joininfo = lappend(joinrel->joininfo, - new_joininfo); - } - } - } - } - } - } - foreach(xrel, outerrels) - { - rel = (RelOptInfo *) lfirst(xrel); - rel->superrels = NIL; - } -} - -/* - * final_join_rels - * 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) -{ - List *xrel = 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) - { - RelOptInfo *rel = (RelOptInfo *) lfirst(xrel); - List *xjoininfo = NIL; - bool final = true; - - foreach(xjoininfo, rel->joininfo) - { - JoinInfo *joininfo = (JoinInfo *) lfirst(xjoininfo); - - if (joininfo->otherrels != NIL) - { - final = false; - break; - } - } - if (final) - { - t_list = lappend(t_list, rel); - } - } - - return t_list; -} - -/* - * add_superrels - * add rel to the temporary property list superrels. - * - * 'rel' a rel node - * 'super_rel' rel node of a join relation that includes rel - * - * Modifies the superrels field of rel - */ -static void -add_superrels(RelOptInfo *rel, RelOptInfo *super_rel) -{ - rel->superrels = lappend(rel->superrels, super_rel); -} - -/* - * nonoverlap_rels - * 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(RelOptInfo *rel1, RelOptInfo *rel2) -{ - return nonoverlap_sets(rel1->relids, rel2->relids); -} - -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; -} - -#endif /* NOTUSED */ - -/* - * geqo_joinrel_size - * compute estimate for join relation tuples, even for - * long join queries; so get logarithm of size when MAXINT overflow; - */ -static void -geqo_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel) -{ - Cost temp; - int ntuples; - - temp = (Cost) inner_rel->tuples * (Cost) outer_rel->tuples; /* cartesian product */ - - if (joinrel->restrictinfo) - temp = temp * product_selec(joinrel->restrictinfo); - - 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; -} - -double -geqo_log(double x, double b) -{ - return log(x) / log(b); -} - static RelOptInfo * geqo_nth(int stop, List *rels) { diff --git a/src/backend/optimizer/geqo/geqo_params.c b/src/backend/optimizer/geqo/geqo_params.c index 56fa631282..1c664c1b3b 100644 --- a/src/backend/optimizer/geqo/geqo_params.c +++ b/src/backend/optimizer/geqo/geqo_params.c @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * -* $Id: geqo_params.c,v 1.13 1999/02/13 23:16:10 momjian Exp $ +* $Id: geqo_params.c,v 1.14 1999/02/15 03:22:01 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -61,6 +61,7 @@ static int gimme_pool_size(int string_length); static int gimme_number_generations(int pool_size, int effort); static int next_token(FILE *, char *, int); +static double geqo_log(double x, double b); /* * geqo_param @@ -338,3 +339,9 @@ gimme_number_generations(int pool_size, int effort) return effort * number_gens; } + +static double +geqo_log(double x, double b) +{ + return (log(x) / log(b)); +} diff --git a/src/backend/optimizer/geqo/geqo_paths.c b/src/backend/optimizer/geqo/geqo_paths.c deleted file mode 100644 index 8f1902a18c..0000000000 --- a/src/backend/optimizer/geqo/geqo_paths.c +++ /dev/null @@ -1,104 +0,0 @@ -/*------------------------------------------------------------------------- - * - * geqo_paths.c - * Routines to process redundant paths and relations - * - * Copyright (c) 1994, Regents of the University of California - * - * $Id: geqo_paths.c,v 1.21 1999/02/15 02:04:58 tgl Exp $ - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include "nodes/pg_list.h" -#include "nodes/relation.h" -#include "nodes/primnodes.h" - -#include "utils/palloc.h" -#include "utils/elog.h" - -#include "optimizer/internal.h" -#include "optimizer/paths.h" -#include "optimizer/pathnode.h" -#include "optimizer/clauses.h" -#include "optimizer/cost.h" - -#include "optimizer/geqo_paths.h" - - -static List *geqo_prune_rel(RelOptInfo *rel, List *other_rels); - -/* - * geqo_prune_rels - * Removes any redundant relation entries from a list of rel nodes - * 'rel_list'. - * - * Returns the resulting list. - * - */ -List * -geqo_prune_rels(List *rel_list) -{ - List *temp_list = NIL; - - if (rel_list != NIL) - { - temp_list = lcons(lfirst(rel_list), - geqo_prune_rels(geqo_prune_rel((RelOptInfo *) lfirst(rel_list), - lnext(rel_list)))); - } - return temp_list; -} - -/* - * geqo_prune_rel - * Prunes those relations from 'other_rels' that are redundant with - * 'rel'. A relation is redundant if it is built up of the same - * relations as 'rel'. Paths for the redundant relation are merged into - * the pathlist of 'rel'. - * - * Returns a list of non-redundant relations, and sets the pathlist field - * of 'rel' appropriately. - * - */ -static List * -geqo_prune_rel(RelOptInfo *rel, List *other_rels) -{ - List *t_list = NIL; - List *i; - RelOptInfo *other_rel; - - foreach(i, other_rels) - { - other_rel = (RelOptInfo *) lfirst(i); - if (same(rel->relids, other_rel->relids)) - { - rel->pathlist = add_pathlist(rel, - rel->pathlist, - other_rel->pathlist); - } - else - { - t_list = lappend(t_list, other_rel); - } - } - return t_list; -} - -/* - * geqo_set_cheapest - * For a relation 'rel' (which corresponds to a join - * relation), set pointers to the cheapest path - */ -void -geqo_set_cheapest(RelOptInfo *rel) -{ - JoinPath *cheapest = (JoinPath *)set_cheapest(rel, rel->pathlist); - - if (IsA_JoinPath(cheapest)) - rel->size = compute_joinrel_size(cheapest); - else - rel->size = 0; -} diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 3c7b111769..eec20b250d 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.34 1999/02/14 05:27:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.35 1999/02/15 03:22:03 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -44,7 +44,7 @@ int32 _use_geqo_rels_ = GEQO_RELS; static void find_base_rel_paths(Query *root, List *rels); -static List *find_join_paths(Query *root, List *outer_rels, int levels_needed); +static RelOptInfo *make_one_rel_by_joins(Query *root, List *outer_rels, int levels_needed); #ifdef OPTIMIZER_DEBUG static void debug_print_rel(Query *root, RelOptInfo *rel); @@ -52,14 +52,14 @@ static void debug_print_rel(Query *root, RelOptInfo *rel); #endif /* - * find_paths - * Finds all possible access paths for executing a query, returning the - * top level list of relation entries. + * make_one_rel + * Finds all possible access paths for executing a query, returning a + * single rel. * * 'rels' is the list of single relation entries appearing in the query */ -List * -find_paths(Query *root, List *rels) +RelOptInfo * +make_one_rel(Query *root, List *rels) { int levels_needed; @@ -69,7 +69,7 @@ find_paths(Query *root, List *rels) levels_needed = length(rels); if (levels_needed <= 0) - return NIL; + return NULL; find_base_rel_paths(root, rels); @@ -78,7 +78,7 @@ find_paths(Query *root, List *rels) /* * Unsorted single relation, no more processing is required. */ - return rels; + return lfirst(rels); } else { @@ -88,7 +88,7 @@ find_paths(Query *root, List *rels) */ set_rest_relselec(root, rels); - return find_join_paths(root, rels, levels_needed); + return make_one_rel_by_joins(root, rels, levels_needed); } } @@ -142,7 +142,7 @@ find_base_rel_paths(Query *root, List *rels) } /* - * find_join_paths + * make_one_rel_by_joins * Find all possible joinpaths for a query by successively finding ways * to join single relations into join relations. * @@ -158,8 +158,8 @@ find_base_rel_paths(Query *root, List *rels) * Returns the final level of join relations, i.e., the relation that is * the result of joining all the original relations together. */ -static List * -find_join_paths(Query *root, List *outer_rels, int levels_needed) +static RelOptInfo * +make_one_rel_by_joins(Query *root, List *outer_rels, int levels_needed) { List *x; List *joined_rels = NIL; @@ -170,7 +170,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed) * * *******************************************/ if ((_use_geqo_) && length(root->base_rel_list) >= _use_geqo_rels_) - return lcons(geqo(root), NIL); /* returns *one* Rel, so lcons it */ + return geqo(root); /******************************************* * rest will be deprecated in case of GEQO * @@ -184,7 +184,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed) * modify 'joined_rels' accordingly, then eliminate redundant join * relations. */ - joined_rels = make_new_rels_by_joins(root, outer_rels); + joined_rels = make_rels_by_joins(root, outer_rels); update_rels_pathlist_for_joins(root, joined_rels); @@ -202,9 +202,9 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed) rels_set_cheapest(joined_rels); +#ifdef NOT_USED if (BushyPlanFlag) { - /* * In case of bushy trees if there is still a join between a * join relation and another relation, add a new joininfo that @@ -213,6 +213,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed) */ add_new_joininfos(root, joined_rels, outer_rels); } +#endif foreach(x, joined_rels) { @@ -228,6 +229,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed) #endif } +#ifdef NOT_USED if (BushyPlanFlag) { /* @@ -243,16 +245,24 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed) root->join_rel_list = outer_rels; } else - root->join_rel_list = joined_rels; +#endif + root->join_rel_list = joined_rels; +#ifdef NOT_USED if (!BushyPlanFlag) - outer_rels = joined_rels; +#endif + outer_rels = joined_rels; + } + Assert(length(joined_rels) == 1); + +#ifdef NOT_USED if (BushyPlanFlag) return final_join_rels(outer_rels); else - return joined_rels; +#endif + return lfirst(joined_rels); } /***************************************************************************** diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index facadef913..cb30dec42c 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.32 1999/02/13 23:16:16 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.33 1999/02/15 03:22:04 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -440,21 +440,19 @@ compute_joinrel_size(JoinPath *joinpath) Cost temp = 1.0; int temp1 = 0; + /* cartesian product */ temp *= ((Path *) joinpath->outerjoinpath)->parent->size; temp *= ((Path *) joinpath->innerjoinpath)->parent->size; temp = temp * product_selec(joinpath->pathinfo); - if (temp >= (MAXINT - 1)) - temp1 = MAXINT; - else + if (temp >= (MAXINT-1)/2) { - - /* - * should be ceil here, we don't want joinrel size's of one, do - * we? - */ - temp1 = ceil((double) temp); + /* if we exceed (MAXINT-1)/2, we switch to log scale */ + /* +1 prevents log(0) */ + temp1 = ceil(log(temp + 1 - (MAXINT-1)/2) + (MAXINT-1)/2); } + else + temp1 = ceil((double) temp); Assert(temp1 >= 0); return temp1; diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 1c61688373..3a66153fa7 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.46 1999/02/15 02:04:55 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.47 1999/02/15 03:22:05 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1302,13 +1302,13 @@ index_innerjoin(Query *root, RelOptInfo *rel, List *clausegroup_list, pathnode->path.joinid = ((RestrictInfo *) lfirst(clausegroup))->restrictinfojoinid; pathnode->path.path_cost = cost_index((Oid) lfirsti(index->relids), - (int) temp_pages, - temp_selec, - rel->pages, - rel->tuples, - index->pages, - index->tuples, - true); + (int) temp_pages, + temp_selec, + rel->pages, + rel->tuples, + index->pages, + index->tuples, + true); /* * copy restrictinfo list into path for expensive function diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 9dd7580570..3577ebfda2 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.26 1999/02/15 02:04:57 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.27 1999/02/15 03:22:05 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -78,6 +78,7 @@ update_rels_pathlist_for_joins(Query *root, List *joinrels) Path *bestinnerjoin; List *pathlist = NIL; + /* flatten out relids later in this function */ innerrelids = lsecond(joinrel->relids); outerrelids = lfirst(joinrel->relids); diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index 5b063db4c7..cd0a082b73 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.22 1999/02/15 02:04:57 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.23 1999/02/15 03:22:05 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -31,20 +31,15 @@ bool _use_right_sided_plans_ = false; #endif -static List *find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list); -static List *find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels); -static RelOptInfo *init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * 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 add_superrels(RelOptInfo *rel, RelOptInfo *super_rel); static bool nonoverlap_rels(RelOptInfo *rel1, RelOptInfo *rel2); static bool nonoverlap_sets(List *s1, List *s2); static void set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, - JoinInfo * jinfo); + JoinInfo *jinfo); /* - * make_new_rels_by_joins + * make_rels_by_joins * Find all possible joins for each of the outer join relations in * 'outer_rels'. A rel node is created for each possible join relation, * and the resulting list of nodes is returned. If at all possible, only @@ -57,7 +52,7 @@ static void set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptI * Returns a list of rel nodes corresponding to the new join relations. */ List * -make_new_rels_by_joins(Query *root, List *outer_rels) +make_rels_by_joins(Query *root, List *outer_rels) { List *joins = NIL; List *join_list = NIL; @@ -67,16 +62,20 @@ make_new_rels_by_joins(Query *root, List *outer_rels) { RelOptInfo *outer_rel = (RelOptInfo *) lfirst(r); - if (!(joins = find_clause_joins(root, outer_rel, outer_rel->joininfo))) + if (!(joins = make_rels_by_clause_joins(root, outer_rel, + outer_rel->joininfo, + NIL))) { /* * Oops, we have a relation that is not joined to any other * relation. Cartesian product time. */ +#ifdef NOT_USED if (BushyPlanFlag) - joins = find_clauseless_joins(outer_rel, outer_rels); + joins = make_rels_by_clauseless_joins(outer_rel, outer_rels); else - joins = find_clauseless_joins(outer_rel, root->base_rel_list); +#endif + joins = make_rels_by_clauseless_joins(outer_rel, root->base_rel_list); } join_list = nconc(join_list, joins); @@ -86,7 +85,7 @@ make_new_rels_by_joins(Query *root, List *outer_rels) } /* - * find_clause_joins + * make_rels_by_clause_joins * Determines whether joins can be performed between an outer relation * 'outer_rel' and those relations within 'outer_rel's joininfo nodes * (i.e., relations that participate in join clauses that 'outer_rel' @@ -100,8 +99,9 @@ make_new_rels_by_joins(Query *root, List *outer_rels) * * Returns a list of new join relations. */ -static List * -find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list) +List * +make_rels_by_clause_joins(Query *root, RelOptInfo *outer_rel, + List *joininfo_list, List *only_relids) { List *join_list = NIL; List *i = NIL; @@ -111,15 +111,18 @@ find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list) JoinInfo *joininfo = (JoinInfo *) lfirst(i); RelOptInfo *rel; - if (!joininfo->inactive) + if (!joininfo->bushy_inactive) { List *other_rels = joininfo->otherrels; if (other_rels != NIL) { - if (length(other_rels) == 1) + if (length(other_rels) == 1 && + (only_relids == NIL || + /* geqo only wants certain relids to make new rels */ + same(joininfo->otherrels, only_relids))) { - rel = init_join_rel(outer_rel, + rel = make_join_rel(outer_rel, get_base_rel(root, lfirsti(other_rels)), joininfo); /* how about right-sided plan ? */ @@ -128,18 +131,20 @@ find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list) { if (rel != NULL) join_list = lappend(join_list, rel); - rel = init_join_rel(get_base_rel(root, + rel = make_join_rel(get_base_rel(root, lfirsti(other_rels)), outer_rel, joininfo); } } +#ifdef NOT_USED else if (BushyPlanFlag) { - rel = init_join_rel(outer_rel, + rel = make_join_rel(outer_rel, get_join_rel(root, other_rels), joininfo); } +#endif else rel = NULL; @@ -153,15 +158,15 @@ find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list) } /* - * find_clauseless_joins + * make_rels_by_clauseless_joins * Given an outer relation 'outer_rel' and a list of inner relations * 'inner_rels', create a join relation between 'outer_rel' and each * member of 'inner_rels' that isn't already included in 'outer_rel'. * * Returns a list of new join relations. */ -static List * -find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels) +List * +make_rels_by_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels) { RelOptInfo *inner_rel; List *t_list = NIL; @@ -173,7 +178,7 @@ find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels) if (nonoverlap_rels(inner_rel, outer_rel)) { t_list = lappend(t_list, - init_join_rel(outer_rel, + make_join_rel(outer_rel, inner_rel, (JoinInfo *) NULL)); } @@ -183,7 +188,7 @@ find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels) } /* - * init_join_rel + * make_join_rel * Creates and initializes a new join relation. * * 'outer_rel' and 'inner_rel' are relation nodes for the relations to be @@ -193,8 +198,8 @@ find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels) * * Returns the new join relation node. */ -static RelOptInfo * -init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo) +RelOptInfo * +make_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo *joininfo) { RelOptInfo *joinrel = makeNode(RelOptInfo); List *joinrel_joininfo_list = NIL; @@ -217,7 +222,7 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo) joinrel->pages = 0; joinrel->tuples = 0; joinrel->width = 0; -/* joinrel->targetlist = NIL;*/ +/* joinrel->targetlist = NIL;*/ joinrel->pathlist = NIL; joinrel->cheapestpath = (Path *) NULL; joinrel->pruneable = true; @@ -229,9 +234,11 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo) joinrel->innerjoin = NIL; joinrel->superrels = NIL; - joinrel->relids = lcons(outer_rel->relids, /* ??? aren't they lists? - * -ay */ - lcons(inner_rel->relids, NIL)); + /* + * This function uses a trick to pass inner/outer rels as + * different lists, and then flattens it out later. + */ + 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; @@ -239,8 +246,10 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo) if (joininfo) { joinrel->restrictinfo = joininfo->jinfo_restrictinfo; +#ifdef NOT_USED if (BushyPlanFlag) - joininfo->inactive = true; + joininfo->bushy_inactive = true; +#endif } joinrel_joininfo_list = new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo), @@ -269,7 +278,7 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo) * * Returns the new target list. */ -static List * +List * new_join_tlist(List *tlist, List *other_relids, int first_resdomno) @@ -352,7 +361,7 @@ new_joininfo_list(List *joininfo_list, List *join_relids) other_joininfo->jinfo_restrictinfo = joininfo->jinfo_restrictinfo; other_joininfo->mergejoinable = joininfo->mergejoinable; other_joininfo->hashjoinable = joininfo->hashjoinable; - other_joininfo->inactive = false; + other_joininfo->bushy_inactive = false; current_joininfo_list = lcons(other_joininfo, current_joininfo_list); @@ -418,7 +427,7 @@ add_new_joininfos(Query *root, List *joinrels, List *outerrels) new_joininfo->jinfo_restrictinfo = restrict_info; new_joininfo->mergejoinable = mergejoinable; new_joininfo->hashjoinable = hashjoinable; - new_joininfo->inactive = false; + new_joininfo->bushy_inactive = false; rel->joininfo = lappend(rel->joininfo, new_joininfo); foreach(xsuper_rel, super_rels) @@ -444,7 +453,7 @@ add_new_joininfos(Query *root, List *joinrels, List *outerrels) new_joininfo->jinfo_restrictinfo = restrict_info; new_joininfo->mergejoinable = mergejoinable; new_joininfo->hashjoinable = hashjoinable; - new_joininfo->inactive = false; + new_joininfo->bushy_inactive = false; joinrel->joininfo = lappend(joinrel->joininfo, new_joininfo); } @@ -461,6 +470,7 @@ add_new_joininfos(Query *root, List *joinrels, List *outerrels) } } +#ifdef NOT_USED /* * final_join_rels * Find the join relation that includes all the original @@ -470,11 +480,11 @@ add_new_joininfos(Query *root, List *joinrels, List *outerrels) * * Returns the list of final join relations. */ -List * +RelOptInfo * final_join_rels(List *join_rel_list) { List *xrel = NIL; - List *t_list = NIL; + RelOptInfo *final_rel = NULL; /* * find the relations that has no further joins, i.e., its joininfos @@ -497,13 +507,14 @@ final_join_rels(List *join_rel_list) } } if (final) - { - t_list = lappend(t_list, rel); - } + if (final_rel == NULL || + path_is_cheaper(rel->cheapestpath, final_rel->cheapestpath)) + final_rel = rel; } - return t_list; + return final_rel; } +#endif /* * add_superrels @@ -551,7 +562,7 @@ nonoverlap_sets(List *s1, List *s2) } static void -set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * jinfo) +set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo *jinfo) { int ntuples; float selec; diff --git a/src/backend/optimizer/path/mergeutils.c b/src/backend/optimizer/path/mergeutils.c index d6af886f1e..7d0009c3e8 100644 --- a/src/backend/optimizer/path/mergeutils.c +++ b/src/backend/optimizer/path/mergeutils.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.18 1999/02/13 23:16:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.19 1999/02/15 03:22:06 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -47,7 +47,6 @@ group_clauses_by_order(List *restrictinfo_list, if (merge_ordering) { - /* * Create a new mergeinfo node and add it to 'mergeinfo_list' * if one does not yet exist for this merge ordering. diff --git a/src/backend/optimizer/path/prune.c b/src/backend/optimizer/path/prune.c index 828b8cce80..ab1e8fff66 100644 --- a/src/backend/optimizer/path/prune.c +++ b/src/backend/optimizer/path/prune.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.32 1999/02/14 04:56:47 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.33 1999/02/15 03:22:06 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -106,7 +106,7 @@ rels_set_cheapest(List *rel_list) } } - +#ifdef NOT_USED /* * merge_joinrels * Given two lists of rel nodes that are already @@ -133,7 +133,7 @@ merge_joinrels(List *rel_list1, List *rel_list2) /* * prune_oldrels - * If all the joininfo's in a rel node are inactive, + * If all the joininfo's in a rel node are bushy_inactive, * that means that this node has been joined into * other nodes in all possible ways, therefore * this node can be discarded. If not, it will cause @@ -165,7 +165,7 @@ prune_oldrels(List *old_rels) { JoinInfo *joininfo = (JoinInfo *) lfirst(xjoininfo); - if (!joininfo->inactive) + if (!joininfo->bushy_inactive) { temp_list = lcons(rel, temp_list); break; @@ -175,3 +175,5 @@ prune_oldrels(List *old_rels) } return temp_list; } +#endif + diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e379a2bbed..bb6b48b536 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.25 1999/02/15 01:06:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.26 1999/02/15 03:22:11 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -339,14 +339,14 @@ set_joininfo_mergeable_hashable(List *rel_list) if (_enable_mergejoin_) sortop = mergejoinop(clause); - if (_enable_hashjoin_) - hashop = hashjoinop(clause); - if (sortop) { restrictinfo->mergejoinorder = sortop; joininfo->mergejoinable = true; } + + if (_enable_hashjoin_) + hashop = hashjoinop(clause); if (hashop) { restrictinfo->hashjoinoperator = hashop; diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index ff84df67ed..24b746e606 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.32 1999/02/14 04:56:50 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.33 1999/02/15 03:22:12 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -215,7 +215,6 @@ query_planner(Query *root, } #ifdef NOT_USED - /* * Destructively modify the query plan's targetlist to add fjoin lists * to flatten functions that return sets of base types @@ -243,7 +242,6 @@ subplanner(Query *root, List *qual) { RelOptInfo *final_rel; - List *final_rel_list; /* * Initialize the targetlist and qualification, adding entries to @@ -259,12 +257,7 @@ subplanner(Query *root, set_joininfo_mergeable_hashable(root->base_rel_list); - final_rel_list = find_paths(root, root->base_rel_list); - - if (final_rel_list) - final_rel = (RelOptInfo *) lfirst(final_rel_list); - else - final_rel = (RelOptInfo *) NIL; + final_rel = make_one_rel(root, root->base_rel_list); #if 0 /* fix xfunc */ @@ -297,7 +290,7 @@ subplanner(Query *root, return create_plan((Path *) final_rel->cheapestpath); else { - elog(NOTICE, "final relation is nil"); + elog(NOTICE, "final relation is null"); return create_plan((Path *) NULL); } diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c index 4b9dce6e5a..339a455018 100644 --- a/src/backend/optimizer/util/joininfo.c +++ b/src/backend/optimizer/util/joininfo.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/joininfo.c,v 1.15 1999/02/13 23:16:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/joininfo.c,v 1.16 1999/02/15 03:22:16 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -74,7 +74,7 @@ find_joininfo_node(RelOptInfo *this_rel, List *join_relids) joininfo->jinfo_restrictinfo = NIL; joininfo->mergejoinable = false; joininfo->hashjoinable = false; - joininfo->inactive = false; + joininfo->bushy_inactive = false; this_rel->joininfo = lcons(joininfo, this_rel->joininfo); } return joininfo; diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index cf3072a8be..8e72cabb74 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.35 1999/02/13 23:16:46 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.36 1999/02/15 03:22:16 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -381,15 +381,15 @@ create_index_path(Query *root, /* 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 */ + index->pages, + 1.0, + 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 = (pathnode->path_cost + diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 1b0c1d6947..63c0ca4f47 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.13 1999/02/13 23:16:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.14 1999/02/15 03:22:17 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -64,14 +64,12 @@ get_base_rel(Query *root, int relid) */ if (relid < 0) { - /* * If the relation is a materialized relation, assume * constants for sizes. */ rel->pages = _NONAME_RELATION_PAGES_; rel->tuples = _NONAME_RELATION_TUPLES_; - } else { diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 059772767f..adf4ddd43e 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.99 1999/02/13 23:18:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.100 1999/02/15 03:22:21 momjian Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -173,8 +173,10 @@ int UseNewLine = 0; /* Use EOF as query delimiters */ * plans * ---------------- */ +#ifdef NOT_USED int BushyPlanFlag = 0; /* default to false -- consider only * left-deep trees */ +#endif /* ** Flags for expensive function optimization -- JMH 3/9/92 @@ -1041,6 +1043,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) #endif break; +#ifdef NOT_USED case 'b': /* ---------------- * set BushyPlanFlag to true. @@ -1048,6 +1051,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) */ BushyPlanFlag = 1; break; +#endif case 'B': /* ---------------- @@ -1538,7 +1542,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.99 $ $Date: 1999/02/13 23:18:45 $\n"); + puts("$Revision: 1.100 $ $Date: 1999/02/15 03:22:21 $\n"); } /* ---------------- diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index f3f08f8efa..250fc29dfe 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: relation.h,v 1.23 1999/02/13 23:21:42 momjian Exp $ + * $Id: relation.h,v 1.24 1999/02/15 03:22:23 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -250,7 +250,7 @@ typedef struct JoinInfo List *jinfo_restrictinfo; bool mergejoinable; bool hashjoinable; - bool inactive; + bool bushy_inactive; } JoinInfo; typedef struct Iter diff --git a/src/include/optimizer/geqo_paths.h b/src/include/optimizer/geqo_paths.h deleted file mode 100644 index 2a62b459be..0000000000 --- a/src/include/optimizer/geqo_paths.h +++ /dev/null @@ -1,28 +0,0 @@ -/*------------------------------------------------------------------------- - * - * geqo_paths.h - * prototypes for various subroutines in geqo_path.c - * - * Copyright (c) 1994, Regents of the University of California - * - * $Id: geqo_paths.h,v 1.9 1999/02/13 23:21:47 momjian Exp $ - * - *------------------------------------------------------------------------- - */ - -/* contributed by: - =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= - * Martin Utesch * Institute of Automatic Control * - = = University of Mining and Technology = - * utesch@aut.tu-freiberg.de * Freiberg, Germany * - =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= - */ - -#ifndef GEQO_PATHS_H -#define GEQO_PATHS_H - - -extern List *geqo_prune_rels(List *rel_list); -extern void geqo_set_cheapest(RelOptInfo *rel); - -#endif /* GEQO_PATHS_H */ diff --git a/src/include/optimizer/internal.h b/src/include/optimizer/internal.h index d818cec770..c372e63e5d 100644 --- a/src/include/optimizer/internal.h +++ b/src/include/optimizer/internal.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: internal.h,v 1.14 1999/02/13 23:21:49 momjian Exp $ + * $Id: internal.h,v 1.15 1999/02/15 03:22:31 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -80,7 +80,9 @@ #define FLOAT_EQUAL(X,Y) ((X) - (Y) < TOLERANCE) #define FLOAT_IS_ZERO(X) (FLOAT_EQUAL(X,0.0)) +#ifdef NOT_USED extern int BushyPlanFlag; +#endif /* #define deactivate_joininfo(joininfo) joininfo->inactive=true*/ /*#define joininfo_inactive(joininfo) joininfo->inactive */ diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 99a1cad980..990cf79224 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -7,7 +7,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: paths.h,v 1.16 1999/02/14 04:56:55 momjian Exp $ + * $Id: paths.h,v 1.17 1999/02/15 03:22:31 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -21,7 +21,7 @@ /* * allpaths.h */ -extern List *find_paths(Query *root, List *rels); +extern RelOptInfo *make_one_rel(Query *root, List *rels); /* * indxpath.h @@ -77,16 +77,19 @@ extern MergeInfo *match_order_mergeinfo(PathOrder *ordering, * joinrels.h * routines to determine which relations to join */ -extern List *make_new_rels_by_joins(Query *root, List *outer_rels); +extern List *make_rels_by_joins(Query *root, List *outer_rels); extern void add_new_joininfos(Query *root, List *joinrels, List *outerrels); -extern List *final_join_rels(List *join_rel_list); +extern List *make_rels_by_clause_joins(Query *root, RelOptInfo *outer_rel, + List *joininfo_list, List *only_relids); +extern List *make_rels_by_clauseless_joins(RelOptInfo *outer_rel, + List *inner_rels); +extern RelOptInfo *make_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo *joininfo); +extern List *new_join_tlist(List *tlist, List *other_relids,int first_resdomno); /* * prototypes for path/prune.c */ extern void merge_rels_with_same_relids(List *rel_list); extern void rels_set_cheapest(List *rel_list); -extern List *merge_joinrels(List *rel_list1, List *rel_list2); -extern List *prune_oldrels(List *old_rels); #endif /* PATHS_H */ diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index aae5b70442..e58572b0c7 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: proc.h,v 1.17 1999/02/13 23:22:09 momjian Exp $ + * $Id: proc.h,v 1.18 1999/02/15 03:22:37 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -75,8 +75,15 @@ typedef struct procglobal extern PROC *MyProc; -#define PROC_INCR_SLOCK(lock) if (MyProc) ((MyProc->sLocks[(lock)])++) -#define PROC_DECR_SLOCK(lock) if (MyProc) ((MyProc->sLocks[(lock)])--) +#define PROC_INCR_SLOCK(lock) \ +do { \ + if (MyProc) (MyProc->sLocks[(lock)])++; \ +} while (0) + +#define PROC_DECR_SLOCK(lock) \ +do { \ + if (MyProc) (MyProc->sLocks[(lock)])--; \ +} while (0) /* * flags explaining why process woke up