| 904 | } |
| 905 | |
| 906 | JoinTreeQueryPlan buildQueryPlanForTableExpression(QueryTreeNodePtr table_expression, |
| 907 | const QueryTreeNodePtr & parent_join_tree, |
| 908 | const SelectQueryInfo & select_query_info, |
| 909 | const SelectQueryOptions & select_query_options, |
| 910 | PlannerContextPtr & planner_context, |
| 911 | bool is_single_table_expression, |
| 912 | bool wrap_read_columns_in_subquery) |
| 913 | { |
| 914 | const auto & query_context = planner_context->getQueryContext(); |
| 915 | const auto & settings = query_context->getSettingsRef(); |
| 916 | |
| 917 | auto & table_expression_data = planner_context->getTableExpressionDataOrThrow(table_expression); |
| 918 | |
| 919 | QueryProcessingStage::Enum till_stage = QueryProcessingStage::Enum::FetchColumns; |
| 920 | |
| 921 | if (wrap_read_columns_in_subquery) |
| 922 | { |
| 923 | auto columns = table_expression_data.getColumns(); |
| 924 | table_expression = buildSubqueryToReadColumnsFromTableExpression(columns, table_expression, query_context); |
| 925 | } |
| 926 | |
| 927 | auto * table_node = table_expression->as<TableNode>(); |
| 928 | auto * table_function_node = table_expression->as<TableFunctionNode>(); |
| 929 | auto * query_node = table_expression->as<QueryNode>(); |
| 930 | auto * union_node = table_expression->as<UnionNode>(); |
| 931 | |
| 932 | /// Hoisted to function scope so the rename block below can skip the recursive |
| 933 | /// `Planner` when trivial count produced a header that already matches the |
| 934 | /// expected one. |
| 935 | bool is_trivial_count_applied = false; |
| 936 | |
| 937 | QueryPlan query_plan; |
| 938 | std::unordered_map<const QueryNode *, const QueryPlan::Node *> query_node_to_plan_step_mapping; |
| 939 | std::set<std::string> used_row_policies; |
| 940 | UsefulSets useful_sets; |
| 941 | |
| 942 | if (table_node || table_function_node) |
| 943 | { |
| 944 | const auto & storage = table_node ? table_node->getStorage() : table_function_node->getStorage(); |
| 945 | const auto & storage_snapshot = table_node ? table_node->getStorageSnapshot() : table_function_node->getStorageSnapshot(); |
| 946 | |
| 947 | auto table_expression_query_info = select_query_info; |
| 948 | table_expression_query_info.table_expression = table_expression; |
| 949 | if (const auto & filter_actions = table_expression_data.getFilterActions()) |
| 950 | table_expression_query_info.filter_actions_dag = std::make_shared<const ActionsDAG>(filter_actions->clone()); |
| 951 | |
| 952 | /// Parse additional_table_filters early so that later decisions (trivial-count, |
| 953 | /// trivial-limit) can see `additional_filter_ast` before the actual filter DAG |
| 954 | /// is built further down |
| 955 | /// |
| 956 | /// Skip under `only_analyze`, since we may not have the database in case of Distributed. |
| 957 | if (!select_query_options.only_analyze) |
| 958 | parseAdditionalFilterAstIfNeeded( |
| 959 | storage, table_expression->getOriginalAlias(), table_expression_query_info, query_context); |
| 960 | |
| 961 | const size_t memory_limited_max_threads = getMaxThreadsForAvailableMemory( |
| 962 | settings[Setting::max_threads], settings[Setting::max_threads_min_free_memory_per_thread]); |
| 963 | size_t max_streams = memory_limited_max_threads; |
no test coverage detected