Change do_tup_output() to take Datum/isnull arrays instead of a char * array,
authorTom Lane <[email protected]>
Wed, 22 Jul 2009 17:00:23 +0000 (17:00 +0000)
committerTom Lane <[email protected]>
Wed, 22 Jul 2009 17:00:23 +0000 (17:00 +0000)
so it doesn't go through BuildTupleFromCStrings.  This is more or less a
wash for current uses, but will avoid inefficiency for planned changes to
EXPLAIN.

Robert Haas

src/backend/executor/execTuples.c
src/backend/utils/misc/guc.c
src/include/executor/executor.h

index 7b5ba41f5fcec6382fbe73f3e87c477fece46f8f..dffc7379cbe850599f99c9f70d0450b6d073a00d 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.107 2009/06/11 14:48:57 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.108 2009/07/22 17:00:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -95,6 +95,7 @@
 #include "catalog/pg_type.h"
 #include "nodes/nodeFuncs.h"
 #include "storage/bufmgr.h"
+#include "utils/builtins.h"
 #include "utils/lsyscache.h"
 #include "utils/typcache.h"
 
@@ -1195,7 +1196,7 @@ BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
  * Functions for sending tuples to the frontend (or other specified destination)
  * as though it is a SELECT result. These are used by utility commands that
  * need to project directly to the destination and don't need or want full
- * Table Function capability. Currently used by EXPLAIN and SHOW ALL
+ * table function capability. Currently used by EXPLAIN and SHOW ALL.
  */
 TupOutputState *
 begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
@@ -1204,7 +1205,6 @@ begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
 
    tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
 
-   tstate->metadata = TupleDescGetAttInMetadata(tupdesc);
    tstate->slot = MakeSingleTupleTableSlot(tupdesc);
    tstate->dest = dest;
 
@@ -1216,17 +1216,17 @@ begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
 /*
  * write a single tuple
  *
- * values is a list of the external C string representations of the values
- * to be projected.
- *
  * XXX This could be made more efficient, since in reality we probably only
  * need a virtual tuple.
  */
 void
-do_tup_output(TupOutputState *tstate, char **values)
+do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
 {
-   /* build a tuple from the input strings using the tupdesc */
-   HeapTuple   tuple = BuildTupleFromCStrings(tstate->metadata, values);
+   TupleDesc   tupdesc = tstate->slot->tts_tupleDescriptor;
+   HeapTuple   tuple;
+
+   /* form a tuple */
+   tuple = heap_form_tuple(tupdesc, values, isnull);
 
    /* put it in a slot */
    ExecStoreTuple(tuple, tstate->slot, InvalidBuffer, true);
@@ -1241,24 +1241,34 @@ do_tup_output(TupOutputState *tstate, char **values)
 /*
  * write a chunk of text, breaking at newline characters
  *
- * NB: scribbles on its input!
- *
  * Should only be used with a single-TEXT-attribute tupdesc.
  */
 void
 do_text_output_multiline(TupOutputState *tstate, char *text)
 {
+   Datum       values[1];
+   bool        isnull[1] = { false };
+
    while (*text)
    {
        char       *eol;
+       int         len;
 
        eol = strchr(text, '\n');
        if (eol)
-           *eol++ = '\0';
+       {
+           len = eol - text;
+           eol++;
+       }
        else
-           eol = text +strlen(text);
+       {
+           len = strlen(text);
+           eol += len;
+       }
 
-       do_tup_output(tstate, &text);
+       values[0] = PointerGetDatum(cstring_to_text_with_len(text, len));
+       do_tup_output(tstate, values, isnull);
+       pfree(DatumGetPointer(values[0]));
        text = eol;
    }
 }
@@ -1269,6 +1279,5 @@ end_tup_output(TupOutputState *tstate)
    (*tstate->dest->rShutdown) (tstate->dest);
    /* note that destroying the dest is not ours to do */
    ExecDropSingleTupleTableSlot(tstate->slot);
-   /* XXX worth cleaning up the attinmetadata? */
    pfree(tstate);
 }
index f3b42da99b15de7284ec901f1835ad437d64aba2..76d3ec9da65470c59ba5aeb7aeac158f9685bb7f 100644 (file)
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <[email protected]>.
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.508 2009/07/16 20:55:44 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.509 2009/07/22 17:00:23 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -5986,7 +5986,8 @@ ShowAllGUCConfig(DestReceiver *dest)
    int         i;
    TupOutputState *tstate;
    TupleDesc   tupdesc;
-   char       *values[3];
+   Datum       values[3];
+   bool        isnull[3] = { false, false, false };
 
    /* need a tuple descriptor representing three TEXT columns */
    tupdesc = CreateTemplateTupleDesc(3, false);
@@ -5997,29 +5998,46 @@ ShowAllGUCConfig(DestReceiver *dest)
    TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
                       TEXTOID, -1, 0);
 
-
    /* prepare for projection of tuples */
    tstate = begin_tup_output_tupdesc(dest, tupdesc);
 
    for (i = 0; i < num_guc_variables; i++)
    {
        struct config_generic *conf = guc_variables[i];
+       char   *setting;
 
        if ((conf->flags & GUC_NO_SHOW_ALL) ||
            ((conf->flags & GUC_SUPERUSER_ONLY) && !am_superuser))
            continue;
 
        /* assign to the values array */
-       values[0] = (char *) conf->name;
-       values[1] = _ShowOption(conf, true);
-       values[2] = (char *) conf->short_desc;
+       values[0] = PointerGetDatum(cstring_to_text(conf->name));
+
+       setting = _ShowOption(conf, true);
+       if (setting)
+       {
+           values[1] = PointerGetDatum(cstring_to_text(setting));
+           isnull[1] = false;
+       }
+       else
+       {
+           values[1] = PointerGetDatum(NULL);
+           isnull[1] = true;
+       }
+
+       values[2] = PointerGetDatum(cstring_to_text(conf->short_desc));
 
        /* send it to dest */
-       do_tup_output(tstate, values);
+       do_tup_output(tstate, values, isnull);
 
        /* clean up */
-       if (values[1] != NULL)
-           pfree(values[1]);
+       pfree(DatumGetPointer(values[0]));
+       if (setting)
+       {
+           pfree(setting);
+           pfree(DatumGetPointer(values[1]));
+       }
+       pfree(DatumGetPointer(values[2]));
    }
 
    end_tup_output(tstate);
index ba625e8ed8c4d9cce4c08de33d7869aa678cabba..86148ed1354cf30944505602e274e16890c0096e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.156 2009/07/18 19:15:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.157 2009/07/22 17:00:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -223,15 +223,13 @@ extern void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg);
 
 typedef struct TupOutputState
 {
-   /* use "struct" here to allow forward reference */
-   struct AttInMetadata *metadata;
    TupleTableSlot *slot;
    DestReceiver *dest;
 } TupOutputState;
 
 extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest,
                         TupleDesc tupdesc);
-extern void do_tup_output(TupOutputState *tstate, char **values);
+extern void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull);
 extern void do_text_output_multiline(TupOutputState *tstate, char *text);
 extern void end_tup_output(TupOutputState *tstate);
 
@@ -240,11 +238,14 @@ extern void end_tup_output(TupOutputState *tstate);
  *
  * Should only be used with a single-TEXT-attribute tupdesc.
  */
-#define do_text_output_oneline(tstate, text_to_emit) \
+#define do_text_output_oneline(tstate, str_to_emit) \
    do { \
-       char *values_[1]; \
-       values_[0] = (text_to_emit); \
-       do_tup_output(tstate, values_); \
+       Datum   values_[1]; \
+       bool    isnull_[1]; \
+       values_[0] = PointerGetDatum(cstring_to_text(str_to_emit)); \
+       isnull_[0] = false; \
+       do_tup_output(tstate, values_, isnull_); \
+       pfree(DatumGetPointer(values_[0])); \
    } while (0)