diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-01-09 00:26:47 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-01-09 00:26:47 +0000 |
commit | 166b5c1def56a8c43536ac64bd0ba92517f67765 (patch) | |
tree | 09a047af2ae3b27e0c071a2fd1fbd32785a66190 /src/backend/nodes | |
parent | 69d4299e3e534686274480ba245566914932c017 (diff) | |
download | postgresql-166b5c1def56a8c43536ac64bd0ba92517f67765.tar.gz postgresql-166b5c1def56a8c43536ac64bd0ba92517f67765.zip |
Another round of planner/optimizer work. This is just restructuring and
code cleanup; no major improvements yet. However, EXPLAIN does produce
more intuitive outputs for nested loops with indexscans now...
Diffstat (limited to 'src/backend/nodes')
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 54 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 19 | ||||
-rw-r--r-- | src/backend/nodes/freefuncs.c | 32 | ||||
-rw-r--r-- | src/backend/nodes/outfuncs.c | 52 | ||||
-rw-r--r-- | src/backend/nodes/print.c | 6 | ||||
-rw-r--r-- | src/backend/nodes/readfuncs.c | 71 |
6 files changed, 148 insertions, 86 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 884926b9b62..53bb27e3294 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.98 1999/12/13 01:26:53 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.99 2000/01/09 00:26:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -75,9 +75,9 @@ static void CopyPlanFields(Plan *from, Plan *newnode) { newnode->cost = from->cost; - newnode->plan_size = from->plan_size; + newnode->plan_rows = from->plan_rows; newnode->plan_width = from->plan_width; - newnode->plan_tupperpage = from->plan_tupperpage; + /* state is NOT copied */ newnode->targetlist = copyObject(from->targetlist); newnode->qual = copyObject(from->qual); newnode->lefttree = copyObject(from->lefttree); @@ -962,25 +962,44 @@ static RelOptInfo * _copyRelOptInfo(RelOptInfo *from) { RelOptInfo *newnode = makeNode(RelOptInfo); - int i, - len; - /* ---------------- - * copy remainder of node - * ---------------- - */ newnode->relids = listCopy(from->relids); - newnode->indexed = from->indexed; - newnode->pages = from->pages; - newnode->tuples = from->tuples; - newnode->size = from->size; + newnode->rows = from->rows; newnode->width = from->width; + Node_Copy(from, newnode, targetlist); Node_Copy(from, newnode, pathlist); + /* XXX cheapestpath should point to a member of pathlist? */ Node_Copy(from, newnode, cheapestpath); newnode->pruneable = from->pruneable; + newnode->indexed = from->indexed; + newnode->pages = from->pages; + newnode->tuples = from->tuples; + + Node_Copy(from, newnode, restrictinfo); + Node_Copy(from, newnode, joininfo); + Node_Copy(from, newnode, innerjoin); + + return newnode; +} + +/* ---------------- + * _copyIndexOptInfo + * ---------------- + */ +static IndexOptInfo * +_copyIndexOptInfo(IndexOptInfo *from) +{ + IndexOptInfo *newnode = makeNode(IndexOptInfo); + int i, + len; + + newnode->indexoid = from->indexoid; + newnode->pages = from->pages; + newnode->tuples = from->tuples; + if (from->classlist) { for (len = 0; from->classlist[len] != 0; len++) @@ -1015,10 +1034,6 @@ _copyRelOptInfo(RelOptInfo *from) newnode->indproc = from->indproc; Node_Copy(from, newnode, indpred); - Node_Copy(from, newnode, restrictinfo); - Node_Copy(from, newnode, joininfo); - Node_Copy(from, newnode, innerjoin); - return newnode; } @@ -1120,7 +1135,6 @@ _copyTidPath(TidPath *from) static void CopyJoinPathFields(JoinPath *from, JoinPath *newnode) { - Node_Copy(from, newnode, pathinfo); Node_Copy(from, newnode, outerjoinpath); Node_Copy(from, newnode, innerjoinpath); } @@ -1229,7 +1243,6 @@ _copyRestrictInfo(RestrictInfo *from) * ---------------- */ Node_Copy(from, newnode, clause); - newnode->selectivity = from->selectivity; Node_Copy(from, newnode, subclauseindices); newnode->mergejoinoperator = from->mergejoinoperator; newnode->left_sortop = from->left_sortop; @@ -1617,6 +1630,9 @@ copyObject(void *from) case T_Stream: retval = _copyStream(from); break; + case T_IndexOptInfo: + retval = _copyIndexOptInfo(from); + break; /* * PARSE NODES diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index cc23555c46f..8d4193e1ed5 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.54 1999/12/24 06:43:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.55 2000/01/09 00:26:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -303,6 +303,17 @@ _equalRelOptInfo(RelOptInfo *a, RelOptInfo *b) } static bool +_equalIndexOptInfo(IndexOptInfo *a, IndexOptInfo *b) +{ + /* We treat IndexOptInfos as equal if they refer to the same index. + * Is this sufficient? + */ + if (a->indexoid != b->indexoid) + return false; + return true; +} + +static bool _equalPathKeyItem(PathKeyItem *a, PathKeyItem *b) { if (a->sortop != b->sortop) @@ -358,8 +369,6 @@ _equalJoinPath(JoinPath *a, JoinPath *b) { if (!_equalPath((Path *) a, (Path *) b)) return false; - if (!equal(a->pathinfo, b->pathinfo)) - return false; if (!equal(a->outerjoinpath, b->outerjoinpath)) return false; if (!equal(a->innerjoinpath, b->innerjoinpath)) @@ -469,7 +478,6 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b) { if (!equal(a->clause, b->clause)) return false; - /* do not check selectivity because of roundoff error worries */ if (!equal(a->subclauseindices, b->subclauseindices)) return false; if (a->mergejoinoperator != b->mergejoinoperator) @@ -792,6 +800,9 @@ equal(void *a, void *b) case T_RelOptInfo: retval = _equalRelOptInfo(a, b); break; + case T_IndexOptInfo: + retval = _equalIndexOptInfo(a, b); + break; case T_PathKeyItem: retval = _equalPathKeyItem(a, b); break; diff --git a/src/backend/nodes/freefuncs.c b/src/backend/nodes/freefuncs.c index 7e9ae5d06f6..c11677b5b71 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.29 1999/12/16 22:19:47 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.30 2000/01/09 00:26:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -730,11 +730,29 @@ _freeRelOptInfo(RelOptInfo *node) freeObject(node->targetlist); freeObject(node->pathlist); - /* is this right? cheapestpath will typically be a pointer into + /* XXX is this right? cheapestpath will typically be a pointer into * pathlist, won't it? */ freeObject(node->cheapestpath); + freeObject(node->restrictinfo); + freeObject(node->joininfo); + freeObject(node->innerjoin); + + pfree(node); +} + +/* ---------------- + * _freeIndexOptInfo + * ---------------- + */ +static void +_freeIndexOptInfo(IndexOptInfo *node) +{ + /* ---------------- + * free remainder of node + * ---------------- + */ if (node->classlist) pfree(node->classlist); @@ -746,10 +764,6 @@ _freeRelOptInfo(RelOptInfo *node) freeObject(node->indpred); - freeObject(node->restrictinfo); - freeObject(node->joininfo); - freeObject(node->innerjoin); - pfree(node); } @@ -837,7 +851,6 @@ _freeTidPath(TidPath *node) static void FreeJoinPathFields(JoinPath *node) { - freeObject(node->pathinfo); freeObject(node->outerjoinpath); freeObject(node->innerjoinpath); } @@ -936,7 +949,7 @@ _freeRestrictInfo(RestrictInfo *node) * ---------------- */ freeObject(node->clause); - /* this is certainly wrong? index RelOptInfos don't belong to + /* this is certainly wrong? IndexOptInfos don't belong to * RestrictInfo... */ freeObject(node->subclauseindices); @@ -1253,6 +1266,9 @@ freeObject(void *node) case T_Stream: _freeStream(node); break; + case T_IndexOptInfo: + _freeIndexOptInfo(node); + break; /* * PARSE NODES diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 7907f1b62ef..1c8754fef57 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.100 1999/12/13 01:26:53 tgl Exp $ + * $Id: outfuncs.c,v 1.101 2000/01/09 00:26:23 tgl Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -265,9 +265,9 @@ static void _outPlanInfo(StringInfo str, Plan *node) { appendStringInfo(str, - ":cost %g :size %d :width %d :state %s :qptargetlist ", + ":cost %g :rows %.0f :width %d :state %s :qptargetlist ", node->cost, - node->plan_size, + node->plan_rows, node->plan_width, node->state ? "not-NULL" : "<>"); _outNode(str, node->targetlist); @@ -834,6 +834,7 @@ _outEState(StringInfo str, EState *node) /* * Stuff from relation.h */ + static void _outRelOptInfo(StringInfo str, RelOptInfo *node) { @@ -841,12 +842,12 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node) _outIntList(str, node->relids); appendStringInfo(str, - " :indexed %s :pages %u :tuples %u :size %u :width %u :targetlist ", + " :rows %.0f :width %d :indexed %s :pages %ld :tuples %.0f :targetlist ", + node->rows, + node->width, node->indexed ? "true" : "false", node->pages, - node->tuples, - node->size, - node->width); + node->tuples); _outNode(str, node->targetlist); appendStringInfo(str, " :pathlist "); @@ -871,6 +872,15 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node) _outNode(str, node->innerjoin); } +static void +_outIndexOptInfo(StringInfo str, IndexOptInfo *node) +{ + appendStringInfo(str, " INDEXOPTINFO :indexoid %u :pages %ld :tuples %g ", + node->indexoid, + node->pages, + node->tuples); +} + /* * TargetEntry is a subclass of Node. */ @@ -910,7 +920,7 @@ _outRowMark(StringInfo str, RowMark *node) static void _outPath(StringInfo str, Path *node) { - appendStringInfo(str, " PATH :pathtype %d :cost %f :pathkeys ", + appendStringInfo(str, " PATH :pathtype %d :cost %.2f :pathkeys ", node->pathtype, node->path_cost); _outNode(str, node->pathkeys); @@ -923,7 +933,7 @@ static void _outIndexPath(StringInfo str, IndexPath *node) { appendStringInfo(str, - " INDEXPATH :pathtype %d :cost %f :pathkeys ", + " INDEXPATH :pathtype %d :cost %.2f :pathkeys ", node->path.pathtype, node->path.path_cost); _outNode(str, node->path.pathkeys); @@ -945,7 +955,7 @@ static void _outTidPath(StringInfo str, TidPath *node) { appendStringInfo(str, - " TIDPATH :pathtype %d :cost %f :pathkeys ", + " TIDPATH :pathtype %d :cost %.2f :pathkeys ", node->path.pathtype, node->path.path_cost); _outNode(str, node->path.pathkeys); @@ -964,14 +974,11 @@ static void _outNestPath(StringInfo str, NestPath *node) { appendStringInfo(str, - " NESTPATH :pathtype %d :cost %f :pathkeys ", + " NESTPATH :pathtype %d :cost %.2f :pathkeys ", node->path.pathtype, node->path.path_cost); _outNode(str, node->path.pathkeys); - appendStringInfo(str, " :pathinfo "); - _outNode(str, node->pathinfo); - /* * Not sure if these are nodes; they're declared as "struct path *". * For now, i'll just print the addresses. @@ -990,14 +997,11 @@ static void _outMergePath(StringInfo str, MergePath *node) { appendStringInfo(str, - " MERGEPATH :pathtype %d :cost %f :pathkeys ", + " MERGEPATH :pathtype %d :cost %.2f :pathkeys ", node->jpath.path.pathtype, node->jpath.path.path_cost); _outNode(str, node->jpath.path.pathkeys); - appendStringInfo(str, " :pathinfo "); - _outNode(str, node->jpath.pathinfo); - /* * Not sure if these are nodes; they're declared as "struct path *". * For now, i'll just print the addresses. @@ -1025,14 +1029,11 @@ static void _outHashPath(StringInfo str, HashPath *node) { appendStringInfo(str, - " HASHPATH :pathtype %d :cost %f :pathkeys ", + " HASHPATH :pathtype %d :cost %.2f :pathkeys ", node->jpath.path.pathtype, node->jpath.path.path_cost); _outNode(str, node->jpath.path.pathkeys); - appendStringInfo(str, " :pathinfo "); - _outNode(str, node->jpath.pathinfo); - /* * Not sure if these are nodes; they're declared as "struct path *". * For now, i'll just print the addresses. @@ -1067,9 +1068,7 @@ _outRestrictInfo(StringInfo str, RestrictInfo *node) appendStringInfo(str, " RESTRICTINFO :clause "); _outNode(str, node->clause); - appendStringInfo(str, - " :selectivity %f :subclauseindices ", - node->selectivity); + appendStringInfo(str, " :subclauseindices "); _outNode(str, node->subclauseindices); appendStringInfo(str, " :mergejoinoperator %u ", node->mergejoinoperator); @@ -1466,6 +1465,9 @@ _outNode(StringInfo str, void *obj) case T_RelOptInfo: _outRelOptInfo(str, obj); break; + case T_IndexOptInfo: + _outIndexOptInfo(str, obj); + break; case T_TargetEntry: _outTargetEntry(str, obj); break; diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c index 3241816cd38..bfd30ff8a7f 100644 --- a/src/backend/nodes/print.c +++ b/src/backend/nodes/print.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.33 1999/11/23 20:06:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.34 2000/01/09 00:26:24 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -364,8 +364,8 @@ print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label) return; for (i = 0; i < indentLevel; i++) printf(" "); - printf("%s%s :c=%.4f :s=%d :w=%d ", label, plannode_type(p), - p->cost, p->plan_size, p->plan_width); + printf("%s%s :c=%.4f :r=%.0f :w=%d ", label, plannode_type(p), + p->cost, p->plan_rows, p->plan_width); if (IsA(p, Scan) ||IsA(p, SeqScan)) { RangeTblEntry *rte; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 83683ff3b10..8f7bb5271ac 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.76 1999/12/13 01:26:54 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.77 2000/01/09 00:26:24 tgl Exp $ * * NOTES * Most of the read functions for plan nodes are tested. (In fact, they @@ -233,9 +233,9 @@ _getPlan(Plan *node) token = lsptok(NULL, &length); /* next is the actual cost */ node->cost = (Cost) atof(token); - token = lsptok(NULL, &length); /* skip the :size */ - token = lsptok(NULL, &length); /* get the plan_size */ - node->plan_size = atoi(token); + token = lsptok(NULL, &length); /* skip the :rows */ + token = lsptok(NULL, &length); /* get the plan_rows */ + node->plan_rows = atof(token); token = lsptok(NULL, &length); /* skip the :width */ token = lsptok(NULL, &length); /* get the plan_width */ @@ -1293,6 +1293,14 @@ _readRelOptInfo() token = lsptok(NULL, &length); /* get :relids */ local_node->relids = toIntList(nodeRead(true)); /* now read it */ + token = lsptok(NULL, &length); /* get :rows */ + token = lsptok(NULL, &length); /* now read it */ + local_node->rows = atof(token); + + token = lsptok(NULL, &length); /* get :width */ + token = lsptok(NULL, &length); /* now read it */ + local_node->width = atoi(token); + token = lsptok(NULL, &length); /* get :indexed */ token = lsptok(NULL, &length); /* now read it */ @@ -1303,19 +1311,11 @@ _readRelOptInfo() token = lsptok(NULL, &length); /* get :pages */ token = lsptok(NULL, &length); /* now read it */ - local_node->pages = (unsigned int) atoi(token); + local_node->pages = atol(token); token = lsptok(NULL, &length); /* get :tuples */ token = lsptok(NULL, &length); /* now read it */ - local_node->tuples = (unsigned int) atoi(token); - - token = lsptok(NULL, &length); /* get :size */ - token = lsptok(NULL, &length); /* now read it */ - local_node->size = (unsigned int) atoi(token); - - token = lsptok(NULL, &length); /* get :width */ - token = lsptok(NULL, &length); /* now read it */ - local_node->width = (unsigned int) atoi(token); + local_node->tuples = atof(token); token = lsptok(NULL, &length); /* get :targetlist */ local_node->targetlist = nodeRead(true); /* now read it */ @@ -1349,6 +1349,34 @@ _readRelOptInfo() } /* ---------------- + * _readIndexOptInfo + * ---------------- + */ +static IndexOptInfo * +_readIndexOptInfo() +{ + IndexOptInfo *local_node; + char *token; + int length; + + local_node = makeNode(IndexOptInfo); + + token = lsptok(NULL, &length); /* get :indexoid */ + token = lsptok(NULL, &length); /* now read it */ + local_node->indexoid = (Oid) atoi(token); + + token = lsptok(NULL, &length); /* get :pages */ + token = lsptok(NULL, &length); /* now read it */ + local_node->pages = atol(token); + + token = lsptok(NULL, &length); /* get :tuples */ + token = lsptok(NULL, &length); /* now read it */ + local_node->tuples = atof(token); + + return local_node; +} + +/* ---------------- * _readTargetEntry * ---------------- */ @@ -1572,9 +1600,6 @@ _readNestPath() token = lsptok(NULL, &length); /* get :pathkeys */ local_node->path.pathkeys = nodeRead(true); /* now read it */ - token = lsptok(NULL, &length); /* get :pathinfo */ - local_node->pathinfo = nodeRead(true); /* now read it */ - /* * Not sure if these are nodes; they're declared as "struct path *". * For now, i'll just print the addresses. @@ -1626,9 +1651,6 @@ _readMergePath() token = lsptok(NULL, &length); /* get :pathkeys */ local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */ - token = lsptok(NULL, &length); /* get :pathinfo */ - local_node->jpath.pathinfo = nodeRead(true); /* now read it */ - /* * Not sure if these are nodes; they're declared as "struct path *". * For now, i'll just print the addresses. @@ -1689,9 +1711,6 @@ _readHashPath() token = lsptok(NULL, &length); /* get :pathkeys */ local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */ - token = lsptok(NULL, &length); /* get :pathinfo */ - local_node->jpath.pathinfo = nodeRead(true); /* now read it */ - /* * Not sure if these are nodes; they're declared as "struct path *". * For now, i'll just print the addresses. @@ -1762,10 +1781,6 @@ _readRestrictInfo() token = lsptok(NULL, &length); /* get :clause */ local_node->clause = nodeRead(true); /* now read it */ - token = lsptok(NULL, &length); /* get :selectivity */ - token = lsptok(NULL, &length); /* now read it */ - local_node->selectivity = atof(token); - token = lsptok(NULL, &length); /* get :subclauseindices */ local_node->subclauseindices = nodeRead(true); /* now read it */ @@ -1909,6 +1924,8 @@ parsePlanString(void) return_value = _readEState(); else if (!strncmp(token, "RELOPTINFO", length)) return_value = _readRelOptInfo(); + else if (!strncmp(token, "INDEXOPTINFO", length)) + return_value = _readIndexOptInfo(); else if (!strncmp(token, "TARGETENTRY", length)) return_value = _readTargetEntry(); else if (!strncmp(token, "RTE", length)) |