On Mon, Jun 15, 2009 at 1:20 PM, Tom Lane<t...@sss.pgh.pa.us> wrote:
> Robert Haas <robertmh...@gmail.com> writes:
>> it looks like I can probably rip that member out of TupOutputState
>> altogether.
>
>> Will update patch.  Does this look like what you were thinking otherwise?
>
> Yeah, that's exactly what I was thinking.

Excellent.  Revised patch attached.

...Robert
*** a/src/backend/executor/execTuples.c
--- b/src/backend/executor/execTuples.c
***************
*** 95,100 ****
--- 95,101 ----
  #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"
  
***************
*** 1204,1210 **** begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
  
  	tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
  
! 	tstate->metadata = TupleDescGetAttInMetadata(tupdesc);
  	tstate->slot = MakeSingleTupleTableSlot(tupdesc);
  	tstate->dest = dest;
  
--- 1205,1211 ----
  
  	tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
  
! 	tstate->tupdesc = tupdesc;
  	tstate->slot = MakeSingleTupleTableSlot(tupdesc);
  	tstate->dest = dest;
  
***************
*** 1216,1232 **** 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)
  {
! 	/* build a tuple from the input strings using the tupdesc */
! 	HeapTuple	tuple = BuildTupleFromCStrings(tstate->metadata, values);
  
  	/* put it in a slot */
  	ExecStoreTuple(tuple, tstate->slot, InvalidBuffer, true);
--- 1217,1233 ----
  /*
   * 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->tupdesc;
! 	HeapTuple	tuple;
! 
! 	/* Form a tuple. */
! 	tuple = heap_form_tuple(tupdesc, values, isnull);
  
  	/* put it in a slot */
  	ExecStoreTuple(tuple, tstate->slot, InvalidBuffer, true);
***************
*** 1241,1264 **** 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)
  {
  	while (*text)
  	{
  		char	   *eol;
  
  		eol = strchr(text, '\n');
  		if (eol)
! 			*eol++ = '\0';
  		else
! 			eol = text +strlen(text);
  
! 		do_tup_output(tstate, &text);
  		text = eol;
  	}
  }
--- 1242,1275 ----
  /*
   * write a chunk of text, breaking at newline characters
   *
   * 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)
! 		{
! 			len = eol - text;
! 			++eol;
! 		}
  		else
! 		{
! 			len = strlen(text);
! 			eol += len;
! 		}
  
! 		values[0] = PointerGetDatum(cstring_to_text_with_len(text, len));
! 		do_tup_output(tstate, values, isnull);
! 		pfree(DatumGetPointer(values[0]));
  		text = eol;
  	}
  }
***************
*** 1269,1274 **** 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);
  }
--- 1280,1284 ----
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 5978,5984 **** ShowAllGUCConfig(DestReceiver *dest)
  	int			i;
  	TupOutputState *tstate;
  	TupleDesc	tupdesc;
! 	char	   *values[3];
  
  	/* need a tuple descriptor representing three TEXT columns */
  	tupdesc = CreateTemplateTupleDesc(3, false);
--- 5978,5985 ----
  	int			i;
  	TupOutputState *tstate;
  	TupleDesc	tupdesc;
! 	Datum	    values[3];
! 	bool		isnull[3] = { false, false, false };
  
  	/* need a tuple descriptor representing three TEXT columns */
  	tupdesc = CreateTemplateTupleDesc(3, false);
***************
*** 5996,6017 **** ShowAllGUCConfig(DestReceiver *dest)
  	for (i = 0; i < num_guc_variables; i++)
  	{
  		struct config_generic *conf = guc_variables[i];
  
  		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;
  
  		/* send it to dest */
! 		do_tup_output(tstate, values);
  
  		/* clean up */
! 		if (values[1] != NULL)
! 			pfree(values[1]);
  	}
  
  	end_tup_output(tstate);
--- 5997,6034 ----
  	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] = 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, isnull);
  
  		/* clean up */
! 		pfree(DatumGetPointer(values[0]));
! 		if (setting != NULL)
! 		{
! 			pfree(setting);
! 			pfree(DatumGetPointer(values[1]));
! 		}
! 		pfree(DatumGetPointer(values[2]));
  	}
  
  	end_tup_output(tstate);
*** a/src/include/executor/executor.h
--- b/src/include/executor/executor.h
***************
*** 223,237 **** 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_text_output_multiline(TupOutputState *tstate, char *text);
  extern void end_tup_output(TupOutputState *tstate);
  
--- 223,237 ----
  
  typedef struct TupOutputState
  {
! 	TupleDesc tupdesc;
  	TupleTableSlot *slot;
  	DestReceiver *dest;
  } TupOutputState;
  
  extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest,
  						 TupleDesc tupdesc);
! extern void do_tup_output(TupOutputState *tstate, Datum *dvalues,
! 							bool *isnull);
  extern void do_text_output_multiline(TupOutputState *tstate, char *text);
  extern void end_tup_output(TupOutputState *tstate);
  
***************
*** 242,250 **** extern void end_tup_output(TupOutputState *tstate);
   */
  #define do_text_output_oneline(tstate, text_to_emit) \
  	do { \
! 		char *values_[1]; \
! 		values_[0] = (text_to_emit); \
! 		do_tup_output(tstate, values_); \
  	} while (0)
  
  
--- 242,253 ----
   */
  #define do_text_output_oneline(tstate, text_to_emit) \
  	do { \
! 		Datum values_[1]; \
! 		bool isnull_[1]; \
! 		values_[0] = PointerGetDatum(cstring_to_text(text_to_emit)); \
! 		isnull_[0] = false; \
! 		do_tup_output(tstate, values_, isnull_); \
! 		pfree(DatumGetPointer(values_[0])); \
  	} while (0)
  
  
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to