Shared implementation for column reading with predicate pushdown and optional delete bitmap masking.
(
&self,
col_idx: usize,
predicates: &[ScanPredicate],
deletes: &DeleteBitmap,
)
| 190 | /// Shared implementation for column reading with predicate pushdown and |
| 191 | /// optional delete bitmap masking. |
| 192 | fn read_column_impl( |
| 193 | &self, |
| 194 | col_idx: usize, |
| 195 | predicates: &[ScanPredicate], |
| 196 | deletes: &DeleteBitmap, |
| 197 | ) -> Result<DecodedColumn, ColumnarError> { |
| 198 | if col_idx >= self.footer.columns.len() { |
| 199 | return Err(ColumnarError::ColumnOutOfRange { |
| 200 | index: col_idx, |
| 201 | count: self.footer.columns.len(), |
| 202 | }); |
| 203 | } |
| 204 | |
| 205 | let col_meta = &self.footer.columns[col_idx]; |
| 206 | let my_preds: Vec<&ScanPredicate> = |
| 207 | predicates.iter().filter(|p| p.col_idx == col_idx).collect(); |
| 208 | |
| 209 | let col_start = HEADER_SIZE + col_meta.offset as usize; |
| 210 | let mut cursor = col_start; |
| 211 | let col_type = infer_column_type(col_meta); |
| 212 | let mut result = empty_decoded(&col_type); |
| 213 | let mut global_row: u32 = 0; |
| 214 | |
| 215 | for block_stat in &col_meta.block_stats { |
| 216 | let block_row_count = block_stat.row_count; |
| 217 | |
| 218 | if cursor + 4 > self.data.len() { |
| 219 | return Err(ColumnarError::TruncatedSegment { |
| 220 | expected: cursor + 4, |
| 221 | got: self.data.len(), |
| 222 | }); |
| 223 | } |
| 224 | let block_len = u32::from_le_bytes([ |
| 225 | self.data[cursor], |
| 226 | self.data[cursor + 1], |
| 227 | self.data[cursor + 2], |
| 228 | self.data[cursor + 3], |
| 229 | ]) as usize; |
| 230 | cursor += 4; |
| 231 | let block_data = &self.data[cursor..cursor + block_len]; |
| 232 | cursor += block_len; |
| 233 | |
| 234 | // Skip via predicate pushdown. |
| 235 | let pred_skip = my_preds.iter().any(|p| p.can_skip_block(block_stat)); |
| 236 | |
| 237 | // Skip if entire block is deleted. |
| 238 | let delete_skip = |
| 239 | !deletes.is_empty() && deletes.is_block_fully_deleted(global_row, block_row_count); |
| 240 | |
| 241 | if pred_skip || delete_skip { |
| 242 | append_null_fill(&mut result, block_row_count as usize); |
| 243 | global_row += block_row_count; |
| 244 | continue; |
| 245 | } |
| 246 | |
| 247 | // Decode the block. |
| 248 | let pre_len = result_valid_len(&result); |
| 249 | decode_block( |
no test coverage detected