| 1821 | } |
| 1822 | |
| 1823 | JoinTreeQueryPlan buildQueryPlanForJoinNode( |
| 1824 | const QueryTreeNodePtr & join_table_expression, |
| 1825 | JoinTreeQueryPlan left_join_tree_query_plan, |
| 1826 | JoinTreeQueryPlan right_join_tree_query_plan, |
| 1827 | const ColumnIdentifierSet & outer_scope_columns, |
| 1828 | PlannerContextPtr & planner_context) |
| 1829 | { |
| 1830 | auto & join_node = join_table_expression->as<JoinNode &>(); |
| 1831 | if (left_join_tree_query_plan.stage != QueryProcessingStage::FetchColumns) |
| 1832 | throw Exception(ErrorCodes::UNSUPPORTED_METHOD, |
| 1833 | "JOIN {} left table expression expected to process query to fetch columns stage. Actual {}", |
| 1834 | join_node.formatASTForErrorMessage(), |
| 1835 | QueryProcessingStage::toString(left_join_tree_query_plan.stage)); |
| 1836 | |
| 1837 | const auto & query_context = planner_context->getQueryContext(); |
| 1838 | const auto & settings = query_context->getSettingsRef(); |
| 1839 | |
| 1840 | auto join_step_logical = buildJoinStepLogical( |
| 1841 | left_join_tree_query_plan.query_plan.getCurrentHeader(), |
| 1842 | right_join_tree_query_plan.query_plan.getCurrentHeader(), |
| 1843 | outer_scope_columns, |
| 1844 | join_node, |
| 1845 | planner_context); |
| 1846 | |
| 1847 | PreparedJoinStorage prepared_join; |
| 1848 | bool allow_storage_join = right_join_tree_query_plan.used_row_policies.empty() |
| 1849 | && right_join_tree_query_plan.stage == QueryProcessingStage::FetchColumns |
| 1850 | && right_join_tree_query_plan.useful_sets.empty(); |
| 1851 | if (allow_storage_join) |
| 1852 | prepared_join = tryGetStorageInTableJoin(join_node.getRightTableExpression(), planner_context); |
| 1853 | if (prepared_join) |
| 1854 | { |
| 1855 | bool use_nulls = settings[Setting::join_use_nulls] && isLeftOrFull(join_node.getKind()); |
| 1856 | auto join_lookup_step = std::make_unique<JoinStepLogicalLookup>(std::move(right_join_tree_query_plan.query_plan), std::move(prepared_join), use_nulls); |
| 1857 | right_join_tree_query_plan.query_plan = {}; |
| 1858 | right_join_tree_query_plan.query_plan.addStep(std::move(join_lookup_step)); |
| 1859 | } |
| 1860 | else |
| 1861 | { |
| 1862 | tryMakeDirectJoinWithMergeTree(join_step_logical->getJoinOperator(), right_join_tree_query_plan.query_plan, prepared_join, planner_context); |
| 1863 | } |
| 1864 | |
| 1865 | appendSetsFromActionsDAG(join_step_logical->getActionsDAG(), left_join_tree_query_plan.useful_sets); |
| 1866 | return joinPlansWithStep( |
| 1867 | std::move(join_step_logical), |
| 1868 | std::move(left_join_tree_query_plan), |
| 1869 | std::move(right_join_tree_query_plan)); |
| 1870 | } |
| 1871 | |
| 1872 | JoinTreeQueryPlan buildQueryPlanForArrayJoinNode(const QueryTreeNodePtr & array_join_table_expression, |
| 1873 | JoinTreeQueryPlan join_tree_query_plan, |
no test coverage detected