diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-11-06 00:00:45 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-11-06 00:00:45 +0000 |
commit | f6dba10e623fa575c8446f854aa63c97d4fedea3 (patch) | |
tree | 2c5eb86c8e2961c90b524b49f25e3c25efa6eee2 /src/backend/nodes | |
parent | a8c18b980e1e00fe08ac02562f81e3e64d4e9fd4 (diff) |
First phase of implementing hash-based grouping/aggregation. An AGG plan
node now does its own grouping of the input rows, and has no need for a
preceding GROUP node in the plan pipeline. This allows elimination of
the misnamed tuplePerGroup option for GROUP, and actually saves more code
in nodeGroup.c than it costs in nodeAgg.c, as well as being presumably
faster. Restructure the API of query_planner so that we do not commit to
using a sorted or unsorted plan in query_planner; instead grouping_planner
makes the decision. (Right now it isn't any smarter than query_planner
was, but that will change as soon as it has the option to select a hash-
based aggregation step.) Despite all the hackery, no initdb needed since
only in-memory node types changed.
Diffstat (limited to 'src/backend/nodes')
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 41 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 17 | ||||
-rw-r--r-- | src/backend/nodes/outfuncs.c | 33 | ||||
-rw-r--r-- | src/backend/nodes/readfuncs.c | 56 |
4 files changed, 123 insertions, 24 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 5fff2f762ab..0438e0ce609 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.214 2002/10/14 22:14:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.215 2002/11/06 00:00:43 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -497,10 +497,10 @@ _copyGroup(Group *from) CopyPlanFields((Plan *) from, (Plan *) newnode); - newnode->tuplePerGroup = from->tuplePerGroup; newnode->numCols = from->numCols; newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber)); - memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber)); + memcpy(newnode->grpColIdx, from->grpColIdx, + from->numCols * sizeof(AttrNumber)); return newnode; } @@ -516,6 +516,15 @@ _copyAgg(Agg *from) CopyPlanFields((Plan *) from, (Plan *) newnode); + newnode->aggstrategy = from->aggstrategy; + newnode->numCols = from->numCols; + if (from->numCols > 0) + { + newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber)); + memcpy(newnode->grpColIdx, from->grpColIdx, + from->numCols * sizeof(AttrNumber)); + } + return newnode; } @@ -1281,6 +1290,29 @@ _copyAppendPath(AppendPath *from) } /* ---------------- + * _copyResultPath + * ---------------- + */ +static ResultPath * +_copyResultPath(ResultPath *from) +{ + ResultPath *newnode = makeNode(ResultPath); + + /* + * copy the node superclass fields + */ + CopyPathFields((Path *) from, (Path *) newnode); + + /* + * copy remainder of node + */ + Node_Copy(from, newnode, subpath); + Node_Copy(from, newnode, constantqual); + + return newnode; +} + +/* ---------------- * CopyJoinPathFields * * This function copies the fields of the JoinPath node. It is used by @@ -2878,6 +2910,9 @@ copyObject(void *from) case T_AppendPath: retval = _copyAppendPath(from); break; + case T_ResultPath: + retval = _copyResultPath(from); + break; case T_NestPath: retval = _copyNestPath(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 551c32d5dba..122de38fed9 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.161 2002/10/14 22:14:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.162 2002/11/06 00:00:43 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -464,6 +464,18 @@ _equalAppendPath(AppendPath *a, AppendPath *b) } static bool +_equalResultPath(ResultPath *a, ResultPath *b) +{ + if (!_equalPath((Path *) a, (Path *) b)) + return false; + if (!equal(a->subpath, b->subpath)) + return false; + if (!equal(a->constantqual, b->constantqual)) + return false; + return true; +} + +static bool _equalJoinPath(JoinPath *a, JoinPath *b) { if (!_equalPath((Path *) a, (Path *) b)) @@ -2103,6 +2115,9 @@ equal(void *a, void *b) case T_AppendPath: retval = _equalAppendPath(a, b); break; + case T_ResultPath: + retval = _equalResultPath(a, b); + break; case T_IndexOptInfo: retval = _equalIndexOptInfo(a, b); break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index e1a34118a62..2d6db222b29 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.176 2002/10/14 22:14:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.177 2002/11/06 00:00:44 tgl Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -597,6 +597,8 @@ _outAgg(StringInfo str, Agg *node) { appendStringInfo(str, " AGG "); _outPlanInfo(str, (Plan *) node); + appendStringInfo(str, " :aggstrategy %d :numCols %d ", + (int) node->aggstrategy, node->numCols); } static void @@ -604,11 +606,7 @@ _outGroup(StringInfo str, Group *node) { appendStringInfo(str, " GRP "); _outPlanInfo(str, (Plan *) node); - - /* the actual Group fields */ - appendStringInfo(str, " :numCols %d :tuplePerGroup %s ", - node->numCols, - booltostr(node->tuplePerGroup)); + appendStringInfo(str, " :numCols %d ", node->numCols); } static void @@ -1115,6 +1113,26 @@ _outAppendPath(StringInfo str, AppendPath *node) } /* + * ResultPath is a subclass of Path. + */ +static void +_outResultPath(StringInfo str, ResultPath *node) +{ + appendStringInfo(str, + " RESULTPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ", + node->path.pathtype, + node->path.startup_cost, + node->path.total_cost); + _outNode(str, node->path.pathkeys); + + appendStringInfo(str, " :subpath "); + _outNode(str, node->subpath); + + appendStringInfo(str, " :constantqual "); + _outNode(str, node->constantqual); +} + +/* * NestPath is a subclass of Path */ static void @@ -1717,6 +1735,9 @@ _outNode(StringInfo str, void *obj) case T_AppendPath: _outAppendPath(str, obj); break; + case T_ResultPath: + _outResultPath(str, obj); + break; case T_NestPath: _outNestPath(str, obj); break; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 33e28413439..568bf8ee1e4 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.135 2002/10/14 22:14:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.136 2002/11/06 00:00:44 tgl Exp $ * * NOTES * Most of the read functions for plan nodes are tested. (In fact, they @@ -696,17 +696,6 @@ _readSort(void) return local_node; } -static Agg * -_readAgg(void) -{ - Agg *local_node; - - local_node = makeNode(Agg); - _getPlan((Plan *) local_node); - - return local_node; -} - /* ---------------- * _readHash * @@ -1881,6 +1870,45 @@ _readAppendPath(void) } /* ---------------- + * _readResultPath + * + * ResultPath is a subclass of Path. + * ---------------- + */ +static ResultPath * +_readResultPath(void) +{ + ResultPath *local_node; + char *token; + int length; + + local_node = makeNode(ResultPath); + + token = pg_strtok(&length); /* get :pathtype */ + token = pg_strtok(&length); /* now read it */ + local_node->path.pathtype = atoi(token); + + token = pg_strtok(&length); /* get :startup_cost */ + token = pg_strtok(&length); /* now read it */ + local_node->path.startup_cost = (Cost) atof(token); + + token = pg_strtok(&length); /* get :total_cost */ + token = pg_strtok(&length); /* now read it */ + local_node->path.total_cost = (Cost) atof(token); + + token = pg_strtok(&length); /* get :pathkeys */ + local_node->path.pathkeys = nodeRead(true); /* now read it */ + + token = pg_strtok(&length); /* get :subpath */ + local_node->subpath = nodeRead(true); /* now read it */ + + token = pg_strtok(&length); /* get :constantqual */ + local_node->constantqual = nodeRead(true); /* now read it */ + + return local_node; +} + +/* ---------------- * _readNestPath * * NestPath is a subclass of Path @@ -2196,8 +2224,6 @@ parsePlanString(void) return_value = _readFromExpr(); else if (length == 8 && strncmp(token, "JOINEXPR", length) == 0) return_value = _readJoinExpr(); - else if (length == 3 && strncmp(token, "AGG", length) == 0) - return_value = _readAgg(); else if (length == 4 && strncmp(token, "HASH", length) == 0) return_value = _readHash(); else if (length == 6 && strncmp(token, "RESDOM", length) == 0) @@ -2240,6 +2266,8 @@ parsePlanString(void) return_value = _readTidPath(); else if (length == 10 && strncmp(token, "APPENDPATH", length) == 0) return_value = _readAppendPath(); + else if (length == 10 && strncmp(token, "RESULTPATH", length) == 0) + return_value = _readResultPath(); else if (length == 8 && strncmp(token, "NESTPATH", length) == 0) return_value = _readNestPath(); else if (length == 9 && strncmp(token, "MERGEPATH", length) == 0) |