Save a few cycles in EXPLAIN and related commands by not bothering to form
authorTom Lane <[email protected]>
Thu, 23 Jul 2009 21:27:10 +0000 (21:27 +0000)
committerTom Lane <[email protected]>
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);
 }
 
 /*