diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 7b5ba41f5f..dffc7379cb 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -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); } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index f3b42da99b..76d3ec9da6 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut . * * 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); diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index ba625e8ed8..86148ed135 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -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)