| 102 | } |
| 103 | |
| 104 | void PartialSortingTransform::transform(Chunk & chunk) |
| 105 | { |
| 106 | if (chunk.getNumRows()) |
| 107 | { |
| 108 | // The following code works with Blocks and will lose the number of |
| 109 | // rows when there are no columns. We shouldn't get such block, because |
| 110 | // we have to sort by at least one column. |
| 111 | chassert(chunk.getNumColumns()); |
| 112 | } |
| 113 | |
| 114 | if (read_rows) |
| 115 | read_rows->add(chunk.getNumRows()); |
| 116 | |
| 117 | auto block = getInputPort().getHeader().cloneWithColumns(chunk.detachColumns()); |
| 118 | |
| 119 | /// Materialize sort key columns that are ColumnReplicated to avoid index indirection during comparison and sorting. |
| 120 | for (const auto & col_desc : description) |
| 121 | { |
| 122 | auto & column_entry = block.getByName(col_desc.column_name); |
| 123 | column_entry.column = convertToFullColumnIfReplicationNotUseful(column_entry.column); |
| 124 | } |
| 125 | |
| 126 | /** If we've saved columns from previously blocks we could filter all rows from current block |
| 127 | * which are unnecessary for sortBlock(...) because they obviously won't be in the top LIMIT rows. |
| 128 | */ |
| 129 | if (!sort_description_threshold_columns.empty() && !threshold_tracker) |
| 130 | { |
| 131 | UInt64 rows_num = block.rows(); |
| 132 | auto block_columns = extractRawColumns(block, description_with_positions); |
| 133 | |
| 134 | size_t result_size_hint = getFilterMask( |
| 135 | block_columns, sort_description_threshold_columns, |
| 136 | description, rows_num, filter, rows_to_compare, compare_results); |
| 137 | |
| 138 | /// Everything was filtered. Skip whole chunk. |
| 139 | if (result_size_hint == 0) |
| 140 | return; |
| 141 | |
| 142 | if (result_size_hint < rows_num) |
| 143 | { |
| 144 | for (auto & column : block) |
| 145 | column.column = column.column->filter(filter, result_size_hint); |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | sortBlock(block, description, limit); |
| 150 | |
| 151 | /// Check if we can use this block for optimization. |
| 152 | if ((min_limit_for_partial_sort_optimization <= limit || threshold_tracker) && limit <= block.rows()) |
| 153 | { |
| 154 | /** If we filtered more than limit rows from block take block last row. |
| 155 | * Otherwise take last limit row. |
| 156 | * |
| 157 | * If current threshold value is empty, update current threshold value. |
| 158 | * If min block value is less than current threshold value, update current threshold value. |
| 159 | */ |
| 160 | size_t min_row_to_compare = limit - 1; |
| 161 | auto raw_block_columns = extractRawColumns(block, description_with_positions); |
nothing calls this directly
no test coverage detected