13
13
* columns. (ie. tuples from the same group are consecutive)
14
14
*
15
15
* 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 $
17
17
*
18
18
*-------------------------------------------------------------------------
19
19
*/
31
31
static TupleTableSlot * ExecGroupEveryTuple (Group * node );
32
32
static TupleTableSlot * ExecGroupOneTuple (Group * node );
33
33
static bool
34
- sameGroup (TupleTableSlot * oldslot , TupleTableSlot * newslot ,
34
+ sameGroup (HeapTuple oldslot , HeapTuple newslot ,
35
35
int numCols , AttrNumber * grpColIdx , TupleDesc tupdesc );
36
36
37
37
/* ---------------------------------------
@@ -71,8 +71,8 @@ ExecGroupEveryTuple(Group *node)
71
71
ExprContext * econtext ;
72
72
73
73
HeapTuple outerTuple = NULL ;
74
- TupleTableSlot * outerslot ,
75
- * lastslot ;
74
+ HeapTuple firsttuple ;
75
+ TupleTableSlot * outerslot ;
76
76
ProjectionInfo * projInfo ;
77
77
TupleTableSlot * resultSlot ;
78
78
@@ -90,18 +90,14 @@ ExecGroupEveryTuple(Group *node)
90
90
91
91
econtext = grpstate -> csstate .cstate .cs_ExprContext ;
92
92
93
- if (grpstate -> grp_useLastTuple )
93
+ /* if we haven't returned first tuple of new group yet ... */
94
+ if (grpstate -> grp_useFirstTuple )
94
95
{
96
+ grpstate -> grp_useFirstTuple = FALSE;
95
97
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 ,
103
99
grpstate -> csstate .css_ScanTupleSlot ,
104
- grpstate -> grp_lastSlot -> ttc_buffer ,
100
+ InvalidBuffer ,
105
101
false);
106
102
}
107
103
else
@@ -115,29 +111,28 @@ ExecGroupEveryTuple(Group *node)
115
111
return NULL ;
116
112
}
117
113
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
129
121
{
130
- /* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
131
-
132
- grpstate -> grp_useLastTuple = TRUE;
133
-
134
- /* save it for next time */
135
- grpstate -> grp_lastSlot = outerslot ;
136
-
137
122
/*
138
- * signifies the end of the group
123
+ * Compare with first tuple and see if this tuple is of
124
+ * the same group.
139
125
*/
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
+ }
141
136
}
142
137
143
138
ExecStoreTuple (outerTuple ,
@@ -172,8 +167,8 @@ ExecGroupOneTuple(Group *node)
172
167
ExprContext * econtext ;
173
168
174
169
HeapTuple outerTuple = NULL ;
175
- TupleTableSlot * outerslot ,
176
- * lastslot ;
170
+ HeapTuple firsttuple ;
171
+ TupleTableSlot * outerslot ;
177
172
ProjectionInfo * projInfo ;
178
173
TupleTableSlot * resultSlot ;
179
174
@@ -191,15 +186,9 @@ ExecGroupOneTuple(Group *node)
191
186
192
187
econtext = node -> grpstate -> csstate .cstate .cs_ExprContext ;
193
188
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 )
203
192
{
204
193
outerslot = ExecProcNode (outerPlan (node ), (Plan * ) node );
205
194
if (outerslot )
@@ -209,12 +198,8 @@ ExecGroupOneTuple(Group *node)
209
198
grpstate -> grp_done = TRUE;
210
199
return NULL ;
211
200
}
212
- ExecStoreTuple (outerTuple ,
213
- grpstate -> csstate .css_ScanTupleSlot ,
214
- outerslot -> ttc_buffer ,
215
- false);
201
+ grpstate -> grp_firstTuple = firsttuple = heap_copytuple (outerTuple );
216
202
}
217
- lastslot = grpstate -> csstate .css_ScanTupleSlot ;
218
203
219
204
/*
220
205
* find all tuples that belong to a group
@@ -225,58 +210,41 @@ ExecGroupOneTuple(Group *node)
225
210
outerTuple = (outerslot ) ? outerslot -> val : NULL ;
226
211
if (!HeapTupleIsValid (outerTuple ))
227
212
{
228
-
229
- /*
230
- * we have at least one tuple (lastslot) if we reach here
231
- */
232
213
grpstate -> grp_done = TRUE;
233
-
234
- /* return lastslot */
235
214
break ;
236
215
}
237
216
238
217
/* ----------------
239
- * Compare with last tuple and see if this tuple is of
218
+ * Compare with first tuple and see if this tuple is of
240
219
* the same group.
241
220
* ----------------
242
221
*/
243
- if ((!sameGroup (lastslot , outerslot ,
222
+ if ((!sameGroup (firsttuple , outerslot -> val ,
244
223
node -> numCols , node -> grpColIdx ,
245
224
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 */
255
225
break ;
256
- }
257
-
258
- ExecStoreTuple (outerTuple ,
259
- grpstate -> csstate .css_ScanTupleSlot ,
260
- outerslot -> ttc_buffer ,
261
- false);
262
-
263
- lastslot = grpstate -> csstate .css_ScanTupleSlot ;
264
226
}
265
227
266
- ExecStoreTuple (lastslot -> val ,
267
- grpstate -> csstate .css_ScanTupleSlot ,
268
- lastslot -> ttc_buffer ,
269
- false);
270
-
271
228
/* ----------------
272
229
* form a projection tuple, store it in the result tuple
273
230
* slot and return it.
274
231
* ----------------
275
232
*/
276
233
projInfo = grpstate -> csstate .cstate .cs_ProjInfo ;
277
234
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 ;
279
240
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
+ }
280
248
281
249
return resultSlot ;
282
250
}
@@ -304,7 +272,7 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent)
304
272
*/
305
273
grpstate = makeNode (GroupState );
306
274
node -> grpstate = grpstate ;
307
- grpstate -> grp_useLastTuple = FALSE;
275
+ grpstate -> grp_useFirstTuple = FALSE;
308
276
grpstate -> grp_done = FALSE;
309
277
310
278
/*
@@ -370,6 +338,11 @@ ExecEndGroup(Group *node)
370
338
371
339
/* clean up tuple table */
372
340
ExecClearTuple (grpstate -> csstate .css_ScanTupleSlot );
341
+ if (grpstate -> grp_firstTuple != NULL )
342
+ {
343
+ pfree (grpstate -> grp_firstTuple );
344
+ grpstate -> grp_firstTuple = NULL ;
345
+ }
373
346
}
374
347
375
348
/*****************************************************************************
@@ -380,8 +353,8 @@ ExecEndGroup(Group *node)
380
353
* code swiped from nodeUnique.c
381
354
*/
382
355
static bool
383
- sameGroup (TupleTableSlot * oldslot ,
384
- TupleTableSlot * newslot ,
356
+ sameGroup (HeapTuple oldtuple ,
357
+ HeapTuple newtuple ,
385
358
int numCols ,
386
359
AttrNumber * grpColIdx ,
387
360
TupleDesc tupdesc )
@@ -401,12 +374,12 @@ sameGroup(TupleTableSlot *oldslot,
401
374
att = grpColIdx [i ];
402
375
typoutput = typtoout ((Oid ) tupdesc -> attrs [att - 1 ]-> atttypid );
403
376
404
- attr1 = heap_getattr (oldslot -> val ,
377
+ attr1 = heap_getattr (oldtuple ,
405
378
att ,
406
379
tupdesc ,
407
380
& isNull1 );
408
381
409
- attr2 = heap_getattr (newslot -> val ,
382
+ attr2 = heap_getattr (newtuple ,
410
383
att ,
411
384
tupdesc ,
412
385
& isNull2 );
0 commit comments