diff --git a/src/query/catalog/src/plan/stream_column.rs b/src/query/catalog/src/plan/stream_column.rs index fd10a1c80bd2..40cdc1d0db72 100644 --- a/src/query/catalog/src/plan/stream_column.rs +++ b/src/query/catalog/src/plan/stream_column.rs @@ -126,10 +126,7 @@ impl StreamColumnMeta { } pub fn build_origin_block_row_num(num_rows: usize) -> BlockEntry { - let mut row_ids = Vec::with_capacity(num_rows); - for i in 0..num_rows { - row_ids.push(i as u64); - } + let row_ids = (0..num_rows as u64).collect(); let column = Value::Column(UInt64Type::from_data(row_ids)); BlockEntry::new( diff --git a/src/query/expression/src/block.rs b/src/query/expression/src/block.rs index 7911dd33d14c..820d5841d4a3 100644 --- a/src/query/expression/src/block.rs +++ b/src/query/expression/src/block.rs @@ -117,7 +117,6 @@ impl DataBlock { num_rows: usize, meta: Option, ) -> Self { - #[cfg(debug_assertions)] Self::check_columns_valid(&columns, num_rows).unwrap(); Self { @@ -130,6 +129,7 @@ impl DataBlock { fn check_columns_valid(columns: &[BlockEntry], num_rows: usize) -> Result<()> { for entry in columns.iter() { if let Value::Column(c) = &entry.value { + #[cfg(debug_assertions)] c.check_valid()?; if c.len() != num_rows { return Err(ErrorCode::Internal(format!( @@ -264,6 +264,12 @@ impl DataBlock { } pub fn slice(&self, range: Range) -> Self { + assert!( + range.end <= self.num_rows(), + "range {:?} out of len {}", + range, + self.num_rows() + ); let columns = self .columns() .iter() @@ -279,7 +285,11 @@ impl DataBlock { .collect(); Self { columns, - num_rows: range.end - range.start, + num_rows: if range.is_empty() { + 0 + } else { + range.end - range.start + }, meta: self.meta.clone(), } } diff --git a/src/query/expression/src/kernels/filter.rs b/src/query/expression/src/kernels/filter.rs index 053d7842b8cf..1b730323a24f 100644 --- a/src/query/expression/src/kernels/filter.rs +++ b/src/query/expression/src/kernels/filter.rs @@ -112,6 +112,7 @@ struct FilterVisitor<'a> { filter: &'a Bitmap, result: Option>, num_rows: usize, + original_rows: usize, } impl<'a> FilterVisitor<'a> { @@ -121,6 +122,7 @@ impl<'a> FilterVisitor<'a> { filter, result: None, num_rows, + original_rows: filter.len(), } } } @@ -130,6 +132,8 @@ impl<'a> ValueVisitor for FilterVisitor<'a> { match value { Value::Scalar(c) => self.visit_scalar(c), Value::Column(c) => { + assert!(c.len() == self.original_rows); + if c.len() == self.num_rows || c.len() == 0 { self.result = Some(Value::Column(c)); } else if self.num_rows == 0 { @@ -255,7 +259,14 @@ impl<'a> ValueVisitor for FilterVisitor<'a> { Ok(()) } - fn visit_boolean(&mut self, bitmap: Bitmap) -> Result<()> { + fn visit_boolean(&mut self, mut bitmap: Bitmap) -> Result<()> { + // faster path for all bits set + if bitmap.unset_bits() == 0 { + bitmap.slice(0, self.num_rows); + self.result = Some(Value::Column(BooleanType::upcast_column(bitmap))); + return Ok(()); + } + let capacity = self.num_rows.saturating_add(7) / 8; let mut builder: Vec = Vec::with_capacity(capacity); let mut builder_ptr = builder.as_mut_ptr(); diff --git a/src/query/expression/src/kernels/sort_compare.rs b/src/query/expression/src/kernels/sort_compare.rs index f492ba7178c9..45d91f0098d0 100644 --- a/src/query/expression/src/kernels/sort_compare.rs +++ b/src/query/expression/src/kernels/sort_compare.rs @@ -263,6 +263,7 @@ impl ValueVisitor for SortCompare { // faster path for numeric fn visit_number(&mut self, column: Buffer) -> Result<()> { let values = column.as_slice(); + assert!(values.len() == self.rows); self.generic_sort(values, |c, idx| c[idx as usize], |a: T, b: T| a.cmp(&b)); Ok(()) } @@ -276,6 +277,7 @@ impl ValueVisitor for SortCompare { } fn visit_typed_column(&mut self, col: T::Column) -> Result<()> { + assert!(T::column_len(&col) == self.rows); self.generic_sort( &col, |c, idx| -> T::ScalarRef<'_> { unsafe { T::index_column_unchecked(c, idx as _) } },