Resolve query. * This function modifies query node during resolve. It is caller responsibility to clone query node before resolve * if it is needed for later use. * * query_node - query_tree_node that must have QueryNode type. * scope - query scope. It is caller responsibility to create it. * * Resolve steps: * 1. Validate subqueries depth, perform GROUP BY validation that does not
| 5818 | * 11. Resolve query tree node with projection columns. |
| 5819 | */ |
| 5820 | void QueryAnalyzer::resolveQuery(const QueryTreeNodePtr & query_node, IdentifierResolveScope & scope) |
| 5821 | { |
| 5822 | size_t max_subquery_depth = scope.context->getSettingsRef()[Setting::max_subquery_depth]; |
| 5823 | if (max_subquery_depth && scope.subquery_depth > max_subquery_depth) |
| 5824 | throw Exception(ErrorCodes::TOO_DEEP_SUBQUERIES, "Too deep subqueries. Maximum: {}", max_subquery_depth); |
| 5825 | |
| 5826 | auto & query_node_typed = query_node->as<QueryNode &>(); |
| 5827 | |
| 5828 | /** It is unsafe to call resolveQuery on already resolved query node, because during identifier resolution process |
| 5829 | * we replace identifiers with expressions without aliases, also at the end of resolveQuery all aliases from all nodes will be removed. |
| 5830 | * For subsequent resolveQuery executions it is possible to have wrong projection header, because for nodes |
| 5831 | * with aliases projection name is alias. |
| 5832 | * |
| 5833 | * If for client it is necessary to resolve query node after clone, client must clear projection columns from query node before resolve. |
| 5834 | */ |
| 5835 | if (query_node_typed.isResolved()) |
| 5836 | return; |
| 5837 | |
| 5838 | bool is_rollup_or_cube = query_node_typed.isGroupByWithRollup() || query_node_typed.isGroupByWithCube(); |
| 5839 | |
| 5840 | if (query_node_typed.isGroupByWithGroupingSets() |
| 5841 | && query_node_typed.isGroupByWithTotals() |
| 5842 | && query_node_typed.getGroupBy().getNodes().size() != 1) |
| 5843 | throw Exception(ErrorCodes::NOT_IMPLEMENTED, "WITH TOTALS and GROUPING SETS are not supported together"); |
| 5844 | |
| 5845 | if (query_node_typed.isGroupByWithGroupingSets() && is_rollup_or_cube) |
| 5846 | throw Exception(ErrorCodes::NOT_IMPLEMENTED, "GROUPING SETS are not supported together with ROLLUP and CUBE"); |
| 5847 | |
| 5848 | if (query_node_typed.isGroupByWithRollup() && (query_node_typed.isGroupByWithGroupingSets() || query_node_typed.isGroupByWithCube())) |
| 5849 | throw Exception(ErrorCodes::NOT_IMPLEMENTED, "ROLLUP is not supported together with GROUPING SETS and CUBE"); |
| 5850 | |
| 5851 | if (query_node_typed.isGroupByWithCube() && (query_node_typed.isGroupByWithGroupingSets() || query_node_typed.isGroupByWithRollup())) |
| 5852 | throw Exception(ErrorCodes::NOT_IMPLEMENTED, "CUBE is not supported together with GROUPING SETS and ROLLUP"); |
| 5853 | |
| 5854 | if (query_node_typed.hasHaving() && query_node_typed.isGroupByWithTotals() && is_rollup_or_cube) |
| 5855 | throw Exception(ErrorCodes::NOT_IMPLEMENTED, "WITH TOTALS and WITH ROLLUP or CUBE are not supported together in presence of HAVING"); |
| 5856 | |
| 5857 | if (query_node_typed.hasQualify() && query_node_typed.isGroupByWithTotals() && is_rollup_or_cube) |
| 5858 | throw Exception(ErrorCodes::NOT_IMPLEMENTED, "WITH TOTALS and WITH ROLLUP or CUBE are not supported together in presence of QUALIFY"); |
| 5859 | |
| 5860 | /// Initialize aliases in query node scope |
| 5861 | QueryExpressionsAliasVisitor visitor(scope.aliases); |
| 5862 | |
| 5863 | if (scope.context->getSettingsRef()[Setting::enable_scopes_for_with_statement]) |
| 5864 | { |
| 5865 | visitor.visit(query_node_typed.getWithNode()); |
| 5866 | } |
| 5867 | else |
| 5868 | { |
| 5869 | QueryExpressionsAliasVisitor alias_collector(scope.global_with_aliases); |
| 5870 | alias_collector.visit(query_node_typed.getWithNode()); |
| 5871 | |
| 5872 | scope.aliases = scope.global_with_aliases; |
| 5873 | } |
| 5874 | |
| 5875 | if (!query_node_typed.getProjection().getNodes().empty()) |
| 5876 | visitor.visit(query_node_typed.getProjectionNode()); |
| 5877 |
nothing calls this directly
no test coverage detected