|
15 | 15 | *
|
16 | 16 | *
|
17 | 17 | * IDENTIFICATION
|
18 |
| - * $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.108 2009/07/22 17:00:20 tgl Exp $ |
| 18 | + * $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.109 2009/07/23 21:27:10 tgl Exp $ |
19 | 19 | *
|
20 | 20 | *-------------------------------------------------------------------------
|
21 | 21 | */
|
@@ -1215,27 +1215,28 @@ begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
|
1215 | 1215 |
|
1216 | 1216 | /*
|
1217 | 1217 | * write a single tuple
|
1218 |
| - * |
1219 |
| - * XXX This could be made more efficient, since in reality we probably only |
1220 |
| - * need a virtual tuple. |
1221 | 1218 | */
|
1222 | 1219 | void
|
1223 | 1220 | do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
|
1224 | 1221 | {
|
1225 |
| - TupleDesc tupdesc = tstate->slot->tts_tupleDescriptor; |
1226 |
| - HeapTuple tuple; |
| 1222 | + TupleTableSlot *slot = tstate->slot; |
| 1223 | + int natts = slot->tts_tupleDescriptor->natts; |
1227 | 1224 |
|
1228 |
| - /* form a tuple */ |
1229 |
| - tuple = heap_form_tuple(tupdesc, values, isnull); |
| 1225 | + /* make sure the slot is clear */ |
| 1226 | + ExecClearTuple(slot); |
1230 | 1227 |
|
1231 |
| - /* put it in a slot */ |
1232 |
| - ExecStoreTuple(tuple, tstate->slot, InvalidBuffer, true); |
| 1228 | + /* insert data */ |
| 1229 | + memcpy(slot->tts_values, values, natts * sizeof(Datum)); |
| 1230 | + memcpy(slot->tts_isnull, isnull, natts * sizeof(bool)); |
| 1231 | + |
| 1232 | + /* mark slot as containing a virtual tuple */ |
| 1233 | + ExecStoreVirtualTuple(slot); |
1233 | 1234 |
|
1234 | 1235 | /* send the tuple to the receiver */
|
1235 |
| - (*tstate->dest->receiveSlot) (tstate->slot, tstate->dest); |
| 1236 | + (*tstate->dest->receiveSlot) (slot, tstate->dest); |
1236 | 1237 |
|
1237 | 1238 | /* clean up */
|
1238 |
| - ExecClearTuple(tstate->slot); |
| 1239 | + ExecClearTuple(slot); |
1239 | 1240 | }
|
1240 | 1241 |
|
1241 | 1242 | /*
|
|
0 commit comments