Skip to content

Commit b1b246a

Browse files
committed
New nodeGroup.c code uses own copy of first tuple in a group.
Free memory after comparison in nodeUnique.c
1 parent 3d18ca7 commit b1b246a

File tree

2 files changed

+66
-88
lines changed

2 files changed

+66
-88
lines changed

src/backend/executor/nodeGroup.c

Lines changed: 58 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* columns. (ie. tuples from the same group are consecutive)
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.16 1998/02/10 16:02:58 momjian Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.17 1998/02/18 12:40:43 vadim Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -31,7 +31,7 @@
3131
static TupleTableSlot *ExecGroupEveryTuple(Group *node);
3232
static TupleTableSlot *ExecGroupOneTuple(Group *node);
3333
static bool
34-
sameGroup(TupleTableSlot *oldslot, TupleTableSlot *newslot,
34+
sameGroup(HeapTuple oldslot, HeapTuple newslot,
3535
int numCols, AttrNumber *grpColIdx, TupleDesc tupdesc);
3636

3737
/* ---------------------------------------
@@ -71,8 +71,8 @@ ExecGroupEveryTuple(Group *node)
7171
ExprContext *econtext;
7272

7373
HeapTuple outerTuple = NULL;
74-
TupleTableSlot *outerslot,
75-
*lastslot;
74+
HeapTuple firsttuple;
75+
TupleTableSlot *outerslot;
7676
ProjectionInfo *projInfo;
7777
TupleTableSlot *resultSlot;
7878

@@ -90,18 +90,14 @@ ExecGroupEveryTuple(Group *node)
9090

9191
econtext = grpstate->csstate.cstate.cs_ExprContext;
9292

93-
if (grpstate->grp_useLastTuple)
93+
/* if we haven't returned first tuple of new group yet ... */
94+
if (grpstate->grp_useFirstTuple)
9495
{
96+
grpstate->grp_useFirstTuple = FALSE;
9597

96-
/*
97-
* we haven't returned last tuple yet because it is not of the
98-
* same group
99-
*/
100-
grpstate->grp_useLastTuple = FALSE;
101-
102-
ExecStoreTuple(grpstate->grp_lastSlot->val,
98+
ExecStoreTuple(grpstate->grp_firstTuple,
10399
grpstate->csstate.css_ScanTupleSlot,
104-
grpstate->grp_lastSlot->ttc_buffer,
100+
InvalidBuffer,
105101
false);
106102
}
107103
else
@@ -115,29 +111,28 @@ ExecGroupEveryTuple(Group *node)
115111
return NULL;
116112
}
117113

118-
/* ----------------
119-
* Compare with last tuple and see if this tuple is of
120-
* the same group.
121-
* ----------------
122-
*/
123-
lastslot = grpstate->csstate.css_ScanTupleSlot;
124-
125-
if (lastslot->val != NULL &&
126-
(!sameGroup(lastslot, outerslot,
127-
node->numCols, node->grpColIdx,
128-
ExecGetScanType(&grpstate->csstate))))
114+
firsttuple = grpstate->grp_firstTuple;
115+
/* this should occur on the first call only */
116+
if (firsttuple == NULL)
117+
{
118+
grpstate->grp_firstTuple = heap_copytuple (outerTuple);
119+
}
120+
else
129121
{
130-
/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
131-
132-
grpstate->grp_useLastTuple = TRUE;
133-
134-
/* save it for next time */
135-
grpstate->grp_lastSlot = outerslot;
136-
137122
/*
138-
* signifies the end of the group
123+
* Compare with first tuple and see if this tuple is of
124+
* the same group.
139125
*/
140-
return NULL;
126+
if (!sameGroup(firsttuple, outerslot->val,
127+
node->numCols, node->grpColIdx,
128+
ExecGetScanType(&grpstate->csstate)))
129+
{
130+
grpstate->grp_useFirstTuple = TRUE;
131+
pfree (firsttuple);
132+
grpstate->grp_firstTuple = heap_copytuple (outerTuple);
133+
134+
return NULL; /* signifies the end of the group */
135+
}
141136
}
142137

143138
ExecStoreTuple(outerTuple,
@@ -172,8 +167,8 @@ ExecGroupOneTuple(Group *node)
172167
ExprContext *econtext;
173168

174169
HeapTuple outerTuple = NULL;
175-
TupleTableSlot *outerslot,
176-
*lastslot;
170+
HeapTuple firsttuple;
171+
TupleTableSlot *outerslot;
177172
ProjectionInfo *projInfo;
178173
TupleTableSlot *resultSlot;
179174

@@ -191,15 +186,9 @@ ExecGroupOneTuple(Group *node)
191186

192187
econtext = node->grpstate->csstate.cstate.cs_ExprContext;
193188

194-
if (grpstate->grp_useLastTuple)
195-
{
196-
grpstate->grp_useLastTuple = FALSE;
197-
ExecStoreTuple(grpstate->grp_lastSlot->val,
198-
grpstate->csstate.css_ScanTupleSlot,
199-
grpstate->grp_lastSlot->ttc_buffer,
200-
false);
201-
}
202-
else
189+
firsttuple = grpstate->grp_firstTuple;
190+
/* this should occur on the first call only */
191+
if (firsttuple == NULL)
203192
{
204193
outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
205194
if (outerslot)
@@ -209,12 +198,8 @@ ExecGroupOneTuple(Group *node)
209198
grpstate->grp_done = TRUE;
210199
return NULL;
211200
}
212-
ExecStoreTuple(outerTuple,
213-
grpstate->csstate.css_ScanTupleSlot,
214-
outerslot->ttc_buffer,
215-
false);
201+
grpstate->grp_firstTuple = firsttuple = heap_copytuple (outerTuple);
216202
}
217-
lastslot = grpstate->csstate.css_ScanTupleSlot;
218203

219204
/*
220205
* find all tuples that belong to a group
@@ -225,58 +210,41 @@ ExecGroupOneTuple(Group *node)
225210
outerTuple = (outerslot) ? outerslot->val : NULL;
226211
if (!HeapTupleIsValid(outerTuple))
227212
{
228-
229-
/*
230-
* we have at least one tuple (lastslot) if we reach here
231-
*/
232213
grpstate->grp_done = TRUE;
233-
234-
/* return lastslot */
235214
break;
236215
}
237216

238217
/* ----------------
239-
* Compare with last tuple and see if this tuple is of
218+
* Compare with first tuple and see if this tuple is of
240219
* the same group.
241220
* ----------------
242221
*/
243-
if ((!sameGroup(lastslot, outerslot,
222+
if ((!sameGroup(firsttuple, outerslot->val,
244223
node->numCols, node->grpColIdx,
245224
ExecGetScanType(&grpstate->csstate))))
246-
{
247-
/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
248-
249-
grpstate->grp_useLastTuple = TRUE;
250-
251-
/* save it for next time */
252-
grpstate->grp_lastSlot = outerslot;
253-
254-
/* return lastslot */
255225
break;
256-
}
257-
258-
ExecStoreTuple(outerTuple,
259-
grpstate->csstate.css_ScanTupleSlot,
260-
outerslot->ttc_buffer,
261-
false);
262-
263-
lastslot = grpstate->csstate.css_ScanTupleSlot;
264226
}
265227

266-
ExecStoreTuple(lastslot->val,
267-
grpstate->csstate.css_ScanTupleSlot,
268-
lastslot->ttc_buffer,
269-
false);
270-
271228
/* ----------------
272229
* form a projection tuple, store it in the result tuple
273230
* slot and return it.
274231
* ----------------
275232
*/
276233
projInfo = grpstate->csstate.cstate.cs_ProjInfo;
277234

278-
econtext->ecxt_scantuple = lastslot;
235+
ExecStoreTuple(firsttuple,
236+
grpstate->csstate.css_ScanTupleSlot,
237+
InvalidBuffer,
238+
false);
239+
econtext->ecxt_scantuple = grpstate->csstate.css_ScanTupleSlot;
279240
resultSlot = ExecProject(projInfo, &isDone);
241+
242+
/* save outerTuple if we are not done yet */
243+
if (!grpstate->grp_done)
244+
{
245+
pfree (firsttuple);
246+
grpstate->grp_firstTuple = heap_copytuple (outerTuple);
247+
}
280248

281249
return resultSlot;
282250
}
@@ -304,7 +272,7 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent)
304272
*/
305273
grpstate = makeNode(GroupState);
306274
node->grpstate = grpstate;
307-
grpstate->grp_useLastTuple = FALSE;
275+
grpstate->grp_useFirstTuple = FALSE;
308276
grpstate->grp_done = FALSE;
309277

310278
/*
@@ -370,6 +338,11 @@ ExecEndGroup(Group *node)
370338

371339
/* clean up tuple table */
372340
ExecClearTuple(grpstate->csstate.css_ScanTupleSlot);
341+
if (grpstate->grp_firstTuple != NULL)
342+
{
343+
pfree (grpstate->grp_firstTuple);
344+
grpstate->grp_firstTuple = NULL;
345+
}
373346
}
374347

375348
/*****************************************************************************
@@ -380,8 +353,8 @@ ExecEndGroup(Group *node)
380353
* code swiped from nodeUnique.c
381354
*/
382355
static bool
383-
sameGroup(TupleTableSlot *oldslot,
384-
TupleTableSlot *newslot,
356+
sameGroup(HeapTuple oldtuple,
357+
HeapTuple newtuple,
385358
int numCols,
386359
AttrNumber *grpColIdx,
387360
TupleDesc tupdesc)
@@ -401,12 +374,12 @@ sameGroup(TupleTableSlot *oldslot,
401374
att = grpColIdx[i];
402375
typoutput = typtoout((Oid) tupdesc->attrs[att - 1]->atttypid);
403376

404-
attr1 = heap_getattr(oldslot->val,
377+
attr1 = heap_getattr(oldtuple,
405378
att,
406379
tupdesc,
407380
&isNull1);
408381

409-
attr2 = heap_getattr(newslot->val,
382+
attr2 = heap_getattr(newtuple,
410383
att,
411384
tupdesc,
412385
&isNull2);

src/backend/executor/nodeUnique.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.14 1998/02/10 16:03:03 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.15 1998/02/18 12:40:44 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -208,9 +208,14 @@ ExecUnique(Unique *node)
208208
* use strcmp for comparison
209209
*/
210210
if (strcmp(val1, val2) == 0) /* they are equal */
211+
{
212+
pfree (val1);
213+
pfree (val2);
211214
continue;
212-
else
213-
break;
215+
}
216+
pfree (val1);
217+
pfree (val2);
218+
break;
214219
}
215220
else
216221
/* one is null and the other isn't, they aren't equal */

0 commit comments

Comments
 (0)