Skip to content

Commit 1ce0360

Browse files
committed
> 2. This patch includes the same Table Function API fixes that I
> submitted on July 9: > > http://archives.postgresql.org/pgsql-patches/2002-07/msg00056.php > > Please disregard that one *if* this one is applied. If this one is > rejected please go ahead with the July 9th patch. The July 9th Table Function API patch mentioned above is now in CVS, so here is an updated version of the guc patch which should apply cleanly against CVS tip. Joe Conway
1 parent b6d2faa commit 1ce0360

File tree

7 files changed

+302
-115
lines changed

7 files changed

+302
-115
lines changed

src/backend/commands/explain.c

Lines changed: 20 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
66
* Portions Copyright (c) 1994-5, Regents of the University of California
77
*
8-
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.81 2002/07/20 05:16:57 momjian Exp $
8+
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.82 2002/07/20 05:49:27 momjian Exp $
99
*
1010
*/
1111

@@ -15,6 +15,7 @@
1515
#include "access/heapam.h"
1616
#include "catalog/pg_type.h"
1717
#include "commands/explain.h"
18+
#include "executor/executor.h"
1819
#include "executor/instrument.h"
1920
#include "lib/stringinfo.h"
2021
#include "nodes/print.h"
@@ -38,15 +39,9 @@ typedef struct ExplainState
3839
List *rtable; /* range table */
3940
} ExplainState;
4041

41-
typedef struct TextOutputState
42-
{
43-
TupleDesc tupdesc;
44-
DestReceiver *destfunc;
45-
} TextOutputState;
46-
4742
static StringInfo Explain_PlanToString(Plan *plan, ExplainState *es);
4843
static void ExplainOneQuery(Query *query, ExplainStmt *stmt,
49-
TextOutputState *tstate);
44+
TupOutputState *tstate);
5045
static void explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
5146
int indent, ExplainState *es);
5247
static void show_scan_qual(List *qual, bool is_or_qual, const char *qlabel,
@@ -59,11 +54,6 @@ static void show_upper_qual(List *qual, const char *qlabel,
5954
static void show_sort_keys(List *tlist, int nkeys, const char *qlabel,
6055
StringInfo str, int indent, ExplainState *es);
6156
static Node *make_ors_ands_explicit(List *orclauses);
62-
static TextOutputState *begin_text_output(CommandDest dest, char *title);
63-
static void do_text_output(TextOutputState *tstate, char *aline);
64-
static void do_text_output_multiline(TextOutputState *tstate, char *text);
65-
static void end_text_output(TextOutputState *tstate);
66-
6757

6858
/*
6959
* ExplainQuery -
@@ -73,16 +63,23 @@ void
7363
ExplainQuery(ExplainStmt *stmt, CommandDest dest)
7464
{
7565
Query *query = stmt->query;
76-
TextOutputState *tstate;
66+
TupOutputState *tstate;
67+
TupleDesc tupdesc;
7768
List *rewritten;
7869
List *l;
7970

80-
tstate = begin_text_output(dest, "QUERY PLAN");
71+
/* need a tuple descriptor representing a single TEXT column */
72+
tupdesc = CreateTemplateTupleDesc(1);
73+
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN",
74+
TEXTOID, -1, 0, false);
75+
76+
/* prepare for projection of tuples */
77+
tstate = begin_tup_output_tupdesc(dest, tupdesc);
8178

8279
if (query->commandType == CMD_UTILITY)
8380
{
8481
/* rewriter will not cope with utility statements */
85-
do_text_output(tstate, "Utility statements have no plan structure");
82+
PROJECT_LINE_OF_TEXT("Utility statements have no plan structure");
8683
}
8784
else
8885
{
@@ -92,7 +89,7 @@ ExplainQuery(ExplainStmt *stmt, CommandDest dest)
9289
if (rewritten == NIL)
9390
{
9491
/* In the case of an INSTEAD NOTHING, tell at least that */
95-
do_text_output(tstate, "Query rewrites to nothing");
92+
PROJECT_LINE_OF_TEXT("Query rewrites to nothing");
9693
}
9794
else
9895
{
@@ -102,20 +99,20 @@ ExplainQuery(ExplainStmt *stmt, CommandDest dest)
10299
ExplainOneQuery(lfirst(l), stmt, tstate);
103100
/* put a blank line between plans */
104101
if (lnext(l) != NIL)
105-
do_text_output(tstate, "");
102+
PROJECT_LINE_OF_TEXT("");
106103
}
107104
}
108105
}
109106

110-
end_text_output(tstate);
107+
end_tup_output(tstate);
111108
}
112109

113110
/*
114111
* ExplainOneQuery -
115112
* print out the execution plan for one query
116113
*/
117114
static void
118-
ExplainOneQuery(Query *query, ExplainStmt *stmt, TextOutputState *tstate)
115+
ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate)
119116
{
120117
Plan *plan;
121118
ExplainState *es;
@@ -125,9 +122,9 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TextOutputState *tstate)
125122
if (query->commandType == CMD_UTILITY)
126123
{
127124
if (query->utilityStmt && IsA(query->utilityStmt, NotifyStmt))
128-
do_text_output(tstate, "NOTIFY");
125+
PROJECT_LINE_OF_TEXT("NOTIFY");
129126
else
130-
do_text_output(tstate, "UTILITY");
127+
PROJECT_LINE_OF_TEXT("UTILITY");
131128
return;
132129
}
133130

@@ -192,7 +189,7 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TextOutputState *tstate)
192189
do_text_output_multiline(tstate, f);
193190
pfree(f);
194191
if (es->printCost)
195-
do_text_output(tstate, ""); /* separator line */
192+
PROJECT_LINE_OF_TEXT(""); /* separator line */
196193
}
197194
}
198195

@@ -837,78 +834,3 @@ make_ors_ands_explicit(List *orclauses)
837834
return (Node *) make_orclause(args);
838835
}
839836
}
840-
841-
842-
/*
843-
* Functions for sending text to the frontend (or other specified destination)
844-
* as though it is a SELECT result.
845-
*
846-
* We tell the frontend that the table structure is a single TEXT column.
847-
*/
848-
849-
static TextOutputState *
850-
begin_text_output(CommandDest dest, char *title)
851-
{
852-
TextOutputState *tstate;
853-
TupleDesc tupdesc;
854-
855-
tstate = (TextOutputState *) palloc(sizeof(TextOutputState));
856-
857-
/* need a tuple descriptor representing a single TEXT column */
858-
tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID);
859-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, title,
860-
TEXTOID, -1, 0, false);
861-
862-
tstate->tupdesc = tupdesc;
863-
tstate->destfunc = DestToFunction(dest);
864-
865-
(*tstate->destfunc->setup) (tstate->destfunc, (int) CMD_SELECT,
866-
NULL, tupdesc);
867-
868-
return tstate;
869-
}
870-
871-
/* write a single line of text */
872-
static void
873-
do_text_output(TextOutputState *tstate, char *aline)
874-
{
875-
HeapTuple tuple;
876-
Datum values[1];
877-
char nulls[1];
878-
879-
/* form a tuple and send it to the receiver */
880-
values[0] = DirectFunctionCall1(textin, CStringGetDatum(aline));
881-
nulls[0] = ' ';
882-
tuple = heap_formtuple(tstate->tupdesc, values, nulls);
883-
(*tstate->destfunc->receiveTuple) (tuple,
884-
tstate->tupdesc,
885-
tstate->destfunc);
886-
pfree(DatumGetPointer(values[0]));
887-
heap_freetuple(tuple);
888-
}
889-
890-
/* write a chunk of text, breaking at newline characters */
891-
/* NB: scribbles on its input! */
892-
static void
893-
do_text_output_multiline(TextOutputState *tstate, char *text)
894-
{
895-
while (*text)
896-
{
897-
char *eol;
898-
899-
eol = strchr(text, '\n');
900-
if (eol)
901-
*eol++ = '\0';
902-
else
903-
eol = text + strlen(text);
904-
do_text_output(tstate, text);
905-
text = eol;
906-
}
907-
}
908-
909-
static void
910-
end_text_output(TextOutputState *tstate)
911-
{
912-
(*tstate->destfunc->cleanup) (tstate->destfunc);
913-
pfree(tstate);
914-
}

src/backend/executor/execTuples.c

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.55 2002/07/20 05:16:57 momjian Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.56 2002/07/20 05:49:27 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -791,3 +791,73 @@ BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
791791
return tuple;
792792
}
793793

794+
/*
795+
* Functions for sending tuples to the frontend (or other specified destination)
796+
* as though it is a SELECT result. These are used by utility commands that
797+
* need to project directly to the destination and don't need or want full
798+
* Table Function capability. Currently used by EXPLAIN and SHOW ALL
799+
*/
800+
TupOutputState *
801+
begin_tup_output_tupdesc(CommandDest dest, TupleDesc tupdesc)
802+
{
803+
TupOutputState *tstate;
804+
805+
tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
806+
807+
tstate->tupdesc = tupdesc;
808+
tstate->destfunc = DestToFunction(dest);
809+
810+
(*tstate->destfunc->setup) (tstate->destfunc, (int) CMD_SELECT,
811+
NULL, tupdesc);
812+
813+
return tstate;
814+
}
815+
816+
/*
817+
* write a single tuple
818+
*
819+
* values is a list of the external C string representations of the values
820+
* to be projected.
821+
*/
822+
void
823+
do_tup_output(TupOutputState *tstate, char **values)
824+
{
825+
/* build a tuple from the input strings using the tupdesc */
826+
AttInMetadata *attinmeta = TupleDescGetAttInMetadata(tstate->tupdesc);
827+
HeapTuple tuple = BuildTupleFromCStrings(attinmeta, values);
828+
829+
/* send the tuple to the receiver */
830+
(*tstate->destfunc->receiveTuple) (tuple,
831+
tstate->tupdesc,
832+
tstate->destfunc);
833+
/* clean up */
834+
heap_freetuple(tuple);
835+
}
836+
837+
/* write a chunk of text, breaking at newline characters
838+
* NB: scribbles on its input!
839+
* Should only be used for a single TEXT attribute tupdesc.
840+
*/
841+
void
842+
do_text_output_multiline(TupOutputState *tstate, char *text)
843+
{
844+
while (*text)
845+
{
846+
char *eol;
847+
848+
eol = strchr(text, '\n');
849+
if (eol)
850+
*eol++ = '\0';
851+
else
852+
eol = text + strlen(text);
853+
do_tup_output(tstate, &text);
854+
text = eol;
855+
}
856+
}
857+
858+
void
859+
end_tup_output(TupOutputState *tstate)
860+
{
861+
(*tstate->destfunc->cleanup) (tstate->destfunc);
862+
pfree(tstate);
863+
}

0 commit comments

Comments
 (0)