On Mon, Jun 15, 2009 at 1:20 PM, Tom Lane<[email protected]> wrote:
> Robert Haas <[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers