| 448 | } |
| 449 | |
| 450 | ASTPtr QueryNode::toASTImpl(const ConvertToASTOptions & options) const |
| 451 | { |
| 452 | auto select_query = make_intrusive<ASTSelectQuery>(); |
| 453 | /// Preserve the parser invariant `recursive_with -> with() != nullptr`. |
| 454 | select_query->recursive_with = is_recursive_with && hasWith(); |
| 455 | select_query->distinct = is_distinct; |
| 456 | select_query->limit_with_ties = is_limit_with_ties; |
| 457 | select_query->group_by_with_totals = is_group_by_with_totals; |
| 458 | select_query->group_by_with_rollup = is_group_by_with_rollup; |
| 459 | select_query->group_by_with_cube = is_group_by_with_cube; |
| 460 | select_query->group_by_with_grouping_sets = is_group_by_with_grouping_sets; |
| 461 | select_query->group_by_all = is_group_by_all; |
| 462 | select_query->order_by_all = is_order_by_all; |
| 463 | select_query->limit_by_all = is_limit_by_all; |
| 464 | |
| 465 | if (hasWith()) |
| 466 | { |
| 467 | const auto & with = getWith(); |
| 468 | auto expression_list_ast = make_intrusive<ASTExpressionList>(); |
| 469 | expression_list_ast->children.reserve(with.getNodes().size()); |
| 470 | |
| 471 | for (const auto & with_node : with) |
| 472 | { |
| 473 | auto with_node_ast = with_node->toAST(options); |
| 474 | expression_list_ast->children.push_back(with_node_ast); |
| 475 | |
| 476 | const auto * with_query_node = with_node->as<QueryNode>(); |
| 477 | const auto * with_union_node = with_node->as<UnionNode>(); |
| 478 | if (!with_query_node && !with_union_node) |
| 479 | continue; |
| 480 | |
| 481 | bool is_with_node_cte = with_query_node ? with_query_node->isCTE() : with_union_node->isCTE(); |
| 482 | if (!is_with_node_cte) |
| 483 | continue; |
| 484 | |
| 485 | const auto & with_node_cte_name = with_query_node ? with_query_node->cte_name : with_union_node->getCTEName(); |
| 486 | |
| 487 | auto * with_node_ast_subquery = with_node_ast->as<ASTSubquery>(); |
| 488 | if (with_node_ast_subquery) |
| 489 | with_node_ast_subquery->cte_name = ""; |
| 490 | |
| 491 | auto with_element_ast = make_intrusive<ASTWithElement>(); |
| 492 | with_element_ast->name = with_node_cte_name; |
| 493 | with_element_ast->subquery = std::move(with_node_ast); |
| 494 | with_element_ast->children.push_back(with_element_ast->subquery); |
| 495 | with_element_ast->is_materialized = with_query_node ? with_query_node->isMaterialized() : with_union_node->isMaterialized(); |
| 496 | |
| 497 | expression_list_ast->children.back() = std::move(with_element_ast); |
| 498 | } |
| 499 | |
| 500 | select_query->setExpression(ASTSelectQuery::Expression::WITH, std::move(expression_list_ast)); |
| 501 | } |
| 502 | |
| 503 | auto projection_ast = getProjection().toAST(options); |
| 504 | auto & projection_expression_list_ast = projection_ast->as<ASTExpressionList &>(); |
| 505 | size_t projection_expression_list_ast_children_size = projection_expression_list_ast.children.size(); |
| 506 | if (projection_expression_list_ast_children_size != getProjection().getNodes().size()) |
| 507 | throw Exception(ErrorCodes::LOGICAL_ERROR, "Query node invalid projection conversion to AST"); |
nothing calls this directly
no test coverage detected