|
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 |
| - bool timing_set = false; |
181 |
| - bool buffers_set = false; |
182 |
| - bool summary_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 |
| - else if (strcmp(opt->defname, "verbose") == 0) |
192 |
| - es->verbose = defGetBoolean(opt); |
193 |
| - else if (strcmp(opt->defname, "costs") == 0) |
194 |
| - es->costs = defGetBoolean(opt); |
195 |
| - else if (strcmp(opt->defname, "buffers") == 0) |
196 |
| - { |
197 |
| - buffers_set = true; |
198 |
| - es->buffers = defGetBoolean(opt); |
199 |
| - } |
200 |
| - else if (strcmp(opt->defname, "wal") == 0) |
201 |
| - es->wal = defGetBoolean(opt); |
202 |
| - else if (strcmp(opt->defname, "settings") == 0) |
203 |
| - es->settings = defGetBoolean(opt); |
204 |
| - else if (strcmp(opt->defname, "generic_plan") == 0) |
205 |
| - es->generic = defGetBoolean(opt); |
206 |
| - else if (strcmp(opt->defname, "timing") == 0) |
207 |
| - { |
208 |
| - timing_set = true; |
209 |
| - es->timing = defGetBoolean(opt); |
210 |
| - } |
211 |
| - else if (strcmp(opt->defname, "summary") == 0) |
212 |
| - { |
213 |
| - summary_set = true; |
214 |
| - es->summary = defGetBoolean(opt); |
215 |
| - } |
216 |
| - else if (strcmp(opt->defname, "memory") == 0) |
217 |
| - es->memory = defGetBoolean(opt); |
218 |
| - else if (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 |
| - else if (strcmp(p, "text") == 0) |
227 |
| - es->serialize = EXPLAIN_SERIALIZE_TEXT; |
228 |
| - else if (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 |
| - else if (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 |
| - else if (strcmp(p, "xml") == 0) |
250 |
| - es->format = EXPLAIN_FORMAT_XML; |
251 |
| - else if (strcmp(p, "json") == 0) |
252 |
| - es->format = EXPLAIN_FORMAT_JSON; |
253 |
| - else if (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 |
| - return es; |
377 |
| -} |
378 |
| - |
379 | 246 | /*
|
380 | 247 | * ExplainResultDesc -
|
381 | 248 | * construct the result tupledesc for an EXPLAIN
|
|
0 commit comments