| 161 | |
| 162 | |
| 163 | void AddingDefaultsTransform::transform(Chunk & chunk) |
| 164 | { |
| 165 | if (column_defaults.empty()) |
| 166 | return; |
| 167 | |
| 168 | const BlockMissingValues & block_missing_values = input_format.getMissingValues(); |
| 169 | if (block_missing_values.empty()) |
| 170 | return; |
| 171 | |
| 172 | const auto & header = getOutputPort().getHeader(); |
| 173 | size_t num_rows = chunk.getNumRows(); |
| 174 | auto res = header.cloneWithColumns(chunk.detachColumns()); |
| 175 | |
| 176 | /// res block already has all columns values, with default value for type |
| 177 | /// (not value specified in table). We identify which columns we need to |
| 178 | /// recalculate with help of block_missing_values. |
| 179 | Block evaluate_block{res}; |
| 180 | /// remove columns for recalculation |
| 181 | for (const auto & column : column_defaults) |
| 182 | { |
| 183 | if (evaluate_block.has(column.first)) |
| 184 | { |
| 185 | size_t column_idx = res.getPositionByName(column.first); |
| 186 | if (block_missing_values.hasDefaultBits(column_idx)) |
| 187 | evaluate_block.erase(column.first); |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | if (!evaluate_block.columns()) |
| 192 | evaluate_block.insert({ColumnConst::create(ColumnUInt8::create(1, 0), num_rows), std::make_shared<DataTypeUInt8>(), "_dummy"}); |
| 193 | |
| 194 | auto dag = evaluateMissingDefaults(evaluate_block, header.getNamesAndTypesList(), columns, context, false); |
| 195 | if (dag) |
| 196 | { |
| 197 | auto actions = std::make_shared<ExpressionActions>(std::move(dag), ExpressionActionsSettings::fromContext(context, CompileExpressions::yes)); |
| 198 | actions->execute(evaluate_block); |
| 199 | } |
| 200 | |
| 201 | std::unordered_map<size_t, MutableColumnPtr> mixed_columns; |
| 202 | |
| 203 | for (const ColumnWithTypeAndName & column_def : evaluate_block) |
| 204 | { |
| 205 | const String & column_name = column_def.name; |
| 206 | |
| 207 | if (column_defaults.count(column_name) == 0) |
| 208 | continue; |
| 209 | |
| 210 | size_t block_column_position = res.getPositionByName(column_name); |
| 211 | ColumnWithTypeAndName & column_read = res.getByPosition(block_column_position); |
| 212 | const auto & defaults_mask = block_missing_values.getDefaultsBitmask(block_column_position); |
| 213 | |
| 214 | checkCalculated(column_read, column_def, defaults_mask.size()); |
| 215 | |
| 216 | if (!defaults_mask.empty()) |
| 217 | { |
| 218 | /// TODO: FixedString |
| 219 | if (isColumnedAsNumber(column_read.type) || isDecimal(column_read.type)) |
| 220 | { |
nothing calls this directly
no test coverage detected