summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2009-07-23 21:27:10 +0000
committerTom Lane2009-07-23 21:27:10 +0000
commit166f7538d34a4e9db70730f58afd1d289f3bb630 (patch)
tree8c501f837fdce4545e083ddb894cef50d079e64a
parent3d332de2eab8a01c0ef3f58ea69de2010fe8a1e1 (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.c23
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);
}
/*