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