5
5
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
6
6
* Portions Copyright (c) 1994-5, Regents of the University of California
7
7
*
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 $
9
9
*
10
10
*/
11
11
15
15
#include "access/heapam.h"
16
16
#include "catalog/pg_type.h"
17
17
#include "commands/explain.h"
18
+ #include "executor/executor.h"
18
19
#include "executor/instrument.h"
19
20
#include "lib/stringinfo.h"
20
21
#include "nodes/print.h"
@@ -38,15 +39,9 @@ typedef struct ExplainState
38
39
List * rtable ; /* range table */
39
40
} ExplainState ;
40
41
41
- typedef struct TextOutputState
42
- {
43
- TupleDesc tupdesc ;
44
- DestReceiver * destfunc ;
45
- } TextOutputState ;
46
-
47
42
static StringInfo Explain_PlanToString (Plan * plan , ExplainState * es );
48
43
static void ExplainOneQuery (Query * query , ExplainStmt * stmt ,
49
- TextOutputState * tstate );
44
+ TupOutputState * tstate );
50
45
static void explain_outNode (StringInfo str , Plan * plan , Plan * outer_plan ,
51
46
int indent , ExplainState * es );
52
47
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,
59
54
static void show_sort_keys (List * tlist , int nkeys , const char * qlabel ,
60
55
StringInfo str , int indent , ExplainState * es );
61
56
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
-
67
57
68
58
/*
69
59
* ExplainQuery -
73
63
ExplainQuery (ExplainStmt * stmt , CommandDest dest )
74
64
{
75
65
Query * query = stmt -> query ;
76
- TextOutputState * tstate ;
66
+ TupOutputState * tstate ;
67
+ TupleDesc tupdesc ;
77
68
List * rewritten ;
78
69
List * l ;
79
70
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 );
81
78
82
79
if (query -> commandType == CMD_UTILITY )
83
80
{
84
81
/* 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" );
86
83
}
87
84
else
88
85
{
@@ -92,7 +89,7 @@ ExplainQuery(ExplainStmt *stmt, CommandDest dest)
92
89
if (rewritten == NIL )
93
90
{
94
91
/* 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" );
96
93
}
97
94
else
98
95
{
@@ -102,20 +99,20 @@ ExplainQuery(ExplainStmt *stmt, CommandDest dest)
102
99
ExplainOneQuery (lfirst (l ), stmt , tstate );
103
100
/* put a blank line between plans */
104
101
if (lnext (l ) != NIL )
105
- do_text_output ( tstate , "" );
102
+ PROJECT_LINE_OF_TEXT ( "" );
106
103
}
107
104
}
108
105
}
109
106
110
- end_text_output (tstate );
107
+ end_tup_output (tstate );
111
108
}
112
109
113
110
/*
114
111
* ExplainOneQuery -
115
112
* print out the execution plan for one query
116
113
*/
117
114
static void
118
- ExplainOneQuery (Query * query , ExplainStmt * stmt , TextOutputState * tstate )
115
+ ExplainOneQuery (Query * query , ExplainStmt * stmt , TupOutputState * tstate )
119
116
{
120
117
Plan * plan ;
121
118
ExplainState * es ;
@@ -125,9 +122,9 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TextOutputState *tstate)
125
122
if (query -> commandType == CMD_UTILITY )
126
123
{
127
124
if (query -> utilityStmt && IsA (query -> utilityStmt , NotifyStmt ))
128
- do_text_output ( tstate , "NOTIFY" );
125
+ PROJECT_LINE_OF_TEXT ( "NOTIFY" );
129
126
else
130
- do_text_output ( tstate , "UTILITY" );
127
+ PROJECT_LINE_OF_TEXT ( "UTILITY" );
131
128
return ;
132
129
}
133
130
@@ -192,7 +189,7 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TextOutputState *tstate)
192
189
do_text_output_multiline (tstate , f );
193
190
pfree (f );
194
191
if (es -> printCost )
195
- do_text_output ( tstate , "" ); /* separator line */
192
+ PROJECT_LINE_OF_TEXT ( "" ); /* separator line */
196
193
}
197
194
}
198
195
@@ -837,78 +834,3 @@ make_ors_ands_explicit(List *orclauses)
837
834
return (Node * ) make_orclause (args );
838
835
}
839
836
}
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
- }
0 commit comments