]> granicus.if.org Git - postgresql/commitdiff
Save a few cycles in EXPLAIN and related commands by not bothering to form
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 23 Jul 2009 21:27:10 +0000 (21:27 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 23 Jul 2009 21:27:10 +0000 (21:27 +0000)
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.

src/backend/executor/execTuples.c

index dffc7379cbe850599f99c9f70d0450b6d073a00d..d92ba062d44a73177014990cd3f4cfa646dcb251 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.108 2009/07/22 17:00:20 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.109 2009/07/23 21:27:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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);
 }
 
 /*