Commit b1b246ab authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

New nodeGroup.c code uses own copy of first tuple in a group.

Free memory after comparison in nodeUnique.c
parent 3d18ca70
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* columns. (ie. tuples from the same group are consecutive) * columns. (ie. tuples from the same group are consecutive)
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.16 1998/02/10 16:02:58 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.17 1998/02/18 12:40:43 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
static TupleTableSlot *ExecGroupEveryTuple(Group *node); static TupleTableSlot *ExecGroupEveryTuple(Group *node);
static TupleTableSlot *ExecGroupOneTuple(Group *node); static TupleTableSlot *ExecGroupOneTuple(Group *node);
static bool static bool
sameGroup(TupleTableSlot *oldslot, TupleTableSlot *newslot, sameGroup(HeapTuple oldslot, HeapTuple newslot,
int numCols, AttrNumber *grpColIdx, TupleDesc tupdesc); int numCols, AttrNumber *grpColIdx, TupleDesc tupdesc);
/* --------------------------------------- /* ---------------------------------------
...@@ -71,8 +71,8 @@ ExecGroupEveryTuple(Group *node) ...@@ -71,8 +71,8 @@ ExecGroupEveryTuple(Group *node)
ExprContext *econtext; ExprContext *econtext;
HeapTuple outerTuple = NULL; HeapTuple outerTuple = NULL;
TupleTableSlot *outerslot, HeapTuple firsttuple;
*lastslot; TupleTableSlot *outerslot;
ProjectionInfo *projInfo; ProjectionInfo *projInfo;
TupleTableSlot *resultSlot; TupleTableSlot *resultSlot;
...@@ -90,18 +90,14 @@ ExecGroupEveryTuple(Group *node) ...@@ -90,18 +90,14 @@ ExecGroupEveryTuple(Group *node)
econtext = grpstate->csstate.cstate.cs_ExprContext; econtext = grpstate->csstate.cstate.cs_ExprContext;
if (grpstate->grp_useLastTuple) /* if we haven't returned first tuple of new group yet ... */
if (grpstate->grp_useFirstTuple)
{ {
grpstate->grp_useFirstTuple = FALSE;
/* ExecStoreTuple(grpstate->grp_firstTuple,
* we haven't returned last tuple yet because it is not of the
* same group
*/
grpstate->grp_useLastTuple = FALSE;
ExecStoreTuple(grpstate->grp_lastSlot->val,
grpstate->csstate.css_ScanTupleSlot, grpstate->csstate.css_ScanTupleSlot,
grpstate->grp_lastSlot->ttc_buffer, InvalidBuffer,
false); false);
} }
else else
...@@ -115,29 +111,28 @@ ExecGroupEveryTuple(Group *node) ...@@ -115,29 +111,28 @@ ExecGroupEveryTuple(Group *node)
return NULL; return NULL;
} }
/* ---------------- firsttuple = grpstate->grp_firstTuple;
* Compare with last tuple and see if this tuple is of /* this should occur on the first call only */
* the same group. if (firsttuple == NULL)
* ---------------- {
*/ grpstate->grp_firstTuple = heap_copytuple (outerTuple);
lastslot = grpstate->csstate.css_ScanTupleSlot; }
else
if (lastslot->val != NULL &&
(!sameGroup(lastslot, outerslot,
node->numCols, node->grpColIdx,
ExecGetScanType(&grpstate->csstate))))
{ {
/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
grpstate->grp_useLastTuple = TRUE;
/* save it for next time */
grpstate->grp_lastSlot = outerslot;
/* /*
* signifies the end of the group * Compare with first tuple and see if this tuple is of
* the same group.
*/ */
return NULL; if (!sameGroup(firsttuple, outerslot->val,
node->numCols, node->grpColIdx,
ExecGetScanType(&grpstate->csstate)))
{
grpstate->grp_useFirstTuple = TRUE;
pfree (firsttuple);
grpstate->grp_firstTuple = heap_copytuple (outerTuple);
return NULL; /* signifies the end of the group */
}
} }
ExecStoreTuple(outerTuple, ExecStoreTuple(outerTuple,
...@@ -172,8 +167,8 @@ ExecGroupOneTuple(Group *node) ...@@ -172,8 +167,8 @@ ExecGroupOneTuple(Group *node)
ExprContext *econtext; ExprContext *econtext;
HeapTuple outerTuple = NULL; HeapTuple outerTuple = NULL;
TupleTableSlot *outerslot, HeapTuple firsttuple;
*lastslot; TupleTableSlot *outerslot;
ProjectionInfo *projInfo; ProjectionInfo *projInfo;
TupleTableSlot *resultSlot; TupleTableSlot *resultSlot;
...@@ -191,15 +186,9 @@ ExecGroupOneTuple(Group *node) ...@@ -191,15 +186,9 @@ ExecGroupOneTuple(Group *node)
econtext = node->grpstate->csstate.cstate.cs_ExprContext; econtext = node->grpstate->csstate.cstate.cs_ExprContext;
if (grpstate->grp_useLastTuple) firsttuple = grpstate->grp_firstTuple;
{ /* this should occur on the first call only */
grpstate->grp_useLastTuple = FALSE; if (firsttuple == NULL)
ExecStoreTuple(grpstate->grp_lastSlot->val,
grpstate->csstate.css_ScanTupleSlot,
grpstate->grp_lastSlot->ttc_buffer,
false);
}
else
{ {
outerslot = ExecProcNode(outerPlan(node), (Plan *) node); outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
if (outerslot) if (outerslot)
...@@ -209,12 +198,8 @@ ExecGroupOneTuple(Group *node) ...@@ -209,12 +198,8 @@ ExecGroupOneTuple(Group *node)
grpstate->grp_done = TRUE; grpstate->grp_done = TRUE;
return NULL; return NULL;
} }
ExecStoreTuple(outerTuple, grpstate->grp_firstTuple = firsttuple = heap_copytuple (outerTuple);
grpstate->csstate.css_ScanTupleSlot,
outerslot->ttc_buffer,
false);
} }
lastslot = grpstate->csstate.css_ScanTupleSlot;
/* /*
* find all tuples that belong to a group * find all tuples that belong to a group
...@@ -225,49 +210,21 @@ ExecGroupOneTuple(Group *node) ...@@ -225,49 +210,21 @@ ExecGroupOneTuple(Group *node)
outerTuple = (outerslot) ? outerslot->val : NULL; outerTuple = (outerslot) ? outerslot->val : NULL;
if (!HeapTupleIsValid(outerTuple)) if (!HeapTupleIsValid(outerTuple))
{ {
/*
* we have at least one tuple (lastslot) if we reach here
*/
grpstate->grp_done = TRUE; grpstate->grp_done = TRUE;
/* return lastslot */
break; break;
} }
/* ---------------- /* ----------------
* Compare with last tuple and see if this tuple is of * Compare with first tuple and see if this tuple is of
* the same group. * the same group.
* ---------------- * ----------------
*/ */
if ((!sameGroup(lastslot, outerslot, if ((!sameGroup(firsttuple, outerslot->val,
node->numCols, node->grpColIdx, node->numCols, node->grpColIdx,
ExecGetScanType(&grpstate->csstate)))) ExecGetScanType(&grpstate->csstate))))
{
/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
grpstate->grp_useLastTuple = TRUE;
/* save it for next time */
grpstate->grp_lastSlot = outerslot;
/* return lastslot */
break; break;
}
ExecStoreTuple(outerTuple,
grpstate->csstate.css_ScanTupleSlot,
outerslot->ttc_buffer,
false);
lastslot = grpstate->csstate.css_ScanTupleSlot;
} }
ExecStoreTuple(lastslot->val,
grpstate->csstate.css_ScanTupleSlot,
lastslot->ttc_buffer,
false);
/* ---------------- /* ----------------
* form a projection tuple, store it in the result tuple * form a projection tuple, store it in the result tuple
* slot and return it. * slot and return it.
...@@ -275,8 +232,19 @@ ExecGroupOneTuple(Group *node) ...@@ -275,8 +232,19 @@ ExecGroupOneTuple(Group *node)
*/ */
projInfo = grpstate->csstate.cstate.cs_ProjInfo; projInfo = grpstate->csstate.cstate.cs_ProjInfo;
econtext->ecxt_scantuple = lastslot; ExecStoreTuple(firsttuple,
grpstate->csstate.css_ScanTupleSlot,
InvalidBuffer,
false);
econtext->ecxt_scantuple = grpstate->csstate.css_ScanTupleSlot;
resultSlot = ExecProject(projInfo, &isDone); resultSlot = ExecProject(projInfo, &isDone);
/* save outerTuple if we are not done yet */
if (!grpstate->grp_done)
{
pfree (firsttuple);
grpstate->grp_firstTuple = heap_copytuple (outerTuple);
}
return resultSlot; return resultSlot;
} }
...@@ -304,7 +272,7 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent) ...@@ -304,7 +272,7 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent)
*/ */
grpstate = makeNode(GroupState); grpstate = makeNode(GroupState);
node->grpstate = grpstate; node->grpstate = grpstate;
grpstate->grp_useLastTuple = FALSE; grpstate->grp_useFirstTuple = FALSE;
grpstate->grp_done = FALSE; grpstate->grp_done = FALSE;
/* /*
...@@ -370,6 +338,11 @@ ExecEndGroup(Group *node) ...@@ -370,6 +338,11 @@ ExecEndGroup(Group *node)
/* clean up tuple table */ /* clean up tuple table */
ExecClearTuple(grpstate->csstate.css_ScanTupleSlot); ExecClearTuple(grpstate->csstate.css_ScanTupleSlot);
if (grpstate->grp_firstTuple != NULL)
{
pfree (grpstate->grp_firstTuple);
grpstate->grp_firstTuple = NULL;
}
} }
/***************************************************************************** /*****************************************************************************
...@@ -380,8 +353,8 @@ ExecEndGroup(Group *node) ...@@ -380,8 +353,8 @@ ExecEndGroup(Group *node)
* code swiped from nodeUnique.c * code swiped from nodeUnique.c
*/ */
static bool static bool
sameGroup(TupleTableSlot *oldslot, sameGroup(HeapTuple oldtuple,
TupleTableSlot *newslot, HeapTuple newtuple,
int numCols, int numCols,
AttrNumber *grpColIdx, AttrNumber *grpColIdx,
TupleDesc tupdesc) TupleDesc tupdesc)
...@@ -401,12 +374,12 @@ sameGroup(TupleTableSlot *oldslot, ...@@ -401,12 +374,12 @@ sameGroup(TupleTableSlot *oldslot,
att = grpColIdx[i]; att = grpColIdx[i];
typoutput = typtoout((Oid) tupdesc->attrs[att - 1]->atttypid); typoutput = typtoout((Oid) tupdesc->attrs[att - 1]->atttypid);
attr1 = heap_getattr(oldslot->val, attr1 = heap_getattr(oldtuple,
att, att,
tupdesc, tupdesc,
&isNull1); &isNull1);
attr2 = heap_getattr(newslot->val, attr2 = heap_getattr(newtuple,
att, att,
tupdesc, tupdesc,
&isNull2); &isNull2);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.14 1998/02/10 16:03:03 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.15 1998/02/18 12:40:44 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -208,9 +208,14 @@ ExecUnique(Unique *node) ...@@ -208,9 +208,14 @@ ExecUnique(Unique *node)
* use strcmp for comparison * use strcmp for comparison
*/ */
if (strcmp(val1, val2) == 0) /* they are equal */ if (strcmp(val1, val2) == 0) /* they are equal */
{
pfree (val1);
pfree (val2);
continue; continue;
else }
break; pfree (val1);
pfree (val2);
break;
} }
else else
/* one is null and the other isn't, they aren't equal */ /* one is null and the other isn't, they aren't equal */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment