From 3fdb9bb9c74afa79f574438cbbf5178d30463bb6 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 12 Feb 1999 05:57:08 +0000 Subject: [PATCH] Fix optimizer and make faster. --- src/backend/nodes/copyfuncs.c | 3 +- src/backend/nodes/freefuncs.c | 3 +- src/backend/nodes/outfuncs.c | 5 +-- src/backend/nodes/readfuncs.c | 8 +--- src/backend/optimizer/geqo/geqo_eval.c | 6 +-- src/backend/optimizer/geqo/geqo_paths.c | 58 +++---------------------- src/backend/optimizer/path/allpaths.c | 6 +-- src/backend/optimizer/path/joinrels.c | 3 +- src/backend/optimizer/path/prune.c | 55 +++-------------------- src/backend/optimizer/util/indexnode.c | 3 +- src/backend/optimizer/util/pathnode.c | 36 ++++++++++++--- src/backend/optimizer/util/relnode.c | 3 +- src/include/nodes/relation.h | 7 +-- src/include/optimizer/geqo_paths.h | 4 +- src/include/optimizer/paths.h | 5 +-- 15 files changed, 60 insertions(+), 145 deletions(-) diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 867ea731c4..30d93ad012 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.67 1999/02/11 14:58:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.68 1999/02/12 05:56:45 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1026,7 +1026,6 @@ _copyRelOptInfo(RelOptInfo * from) newnode->width = from->width; Node_Copy(from, newnode, targetlist); Node_Copy(from, newnode, pathlist); - Node_Copy(from, newnode, unorderedpath); Node_Copy(from, newnode, cheapestpath); newnode->pruneable = from->pruneable; diff --git a/src/backend/nodes/freefuncs.c b/src/backend/nodes/freefuncs.c index 5079855cde..42b1135c40 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.7 1999/02/11 14:58:49 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.8 1999/02/12 05:56:45 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -724,7 +724,6 @@ _freeRelOptInfo(RelOptInfo *node) freeObject(node->targetlist); freeObject(node->pathlist); - freeObject(node->unorderedpath); freeObject(node->cheapestpath); if (node->classlist) diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index eb15c4e66b..15b39c7faf 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.69 1999/02/11 14:58:49 momjian Exp $ + * $Id: outfuncs.c,v 1.70 1999/02/12 05:56:46 momjian Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -879,8 +879,7 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node) */ appendStringInfo(str, - " :unorderedpath @ 0x%x :cheapestpath @ 0x%x :pruneable %s :restrictinfo ", - (int) node->unorderedpath, + " :cheapestpath @ 0x%x :pruneable %s :restrictinfo ", (int) node->cheapestpath, node->pruneable ? "true" : "false"); _outNode(str, node->restrictinfo); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index f069e95af3..18317684ab 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.54 1999/02/11 14:58:49 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.55 1999/02/12 05:56:46 momjian Exp $ * * NOTES * Most of the read functions for plan nodes are tested. (In fact, they @@ -1334,12 +1334,6 @@ _readRelOptInfo() * This can be changed later, if necessary. */ - token = lsptok(NULL, &length); /* get :unorderpath */ - token = lsptok(NULL, &length); /* get @ */ - token = lsptok(NULL, &length); /* now read it */ - - sscanf(token, "%x", (unsigned int *) &local_node->unorderedpath); - token = lsptok(NULL, &length); /* get :cheapestpath */ token = lsptok(NULL, &length); /* get @ */ token = lsptok(NULL, &length); /* now read it */ diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c index db1a351647..574cdb9c23 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.27 1999/02/10 21:02:34 momjian Exp $ + * $Id: geqo_eval.c,v 1.28 1999/02/12 05:56:47 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -161,8 +161,7 @@ gimme_tree(Query *root, Gene *tour, int rel_count, int num_gene, RelOptInfo *out new_rel = (RelOptInfo *) lfirst(new_rels); rel_count++; - /* process new_rel->cheapestpath, new_rel->unorderedpath */ - geqo_rel_paths(new_rel); + geqo_set_cheapest(new_rel); /* processing of other new_rel attributes */ if (new_rel->size <= 0) @@ -282,7 +281,6 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo) joinrel->width = 0; /* joinrel->targetlist = NIL;*/ joinrel->pathlist = NIL; - joinrel->unorderedpath = (Path *) NULL; joinrel->cheapestpath = (Path *) NULL; joinrel->pruneable = true; joinrel->classlist = NULL; diff --git a/src/backend/optimizer/geqo/geqo_paths.c b/src/backend/optimizer/geqo/geqo_paths.c index a04c1703f7..c372ebf2da 100644 --- a/src/backend/optimizer/geqo/geqo_paths.c +++ b/src/backend/optimizer/geqo/geqo_paths.c @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: geqo_paths.c,v 1.16 1999/02/11 14:58:50 momjian Exp $ + * $Id: geqo_paths.c,v 1.17 1999/02/12 05:56:48 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -29,7 +29,6 @@ static List *geqo_prune_rel(RelOptInfo *rel, List *other_rels); -static Path *set_paths(RelOptInfo *rel, Path *unorderedpath); /* * geqo-prune-rels-- @@ -92,62 +91,17 @@ geqo_prune_rel(RelOptInfo *rel, List *other_rels) } /* - * geqo-rel-paths-- + * geqo-set-cheapest-- * For a relation 'rel' (which corresponds to a join - * relation), set pointers to the unordered path and cheapest paths - * (if the unordered path isn't the cheapest, it is pruned), and - * reset the relation's size field to reflect the join. - * - * Returns nothing of interest. - * + * relation), set pointers to the cheapest path */ void -geqo_rel_paths(RelOptInfo *rel) +geqo_set_cheapest(RelOptInfo *rel) { - List *y = NIL; - Path *path = (Path *) NULL; - JoinPath *cheapest = (JoinPath *) NULL; + JoinPath *cheapest = (JoinPath *)set_cheapest(rel, rel->pathlist); - rel->size = 0; - foreach(y, rel->pathlist) - { - path = (Path *) lfirst(y); - - if (!path->pathorder->ord.sortop) - break; - } - - cheapest = (JoinPath *) set_paths(rel, path); if (IsA_JoinPath(cheapest)) rel->size = compute_joinrel_size(cheapest); -} - - -/* - * set-path-- - * Compares the unordered path for a relation with the cheapest path. If - * the unordered path is not cheapest, it is pruned. - * - * Resets the pointers in 'rel' for unordered and cheapest paths. - * - * Returns the cheapest path. - * - */ -static Path * -set_paths(RelOptInfo *rel, Path *unorderedpath) -{ - Path *cheapest = set_cheapest(rel, rel->pathlist); - - /* don't prune if not pruneable -- JMH, 11/23/92 */ - if (unorderedpath != cheapest - && rel->pruneable) - { - - rel->unorderedpath = (Path *) NULL; - rel->pathlist = lremove(unorderedpath, rel->pathlist); - } else - rel->unorderedpath = (Path *) unorderedpath; - - return cheapest; + rel->size = 0; } diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 90d75099be..c11f5cf7c8 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.27 1999/02/10 21:02:36 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.28 1999/02/12 05:56:49 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -139,7 +139,7 @@ find_rel_paths(Query *root, List *rels) lastpath = rel->pathlist; while (lnext(lastpath) != NIL) lastpath = lnext(lastpath); - prune_rel_path(rel, (Path *) lfirst(lastpath)); + set_cheapest(rel, rel->pathlist); /* * if there is a qualification of sequential scan the selec. value @@ -223,7 +223,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed) xfunc_trypullup((RelOptInfo *) lfirst(x)); #endif - prune_rel_paths(new_rels); + rels_set_cheapest(new_rels); if (BushyPlanFlag) { diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index a87248b485..a9f473c88a 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.18 1999/02/10 21:02:39 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.19 1999/02/12 05:56:50 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -216,7 +216,6 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo) joinrel->width = 0; /* joinrel->targetlist = NIL;*/ joinrel->pathlist = NIL; - joinrel->unorderedpath = (Path *) NULL; joinrel->cheapestpath = (Path *) NULL; joinrel->pruneable = true; joinrel->classlist = NULL; diff --git a/src/backend/optimizer/path/prune.c b/src/backend/optimizer/path/prune.c index c3cc734460..3be875db6d 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.27 1999/02/11 14:58:54 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.28 1999/02/12 05:56:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -77,42 +77,28 @@ prune_joinrel(RelOptInfo *rel, List *other_rels) rel->pathlist, other_rel->pathlist); else - result = nconc(result, lcons(other_rel, NIL)); + result = lappend(result, other_rel); } return result; } /* - * prune-rel-paths-- + * rels-set-cheapest * For each relation entry in 'rel-list' (which corresponds to a join - * relation), set pointers to the unordered path and cheapest paths - * (if the unordered path isn't the cheapest, it is pruned), and - * reset the relation's size field to reflect the join. - * - * Returns nothing of interest. - * + * relation), set pointers to the cheapest path */ void -prune_rel_paths(List *rel_list) +rels_set_cheapest(List *rel_list) { List *x = NIL; - List *y = NIL; - Path *path = NULL; RelOptInfo *rel = (RelOptInfo *) NULL; - JoinPath *cheapest = (JoinPath *) NULL; + JoinPath *cheapest; foreach(x, rel_list) { rel = (RelOptInfo *) lfirst(x); - rel->size = 0; - foreach(y, rel->pathlist) - { - path = (Path *) lfirst(y); - if (!path->pathorder->ord.sortop) - break; - } - cheapest = (JoinPath *) prune_rel_path(rel, path); + cheapest = (JoinPath *) set_cheapest(rel, rel->pathlist); if (IsA_JoinPath(cheapest)) rel->size = compute_joinrel_size(cheapest); else @@ -121,33 +107,6 @@ prune_rel_paths(List *rel_list) } -/* - * prune-rel-path-- - * Compares the unordered path for a relation with the cheapest path. If - * the unordered path is not cheapest, it is pruned. - * - * Resets the pointers in 'rel' for unordered and cheapest paths. - * - * Returns the cheapest path. - * - */ -Path * -prune_rel_path(RelOptInfo *rel, Path *unorderedpath) -{ - Path *cheapest = set_cheapest(rel, rel->pathlist); - - /* don't prune if not pruneable -- JMH, 11/23/92 */ - if (unorderedpath != cheapest && rel->pruneable) - { - rel->unorderedpath = (Path *) NULL; - rel->pathlist = lremove(unorderedpath, rel->pathlist); - } - else - rel->unorderedpath = (Path *) unorderedpath; - - return cheapest; -} - /* * merge-joinrels-- * Given two lists of rel nodes that are already diff --git a/src/backend/optimizer/util/indexnode.c b/src/backend/optimizer/util/indexnode.c index e1aab56d3a..dafeb8ddee 100644 --- a/src/backend/optimizer/util/indexnode.c +++ b/src/backend/optimizer/util/indexnode.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/indexnode.c,v 1.12 1999/02/10 21:02:40 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/indexnode.c,v 1.13 1999/02/12 05:56:55 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -78,7 +78,6 @@ find_secondary_index(Query *root, Oid relid) indexnode->width = 0; indexnode->targetlist = NIL; indexnode->pathlist = NIL; - indexnode->unorderedpath = NULL; indexnode->cheapestpath = NULL; indexnode->pruneable = true; indexnode->restrictinfo = NIL; diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 43db1bd267..f424fd0dc4 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.32 1999/02/12 02:37:52 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.33 1999/02/12 05:56:57 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -159,12 +159,21 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) List *temp = NIL; int better_key; int better_sort; - + +#ifdef OPTDUP_DEBUG + printf("better_path entry\n"); + printf("new\n"); + pprint(new_path); + printf("unique_paths\n"); + pprint(unique_paths); +#endif + foreach(temp, unique_paths) { path = (Path *) lfirst(temp); -#ifdef OPTDUP_DEBUG +#if 0 +/*def OPTDUP_DEBUG*/ if (!pathkeys_match(new_path->pathkeys, path->pathkeys, &better_key) || better_key != 0) { @@ -210,6 +219,13 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) (better_key != 2 && better_sort == 1)) && new_path->path_cost <= path->path_cost)) { +#ifdef OPTDUP_DEBUG + printf("replace with new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort); + printf("old\n"); + pprint(path); + printf("new\n"); + pprint(new_path); +#endif *is_new = false; return path; } @@ -223,12 +239,12 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) (better_key != 1 && better_sort == 2)) && new_path->path_cost >= path->path_cost)) { -#ifdef OPTDB_DEBUG - printf("better key %d better sort %d\n", better_key, better_sort); - printf("new\n"); - pprint(new_path); +#ifdef OPTDUP_DEBUG + printf("skip new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort); printf("old\n"); pprint(path); + printf("new\n"); + pprint(new_path); #endif *is_new = false; return NULL; @@ -236,6 +252,12 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) } } +#ifdef OPTDUP_DEBUG + printf("add new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort); + printf("new\n"); + pprint(new_path); +#endif + *is_new = true; return NULL; } diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 9706f654eb..fd474f65c0 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.11 1999/02/09 17:03:01 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.12 1999/02/12 05:56:58 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -45,7 +45,6 @@ get_base_rel(Query *root, int relid) rel->width = 0; rel->targetlist = NIL; rel->pathlist = NIL; - rel->unorderedpath = (Path *) NULL; rel->cheapestpath = (Path *) NULL; rel->pruneable = true; rel->classlist = NULL; diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index a672e05fe5..966f73732b 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.19 1999/02/11 14:59:03 momjian Exp $ + * $Id: relation.h,v 1.20 1999/02/12 05:57:01 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -41,10 +41,6 @@ typedef List *Relid; * targetlist - List of TargetList nodes * pathlist - List of Path nodes, one for each possible method of * generating the relation - * unorderedpath - a Path node generating this relation whose resulting - * tuples are unordered (this isn't necessarily a - * sequential scan path, e.g., scanning with a hash index - * leaves the tuples unordered) * cheapestpath - least expensive Path (regardless of final order) * pruneable - flag to let the planner know whether it can prune the plan * space of this RelOptInfo or not. @@ -88,7 +84,6 @@ typedef struct RelOptInfo /* materialization information */ List *targetlist; List *pathlist; /* Path structures */ - struct Path *unorderedpath; struct Path *cheapestpath; bool pruneable; diff --git a/src/include/optimizer/geqo_paths.h b/src/include/optimizer/geqo_paths.h index 507bba9056..abef40dd95 100644 --- a/src/include/optimizer/geqo_paths.h +++ b/src/include/optimizer/geqo_paths.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: geqo_paths.h,v 1.7 1999/02/10 21:02:47 momjian Exp $ + * $Id: geqo_paths.h,v 1.8 1999/02/12 05:57:06 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -23,6 +23,6 @@ extern List *geqo_prune_rels(List *rel_list); -extern void geqo_rel_paths(RelOptInfo *rel); +extern void geqo_set_cheapest(RelOptInfo *rel); #endif /* GEQO_PATHS_H */ diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 262505c6c3..e2f2046974 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.13 1999/02/10 21:02:49 momjian Exp $ + * $Id: paths.h,v 1.14 1999/02/12 05:57:08 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -85,8 +85,7 @@ extern List *final_join_rels(List *join_rel_list); * prototypes for path/prune.c */ extern void prune_joinrels(List *rel_list); -extern void prune_rel_paths(List *rel_list); -extern Path *prune_rel_path(RelOptInfo *rel, Path *unorderedpath); +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);