diff --git a/Cargo.lock b/Cargo.lock index 4bfbb7ff4743..b7b8361abbd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2301,6 +2301,7 @@ dependencies = [ "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "chrono-tz 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "codec 0.0.1", "cop_codegen 0.0.1", "cop_datatype 0.0.1", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index b3da276131d7..0e063d7d48bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -126,6 +126,7 @@ profiler = { path = "components/profiler" } match_template = { path = "components/match_template" } cop_datatype = { path = "components/cop_datatype" } cop_codegen = { path = "components/cop_codegen" } +codec = { path = "components/codec" } tipb_helper = { path = "components/tipb_helper" } tipb = { git = "https://github.com/pingcap/tipb.git" } # TODO: use master branch after the next version is released. diff --git a/src/coprocessor/codec/batch/buffer_vec.rs b/src/coprocessor/codec/batch/buffer_vec.rs index f15525485d94..75996f61ea02 100644 --- a/src/coprocessor/codec/batch/buffer_vec.rs +++ b/src/coprocessor/codec/batch/buffer_vec.rs @@ -1,7 +1,5 @@ // Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0. -#![allow(dead_code)] - use std::iter::*; /// A vector like container storing multiple buffers. Each buffer is a `[u8]` slice in @@ -189,7 +187,7 @@ impl BufferVec { } } - /// Retain the elements according to a boolean array. + /// Retains the elements according to a boolean array. /// /// # Panics /// diff --git a/src/coprocessor/codec/batch/lazy_column.rs b/src/coprocessor/codec/batch/lazy_column.rs index 130b3c513ece..8dba4259bb16 100644 --- a/src/coprocessor/codec/batch/lazy_column.rs +++ b/src/coprocessor/codec/batch/lazy_column.rs @@ -2,11 +2,10 @@ use std::convert::TryFrom; -use smallvec::SmallVec; - use cop_datatype::{EvalType, FieldTypeAccessor}; use tipb::expression::FieldType; +use super::BufferVec; use crate::coprocessor::codec::data_type::VectorValue; use crate::coprocessor::codec::mysql::Tz; use crate::coprocessor::codec::Result; @@ -19,29 +18,12 @@ use crate::coprocessor::codec::Result; /// to avoid unnecessary repeated serialization / deserialization. In future, Coprocessor will /// respond all data in Arrow format which is different to the format in storage. At that time, /// this structure is no longer useful and should be removed. +#[derive(Clone, Debug)] pub enum LazyBatchColumn { - /// Ensure that small datum values (i.e. Int, Real, Time) are stored compactly. - /// When using VarInt encoding there are 9 bytes. Plus 1 extra byte to store the datum flag. - /// Thus totally there are 10 bytes. - Raw(Vec>), + Raw(BufferVec), Decoded(VectorValue), } -impl std::fmt::Debug for LazyBatchColumn { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - LazyBatchColumn::Raw(ref v) => { - let vec_display: Vec<_> = v - .iter() - .map(|item| tikv_util::escape(item.as_slice())) - .collect(); - f.debug_tuple("Raw").field(&vec_display).finish() - } - LazyBatchColumn::Decoded(ref v) => f.debug_tuple("Decoded").field(v).finish(), - } - } -} - impl From for LazyBatchColumn { #[inline] fn from(vec: VectorValue) -> Self { @@ -49,28 +31,16 @@ impl From for LazyBatchColumn { } } -impl Clone for LazyBatchColumn { - #[inline] - fn clone(&self) -> Self { - match self { - LazyBatchColumn::Raw(v) => { - // This is much more efficient than `SmallVec::clone`. - let mut raw_vec = Vec::with_capacity(v.capacity()); - for d in v { - raw_vec.push(SmallVec::from_slice(d.as_slice())); - } - LazyBatchColumn::Raw(raw_vec) - } - LazyBatchColumn::Decoded(v) => LazyBatchColumn::Decoded(v.clone()), - } - } -} - impl LazyBatchColumn { /// Creates a new `LazyBatchColumn::Raw` with specified capacity. #[inline] pub fn raw_with_capacity(capacity: usize) -> Self { - LazyBatchColumn::Raw(Vec::with_capacity(capacity)) + use codec::number::MAX_VARINT64_LENGTH; + // We assume that each element *may* has a size of MAX_VAR_INT_LEN + Datum Flag (1 byte). + LazyBatchColumn::Raw(BufferVec::with_capacity( + capacity, + capacity * (MAX_VARINT64_LENGTH + 1), + )) } /// Creates a new `LazyBatchColumn::Decoded` with specified capacity and eval type. @@ -99,7 +69,7 @@ impl LazyBatchColumn { pub fn decoded(&self) -> &VectorValue { match self { LazyBatchColumn::Raw(_) => panic!("LazyBatchColumn is not decoded"), - LazyBatchColumn::Decoded(ref v) => v, + LazyBatchColumn::Decoded(v) => v, } } @@ -107,22 +77,22 @@ impl LazyBatchColumn { pub fn mut_decoded(&mut self) -> &mut VectorValue { match self { LazyBatchColumn::Raw(_) => panic!("LazyBatchColumn is not decoded"), - LazyBatchColumn::Decoded(ref mut v) => v, + LazyBatchColumn::Decoded(v) => v, } } #[inline] - pub fn raw(&self) -> &Vec> { + pub fn raw(&self) -> &BufferVec { match self { - LazyBatchColumn::Raw(ref v) => v, + LazyBatchColumn::Raw(v) => v, LazyBatchColumn::Decoded(_) => panic!("LazyBatchColumn is already decoded"), } } #[inline] - pub fn mut_raw(&mut self) -> &mut Vec> { + pub fn mut_raw(&mut self) -> &mut BufferVec { match self { - LazyBatchColumn::Raw(ref mut v) => v, + LazyBatchColumn::Raw(v) => v, LazyBatchColumn::Decoded(_) => panic!("LazyBatchColumn is already decoded"), } } @@ -130,22 +100,25 @@ impl LazyBatchColumn { #[inline] pub fn len(&self) -> usize { match self { - LazyBatchColumn::Raw(ref v) => v.len(), - LazyBatchColumn::Decoded(ref v) => v.len(), + LazyBatchColumn::Raw(v) => v.len(), + LazyBatchColumn::Decoded(v) => v.len(), } } #[inline] pub fn truncate(&mut self, len: usize) { match self { - LazyBatchColumn::Raw(ref mut v) => v.truncate(len), - LazyBatchColumn::Decoded(ref mut v) => v.truncate(len), + LazyBatchColumn::Raw(v) => v.truncate(len), + LazyBatchColumn::Decoded(v) => v.truncate(len), }; } #[inline] pub fn clear(&mut self) { - self.truncate(0) + match self { + LazyBatchColumn::Raw(v) => v.clear(), + LazyBatchColumn::Decoded(v) => v.clear(), + }; } #[inline] @@ -156,28 +129,21 @@ impl LazyBatchColumn { #[inline] pub fn capacity(&self) -> usize { match self { - LazyBatchColumn::Raw(ref v) => v.capacity(), - LazyBatchColumn::Decoded(ref v) => v.capacity(), + LazyBatchColumn::Raw(v) => v.capacity(), + LazyBatchColumn::Decoded(v) => v.capacity(), } } + /// Retains the elements according to a boolean array. + /// + /// # Panics + /// + /// Panics if `retain_arr` is not long enough. #[inline] - pub fn retain_by_index(&mut self, mut f: F) - where - F: FnMut(usize) -> bool, - { + pub fn retain_by_array(&mut self, retain_arr: &[bool]) { match self { - LazyBatchColumn::Raw(ref mut v) => { - let mut idx = 0; - v.retain(|_| { - let r = f(idx); - idx += 1; - r - }); - } - LazyBatchColumn::Decoded(ref mut v) => { - v.retain_by_index(f); - } + LazyBatchColumn::Raw(v) => v.retain_by_array(retain_arr), + LazyBatchColumn::Decoded(v) => v.retain_by_array(retain_arr), } } @@ -186,7 +152,7 @@ impl LazyBatchColumn { /// The field type is needed because we use the same `DateTime` structure when handling /// Date, Time or Timestamp. // TODO: Maybe it's a better idea to assign different eval types for different date types. - pub fn decode(&mut self, time_zone: &Tz, field_type: &FieldType) -> Result<()> { + pub fn ensure_decoded(&mut self, time_zone: &Tz, field_type: &FieldType) -> Result<()> { if self.is_decoded() { return Ok(()); } @@ -195,10 +161,8 @@ impl LazyBatchColumn { let mut decoded_column = VectorValue::with_capacity(self.capacity(), eval_type); { - let raw_values = self.raw(); - for raw_value in raw_values { - let raw_datum = raw_value.as_slice(); - decoded_column.push_datum(raw_datum, time_zone, field_type)?; + for value in self.raw().iter() { + decoded_column.push_datum(value, time_zone, field_type)?; } } *self = LazyBatchColumn::Decoded(decoded_column); @@ -206,56 +170,11 @@ impl LazyBatchColumn { Ok(()) } - /// Push a raw datum which is not yet decoded. - /// - /// `raw_datum.len()` can be 0, indicating a missing value for corresponding cell. - /// - /// # Panics - /// - /// Panics when current column is already decoded. - // TODO: Deprecate this function. mut_raw should be preferred so that there won't be repeated - // match for each iteration. - #[inline] - pub fn push_raw(&mut self, raw_datum: impl AsRef<[u8]>) { - match self { - LazyBatchColumn::Raw(ref mut v) => { - v.push(SmallVec::from_slice(raw_datum.as_ref())); - } - LazyBatchColumn::Decoded(_) => panic!("LazyBatchColumn is already decoded"), - } - } - - /// Moves all elements of `other` into `Self`, leaving `other` empty. - /// - /// # Panics - /// - /// Panics when `other` and `Self` does not have identical decoded status or identical - /// `EvalType`, i.e. one is `decoded` but another is `raw`, or one is `decoded(Int)` but - /// another is `decoded(Real)`. - pub fn append(&mut self, other: &mut Self) { - match self { - LazyBatchColumn::Raw(ref mut dest) => match other { - LazyBatchColumn::Raw(ref mut src) => dest.append(src), - _ => panic!("Cannot append decoded LazyBatchColumn into raw LazyBatchColumn"), - }, - LazyBatchColumn::Decoded(ref mut dest) => match other { - LazyBatchColumn::Decoded(ref mut src) => dest.append(src), - _ => panic!("Cannot append raw LazyBatchColumn into decoded LazyBatchColumn"), - }, - } - } - /// Returns maximum encoded size. pub fn maximum_encoded_size(&self) -> Result { match self { - LazyBatchColumn::Raw(ref v) => { - let mut size = 0; - for s in v { - size += s.len(); - } - Ok(size) - } - LazyBatchColumn::Decoded(ref v) => v.maximum_encoded_size(), + LazyBatchColumn::Raw(v) => Ok(v.total_len()), + LazyBatchColumn::Decoded(v) => v.maximum_encoded_size(), } } @@ -268,8 +187,8 @@ impl LazyBatchColumn { output: &mut Vec, ) -> Result<()> { match self { - LazyBatchColumn::Raw(ref v) => { - output.extend_from_slice(v[row_index].as_slice()); + LazyBatchColumn::Raw(v) => { + output.extend_from_slice(&v[row_index]); Ok(()) } LazyBatchColumn::Decoded(ref v) => v.encode(row_index, field_type, output), @@ -303,7 +222,8 @@ mod tests { { // Empty raw to empty decoded. let mut col = col.clone(); - col.decode(&Tz::utc(), &FieldTypeTp::Long.into()).unwrap(); + col.ensure_decoded(&Tz::utc(), &FieldTypeTp::Long.into()) + .unwrap(); assert!(col.is_decoded()); assert_eq!(col.len(), 0); assert_eq!(col.capacity(), 5); @@ -320,18 +240,18 @@ mod tests { let mut datum_raw_1 = Vec::new(); DatumEncoder::encode(&mut datum_raw_1, &[Datum::U64(32)], false).unwrap(); - col.push_raw(&datum_raw_1); + col.mut_raw().push(&datum_raw_1); let mut datum_raw_2 = Vec::new(); DatumEncoder::encode(&mut datum_raw_2, &[Datum::U64(7)], true).unwrap(); - col.push_raw(&datum_raw_2); + col.mut_raw().push(&datum_raw_2); assert!(col.is_raw()); assert_eq!(col.len(), 2); assert_eq!(col.capacity(), 5); assert_eq!(col.raw().len(), 2); - assert_eq!(col.raw()[0].as_slice(), datum_raw_1.as_slice()); - assert_eq!(col.raw()[1].as_slice(), datum_raw_2.as_slice()); + assert_eq!(&col.raw()[0], datum_raw_1.as_slice()); + assert_eq!(&col.raw()[1], datum_raw_2.as_slice()); { // Clone non-empty raw LazyBatchColumn. let col = col.clone(); @@ -339,11 +259,12 @@ mod tests { assert_eq!(col.len(), 2); assert_eq!(col.capacity(), 5); assert_eq!(col.raw().len(), 2); - assert_eq!(col.raw()[0].as_slice(), datum_raw_1.as_slice()); - assert_eq!(col.raw()[1].as_slice(), datum_raw_2.as_slice()); + assert_eq!(&col.raw()[0], datum_raw_1.as_slice()); + assert_eq!(&col.raw()[1], datum_raw_2.as_slice()); } // Non-empty raw to non-empty decoded. - col.decode(&Tz::utc(), &FieldTypeTp::Long.into()).unwrap(); + col.ensure_decoded(&Tz::utc(), &FieldTypeTp::Long.into()) + .unwrap(); assert!(col.is_decoded()); assert_eq!(col.len(), 2); assert_eq!(col.capacity(), 5); @@ -370,39 +291,7 @@ mod benches { b.iter(|| { let column = test::black_box(&mut column); for _ in 0..1000 { - column.push_raw(test::black_box(&val)) - } - test::black_box(&column); - column.clear(); - test::black_box(&column); - }); - } - - #[bench] - fn bench_lazy_batch_column_push_raw_9bytes(b: &mut test::Bencher) { - let mut column = LazyBatchColumn::raw_with_capacity(1000); - let val = vec![0; 9]; - b.iter(|| { - let column = test::black_box(&mut column); - for _ in 0..1000 { - column.push_raw(test::black_box(&val)) - } - test::black_box(&column); - column.clear(); - test::black_box(&column); - }); - } - - /// 10 bytes > inline size for LazyBatchColumn, which will be slower. - /// This benchmark shows how slow it will be. - #[bench] - fn bench_lazy_batch_column_push_raw_10bytes(b: &mut test::Bencher) { - let mut column = LazyBatchColumn::raw_with_capacity(1000); - let val = vec![0; 10]; - b.iter(|| { - let column = test::black_box(&mut column); - for _ in 0..1000 { - column.push_raw(test::black_box(&val)) + column.mut_raw().push(test::black_box(&val)) } test::black_box(&column); column.clear(); @@ -410,49 +299,6 @@ mod benches { }); } - /// Bench performance of cloning a raw column which size <= inline size. - #[bench] - fn bench_lazy_batch_column_clone(b: &mut test::Bencher) { - let mut column = LazyBatchColumn::raw_with_capacity(1000); - let val = vec![0; 9]; - for _ in 0..1000 { - column.push_raw(&val); - } - b.iter(|| { - test::black_box(test::black_box(&column).clone()); - }); - } - - /// Bench performance of cloning a raw column which size > inline size. - #[bench] - fn bench_lazy_batch_column_clone_10bytes(b: &mut test::Bencher) { - let mut column = LazyBatchColumn::raw_with_capacity(1000); - let val = vec![0; 10]; - for _ in 0..1000 { - column.push_raw(&val); - } - b.iter(|| { - test::black_box(test::black_box(&column).clone()); - }); - } - - /// Bench performance of naively cloning a raw column - /// (which uses `SmallVec::clone()` instead of our own) - #[bench] - fn bench_lazy_batch_column_clone_naive(b: &mut test::Bencher) { - let mut column = LazyBatchColumn::raw_with_capacity(1000); - let val = vec![0; 10]; - for _ in 0..1000 { - column.push_raw(&val); - } - b.iter(|| match test::black_box(&column) { - LazyBatchColumn::Raw(raw_vec) => { - test::black_box(raw_vec.clone()); - } - _ => panic!(), - }) - } - /// Bench performance of cloning a decoded column. #[bench] fn bench_lazy_batch_column_clone_decoded(b: &mut test::Bencher) { @@ -465,11 +311,11 @@ mod benches { DatumEncoder::encode(&mut datum_raw, &[Datum::U64(0xDEADBEEF)], true).unwrap(); for _ in 0..1000 { - column.push_raw(datum_raw.as_slice()); + column.mut_raw().push(datum_raw.as_slice()); } column - .decode(&Tz::utc(), &FieldTypeTp::LongLong.into()) + .ensure_decoded(&Tz::utc(), &FieldTypeTp::LongLong.into()) .unwrap(); b.iter(|| { @@ -491,7 +337,7 @@ mod benches { DatumEncoder::encode(&mut datum_raw, &[Datum::U64(0xDEADBEEF)], true).unwrap(); for _ in 0..1000 { - column.push_raw(datum_raw.as_slice()); + column.mut_raw().push(datum_raw.as_slice()); } let ft = FieldTypeTp::LongLong.into(); @@ -499,7 +345,7 @@ mod benches { b.iter(|| { let mut col = test::black_box(&column).clone(); - col.decode(test::black_box(&tz), test::black_box(&ft)) + col.ensure_decoded(test::black_box(&tz), test::black_box(&ft)) .unwrap(); test::black_box(&col); }); @@ -519,17 +365,17 @@ mod benches { DatumEncoder::encode(&mut datum_raw, &[Datum::U64(0xDEADBEEF)], true).unwrap(); for _ in 0..1000 { - column.push_raw(datum_raw.as_slice()); + column.mut_raw().push(datum_raw.as_slice()); } let ft = FieldTypeTp::LongLong.into(); let tz = Tz::utc(); - column.decode(&tz, &ft).unwrap(); + column.ensure_decoded(&tz, &ft).unwrap(); b.iter(|| { let mut col = test::black_box(&column).clone(); - col.decode(test::black_box(&tz), test::black_box(&ft)) + col.ensure_decoded(test::black_box(&tz), test::black_box(&ft)) .unwrap(); test::black_box(&col); }); diff --git a/src/coprocessor/codec/batch/lazy_column_vec.rs b/src/coprocessor/codec/batch/lazy_column_vec.rs index 96eefecf2844..298819f9c0f1 100644 --- a/src/coprocessor/codec/batch/lazy_column_vec.rs +++ b/src/coprocessor/codec/batch/lazy_column_vec.rs @@ -4,7 +4,6 @@ use tipb::expression::FieldType; use super::LazyBatchColumn; use crate::coprocessor::codec::data_type::VectorValue; -use crate::coprocessor::codec::mysql::Tz; use crate::coprocessor::codec::Result; /// Stores multiple `LazyBatchColumn`s. Each column has an equal length. @@ -48,7 +47,6 @@ impl LazyBatchColumnVec { } /// Creates a new `LazyBatchColumnVec`, which contains `columns_count` number of raw columns. - #[inline] #[cfg(test)] pub fn with_raw_columns(columns_count: usize) -> Self { let mut columns = Vec::with_capacity(columns_count); @@ -59,46 +57,6 @@ impl LazyBatchColumnVec { Self { columns } } - /// Moves all elements of `other` into `Self`, leaving `other` empty. - /// - /// # Panics - /// - /// Panics when `other` and `Self` does not have same column schemas. - #[inline] - pub fn append(&mut self, other: &mut Self) { - let len = self.columns_len(); - assert_eq!(len, other.columns_len()); - for i in 0..len { - self.columns[i].append(&mut other[i]); - } - - self.assert_columns_equal_length(); - } - - /// Ensures that a column at specified `column_index` is decoded and returns a reference - /// to the decoded column. - /// - /// If the column is already decoded, this function does nothing. - #[inline] - pub fn ensure_column_decoded( - &mut self, - column_index: usize, - time_zone: &Tz, - field_type: &FieldType, - ) -> Result<&VectorValue> { - let number_of_rows = self.rows_len(); - let col = &mut self.columns[column_index]; - assert_eq!(col.len(), number_of_rows); - col.decode(time_zone, field_type)?; - Ok(col.decoded()) - } - - /// Returns whether column at specified `column_index` is decoded. - #[inline] - pub fn is_column_decoded(&self, column_index: usize) -> bool { - self.columns[column_index].is_decoded() - } - /// Returns the number of columns. /// /// It might be possible that there is no row but multiple columns. @@ -125,14 +83,12 @@ impl LazyBatchColumnVec { } } - /// Retains only the rows specified by the predicate, which accepts index only. + /// Retains the elements according to a boolean array. /// - /// In other words, remove all rows such that `f(row_index)` returns `false`. - #[inline] - pub fn retain_rows_by_index(&mut self, mut f: F) - where - F: FnMut(usize) -> bool, - { + /// # Panics + /// + /// Panics if `retain_arr` is not long enough. + pub fn retain_rows_by_array(&mut self, retain_arr: &[bool]) { if self.rows_len() == 0 { return; } @@ -142,7 +98,7 @@ impl LazyBatchColumnVec { // We retain column by column to be efficient. for col in &mut self.columns { assert_eq!(col.len(), current_rows_len); - col.retain_by_index(&mut f); + col.retain_by_array(retain_arr); } self.assert_columns_equal_length(); @@ -219,6 +175,7 @@ mod tests { use crate::coprocessor::codec::data_type::Real; use crate::coprocessor::codec::datum::{Datum, DatumEncoder}; + use crate::coprocessor::codec::mysql::Tz; /// Pushes a raw row. There must be no empty datum. /// @@ -239,7 +196,7 @@ mod tests { for (col_index, raw_datum) in raw_row_slice.iter().enumerate() { let lazy_col = &mut columns.columns[col_index]; assert!(lazy_col.is_raw()); - lazy_col.push_raw(raw_datum); + lazy_col.mut_raw().push(raw_datum); } columns.assert_columns_equal_length(); @@ -289,65 +246,64 @@ mod tests { assert_eq!(columns.rows_len(), values.len()); // Decode Column Index 2 - assert!(!columns.is_column_decoded(2)); + assert!(!columns[2].is_decoded()); { - let col = columns - .ensure_column_decoded(2, &Tz::utc(), &schema[2]) - .unwrap(); + columns[2].ensure_decoded(&Tz::utc(), &schema[2]).unwrap(); + let col = columns[2].decoded(); assert_eq!(col.len(), 2); assert_eq!(col.eval_type(), EvalType::Bytes); assert_eq!(col.as_bytes_slice(), &[None, Some(vec![0u8, 2u8])]); } // Decode a decoded column - assert!(columns.is_column_decoded(2)); + assert!(columns[2].is_decoded()); { - let col = columns - .ensure_column_decoded(2, &Tz::utc(), &schema[2]) - .unwrap(); + columns[2].ensure_decoded(&Tz::utc(), &schema[2]).unwrap(); + let col = columns[2].decoded(); assert_eq!(col.len(), 2); assert_eq!(col.eval_type(), EvalType::Bytes); assert_eq!(col.as_bytes_slice(), &[None, Some(vec![0u8, 2u8])]); } - assert!(columns.is_column_decoded(2)); + assert!(columns[2].is_decoded()); // Decode Column Index 0 - assert!(!columns.is_column_decoded(0)); + assert!(!columns[0].is_decoded()); { - let col = columns - .ensure_column_decoded(0, &Tz::utc(), &schema[0]) - .unwrap(); + columns[0].ensure_decoded(&Tz::utc(), &schema[0]).unwrap(); + let col = columns[0].decoded(); assert_eq!(col.len(), 2); assert_eq!(col.eval_type(), EvalType::Int); assert_eq!(col.as_int_slice(), &[Some(1), None]); } - assert!(columns.is_column_decoded(0)); + assert!(columns[0].is_decoded()); // Decode Column Index 1 - assert!(!columns.is_column_decoded(1)); + assert!(!columns[1].is_decoded()); { - let col = columns - .ensure_column_decoded(1, &Tz::utc(), &schema[1]) - .unwrap(); + columns[1].ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); + let col = columns[1].decoded(); assert_eq!(col.len(), 2); assert_eq!(col.eval_type(), EvalType::Real); assert_eq!(col.as_real_slice(), &[Real::new(1.0).ok(), None]); } - assert!(columns.is_column_decoded(1)); + assert!(columns[1].is_decoded()); } } #[test] - fn test_retain_rows_by_index() { + fn test_retain_rows_by_array() { use cop_datatype::FieldTypeTp; let schema = [FieldTypeTp::Long.into(), FieldTypeTp::Double.into()]; let mut columns = LazyBatchColumnVec::with_raw_columns(2); assert_eq!(columns.rows_len(), 0); assert_eq!(columns.columns_len(), 2); - columns.retain_rows_by_index(|_| true); + columns.retain_rows_by_array(&[]); + assert_eq!(columns.rows_len(), 0); + assert_eq!(columns.columns_len(), 2); + columns.retain_rows_by_array(&[true]); assert_eq!(columns.rows_len(), 0); assert_eq!(columns.columns_len(), 2); - columns.retain_rows_by_index(|_| false); + columns.retain_rows_by_array(&[false]); assert_eq!(columns.rows_len(), 0); assert_eq!(columns.columns_len(), 2); @@ -358,15 +314,14 @@ mod tests { push_raw_row_from_datums(&mut columns, &[Datum::U64(11), Datum::F64(7.5)], true); push_raw_row_from_datums(&mut columns, &[Datum::Null, Datum::F64(13.1)], true); - let retain_map = &[true, true, false, false, true, false]; - columns.retain_rows_by_index(|idx| retain_map[idx]); + columns.retain_rows_by_array(&[true, true, false, false, true, false]); assert_eq!(columns.rows_len(), 3); assert_eq!(columns.columns_len(), 2); { let mut column0 = columns[0].clone(); assert!(column0.is_raw()); - column0.decode(&Tz::utc(), &schema[0]).unwrap(); + column0.ensure_decoded(&Tz::utc(), &schema[0]).unwrap(); assert_eq!(column0.decoded().len(), 3); assert_eq!(column0.decoded().eval_type(), EvalType::Int); assert_eq!(column0.decoded().as_int_slice(), &[None, None, Some(11)]); @@ -374,7 +329,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 3); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!( @@ -393,7 +348,7 @@ mod tests { { let mut column0 = columns[0].clone(); assert!(column0.is_raw()); - column0.decode(&Tz::utc(), &schema[0]).unwrap(); + column0.ensure_decoded(&Tz::utc(), &schema[0]).unwrap(); assert_eq!(column0.decoded().len(), 7); assert_eq!(column0.decoded().eval_type(), EvalType::Int); assert_eq!( @@ -404,7 +359,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 7); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!( @@ -421,15 +376,14 @@ mod tests { ); } - let retain_map = &[true, false, true, false, false, true, true]; - columns.retain_rows_by_index(|idx| retain_map[idx]); + columns.retain_rows_by_array(&[true, false, true, false, false, true, true]); assert_eq!(columns.rows_len(), 4); assert_eq!(columns.columns_len(), 2); { let mut column0 = columns[0].clone(); assert!(column0.is_raw()); - column0.decode(&Tz::utc(), &schema[0]).unwrap(); + column0.ensure_decoded(&Tz::utc(), &schema[0]).unwrap(); assert_eq!(column0.decoded().len(), 4); assert_eq!(column0.decoded().eval_type(), EvalType::Int); assert_eq!( @@ -440,7 +394,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 4); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!( @@ -454,14 +408,14 @@ mod tests { ); } - columns.retain_rows_by_index(|_| true); + columns.retain_rows_by_array(&[true, true, true, true]); assert_eq!(columns.rows_len(), 4); assert_eq!(columns.columns_len(), 2); { let mut column0 = columns[0].clone(); assert!(column0.is_raw()); - column0.decode(&Tz::utc(), &schema[0]).unwrap(); + column0.ensure_decoded(&Tz::utc(), &schema[0]).unwrap(); assert_eq!(column0.decoded().len(), 4); assert_eq!(column0.decoded().eval_type(), EvalType::Int); assert_eq!( @@ -472,7 +426,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 4); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!( @@ -486,14 +440,14 @@ mod tests { ); } - columns.retain_rows_by_index(|_| false); + columns.retain_rows_by_array(&[false, false, false, false]); assert_eq!(columns.rows_len(), 0); assert_eq!(columns.columns_len(), 2); { let mut column0 = columns[0].clone(); assert!(column0.is_raw()); - column0.decode(&Tz::utc(), &schema[0]).unwrap(); + column0.ensure_decoded(&Tz::utc(), &schema[0]).unwrap(); assert_eq!(column0.decoded().len(), 0); assert_eq!(column0.decoded().eval_type(), EvalType::Int); assert_eq!(column0.decoded().as_int_slice(), &[]); @@ -501,7 +455,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 0); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!(column1.decoded().as_real_slice(), &[]); @@ -516,7 +470,7 @@ mod tests { { let mut column0 = columns[0].clone(); assert!(column0.is_raw()); - column0.decode(&Tz::utc(), &schema[0]).unwrap(); + column0.ensure_decoded(&Tz::utc(), &schema[0]).unwrap(); assert_eq!(column0.decoded().len(), 3); assert_eq!(column0.decoded().eval_type(), EvalType::Int); assert_eq!(column0.decoded().as_int_slice(), &[None, Some(5), Some(1)]); @@ -524,7 +478,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 3); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!( @@ -534,11 +488,9 @@ mod tests { } // Let's change a column from lazy to decoded and test whether retain works - columns - .ensure_column_decoded(0, &Tz::utc(), &schema[0]) - .unwrap(); + columns[0].ensure_decoded(&Tz::utc(), &schema[0]).unwrap(); - columns.retain_rows_by_index(|_| true); + columns.retain_rows_by_array(&[true, true, true]); assert_eq!(columns.rows_len(), 3); assert_eq!(columns.columns_len(), 2); @@ -552,7 +504,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 3); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!( @@ -561,8 +513,7 @@ mod tests { ); } - let retain_map = &[true, false, true]; - columns.retain_rows_by_index(|idx| retain_map[idx]); + columns.retain_rows_by_array(&[true, false, true]); assert_eq!(columns.rows_len(), 2); assert_eq!(columns.columns_len(), 2); @@ -576,7 +527,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 2); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!( @@ -585,7 +536,7 @@ mod tests { ); } - columns.retain_rows_by_index(|_| false); + columns.retain_rows_by_array(&[false, false]); assert_eq!(columns.rows_len(), 0); assert_eq!(columns.columns_len(), 2); @@ -599,7 +550,7 @@ mod tests { { let mut column1 = columns[1].clone(); assert!(column1.is_raw()); - column1.decode(&Tz::utc(), &schema[1]).unwrap(); + column1.ensure_decoded(&Tz::utc(), &schema[1]).unwrap(); assert_eq!(column1.decoded().len(), 0); assert_eq!(column1.decoded().eval_type(), EvalType::Real); assert_eq!(column1.decoded().as_real_slice(), &[]); diff --git a/src/coprocessor/codec/data_type/vector.rs b/src/coprocessor/codec/data_type/vector.rs index 286886045453..a9cfc20752a7 100644 --- a/src/coprocessor/codec/data_type/vector.rs +++ b/src/coprocessor/codec/data_type/vector.rs @@ -108,20 +108,19 @@ impl VectorValue { } } - /// Retains only the elements specified by the predicate, which accepts index only. + /// Retains the elements according to a boolean array. /// - /// In other words, remove all rows such that `f(element_index)` returns `false`. - #[inline] - pub fn retain_by_index(&mut self, mut f: F) - where - F: FnMut(usize) -> bool, - { + /// # Panics + /// + /// Panics if `retain_arr` is not long enough. + pub fn retain_by_array(&mut self, retain_arr: &[bool]) { + assert!(self.len() <= retain_arr.len()); match_template_evaluable! { TT, match self { VectorValue::TT(v) => { let mut idx = 0; v.retain(|_| { - let r = f(idx); + let r = retain_arr[idx]; idx += 1; r }); @@ -794,14 +793,17 @@ mod tests { } #[test] - fn test_retain_by_index() { + fn test_retain_by_array() { let mut column = VectorValue::with_capacity(3, EvalType::Real); assert_eq!(column.len(), 0); assert_eq!(column.capacity(), 3); - column.retain_by_index(|_| true); + column.retain_by_array(&[]); + assert_eq!(column.len(), 0); + assert_eq!(column.capacity(), 3); + column.retain_by_array(&[true]); assert_eq!(column.len(), 0); assert_eq!(column.capacity(), 3); - column.retain_by_index(|_| false); + column.retain_by_array(&[false]); assert_eq!(column.len(), 0); assert_eq!(column.capacity(), 3); @@ -812,8 +814,7 @@ mod tests { column.push_real(Real::new(5.0).ok()); column.push_real(None); - let retain_map = &[true, true, false, false, true, false]; - column.retain_by_index(|idx| retain_map[idx]); + column.retain_by_array(&[true, true, false, false, true, false]); assert_eq!(column.len(), 3); assert!(column.capacity() > 3); @@ -841,8 +842,7 @@ mod tests { ] ); - let retain_map = &[true, false, true, false, false, true, true]; - column.retain_by_index(|idx| retain_map[idx]); + column.retain_by_array(&[true, false, true, false, false, true, true]); assert_eq!(column.len(), 4); assert_eq!( @@ -850,14 +850,14 @@ mod tests { &[None, Real::new(5.0).ok(), None, Real::new(4.0).ok()] ); - column.retain_by_index(|_| true); + column.retain_by_array(&[true, true, true, true]); assert_eq!(column.len(), 4); assert_eq!( column.as_real_slice(), &[None, Real::new(5.0).ok(), None, Real::new(4.0).ok()] ); - column.retain_by_index(|_| false); + column.retain_by_array(&[false, false, false, false]); assert_eq!(column.len(), 0); assert_eq!(column.as_real_slice(), &[]); @@ -1024,7 +1024,7 @@ mod benches { b.iter(|| { let should_retain = test::black_box(&should_retain); let mut c = test::black_box(&column).clone(); - c.retain_by_index(|idx| should_retain[idx]); + c.retain_by_array(should_retain.as_slice()); test::black_box(c); }); } diff --git a/src/coprocessor/dag/batch/executors/fast_hash_aggr_executor.rs b/src/coprocessor/dag/batch/executors/fast_hash_aggr_executor.rs index 1edbdecd1a37..53dc0953fd53 100644 --- a/src/coprocessor/dag/batch/executors/fast_hash_aggr_executor.rs +++ b/src/coprocessor/dag/batch/executors/fast_hash_aggr_executor.rs @@ -419,7 +419,9 @@ mod tests { // Let's check group by column first. Group by column is decoded in fast hash agg, // but not decoded in slow hash agg. So decode it anyway. - r.data[4].decode(&Tz::utc(), &exec.schema()[4]).unwrap(); + r.data[4] + .ensure_decoded(&Tz::utc(), &exec.schema()[4]) + .unwrap(); // The row order is not defined. Let's sort it by the group by column before asserting. let mut sort_column: Vec<(usize, _)> = r.data[4] @@ -586,7 +588,9 @@ mod tests { let mut r = exec.next_batch(1); assert_eq!(r.data.rows_len(), 3); assert_eq!(r.data.columns_len(), 1); // 0 result column, 1 group by column - r.data[0].decode(&Tz::utc(), &exec.schema()[0]).unwrap(); + r.data[0] + .ensure_decoded(&Tz::utc(), &exec.schema()[0]) + .unwrap(); let mut sort_column: Vec<(usize, _)> = r.data[0] .decoded() .as_real_slice() diff --git a/src/coprocessor/dag/batch/executors/index_scan_executor.rs b/src/coprocessor/dag/batch/executors/index_scan_executor.rs index 025e5c9b2921..3e00b4f80270 100644 --- a/src/coprocessor/dag/batch/executors/index_scan_executor.rs +++ b/src/coprocessor/dag/batch/executors/index_scan_executor.rs @@ -180,7 +180,7 @@ impl super::util::scan_executor::ScanExecutorImpl for IndexScanExecutorImpl { for i in 0..self.columns_len_without_handle { let (val, remaining) = datum::split_datum(key_payload, false)?; - columns[i].push_raw(val); + columns[i].mut_raw().push(val); key_payload = remaining; } @@ -336,13 +336,17 @@ mod tests { assert_eq!(result.data.columns_len(), 2); assert_eq!(result.data.rows_len(), 3); assert!(result.data[0].is_raw()); - result.data[0].decode(&Tz::utc(), &schema[0]).unwrap(); + result.data[0] + .ensure_decoded(&Tz::utc(), &schema[0]) + .unwrap(); assert_eq!( result.data[0].decoded().as_int_slice(), &[Some(5), Some(5), Some(-5)] ); assert!(result.data[1].is_raw()); - result.data[1].decode(&Tz::utc(), &schema[1]).unwrap(); + result.data[1] + .ensure_decoded(&Tz::utc(), &schema[1]) + .unwrap(); assert_eq!( result.data[1].decoded().as_real_slice(), &[ @@ -386,10 +390,14 @@ mod tests { assert_eq!(result.data.columns_len(), 3); assert_eq!(result.data.rows_len(), 2); assert!(result.data[0].is_raw()); - result.data[0].decode(&Tz::utc(), &schema[0]).unwrap(); + result.data[0] + .ensure_decoded(&Tz::utc(), &schema[0]) + .unwrap(); assert_eq!(result.data[0].decoded().as_int_slice(), &[Some(5), Some(5)]); assert!(result.data[1].is_raw()); - result.data[1].decode(&Tz::utc(), &schema[1]).unwrap(); + result.data[1] + .ensure_decoded(&Tz::utc(), &schema[1]) + .unwrap(); assert_eq!( result.data[1].decoded().as_real_slice(), &[Real::new(5.1).ok(), Real::new(10.5).ok()] @@ -452,10 +460,14 @@ mod tests { assert_eq!(result.data.columns_len(), 3); assert_eq!(result.data.rows_len(), 2); assert!(result.data[0].is_raw()); - result.data[0].decode(&Tz::utc(), &schema[0]).unwrap(); + result.data[0] + .ensure_decoded(&Tz::utc(), &schema[0]) + .unwrap(); assert_eq!(result.data[0].decoded().as_int_slice(), &[Some(5), Some(5)]); assert!(result.data[1].is_raw()); - result.data[1].decode(&Tz::utc(), &schema[1]).unwrap(); + result.data[1] + .ensure_decoded(&Tz::utc(), &schema[1]) + .unwrap(); assert_eq!( result.data[1].decoded().as_real_slice(), &[Real::new(5.1).ok(), Real::new(10.5).ok()] @@ -496,10 +508,14 @@ mod tests { assert_eq!(result.data.columns_len(), 3); assert_eq!(result.data.rows_len(), 1); assert!(result.data[0].is_raw()); - result.data[0].decode(&Tz::utc(), &schema[0]).unwrap(); + result.data[0] + .ensure_decoded(&Tz::utc(), &schema[0]) + .unwrap(); assert_eq!(result.data[0].decoded().as_int_slice(), &[Some(5)]); assert!(result.data[1].is_raw()); - result.data[1].decode(&Tz::utc(), &schema[1]).unwrap(); + result.data[1] + .ensure_decoded(&Tz::utc(), &schema[1]) + .unwrap(); assert_eq!( result.data[1].decoded().as_real_slice(), &[Real::new(5.1).ok()] diff --git a/src/coprocessor/dag/batch/executors/selection_executor.rs b/src/coprocessor/dag/batch/executors/selection_executor.rs index 8ca94b3fd18e..b91d204eaabc 100644 --- a/src/coprocessor/dag/batch/executors/selection_executor.rs +++ b/src/coprocessor/dag/batch/executors/selection_executor.rs @@ -101,10 +101,7 @@ impl BatchExecutor for BatchSelectionExecutor { } // TODO: When there are many conditions, it would be better to filter column each time. - - src_result - .data - .retain_rows_by_index(|idx| base_retain_map[idx]); + src_result.data.retain_rows_by_array(&base_retain_map); } // Only append warnings when there is no error during filtering because we clear the data diff --git a/src/coprocessor/dag/batch/executors/slow_hash_aggr_executor.rs b/src/coprocessor/dag/batch/executors/slow_hash_aggr_executor.rs index 75f1a001dc89..ee00dd9d9330 100644 --- a/src/coprocessor/dag/batch/executors/slow_hash_aggr_executor.rs +++ b/src/coprocessor/dag/batch/executors/slow_hash_aggr_executor.rs @@ -284,7 +284,9 @@ impl AggregationExecutorImpl for SlowHashAggregationImp for group_index in 0..group_by_exps_len { let offset_begin = group_info.group_key_offsets[group_index] as usize; let offset_end = group_info.group_key_offsets[group_index + 1] as usize; - group_by_columns[group_index].push_raw(&group_key[offset_begin..offset_end]); + group_by_columns[group_index] + .mut_raw() + .push(&group_key[offset_begin..offset_end]); } } @@ -372,12 +374,16 @@ mod tests { assert_eq!(r.data.columns_len(), 5); // 3 result column, 2 group by column // Let's check the two group by column first. - r.data[3].decode(&Tz::utc(), &exec.schema()[3]).unwrap(); + r.data[3] + .ensure_decoded(&Tz::utc(), &exec.schema()[3]) + .unwrap(); assert_eq!( r.data[3].decoded().as_int_slice(), &[Some(5), None, None, Some(1)] ); - r.data[4].decode(&Tz::utc(), &exec.schema()[4]).unwrap(); + r.data[4] + .ensure_decoded(&Tz::utc(), &exec.schema()[4]) + .unwrap(); assert_eq!( r.data[4].decoded().as_real_slice(), &[Real::new(2.5).ok(), Real::new(8.0).ok(), None, None] diff --git a/src/coprocessor/dag/batch/executors/table_scan_executor.rs b/src/coprocessor/dag/batch/executors/table_scan_executor.rs index 70aafa4ab427..c8e0d76af2d5 100644 --- a/src/coprocessor/dag/batch/executors/table_scan_executor.rs +++ b/src/coprocessor/dag/batch/executors/table_scan_executor.rs @@ -243,7 +243,7 @@ impl super::util::scan_executor::ScanExecutorImpl for TableScanExecutorImpl { if let Some(index) = some_index { let index = *index; if !self.is_column_filled[index] { - columns[index].push_raw(val); + columns[index].mut_raw().push(val); decoded_columns += 1; self.is_column_filled[index] = true; } else { @@ -285,7 +285,7 @@ impl super::util::scan_executor::ScanExecutorImpl for TableScanExecutorImpl { )); }; - columns[i].push_raw(default_value); + columns[i].mut_raw().push(default_value); } else { // Reset to not-filled, prepare for next function call. self.is_column_filled[i] = false; @@ -541,7 +541,7 @@ mod tests { } else { assert!(columns[id].is_raw()); columns[id] - .decode(&Tz::utc(), self.get_field_type(col_idx)) + .ensure_decoded(&Tz::utc(), self.get_field_type(col_idx)) .unwrap(); } assert_eq!(columns[id].decoded(), &values[col_idx]); @@ -786,10 +786,14 @@ mod tests { assert!(result.data[0].is_decoded()); assert_eq!(result.data[0].decoded().as_int_slice(), &[Some(0), Some(1)]); assert!(result.data[1].is_raw()); - result.data[1].decode(&Tz::utc(), &schema[1]).unwrap(); + result.data[1] + .ensure_decoded(&Tz::utc(), &schema[1]) + .unwrap(); assert_eq!(result.data[1].decoded().as_int_slice(), &[Some(5), None]); assert!(result.data[2].is_raw()); - result.data[2].decode(&Tz::utc(), &schema[2]).unwrap(); + result.data[2] + .ensure_decoded(&Tz::utc(), &schema[2]) + .unwrap(); assert_eq!(result.data[2].decoded().as_int_slice(), &[Some(7), None]); } } @@ -880,7 +884,9 @@ mod tests { assert!(result.data[0].is_decoded()); assert_eq!(result.data[0].decoded().as_int_slice(), &[Some(0)]); assert!(result.data[1].is_raw()); - result.data[1].decode(&Tz::utc(), &schema[1]).unwrap(); + result.data[1] + .ensure_decoded(&Tz::utc(), &schema[1]) + .unwrap(); assert_eq!(result.data[1].decoded().as_int_slice(), &[Some(7)]); } @@ -906,7 +912,9 @@ mod tests { assert!(result.data[0].is_decoded()); assert_eq!(result.data[0].decoded().as_int_slice(), &[Some(0)]); assert!(result.data[1].is_raw()); - result.data[1].decode(&Tz::utc(), &schema[1]).unwrap(); + result.data[1] + .ensure_decoded(&Tz::utc(), &schema[1]) + .unwrap(); assert_eq!(result.data[1].decoded().as_int_slice(), &[Some(7)]); let result = executor.next_batch(1); @@ -952,7 +960,9 @@ mod tests { assert!(result.data[0].is_decoded()); assert_eq!(result.data[0].decoded().as_int_slice(), &[Some(2), Some(0)]); assert!(result.data[1].is_raw()); - result.data[1].decode(&Tz::utc(), &schema[1]).unwrap(); + result.data[1] + .ensure_decoded(&Tz::utc(), &schema[1]) + .unwrap(); assert_eq!(result.data[1].decoded().as_int_slice(), &[Some(5), Some(7)]); } diff --git a/src/coprocessor/dag/rpn_expr/types/expr_eval.rs b/src/coprocessor/dag/rpn_expr/types/expr_eval.rs index 37645a53f1b9..00e89fb80730 100644 --- a/src/coprocessor/dag/rpn_expr/types/expr_eval.rs +++ b/src/coprocessor/dag/rpn_expr/types/expr_eval.rs @@ -181,7 +181,7 @@ impl RpnExpression { ) -> Result<()> { for node in self.as_ref() { if let RpnExpressionNode::ColumnRef { ref offset, .. } = node { - columns.ensure_column_decoded(*offset, tz, &schema[*offset])?; + columns[*offset].ensure_decoded(tz, &schema[*offset])?; } } Ok(()) @@ -505,15 +505,15 @@ mod tests { let mut datum_raw = Vec::new(); DatumEncoder::encode(&mut datum_raw, &[Datum::I64(-5)], false).unwrap(); - col.push_raw(&datum_raw); + col.mut_raw().push(&datum_raw); let mut datum_raw = Vec::new(); DatumEncoder::encode(&mut datum_raw, &[Datum::I64(-7)], false).unwrap(); - col.push_raw(&datum_raw); + col.mut_raw().push(&datum_raw); let mut datum_raw = Vec::new(); DatumEncoder::encode(&mut datum_raw, &[Datum::I64(3)], false).unwrap(); - col.push_raw(&datum_raw); + col.mut_raw().push(&datum_raw); col }]); @@ -751,15 +751,15 @@ mod tests { let mut datum_raw = Vec::new(); DatumEncoder::encode(&mut datum_raw, &[Datum::I64(-5)], false).unwrap(); - col.push_raw(&datum_raw); + col.mut_raw().push(&datum_raw); let mut datum_raw = Vec::new(); DatumEncoder::encode(&mut datum_raw, &[Datum::I64(-7)], false).unwrap(); - col.push_raw(&datum_raw); + col.mut_raw().push(&datum_raw); let mut datum_raw = Vec::new(); DatumEncoder::encode(&mut datum_raw, &[Datum::I64(3)], false).unwrap(); - col.push_raw(&datum_raw); + col.mut_raw().push(&datum_raw); col }]);