| 236 | } |
| 237 | |
| 238 | BlockInputStreamPtr InterpreterExplainQuery::explain() |
| 239 | { |
| 240 | const auto & ast = query->as<ASTExplainQuery &>(); |
| 241 | |
| 242 | Block sample_block = getSampleBlock(); |
| 243 | MutableColumns res_columns = sample_block.cloneEmptyColumns(); |
| 244 | |
| 245 | WriteBufferFromOwnString buf; |
| 246 | bool single_line = false; |
| 247 | |
| 248 | // if settings.enable_optimizer = true && query is supported by optimizer, print plan with optimizer. |
| 249 | // if query is not supported by optimizer, settings `settings.enable_optimizer` in context will be disabled. |
| 250 | if (ast.getKind() == ASTExplainQuery::ParsedAST) |
| 251 | { |
| 252 | if (ast.getSettings()) |
| 253 | throw Exception("Settings are not supported for EXPLAIN AST query.", ErrorCodes::UNKNOWN_SETTING); |
| 254 | |
| 255 | dumpAST(*ast.getExplainedQuery(), buf); |
| 256 | } |
| 257 | else if (ast.getKind() == ASTExplainQuery::AnalyzedSyntax) |
| 258 | { |
| 259 | if (ast.getSettings()) |
| 260 | throw Exception("Settings are not supported for EXPLAIN SYNTAX query.", ErrorCodes::UNKNOWN_SETTING); |
| 261 | |
| 262 | ExplainAnalyzedSyntaxVisitor::Data data(getContext()); |
| 263 | ExplainAnalyzedSyntaxVisitor(data).visit(query); |
| 264 | |
| 265 | ast.getExplainedQuery()->format(IAST::FormatSettings(buf, false)); |
| 266 | } |
| 267 | else if (ast.getKind() == ASTExplainQuery::QueryPlan) |
| 268 | { |
| 269 | if (!dynamic_cast<const ASTSelectWithUnionQuery *>(ast.getExplainedQuery().get())) |
| 270 | throw Exception("Only SELECT is supported for EXPLAIN query", ErrorCodes::INCORRECT_QUERY); |
| 271 | |
| 272 | auto settings = checkAndGetSettings<QueryPlanSettings>(ast.getSettings()); |
| 273 | QueryPlan plan; |
| 274 | |
| 275 | InterpreterSelectWithUnionQuery interpreter(ast.getExplainedQuery(), getContext(), SelectQueryOptions()); |
| 276 | interpreter.buildQueryPlan(plan); |
| 277 | |
| 278 | if (settings.optimize) |
| 279 | plan.optimize(QueryPlanOptimizationSettings::fromContext(getContext())); |
| 280 | |
| 281 | if (settings.json) |
| 282 | { |
| 283 | /// Add extra layers to make plan look more like from postgres. |
| 284 | auto plan_map = std::make_unique<JSONBuilder::JSONMap>(); |
| 285 | plan_map->add("Plan", plan.explainPlan(settings.query_plan_options)); |
| 286 | auto plan_array = std::make_unique<JSONBuilder::JSONArray>(); |
| 287 | plan_array->add(std::move(plan_map)); |
| 288 | |
| 289 | auto format_settings = getFormatSettings(getContext()); |
| 290 | format_settings.json.quote_64bit_integers = false; |
| 291 | |
| 292 | JSONBuilder::FormatSettings json_format_settings{.settings = format_settings}; |
| 293 | JSONBuilder::FormatContext format_context{.out = buf}; |
| 294 | |
| 295 | plan_array->format(json_format_settings, format_context); |
nothing calls this directly
no test coverage detected