Resolve window function window node. * * Node can be identifier or window node. * Example: SELECT count(*) OVER w FROM test_table WINDOW w AS (PARTITION BY id); * Example: SELECT count(*) OVER (PARTITION BY id); * * If node has parent window name specified, then parent window definition is searched in nearest query scope WINDOW section. * If node is identifier, than node is replaced
| 2798 | * Window node frame is validated. |
| 2799 | */ |
| 2800 | ProjectionName QueryAnalyzer::resolveWindow(QueryTreeNodePtr & node, IdentifierResolveScope & scope) |
| 2801 | { |
| 2802 | std::string parent_window_name; |
| 2803 | auto * identifier_node = node->as<IdentifierNode>(); |
| 2804 | |
| 2805 | ProjectionName result_projection_name; |
| 2806 | QueryTreeNodePtr parent_window_node; |
| 2807 | |
| 2808 | if (identifier_node) |
| 2809 | parent_window_name = identifier_node->getIdentifier().getFullName(); |
| 2810 | else if (auto * window_node = node->as<WindowNode>()) |
| 2811 | parent_window_name = window_node->getParentWindowName(); |
| 2812 | |
| 2813 | if (!parent_window_name.empty()) |
| 2814 | { |
| 2815 | auto * nearest_query_scope = scope.getNearestQueryScope(); |
| 2816 | |
| 2817 | if (!nearest_query_scope) |
| 2818 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Window '{}' does not exist.", parent_window_name); |
| 2819 | |
| 2820 | auto & scope_window_name_to_window_node = nearest_query_scope->window_name_to_window_node; |
| 2821 | |
| 2822 | auto window_node_it = scope_window_name_to_window_node.find(parent_window_name); |
| 2823 | if (window_node_it == scope_window_name_to_window_node.end()) |
| 2824 | throw Exception(ErrorCodes::BAD_ARGUMENTS, |
| 2825 | "Window '{}' does not exist. In scope {}", |
| 2826 | parent_window_name, |
| 2827 | nearest_query_scope->scope_node->formatASTForErrorMessage()); |
| 2828 | |
| 2829 | parent_window_node = window_node_it->second; |
| 2830 | |
| 2831 | auto [_, inserted] = windows_in_resolve_process.emplace(parent_window_node.get()); |
| 2832 | if (!inserted) |
| 2833 | throw Exception(ErrorCodes::UNSUPPORTED_METHOD, |
| 2834 | "Recursive window {}. In scope {}", |
| 2835 | node->formatASTForErrorMessage(), |
| 2836 | scope.scope_node->formatASTForErrorMessage()); |
| 2837 | |
| 2838 | if (identifier_node) |
| 2839 | { |
| 2840 | node = parent_window_node->clone(); |
| 2841 | node->removeAlias(); |
| 2842 | result_projection_name = parent_window_name; |
| 2843 | } |
| 2844 | else |
| 2845 | { |
| 2846 | mergeWindowWithParentWindow(node, parent_window_node, scope); |
| 2847 | } |
| 2848 | } |
| 2849 | |
| 2850 | auto & window_node = node->as<WindowNode &>(); |
| 2851 | window_node.setParentWindowName({}); |
| 2852 | |
| 2853 | ProjectionNames partition_by_projection_names = resolveExpressionNodeList( |
| 2854 | window_node.getPartitionByNode(), |
| 2855 | scope, |
| 2856 | false /*allow_lambda_expression*/, |
| 2857 | false /*allow_table_expression*/); |
nothing calls this directly
no test coverage detected