| 96 | } |
| 97 | |
| 98 | static void addToNullableIfNeeded( |
| 99 | JoinExpressionActions & expression_actions, |
| 100 | JoinKind join_kind, |
| 101 | bool use_nulls, |
| 102 | const NameSet & required_output_columns, |
| 103 | std::vector<const ActionsDAG::Node *> & actions_after_join, |
| 104 | const std::unordered_map<String, const ActionsDAG::Node *> & changed_types) |
| 105 | { |
| 106 | auto to_nullable = FunctionFactory::instance().get("toNullable", nullptr); |
| 107 | |
| 108 | auto actions_dag = expression_actions.getActionsDAG(); |
| 109 | auto & outputs = actions_dag->getOutputs(); |
| 110 | outputs.clear(); |
| 111 | |
| 112 | bool to_null_left = use_nulls && isRightOrFull(join_kind); |
| 113 | bool to_null_right = use_nulls && isLeftOrFull(join_kind); |
| 114 | for (const auto * node : actions_dag->getInputs()) |
| 115 | { |
| 116 | if (!required_output_columns.contains(node->result_name) && node->result_name != join_dummy_result_name) |
| 117 | continue; |
| 118 | |
| 119 | String original_name = node->result_name; |
| 120 | |
| 121 | /// The `changed_types` map is used to handle type changes occurred in `USING` clause |
| 122 | if (auto it = changed_types.find(node->result_name); it != changed_types.end()) |
| 123 | { |
| 124 | node = it->second; |
| 125 | } |
| 126 | |
| 127 | JoinActionRef input_action(node, expression_actions); |
| 128 | bool convert_to_nullable = (to_null_left && input_action.fromLeft()) || (to_null_right && input_action.fromRight()); |
| 129 | if (convert_to_nullable && removeLowCardinality(node->result_type)->canBeInsideNullable()) |
| 130 | { |
| 131 | node = &actions_dag->addFunction(to_nullable, {node}, {}); |
| 132 | } |
| 133 | |
| 134 | if (node->result_name != original_name) |
| 135 | node = &actions_dag->addAlias(*node, std::move(original_name)); |
| 136 | |
| 137 | actions_after_join.push_back(node); |
| 138 | outputs.push_back(node); |
| 139 | } |
| 140 | |
| 141 | if (outputs.empty()) |
| 142 | { |
| 143 | auto column_type = std::make_shared<DataTypeUInt8>(); |
| 144 | auto column = column_type->createColumnConst(0, 0); |
| 145 | const auto * node = &actions_dag->addColumn(std::move(column), column_type, String(join_dummy_result_name)); |
| 146 | actions_after_join.push_back(node); |
| 147 | outputs.push_back(node); |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | JoinStepLogical::JoinStepLogical( |
| 152 | SharedHeader left_header_, |
no test coverage detected