| 53 | } |
| 54 | |
| 55 | void DistinctTransform::transform(Chunk & chunk) |
| 56 | { |
| 57 | auto num_rows = chunk.getNumRows(); |
| 58 | auto columns = chunk.detachColumns(); |
| 59 | |
| 60 | /// Stop reading if we already reach the limit. |
| 61 | if (no_more_rows || (limit_hint && data.getTotalRowCount() >= limit_hint)) |
| 62 | { |
| 63 | stopReading(); |
| 64 | return; |
| 65 | } |
| 66 | |
| 67 | ColumnRawPtrs column_ptrs; |
| 68 | column_ptrs.reserve(key_columns_pos.size()); |
| 69 | for (auto pos : key_columns_pos) |
| 70 | column_ptrs.emplace_back(columns[pos].get()); |
| 71 | |
| 72 | if (column_ptrs.empty()) |
| 73 | { |
| 74 | /// Only constants. We need to return single row. |
| 75 | no_more_rows = true; |
| 76 | for (auto & column : columns) |
| 77 | column = column->cut(0, 1); |
| 78 | |
| 79 | chunk.setColumns(std::move(columns), 1); |
| 80 | return; |
| 81 | } |
| 82 | |
| 83 | if (data.empty()) |
| 84 | data.init(SetVariants::chooseMethod(column_ptrs, key_sizes)); |
| 85 | |
| 86 | const auto old_set_size = data.getTotalRowCount(); |
| 87 | IColumn::Filter filter(num_rows); |
| 88 | |
| 89 | switch (data.type) |
| 90 | { |
| 91 | case SetVariants::Type::EMPTY: |
| 92 | break; |
| 93 | case SetVariants::Type::bitmap64: |
| 94 | break; |
| 95 | #define M(NAME) \ |
| 96 | case SetVariants::Type::NAME: \ |
| 97 | buildFilter(*data.NAME, column_ptrs, filter, num_rows, data); \ |
| 98 | break; |
| 99 | APPLY_FOR_SET_VARIANTS(M) |
| 100 | #undef M |
| 101 | } |
| 102 | |
| 103 | /// Just go to the next chunk if there isn't any new record in the current one. |
| 104 | if (data.getTotalRowCount() == old_set_size) |
| 105 | return; |
| 106 | |
| 107 | if (!set_size_limits.check(data.getTotalRowCount(), data.getTotalByteCount(), "DISTINCT", ErrorCodes::SET_SIZE_LIMIT_EXCEEDED)) |
| 108 | return; |
| 109 | |
| 110 | for (auto & column : columns) |
| 111 | column = column->filter(filter, -1); |
| 112 |
nothing calls this directly
no test coverage detected