diff options
author | Tom Lane | 2009-07-23 21:27:10 +0000 |
---|---|---|
committer | Tom Lane | 2009-07-23 21:27:10 +0000 |
commit | 166f7538d34a4e9db70730f58afd1d289f3bb630 (patch) | |
tree | 8c501f837fdce4545e083ddb894cef50d079e64a | |
parent | 3d332de2eab8a01c0ef3f58ea69de2010fe8a1e1 (diff) |
Save a few cycles in EXPLAIN and related commands by not bothering to form
a physical tuple in do_tup_output(). A virtual tuple is easier to set up
and also easier for most tuple receivers to process. Per my comment on
Robert Haas' recent patch in this code.
-rw-r--r-- | src/backend/executor/execTuples.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 598ef503b7..c983066307 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -1215,27 +1215,28 @@ begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc) /* * write a single tuple - * - * XXX This could be made more efficient, since in reality we probably only - * need a virtual tuple. */ void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull) { - TupleDesc tupdesc = tstate->slot->tts_tupleDescriptor; - HeapTuple tuple; + TupleTableSlot *slot = tstate->slot; + int natts = slot->tts_tupleDescriptor->natts; - /* form a tuple */ - tuple = heap_form_tuple(tupdesc, values, isnull); + /* make sure the slot is clear */ + ExecClearTuple(slot); - /* put it in a slot */ - ExecStoreTuple(tuple, tstate->slot, InvalidBuffer, true); + /* insert data */ + memcpy(slot->tts_values, values, natts * sizeof(Datum)); + memcpy(slot->tts_isnull, isnull, natts * sizeof(bool)); + + /* mark slot as containing a virtual tuple */ + ExecStoreVirtualTuple(slot); /* send the tuple to the receiver */ - (*tstate->dest->receiveSlot) (tstate->slot, tstate->dest); + (*tstate->dest->receiveSlot) (slot, tstate->dest); /* clean up */ - ExecClearTuple(tstate->slot); + ExecClearTuple(slot); } /* |