Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8e166e1

Browse files
committed
Rearrange explain.c's API so callers need not embed sizeof(ExplainState).
The folly of the previous arrangement was just demonstrated: there's noconvenient way to add fields to ExplainState without breaking ABI, evenif callers have no need to touch those fields. Since we might well needto do that again someday in back branches, let's change things so thatonly explain.c has to have sizeof(ExplainState) compiled into it. Thiscosts one extra palloc() per EXPLAIN operation, which is surely prettynegligible.
1 parenta5cd70d commit8e166e1

File tree

3 files changed

+55
-56
lines changed

3 files changed

+55
-56
lines changed

‎contrib/auto_explain/auto_explain.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -294,32 +294,31 @@ explain_ExecutorEnd(QueryDesc *queryDesc)
294294
msec=queryDesc->totaltime->total*1000.0;
295295
if (msec >=auto_explain_log_min_duration)
296296
{
297-
ExplainStatees;
298-
299-
ExplainInitState(&es);
300-
es.analyze= (queryDesc->instrument_options&&auto_explain_log_analyze);
301-
es.verbose=auto_explain_log_verbose;
302-
es.buffers= (es.analyze&&auto_explain_log_buffers);
303-
es.timing= (es.analyze&&auto_explain_log_timing);
304-
es.summary=es.analyze;
305-
es.format=auto_explain_log_format;
306-
307-
ExplainBeginOutput(&es);
308-
ExplainQueryText(&es,queryDesc);
309-
ExplainPrintPlan(&es,queryDesc);
310-
if (es.analyze&&auto_explain_log_triggers)
311-
ExplainPrintTriggers(&es,queryDesc);
312-
ExplainEndOutput(&es);
297+
ExplainState*es=NewExplainState();
298+
299+
es->analyze= (queryDesc->instrument_options&&auto_explain_log_analyze);
300+
es->verbose=auto_explain_log_verbose;
301+
es->buffers= (es->analyze&&auto_explain_log_buffers);
302+
es->timing= (es->analyze&&auto_explain_log_timing);
303+
es->summary=es->analyze;
304+
es->format=auto_explain_log_format;
305+
306+
ExplainBeginOutput(es);
307+
ExplainQueryText(es,queryDesc);
308+
ExplainPrintPlan(es,queryDesc);
309+
if (es->analyze&&auto_explain_log_triggers)
310+
ExplainPrintTriggers(es,queryDesc);
311+
ExplainEndOutput(es);
313312

314313
/* Remove last line break */
315-
if (es.str->len>0&&es.str->data[es.str->len-1]=='\n')
316-
es.str->data[--es.str->len]='\0';
314+
if (es->str->len>0&&es->str->data[es->str->len-1]=='\n')
315+
es->str->data[--es->str->len]='\0';
317316

318317
/* Fix JSON to output an object */
319318
if (auto_explain_log_format==EXPLAIN_FORMAT_JSON)
320319
{
321-
es.str->data[0]='{';
322-
es.str->data[es.str->len-1]='}';
320+
es->str->data[0]='{';
321+
es->str->data[es->str->len-1]='}';
323322
}
324323

325324
/*
@@ -330,10 +329,10 @@ explain_ExecutorEnd(QueryDesc *queryDesc)
330329
*/
331330
ereport(LOG,
332331
(errmsg("duration: %.3f ms plan:\n%s",
333-
msec,es.str->data),
332+
msec,es->str->data),
334333
errhidestmt(true)));
335334

336-
pfree(es.str->data);
335+
pfree(es->str->data);
337336
}
338337
}
339338

‎src/backend/commands/explain.c

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -125,45 +125,42 @@ void
125125
ExplainQuery(ExplainStmt*stmt,constchar*queryString,
126126
ParamListInfoparams,DestReceiver*dest)
127127
{
128-
ExplainStatees;
128+
ExplainState*es=NewExplainState();
129129
TupOutputState*tstate;
130130
List*rewritten;
131131
ListCell*lc;
132132
booltiming_set= false;
133133

134-
/* Initialize ExplainState. */
135-
ExplainInitState(&es);
136-
137134
/* Parse options list. */
138135
foreach(lc,stmt->options)
139136
{
140137
DefElem*opt= (DefElem*)lfirst(lc);
141138

142139
if (strcmp(opt->defname,"analyze")==0)
143-
es.analyze=defGetBoolean(opt);
140+
es->analyze=defGetBoolean(opt);
144141
elseif (strcmp(opt->defname,"verbose")==0)
145-
es.verbose=defGetBoolean(opt);
142+
es->verbose=defGetBoolean(opt);
146143
elseif (strcmp(opt->defname,"costs")==0)
147-
es.costs=defGetBoolean(opt);
144+
es->costs=defGetBoolean(opt);
148145
elseif (strcmp(opt->defname,"buffers")==0)
149-
es.buffers=defGetBoolean(opt);
146+
es->buffers=defGetBoolean(opt);
150147
elseif (strcmp(opt->defname,"timing")==0)
151148
{
152149
timing_set= true;
153-
es.timing=defGetBoolean(opt);
150+
es->timing=defGetBoolean(opt);
154151
}
155152
elseif (strcmp(opt->defname,"format")==0)
156153
{
157154
char*p=defGetString(opt);
158155

159156
if (strcmp(p,"text")==0)
160-
es.format=EXPLAIN_FORMAT_TEXT;
157+
es->format=EXPLAIN_FORMAT_TEXT;
161158
elseif (strcmp(p,"xml")==0)
162-
es.format=EXPLAIN_FORMAT_XML;
159+
es->format=EXPLAIN_FORMAT_XML;
163160
elseif (strcmp(p,"json")==0)
164-
es.format=EXPLAIN_FORMAT_JSON;
161+
es->format=EXPLAIN_FORMAT_JSON;
165162
elseif (strcmp(p,"yaml")==0)
166-
es.format=EXPLAIN_FORMAT_YAML;
163+
es->format=EXPLAIN_FORMAT_YAML;
167164
else
168165
ereport(ERROR,
169166
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -177,22 +174,22 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
177174
opt->defname)));
178175
}
179176

180-
if (es.buffers&& !es.analyze)
177+
if (es->buffers&& !es->analyze)
181178
ereport(ERROR,
182179
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
183180
errmsg("EXPLAIN option BUFFERS requires ANALYZE")));
184181

185182
/* if the timing was not set explicitly, set default value */
186-
es.timing= (timing_set) ?es.timing :es.analyze;
183+
es->timing= (timing_set) ?es->timing :es->analyze;
187184

188185
/* check that timing is used with EXPLAIN ANALYZE */
189-
if (es.timing&& !es.analyze)
186+
if (es->timing&& !es->analyze)
190187
ereport(ERROR,
191188
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
192189
errmsg("EXPLAIN option TIMING requires ANALYZE")));
193190

194191
/* currently, summary option is not exposed to users; just set it */
195-
es.summary=es.analyze;
192+
es->summary=es->analyze;
196193

197194
/*
198195
* Parse analysis was done already, but we still have to run the rule
@@ -210,16 +207,16 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
210207
rewritten=QueryRewrite((Query*)copyObject(stmt->query));
211208

212209
/* emit opening boilerplate */
213-
ExplainBeginOutput(&es);
210+
ExplainBeginOutput(es);
214211

215212
if (rewritten==NIL)
216213
{
217214
/*
218215
* In the case of an INSTEAD NOTHING, tell at least that. But in
219216
* non-text format, the output is delimited, so this isn't necessary.
220217
*/
221-
if (es.format==EXPLAIN_FORMAT_TEXT)
222-
appendStringInfoString(es.str,"Query rewrites to nothing\n");
218+
if (es->format==EXPLAIN_FORMAT_TEXT)
219+
appendStringInfoString(es->str,"Query rewrites to nothing\n");
223220
}
224221
else
225222
{
@@ -228,41 +225,44 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
228225
/* Explain every plan */
229226
foreach(l,rewritten)
230227
{
231-
ExplainOneQuery((Query*)lfirst(l),NULL,&es,
228+
ExplainOneQuery((Query*)lfirst(l),NULL,es,
232229
queryString,params);
233230

234231
/* Separate plans with an appropriate separator */
235232
if (lnext(l)!=NULL)
236-
ExplainSeparatePlans(&es);
233+
ExplainSeparatePlans(es);
237234
}
238235
}
239236

240237
/* emit closing boilerplate */
241-
ExplainEndOutput(&es);
242-
Assert(es.indent==0);
238+
ExplainEndOutput(es);
239+
Assert(es->indent==0);
243240

244241
/* output tuples */
245242
tstate=begin_tup_output_tupdesc(dest,ExplainResultDesc(stmt));
246-
if (es.format==EXPLAIN_FORMAT_TEXT)
247-
do_text_output_multiline(tstate,es.str->data);
243+
if (es->format==EXPLAIN_FORMAT_TEXT)
244+
do_text_output_multiline(tstate,es->str->data);
248245
else
249-
do_text_output_oneline(tstate,es.str->data);
246+
do_text_output_oneline(tstate,es->str->data);
250247
end_tup_output(tstate);
251248

252-
pfree(es.str->data);
249+
pfree(es->str->data);
253250
}
254251

255252
/*
256-
*InitializeExplainState.
253+
*Create a newExplainState struct initialized with default options.
257254
*/
258-
void
259-
ExplainInitState(ExplainState*es)
255+
ExplainState*
256+
NewExplainState(void)
260257
{
261-
/* Set default options. */
262-
memset(es,0,sizeof(ExplainState));
258+
ExplainState*es= (ExplainState*)palloc0(sizeof(ExplainState));
259+
260+
/* Set default options (most fields can be left as zeroes). */
263261
es->costs= true;
264262
/* Prepare output buffer. */
265263
es->str=makeStringInfo();
264+
265+
returnes;
266266
}
267267

268268
/*

‎src/include/commands/explain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook;
6060
externvoidExplainQuery(ExplainStmt*stmt,constchar*queryString,
6161
ParamListInfoparams,DestReceiver*dest);
6262

63-
externvoidExplainInitState(ExplainState*es);
63+
externExplainState*NewExplainState(void);
6464

6565
externTupleDescExplainResultDesc(ExplainStmt*stmt);
6666

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp