mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Change do_tup_output() to take Datum/isnull arrays instead of a char * array,
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
This commit is contained in:
parent
ea382424ee
commit
846c364dd4
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "catalog/pg_type.h"
|
||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/typcache.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)
|
* 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
|
* 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
|
* 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 *
|
TupOutputState *
|
||||||
begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
|
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 = (TupOutputState *) palloc(sizeof(TupOutputState));
|
||||||
|
|
||||||
tstate->metadata = TupleDescGetAttInMetadata(tupdesc);
|
|
||||||
tstate->slot = MakeSingleTupleTableSlot(tupdesc);
|
tstate->slot = MakeSingleTupleTableSlot(tupdesc);
|
||||||
tstate->dest = dest;
|
tstate->dest = dest;
|
||||||
|
|
||||||
@ -1216,17 +1216,17 @@ begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
|
|||||||
/*
|
/*
|
||||||
* write a single tuple
|
* 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
|
* XXX This could be made more efficient, since in reality we probably only
|
||||||
* need a virtual tuple.
|
* need a virtual tuple.
|
||||||
*/
|
*/
|
||||||
void
|
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 */
|
TupleDesc tupdesc = tstate->slot->tts_tupleDescriptor;
|
||||||
HeapTuple tuple = BuildTupleFromCStrings(tstate->metadata, values);
|
HeapTuple tuple;
|
||||||
|
|
||||||
|
/* form a tuple */
|
||||||
|
tuple = heap_form_tuple(tupdesc, values, isnull);
|
||||||
|
|
||||||
/* put it in a slot */
|
/* put it in a slot */
|
||||||
ExecStoreTuple(tuple, tstate->slot, InvalidBuffer, true);
|
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
|
* write a chunk of text, breaking at newline characters
|
||||||
*
|
*
|
||||||
* NB: scribbles on its input!
|
|
||||||
*
|
|
||||||
* Should only be used with a single-TEXT-attribute tupdesc.
|
* Should only be used with a single-TEXT-attribute tupdesc.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
do_text_output_multiline(TupOutputState *tstate, char *text)
|
do_text_output_multiline(TupOutputState *tstate, char *text)
|
||||||
{
|
{
|
||||||
|
Datum values[1];
|
||||||
|
bool isnull[1] = { false };
|
||||||
|
|
||||||
while (*text)
|
while (*text)
|
||||||
{
|
{
|
||||||
char *eol;
|
char *eol;
|
||||||
|
int len;
|
||||||
|
|
||||||
eol = strchr(text, '\n');
|
eol = strchr(text, '\n');
|
||||||
if (eol)
|
if (eol)
|
||||||
*eol++ = '\0';
|
{
|
||||||
|
len = eol - text;
|
||||||
|
eol++;
|
||||||
|
}
|
||||||
else
|
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;
|
text = eol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1269,6 +1279,5 @@ end_tup_output(TupOutputState *tstate)
|
|||||||
(*tstate->dest->rShutdown) (tstate->dest);
|
(*tstate->dest->rShutdown) (tstate->dest);
|
||||||
/* note that destroying the dest is not ours to do */
|
/* note that destroying the dest is not ours to do */
|
||||||
ExecDropSingleTupleTableSlot(tstate->slot);
|
ExecDropSingleTupleTableSlot(tstate->slot);
|
||||||
/* XXX worth cleaning up the attinmetadata? */
|
|
||||||
pfree(tstate);
|
pfree(tstate);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
int i;
|
||||||
TupOutputState *tstate;
|
TupOutputState *tstate;
|
||||||
TupleDesc tupdesc;
|
TupleDesc tupdesc;
|
||||||
char *values[3];
|
Datum values[3];
|
||||||
|
bool isnull[3] = { false, false, false };
|
||||||
|
|
||||||
/* need a tuple descriptor representing three TEXT columns */
|
/* need a tuple descriptor representing three TEXT columns */
|
||||||
tupdesc = CreateTemplateTupleDesc(3, false);
|
tupdesc = CreateTemplateTupleDesc(3, false);
|
||||||
@ -5997,29 +5998,46 @@ ShowAllGUCConfig(DestReceiver *dest)
|
|||||||
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
|
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
|
||||||
TEXTOID, -1, 0);
|
TEXTOID, -1, 0);
|
||||||
|
|
||||||
|
|
||||||
/* prepare for projection of tuples */
|
/* prepare for projection of tuples */
|
||||||
tstate = begin_tup_output_tupdesc(dest, tupdesc);
|
tstate = begin_tup_output_tupdesc(dest, tupdesc);
|
||||||
|
|
||||||
for (i = 0; i < num_guc_variables; i++)
|
for (i = 0; i < num_guc_variables; i++)
|
||||||
{
|
{
|
||||||
struct config_generic *conf = guc_variables[i];
|
struct config_generic *conf = guc_variables[i];
|
||||||
|
char *setting;
|
||||||
|
|
||||||
if ((conf->flags & GUC_NO_SHOW_ALL) ||
|
if ((conf->flags & GUC_NO_SHOW_ALL) ||
|
||||||
((conf->flags & GUC_SUPERUSER_ONLY) && !am_superuser))
|
((conf->flags & GUC_SUPERUSER_ONLY) && !am_superuser))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* assign to the values array */
|
/* assign to the values array */
|
||||||
values[0] = (char *) conf->name;
|
values[0] = PointerGetDatum(cstring_to_text(conf->name));
|
||||||
values[1] = _ShowOption(conf, true);
|
|
||||||
values[2] = (char *) conf->short_desc;
|
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 */
|
/* send it to dest */
|
||||||
do_tup_output(tstate, values);
|
do_tup_output(tstate, values, isnull);
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
if (values[1] != NULL)
|
pfree(DatumGetPointer(values[0]));
|
||||||
pfree(values[1]);
|
if (setting)
|
||||||
|
{
|
||||||
|
pfree(setting);
|
||||||
|
pfree(DatumGetPointer(values[1]));
|
||||||
|
}
|
||||||
|
pfree(DatumGetPointer(values[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
end_tup_output(tstate);
|
end_tup_output(tstate);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
typedef struct TupOutputState
|
||||||
{
|
{
|
||||||
/* use "struct" here to allow forward reference */
|
|
||||||
struct AttInMetadata *metadata;
|
|
||||||
TupleTableSlot *slot;
|
TupleTableSlot *slot;
|
||||||
DestReceiver *dest;
|
DestReceiver *dest;
|
||||||
} TupOutputState;
|
} TupOutputState;
|
||||||
|
|
||||||
extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest,
|
extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest,
|
||||||
TupleDesc tupdesc);
|
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 do_text_output_multiline(TupOutputState *tstate, char *text);
|
||||||
extern void end_tup_output(TupOutputState *tstate);
|
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.
|
* 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 { \
|
do { \
|
||||||
char *values_[1]; \
|
Datum values_[1]; \
|
||||||
values_[0] = (text_to_emit); \
|
bool isnull_[1]; \
|
||||||
do_tup_output(tstate, values_); \
|
values_[0] = PointerGetDatum(cstring_to_text(str_to_emit)); \
|
||||||
|
isnull_[0] = false; \
|
||||||
|
do_tup_output(tstate, values_, isnull_); \
|
||||||
|
pfree(DatumGetPointer(values_[0])); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user