|
17 | 17 | #include"catalog/pg_type.h"
|
18 | 18 | #include"commands/createas.h"
|
19 | 19 | #include"commands/defrem.h"
|
| 20 | +#include"commands/explain.h" |
20 | 21 | #include"commands/explain_dr.h"
|
21 | 22 | #include"commands/explain_format.h"
|
| 23 | +#include"commands/explain_state.h" |
22 | 24 | #include"commands/prepare.h"
|
23 | 25 | #include"foreign/fdwapi.h"
|
24 | 26 | #include"jit/jit.h"
|
@@ -176,130 +178,11 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
|
176 | 178 | JumbleState*jstate=NULL;
|
177 | 179 | Query*query;
|
178 | 180 | List*rewritten;
|
179 |
| -ListCell*lc; |
180 |
| -booltiming_set= false; |
181 |
| -boolbuffers_set= false; |
182 |
| -boolsummary_set= false; |
183 |
| - |
184 |
| -/* Parse options list. */ |
185 |
| -foreach(lc,stmt->options) |
186 |
| -{ |
187 |
| -DefElem*opt= (DefElem*)lfirst(lc); |
188 | 181 |
|
189 |
| -if (strcmp(opt->defname,"analyze")==0) |
190 |
| -es->analyze=defGetBoolean(opt); |
191 |
| -elseif (strcmp(opt->defname,"verbose")==0) |
192 |
| -es->verbose=defGetBoolean(opt); |
193 |
| -elseif (strcmp(opt->defname,"costs")==0) |
194 |
| -es->costs=defGetBoolean(opt); |
195 |
| -elseif (strcmp(opt->defname,"buffers")==0) |
196 |
| -{ |
197 |
| -buffers_set= true; |
198 |
| -es->buffers=defGetBoolean(opt); |
199 |
| -} |
200 |
| -elseif (strcmp(opt->defname,"wal")==0) |
201 |
| -es->wal=defGetBoolean(opt); |
202 |
| -elseif (strcmp(opt->defname,"settings")==0) |
203 |
| -es->settings=defGetBoolean(opt); |
204 |
| -elseif (strcmp(opt->defname,"generic_plan")==0) |
205 |
| -es->generic=defGetBoolean(opt); |
206 |
| -elseif (strcmp(opt->defname,"timing")==0) |
207 |
| -{ |
208 |
| -timing_set= true; |
209 |
| -es->timing=defGetBoolean(opt); |
210 |
| -} |
211 |
| -elseif (strcmp(opt->defname,"summary")==0) |
212 |
| -{ |
213 |
| -summary_set= true; |
214 |
| -es->summary=defGetBoolean(opt); |
215 |
| -} |
216 |
| -elseif (strcmp(opt->defname,"memory")==0) |
217 |
| -es->memory=defGetBoolean(opt); |
218 |
| -elseif (strcmp(opt->defname,"serialize")==0) |
219 |
| -{ |
220 |
| -if (opt->arg) |
221 |
| -{ |
222 |
| -char*p=defGetString(opt); |
223 |
| - |
224 |
| -if (strcmp(p,"off")==0||strcmp(p,"none")==0) |
225 |
| -es->serialize=EXPLAIN_SERIALIZE_NONE; |
226 |
| -elseif (strcmp(p,"text")==0) |
227 |
| -es->serialize=EXPLAIN_SERIALIZE_TEXT; |
228 |
| -elseif (strcmp(p,"binary")==0) |
229 |
| -es->serialize=EXPLAIN_SERIALIZE_BINARY; |
230 |
| -else |
231 |
| -ereport(ERROR, |
232 |
| -(errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
233 |
| -errmsg("unrecognized value for EXPLAIN option \"%s\": \"%s\"", |
234 |
| -opt->defname,p), |
235 |
| -parser_errposition(pstate,opt->location))); |
236 |
| -} |
237 |
| -else |
238 |
| -{ |
239 |
| -/* SERIALIZE without an argument is taken as 'text' */ |
240 |
| -es->serialize=EXPLAIN_SERIALIZE_TEXT; |
241 |
| -} |
242 |
| -} |
243 |
| -elseif (strcmp(opt->defname,"format")==0) |
244 |
| -{ |
245 |
| -char*p=defGetString(opt); |
246 |
| - |
247 |
| -if (strcmp(p,"text")==0) |
248 |
| -es->format=EXPLAIN_FORMAT_TEXT; |
249 |
| -elseif (strcmp(p,"xml")==0) |
250 |
| -es->format=EXPLAIN_FORMAT_XML; |
251 |
| -elseif (strcmp(p,"json")==0) |
252 |
| -es->format=EXPLAIN_FORMAT_JSON; |
253 |
| -elseif (strcmp(p,"yaml")==0) |
254 |
| -es->format=EXPLAIN_FORMAT_YAML; |
255 |
| -else |
256 |
| -ereport(ERROR, |
257 |
| -(errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
258 |
| -errmsg("unrecognized value for EXPLAIN option \"%s\": \"%s\"", |
259 |
| -opt->defname,p), |
260 |
| -parser_errposition(pstate,opt->location))); |
261 |
| -} |
262 |
| -else |
263 |
| -ereport(ERROR, |
264 |
| -(errcode(ERRCODE_SYNTAX_ERROR), |
265 |
| -errmsg("unrecognized EXPLAIN option \"%s\"", |
266 |
| -opt->defname), |
267 |
| -parser_errposition(pstate,opt->location))); |
268 |
| -} |
269 |
| - |
270 |
| -/* check that WAL is used with EXPLAIN ANALYZE */ |
271 |
| -if (es->wal&& !es->analyze) |
272 |
| -ereport(ERROR, |
273 |
| -(errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
274 |
| -errmsg("EXPLAIN option %s requires ANALYZE","WAL"))); |
275 |
| - |
276 |
| -/* if the timing was not set explicitly, set default value */ |
277 |
| -es->timing= (timing_set) ?es->timing :es->analyze; |
278 |
| - |
279 |
| -/* if the buffers was not set explicitly, set default value */ |
280 |
| -es->buffers= (buffers_set) ?es->buffers :es->analyze; |
281 |
| - |
282 |
| -/* check that timing is used with EXPLAIN ANALYZE */ |
283 |
| -if (es->timing&& !es->analyze) |
284 |
| -ereport(ERROR, |
285 |
| -(errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
286 |
| -errmsg("EXPLAIN option %s requires ANALYZE","TIMING"))); |
287 |
| - |
288 |
| -/* check that serialize is used with EXPLAIN ANALYZE */ |
289 |
| -if (es->serialize!=EXPLAIN_SERIALIZE_NONE&& !es->analyze) |
290 |
| -ereport(ERROR, |
291 |
| -(errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
292 |
| -errmsg("EXPLAIN option %s requires ANALYZE","SERIALIZE"))); |
293 |
| - |
294 |
| -/* check that GENERIC_PLAN is not used with EXPLAIN ANALYZE */ |
295 |
| -if (es->generic&&es->analyze) |
296 |
| -ereport(ERROR, |
297 |
| -(errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
298 |
| -errmsg("EXPLAIN options ANALYZE and GENERIC_PLAN cannot be used together"))); |
299 |
| - |
300 |
| -/* if the summary was not set explicitly, set default value */ |
301 |
| -es->summary= (summary_set) ?es->summary :es->analyze; |
| 182 | +/* Configure the ExplainState based on the provided options */ |
| 183 | +ParseExplainOptionList(es,stmt->options,pstate); |
302 | 184 |
|
| 185 | +/* Extract the query and, if enabled, jumble it */ |
303 | 186 | query=castNode(Query,stmt->query);
|
304 | 187 | if (IsQueryIdEnabled())
|
305 | 188 | jstate=JumbleQuery(query);
|
@@ -360,22 +243,6 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
|
360 | 243 | pfree(es->str->data);
|
361 | 244 | }
|
362 | 245 |
|
363 |
| -/* |
364 |
| - * Create a new ExplainState struct initialized with default options. |
365 |
| - */ |
366 |
| -ExplainState* |
367 |
| -NewExplainState(void) |
368 |
| -{ |
369 |
| -ExplainState*es= (ExplainState*)palloc0(sizeof(ExplainState)); |
370 |
| - |
371 |
| -/* Set default options (most fields can be left as zeroes). */ |
372 |
| -es->costs= true; |
373 |
| -/* Prepare output buffer. */ |
374 |
| -es->str=makeStringInfo(); |
375 |
| - |
376 |
| -returnes; |
377 |
| -} |
378 |
| - |
379 | 246 | /*
|
380 | 247 | * ExplainResultDesc -
|
381 | 248 | * construct the result tupledesc for an EXPLAIN
|
|