From f69a726ceafc52ce991a3a172a9cc23037038db9 Mon Sep 17 00:00:00 2001 From: Kould Date: Sat, 28 Dec 2024 23:35:30 +0800 Subject: [PATCH 1/2] chore: simplify `DataValue` --- Cargo.toml | 2 +- docs/features.md | 6 +- examples/hello_world.rs | 6 +- src/binder/expr.rs | 8 +- src/binder/select.rs | 8 +- src/db.rs | 32 +- src/execution/dml/analyze.rs | 6 +- src/execution/dml/insert.rs | 2 +- src/execution/dql/aggregate/avg.rs | 4 +- src/execution/dql/aggregate/count.rs | 4 +- src/execution/dql/aggregate/hash_agg.rs | 24 +- src/execution/dql/aggregate/min_max.rs | 21 +- src/execution/dql/aggregate/mod.rs | 4 +- src/execution/dql/aggregate/sum.rs | 4 +- src/execution/dql/describe.rs | 19 +- src/execution/dql/explain.rs | 2 +- src/execution/dql/join/hash_join.rs | 46 +- src/execution/dql/join/nested_loop_join.rs | 54 +- src/execution/dql/mod.rs | 4 +- src/execution/dql/show_table.rs | 2 +- src/execution/dql/sort.rs | 186 +-- src/expression/evaluator.rs | 59 +- src/expression/mod.rs | 61 +- src/expression/range_detacher.rs | 593 ++++---- src/expression/simplify.rs | 10 +- src/function/char_length.rs | 9 +- src/function/current_date.rs | 2 +- src/function/lower.rs | 7 +- src/function/numbers.rs | 2 +- src/function/upper.rs | 7 +- src/optimizer/core/cm_sketch.rs | 4 +- src/optimizer/core/histogram.rs | 248 ++-- src/optimizer/core/memo.rs | 4 +- src/optimizer/core/statistics_meta.rs | 36 +- .../rule/normalization/column_pruning.rs | 2 +- .../rule/normalization/combine_operators.rs | 4 +- .../rule/normalization/pushdown_predicates.rs | 9 +- .../rule/normalization/simplification.rs | 32 +- src/serdes/column.rs | 4 +- src/serdes/data_value.rs | 26 +- src/storage/mod.rs | 24 +- src/storage/rocksdb.rs | 25 +- src/storage/table_codec.rs | 92 +- src/types/evaluator/boolean.rs | 95 +- src/types/evaluator/decimal.rs | 231 +-- src/types/evaluator/float32.rs | 183 ++- src/types/evaluator/float64.rs | 183 ++- src/types/evaluator/mod.rs | 549 +++---- src/types/evaluator/tuple.rs | 140 +- src/types/evaluator/utf8.rs | 214 +-- src/types/tuple.rs | 83 +- src/types/tuple_builder.rs | 4 +- src/types/value.rs | 1281 +++++++---------- tests/macros-test/src/main.rs | 32 +- tests/slt/describe.slt | 4 +- tests/slt/sql_2016/E091_01.slt | 2 +- tests/slt/sql_2016/E091_06.slt | 2 +- tests/slt/sql_2016/E091_07.slt | 2 +- tpcc/src/delivery.rs | 44 +- tpcc/src/new_ord.rs | 103 +- tpcc/src/order_stat.rs | 44 +- tpcc/src/payment.rs | 74 +- tpcc/src/slev.rs | 18 +- 63 files changed, 2288 insertions(+), 2704 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 064da6cd..e47f4ad7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ csv = { version = "1" } dirs = { version = "5" } fixedbitset = { version = "0.4" } itertools = { version = "0.12" } -ordered-float = { version = "4" } +ordered-float = { version = "4", features = ["serde"] } paste = { version = "1" } parking_lot = { version = "0.12", features = ["arc_lock"] } petgraph = { version = "0.6" } diff --git a/docs/features.md b/docs/features.md index b39f6015..094789ee 100644 --- a/docs/features.md +++ b/docs/features.md @@ -14,13 +14,13 @@ struct MyStruct { implement_from_tuple!( MyStruct, ( c1: i32 => |inner: &mut MyStruct, value| { - if let DataValue::Int32(Some(val)) = value { + if let DataValue::Int32(val) = value { inner.c1 = val; } }, c2: String => |inner: &mut MyStruct, value| { - if let DataValue::Utf8(Some(val)) = value { - inner.c2 = val; + if let DataValue::Utf8 { value, .. } = value { + inner.c2 = value; } } ) diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 4237ab65..ec5b02e6 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -12,13 +12,13 @@ struct MyStruct { implement_from_tuple!( MyStruct, ( c1: i32 => |inner: &mut MyStruct, value| { - if let DataValue::Int32(Some(val)) = value { + if let DataValue::Int32(val) = value { inner.c1 = val; } }, c2: String => |inner: &mut MyStruct, value| { - if let DataValue::Utf8 { value: Some(val), .. } = value { - inner.c2 = val; + if let DataValue::Utf8 { value, .. } = value { + inner.c2 = value; } } ) diff --git a/src/binder/expr.rs b/src/binder/expr.rs index a89aea0a..548b7028 100644 --- a/src/binder/expr.rs +++ b/src/binder/expr.rs @@ -82,7 +82,7 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T Expr::TypedString { data_type, value } => { let logical_type = LogicalType::try_from(data_type.clone())?; let value = DataValue::Utf8 { - value: Some(value.to_string()), + value: value.to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, } @@ -429,7 +429,7 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T }; Ok(ScalarExpression::Binary { - op: (op.clone()).into(), + op: (op.clone()).try_into()?, left_expr, right_expr, evaluator: None, @@ -450,7 +450,7 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T }; Ok(ScalarExpression::Unary { - op: (*op).into(), + op: (*op).try_into()?, expr, evaluator: None, ty, @@ -690,7 +690,7 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T fn wildcard_expr() -> ScalarExpression { ScalarExpression::Constant(DataValue::Utf8 { - value: Some("*".to_string()), + value: "*".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }) diff --git a/src/binder/select.rs b/src/binder/select.rs index 322b8194..146649e6 100644 --- a/src/binder/select.rs +++ b/src/binder/select.rs @@ -695,8 +695,8 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<' let expr = self.bind_expr(expr)?; match expr { ScalarExpression::Constant(dv) => match &dv { - DataValue::Int32(Some(v)) if *v >= 0 => limit = Some(*v as usize), - DataValue::Int64(Some(v)) if *v >= 0 => limit = Some(*v as usize), + DataValue::Int32(v) if *v >= 0 => limit = Some(*v as usize), + DataValue::Int64(v) if *v >= 0 => limit = Some(*v as usize), _ => return Err(DatabaseError::InvalidType), }, _ => { @@ -711,8 +711,8 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<' let expr = self.bind_expr(&expr.value)?; match expr { ScalarExpression::Constant(dv) => match &dv { - DataValue::Int32(Some(v)) if *v > 0 => offset = Some(*v as usize), - DataValue::Int64(Some(v)) if *v > 0 => offset = Some(*v as usize), + DataValue::Int32(v) if *v > 0 => offset = Some(*v as usize), + DataValue::Int64(v) if *v > 0 => offset = Some(*v as usize), _ => return Err(DatabaseError::InvalidType), }, _ => { diff --git a/src/db.rs b/src/db.rs index 23628484..e389a999 100644 --- a/src/db.rs +++ b/src/db.rs @@ -530,7 +530,7 @@ pub(crate) mod test { iter.next().unwrap()?, Tuple::new( None, - vec![DataValue::Date32(Some(Local::now().num_days_from_ce()))] + vec![DataValue::Date32(Local::now().num_days_from_ce())] ) ); assert!(iter.next().is_none()); @@ -558,11 +558,11 @@ pub(crate) mod test { assert_eq!(iter.schema(), &Arc::new(vec![ColumnRef::from(column)])); assert_eq!( iter.next().unwrap()?, - Tuple::new(None, vec![DataValue::Int32(Some(3))]) + Tuple::new(None, vec![DataValue::Int32(3)]) ); assert_eq!( iter.next().unwrap()?, - Tuple::new(None, vec![DataValue::Int32(Some(4))]) + Tuple::new(None, vec![DataValue::Int32(4)]) ); Ok(()) } @@ -583,7 +583,7 @@ pub(crate) mod test { { let statement = fnck_sql.prepare("explain select * from t1 where b > ?1")?; - let mut iter = fnck_sql.execute(&statement, &[("?1", DataValue::Int32(Some(0)))])?; + let mut iter = fnck_sql.execute(&statement, &[("?1", DataValue::Int32(0))])?; assert_eq!( iter.next().unwrap()?.values[0].utf8().unwrap(), @@ -601,10 +601,10 @@ pub(crate) mod test { let mut iter = fnck_sql.execute( &statement, &[ - ("?1", DataValue::Int32(Some(0))), - ("?2", DataValue::Int32(Some(0))), - ("?3", DataValue::Int32(Some(1))), - ("?4", DataValue::Int32(Some(0))), + ("?1", DataValue::Int32(0)), + ("?2", DataValue::Int32(0)), + ("?3", DataValue::Int32(1)), + ("?4", DataValue::Int32(0)), ], )?; assert_eq!( @@ -621,10 +621,10 @@ pub(crate) mod test { let mut iter = fnck_sql.execute( &statement, &[ - ("?1", DataValue::Int32(Some(9))), - ("?2", DataValue::Int32(Some(0))), - ("?3", DataValue::Int32(Some(1))), - ("?4", DataValue::Int32(Some(0))), + ("?1", DataValue::Int32(9)), + ("?2", DataValue::Int32(0)), + ("?3", DataValue::Int32(1)), + ("?4", DataValue::Int32(0)), ], )?; assert_eq!( @@ -666,20 +666,20 @@ pub(crate) mod test { assert_eq!( iter_1.next().unwrap()?.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(Some(0))] + vec![DataValue::Int32(0), DataValue::Int32(0)] ); assert_eq!( iter_1.next().unwrap()?.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(Some(1))] + vec![DataValue::Int32(1), DataValue::Int32(1)] ); assert_eq!( iter_2.next().unwrap()?.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(Some(0))] + vec![DataValue::Int32(0), DataValue::Int32(0)] ); assert_eq!( iter_2.next().unwrap()?.values, - vec![DataValue::Int32(Some(3)), DataValue::Int32(Some(3))] + vec![DataValue::Int32(3), DataValue::Int32(3)] ); drop(iter_1); drop(iter_2); diff --git a/src/execution/dml/analyze.rs b/src/execution/dml/analyze.rs index dc890967..c9d66a72 100644 --- a/src/execution/dml/analyze.rs +++ b/src/execution/dml/analyze.rs @@ -92,9 +92,7 @@ impl<'a, T: Transaction + 'a> WriteExecutor<'a, T> for Analyze { if values.len() == 1 { throw!(builder.append(&values[0])); } else { - throw!( - builder.append(&Arc::new(DataValue::Tuple(Some((values, false))))) - ); + throw!(builder.append(&Arc::new(DataValue::Tuple(values, false)))); } } } @@ -121,7 +119,7 @@ impl<'a, T: Transaction + 'a> WriteExecutor<'a, T> for Analyze { throw!(meta.to_file(&temp_path)); values.push(DataValue::Utf8 { - value: Some(path_str.clone()), + value: path_str.clone(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }); diff --git a/src/execution/dml/insert.rs b/src/execution/dml/insert.rs index fe71244e..9c65c5d3 100644 --- a/src/execution/dml/insert.rs +++ b/src/execution/dml/insert.rs @@ -118,7 +118,7 @@ impl<'a, T: Transaction + 'a> WriteExecutor<'a, T> for Insert { if value.is_none() { value = throw!(col.default_value()); } - value.unwrap_or_else(|| DataValue::none(col.datatype())) + value.unwrap_or(DataValue::Null) }; if value.is_null() && !col.nullable() { yield Err(DatabaseError::NotNull); diff --git a/src/execution/dql/aggregate/avg.rs b/src/execution/dql/aggregate/avg.rs index a18028cc..ce19658d 100644 --- a/src/execution/dql/aggregate/avg.rs +++ b/src/execution/dql/aggregate/avg.rs @@ -38,9 +38,9 @@ impl Accumulator for AvgAccumulator { return Ok(DataValue::init(&value_ty)); } let quantity = if value_ty.is_signed_numeric() { - DataValue::Int64(Some(self.count as i64)) + DataValue::Int64(self.count as i64) } else { - DataValue::UInt32(Some(self.count as u32)) + DataValue::UInt32(self.count as u32) }; let quantity_ty = quantity.logical_type(); diff --git a/src/execution/dql/aggregate/count.rs b/src/execution/dql/aggregate/count.rs index 741bad58..5daaae5a 100644 --- a/src/execution/dql/aggregate/count.rs +++ b/src/execution/dql/aggregate/count.rs @@ -24,7 +24,7 @@ impl Accumulator for CountAccumulator { } fn evaluate(&self) -> Result { - Ok(DataValue::Int32(Some(self.result))) + Ok(DataValue::Int32(self.result)) } } @@ -50,6 +50,6 @@ impl Accumulator for DistinctCountAccumulator { } fn evaluate(&self) -> Result { - Ok(DataValue::Int32(Some(self.distinct_values.len() as i32))) + Ok(DataValue::Int32(self.distinct_values.len() as i32)) } } diff --git a/src/execution/dql/aggregate/hash_agg.rs b/src/execution/dql/aggregate/hash_agg.rs index 9debaee2..5df8bcc8 100644 --- a/src/execution/dql/aggregate/hash_agg.rs +++ b/src/execution/dql/aggregate/hash_agg.rs @@ -159,24 +159,24 @@ mod test { operator: Operator::Values(ValuesOperator { rows: vec![ vec![ - DataValue::Int32(Some(0)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(4)), + DataValue::Int32(0), + DataValue::Int32(2), + DataValue::Int32(4), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(3)), - DataValue::Int32(Some(5)), + DataValue::Int32(1), + DataValue::Int32(3), + DataValue::Int32(5), ], vec![ - DataValue::Int32(Some(0)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), + DataValue::Int32(0), + DataValue::Int32(1), + DataValue::Int32(2), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(3)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(3), ], ], schema_ref: t1_schema.clone(), diff --git a/src/execution/dql/aggregate/min_max.rs b/src/execution/dql/aggregate/min_max.rs index bc4200c8..8026c9de 100644 --- a/src/execution/dql/aggregate/min_max.rs +++ b/src/execution/dql/aggregate/min_max.rs @@ -3,27 +3,21 @@ use crate::execution::dql::aggregate::Accumulator; use crate::expression::BinaryOperator; use crate::types::evaluator::EvaluatorFactory; use crate::types::value::DataValue; -use crate::types::LogicalType; pub struct MinMaxAccumulator { inner: Option, op: BinaryOperator, - ty: LogicalType, } impl MinMaxAccumulator { - pub fn new(ty: &LogicalType, is_max: bool) -> Self { + pub fn new(is_max: bool) -> Self { let op = if is_max { BinaryOperator::Lt } else { BinaryOperator::Gt }; - Self { - inner: None, - op, - ty: ty.clone(), - } + Self { inner: None, op } } } @@ -32,12 +26,10 @@ impl Accumulator for MinMaxAccumulator { if !value.is_null() { if let Some(inner_value) = &self.inner { let evaluator = EvaluatorFactory::binary_create(value.logical_type(), self.op)?; - if let DataValue::Boolean(Some(result)) = - evaluator.0.binary_eval(inner_value, value) - { + if let DataValue::Boolean(result) = evaluator.0.binary_eval(inner_value, value) { result } else { - unreachable!() + return Err(DatabaseError::InvalidType); } } else { true @@ -49,9 +41,6 @@ impl Accumulator for MinMaxAccumulator { } fn evaluate(&self) -> Result { - Ok(self - .inner - .clone() - .unwrap_or_else(|| DataValue::none(&self.ty))) + Ok(self.inner.clone().unwrap_or(DataValue::Null)) } } diff --git a/src/execution/dql/aggregate/mod.rs b/src/execution/dql/aggregate/mod.rs index dd1a1617..2afd64c5 100644 --- a/src/execution/dql/aggregate/mod.rs +++ b/src/execution/dql/aggregate/mod.rs @@ -36,8 +36,8 @@ fn create_accumulator(expr: &ScalarExpression) -> Result, D (AggKind::Count, true) => Box::new(DistinctCountAccumulator::new()), (AggKind::Sum, false) => Box::new(SumAccumulator::new(ty)?), (AggKind::Sum, true) => Box::new(DistinctSumAccumulator::new(ty)?), - (AggKind::Min, _) => Box::new(MinMaxAccumulator::new(ty, false)), - (AggKind::Max, _) => Box::new(MinMaxAccumulator::new(ty, true)), + (AggKind::Min, _) => Box::new(MinMaxAccumulator::new(false)), + (AggKind::Max, _) => Box::new(MinMaxAccumulator::new(true)), (AggKind::Avg, _) => Box::new(AvgAccumulator::new(ty)?), }) } else { diff --git a/src/execution/dql/aggregate/sum.rs b/src/execution/dql/aggregate/sum.rs index f258b9da..1a210e4a 100644 --- a/src/execution/dql/aggregate/sum.rs +++ b/src/execution/dql/aggregate/sum.rs @@ -17,7 +17,7 @@ impl SumAccumulator { debug_assert!(ty.is_numeric()); Ok(Self { - result: DataValue::none(ty), + result: DataValue::Null, evaluator: EvaluatorFactory::binary_create(ty.clone(), BinaryOperator::Plus)?, }) } @@ -27,7 +27,7 @@ impl Accumulator for SumAccumulator { fn update_value(&mut self, value: &DataValue) -> Result<(), DatabaseError> { if !value.is_null() { if self.result.is_null() { - self.result = DataValue::clone(value); + self.result = value.clone(); } else { self.result = self.evaluator.0.binary_eval(&self.result, value); } diff --git a/src/execution/dql/describe.rs b/src/execution/dql/describe.rs index 132f4251..14f14bb5 100644 --- a/src/execution/dql/describe.rs +++ b/src/execution/dql/describe.rs @@ -10,19 +10,19 @@ use sqlparser::ast::CharLengthUnits; use std::sync::LazyLock; static PRIMARY_KEY_TYPE: LazyLock = LazyLock::new(|| DataValue::Utf8 { - value: Some(String::from("PRIMARY")), + value: String::from("PRIMARY"), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }); static UNIQUE_KEY_TYPE: LazyLock = LazyLock::new(|| DataValue::Utf8 { - value: Some(String::from("UNIQUE")), + value: String::from("UNIQUE"), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }); static EMPTY_KEY_TYPE: LazyLock = LazyLock::new(|| DataValue::Utf8 { - value: Some(String::from("EMPTY")), + value: String::from("EMPTY"), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }); @@ -72,28 +72,31 @@ impl<'a, T: Transaction + 'a> ReadExecutor<'a, T> for Describe { .unwrap_or_else(|| "null".to_string()); let values = vec![ DataValue::Utf8 { - value: Some(column.name().to_string()), + value: column.name().to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, DataValue::Utf8 { - value: Some(datatype.to_string()), + value: datatype.to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, DataValue::Utf8 { - value: datatype.raw_len().map(|len| len.to_string()), + value: datatype + .raw_len() + .map(|len| len.to_string()) + .unwrap_or_else(|| "variable".to_string()), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, DataValue::Utf8 { - value: Some(column.nullable().to_string()), + value: column.nullable().to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, key_fn(column), DataValue::Utf8 { - value: Some(default), + value: default, ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, diff --git a/src/execution/dql/explain.rs b/src/execution/dql/explain.rs index 2f1c303b..2ca71d63 100644 --- a/src/execution/dql/explain.rs +++ b/src/execution/dql/explain.rs @@ -25,7 +25,7 @@ impl<'a, T: Transaction + 'a> ReadExecutor<'a, T> for Explain { #[coroutine] move || { let values = vec![DataValue::Utf8 { - value: Some(self.plan.explain(0)), + value: self.plan.explain(0), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }]; diff --git a/src/execution/dql/join/hash_join.rs b/src/execution/dql/join/hash_join.rs index b943e7b1..88ffe81f 100644 --- a/src/execution/dql/join/hash_join.rs +++ b/src/execution/dql/join/hash_join.rs @@ -63,7 +63,7 @@ impl HashJoin { ) -> Result, DatabaseError> { if let (Some(expr), false) = (filter, matches!(join_ty, JoinType::Full | JoinType::Cross)) { match &expr.eval(Some((&tuple, schema)))? { - DataValue::Boolean(Some(false) | None) => { + DataValue::Boolean(false) | DataValue::Null => { let full_schema_len = schema.len(); match join_ty { @@ -80,7 +80,7 @@ impl HashJoin { _ => return Ok(None), } } - DataValue::Boolean(Some(true)) => (), + DataValue::Boolean(true) => (), _ => return Err(DatabaseError::InvalidType), } } @@ -350,19 +350,19 @@ mod test { operator: Operator::Values(ValuesOperator { rows: vec![ vec![ - DataValue::Int32(Some(0)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(4)), + DataValue::Int32(0), + DataValue::Int32(2), + DataValue::Int32(4), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(3)), - DataValue::Int32(Some(5)), + DataValue::Int32(1), + DataValue::Int32(3), + DataValue::Int32(5), ], vec![ - DataValue::Int32(Some(3)), - DataValue::Int32(Some(5)), - DataValue::Int32(Some(7)), + DataValue::Int32(3), + DataValue::Int32(5), + DataValue::Int32(7), ], ], schema_ref: Arc::new(t1_columns), @@ -376,24 +376,24 @@ mod test { operator: Operator::Values(ValuesOperator { rows: vec![ vec![ - DataValue::Int32(Some(0)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(4)), + DataValue::Int32(0), + DataValue::Int32(2), + DataValue::Int32(4), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(3)), - DataValue::Int32(Some(5)), + DataValue::Int32(1), + DataValue::Int32(3), + DataValue::Int32(5), ], vec![ - DataValue::Int32(Some(4)), - DataValue::Int32(Some(6)), - DataValue::Int32(Some(8)), + DataValue::Int32(4), + DataValue::Int32(6), + DataValue::Int32(8), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), ], ], schema_ref: Arc::new(t2_columns), diff --git a/src/execution/dql/join/nested_loop_join.rs b/src/execution/dql/join/nested_loop_join.rs index 7df5df1e..b578f9e3 100644 --- a/src/execution/dql/join/nested_loop_join.rs +++ b/src/execution/dql/join/nested_loop_join.rs @@ -180,7 +180,7 @@ impl<'a, T: Transaction + 'a> ReadExecutor<'a, T> for NestedLoopJoin { let value = throw!(filter.eval(Some((&new_tuple, &output_schema_ref)))); match &value { - DataValue::Boolean(Some(true)) => { + DataValue::Boolean(true) => { let tuple = match ty { JoinType::LeftAnti => None, JoinType::LeftSemi if has_matched => None, @@ -200,7 +200,7 @@ impl<'a, T: Transaction + 'a> ReadExecutor<'a, T> for NestedLoopJoin { has_matched = true; tuple } - DataValue::Boolean(Some(_) | None) => None, + DataValue::Boolean(false) | DataValue::Null => None, _ => { yield Err(DatabaseError::InvalidType); return; @@ -441,24 +441,24 @@ mod test { operator: Operator::Values(ValuesOperator { rows: vec![ vec![ - DataValue::Int32(Some(0)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(4)), + DataValue::Int32(0), + DataValue::Int32(2), + DataValue::Int32(4), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(5)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(5), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(3)), - DataValue::Int32(Some(5)), + DataValue::Int32(1), + DataValue::Int32(3), + DataValue::Int32(5), ], vec![ - DataValue::Int32(Some(3)), - DataValue::Int32(Some(5)), - DataValue::Int32(Some(7)), + DataValue::Int32(3), + DataValue::Int32(5), + DataValue::Int32(7), ], ], schema_ref: Arc::new(t1_columns), @@ -472,24 +472,24 @@ mod test { operator: Operator::Values(ValuesOperator { rows: vec![ vec![ - DataValue::Int32(Some(0)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(4)), + DataValue::Int32(0), + DataValue::Int32(2), + DataValue::Int32(4), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(3)), - DataValue::Int32(Some(5)), + DataValue::Int32(1), + DataValue::Int32(3), + DataValue::Int32(5), ], vec![ - DataValue::Int32(Some(4)), - DataValue::Int32(Some(6)), - DataValue::Int32(Some(8)), + DataValue::Int32(4), + DataValue::Int32(6), + DataValue::Int32(8), ], vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), ], ], schema_ref: Arc::new(t2_columns), @@ -523,7 +523,7 @@ mod test { .iter() .map(|v| { if matches!(v, DataValue::Null) { - DataValue::Int32(None) + DataValue::Null } else { v.clone() } diff --git a/src/execution/dql/mod.rs b/src/execution/dql/mod.rs index 54daf4ec..87464b2e 100644 --- a/src/execution/dql/mod.rs +++ b/src/execution/dql/mod.rs @@ -20,6 +20,8 @@ pub(crate) mod test { use itertools::Itertools; pub(crate) fn build_integers(ints: Vec>) -> Vec { - ints.into_iter().map(|i| DataValue::Int32(i)).collect_vec() + ints.into_iter() + .map(|i| i.map(DataValue::Int32).unwrap_or(DataValue::Null)) + .collect_vec() } } diff --git a/src/execution/dql/show_table.rs b/src/execution/dql/show_table.rs index e77fcda0..8ba65ef5 100644 --- a/src/execution/dql/show_table.rs +++ b/src/execution/dql/show_table.rs @@ -21,7 +21,7 @@ impl<'a, T: Transaction + 'a> ReadExecutor<'a, T> for ShowTables { for TableMeta { table_name } in metas { let values = vec![DataValue::Utf8 { - value: Some(table_name.to_string()), + value: table_name.to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }]; diff --git a/src/execution/dql/sort.rs b/src/execution/dql/sort.rs index 8bc40fd1..e253c446 100644 --- a/src/execution/dql/sort.rs +++ b/src/execution/dql/sort.rs @@ -339,84 +339,75 @@ mod test { let arena = Bump::new(); let mut inner = BumpVec::new_in(&arena); - inner.push(Some(( - 0_usize, - Tuple::new(None, vec![DataValue::Int32(None)]), - ))); - inner.push(Some(( - 1_usize, - Tuple::new(None, vec![DataValue::Int32(Some(0))]), - ))); - inner.push(Some(( - 2_usize, - Tuple::new(None, vec![DataValue::Int32(Some(1))]), - ))); + inner.push(Some((0_usize, Tuple::new(None, vec![DataValue::Null])))); + inner.push(Some((1_usize, Tuple::new(None, vec![DataValue::Int32(0)])))); + inner.push(Some((2_usize, Tuple::new(None, vec![DataValue::Int32(1)])))); let tuples = NullableVec(inner); let fn_asc_and_nulls_last_eq = |mut iter: Box>| { if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(Some(0))]) + assert_eq!(tuple.values, vec![DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(Some(1))]) + assert_eq!(tuple.values, vec![DataValue::Int32(1)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(None)]) + assert_eq!(tuple.values, vec![DataValue::Null]) } else { unreachable!() } }; let fn_desc_and_nulls_last_eq = |mut iter: Box>| { if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(Some(1))]) + assert_eq!(tuple.values, vec![DataValue::Int32(1)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(Some(0))]) + assert_eq!(tuple.values, vec![DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(None)]) + assert_eq!(tuple.values, vec![DataValue::Null]) } else { unreachable!() } }; let fn_asc_and_nulls_first_eq = |mut iter: Box>| { if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(None)]) + assert_eq!(tuple.values, vec![DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(Some(0))]) + assert_eq!(tuple.values, vec![DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(Some(1))]) + assert_eq!(tuple.values, vec![DataValue::Int32(1)]) } else { unreachable!() } }; let fn_desc_and_nulls_first_eq = |mut iter: Box>| { if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(None)]) + assert_eq!(tuple.values, vec![DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(Some(1))]) + assert_eq!(tuple.values, vec![DataValue::Int32(1)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!(tuple.values, vec![DataValue::Int32(Some(0))]) + assert_eq!(tuple.values, vec![DataValue::Int32(0)]) } else { unreachable!() } @@ -516,91 +507,58 @@ mod test { let mut inner = BumpVec::new_in(&arena); inner.push(Some(( 0_usize, - Tuple::new(None, vec![DataValue::Int32(None), DataValue::Int32(None)]), + Tuple::new(None, vec![DataValue::Null, DataValue::Null]), ))); inner.push(Some(( 1_usize, - Tuple::new( - None, - vec![DataValue::Int32(Some(0)), DataValue::Int32(None)], - ), + Tuple::new(None, vec![DataValue::Int32(0), DataValue::Null]), ))); inner.push(Some(( 2_usize, - Tuple::new( - None, - vec![DataValue::Int32(Some(1)), DataValue::Int32(None)], - ), + Tuple::new(None, vec![DataValue::Int32(1), DataValue::Null]), ))); inner.push(Some(( 3_usize, - Tuple::new( - None, - vec![DataValue::Int32(None), DataValue::Int32(Some(0))], - ), + Tuple::new(None, vec![DataValue::Null, DataValue::Int32(0)]), ))); inner.push(Some(( 4_usize, - Tuple::new( - None, - vec![DataValue::Int32(Some(0)), DataValue::Int32(Some(0))], - ), + Tuple::new(None, vec![DataValue::Int32(0), DataValue::Int32(0)]), ))); inner.push(Some(( 5_usize, - Tuple::new( - None, - vec![DataValue::Int32(Some(1)), DataValue::Int32(Some(0))], - ), + Tuple::new(None, vec![DataValue::Int32(1), DataValue::Int32(0)]), ))); let tuples = NullableVec(inner); let fn_asc_1_and_nulls_first_1_and_asc_2_and_nulls_first_2_eq = |mut iter: Box>| { if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(None), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Null, DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(None), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Null, DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(0), DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(0), DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Int32(0)]) } else { unreachable!() } @@ -608,50 +566,32 @@ mod test { let fn_asc_1_and_nulls_last_1_and_asc_2_and_nulls_first_2_eq = |mut iter: Box>| { if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(0), DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(0), DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(None), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Null, DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(None), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Null, DataValue::Int32(0)]) } else { unreachable!() } @@ -659,50 +599,32 @@ mod test { let fn_desc_1_and_nulls_first_1_and_asc_2_and_nulls_first_2_eq = |mut iter: Box>| { if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(None), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Null, DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(None), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Null, DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(0), DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(0), DataValue::Int32(0)]) } else { unreachable!() } @@ -710,50 +632,32 @@ mod test { let fn_desc_1_and_nulls_last_1_and_asc_2_and_nulls_first_2_eq = |mut iter: Box>| { if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(0), DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(0)), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(0), DataValue::Int32(0)]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(None), DataValue::Int32(None)] - ) + assert_eq!(tuple.values, vec![DataValue::Null, DataValue::Null]) } else { unreachable!() } if let Some(tuple) = iter.next() { - assert_eq!( - tuple.values, - vec![DataValue::Int32(None), DataValue::Int32(Some(0))] - ) + assert_eq!(tuple.values, vec![DataValue::Null, DataValue::Int32(0)]) } else { unreachable!() } diff --git a/src/expression/evaluator.rs b/src/expression/evaluator.rs index bcf77587..262989c8 100644 --- a/src/expression/evaluator.rs +++ b/src/expression/evaluator.rs @@ -17,11 +17,7 @@ macro_rules! eval_to_num { if let Some(num_i32) = $num_expr.eval($tuple)?.cast(&LogicalType::Integer)?.i32() { num_i32 } else { - return Ok(DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }); + return Ok(DataValue::Null); } }; } @@ -91,7 +87,7 @@ impl ScalarExpression { if *negated { is_null = !is_null; } - Ok(DataValue::Boolean(Some(is_null))) + Ok(DataValue::Boolean(is_null)) } ScalarExpression::In { expr, @@ -100,14 +96,14 @@ impl ScalarExpression { } => { let value = expr.eval(tuple)?; if value.is_null() { - return Ok(DataValue::Boolean(None)); + return Ok(DataValue::Null); } let mut is_in = false; for arg in args { let arg_value = arg.eval(tuple)?; if arg_value.is_null() { - return Ok(DataValue::Boolean(None)); + return Ok(DataValue::Null); } if arg_value == value { is_in = true; @@ -117,7 +113,7 @@ impl ScalarExpression { if *negated { is_in = !is_in; } - Ok(DataValue::Boolean(Some(is_in))) + Ok(DataValue::Boolean(is_in)) } ScalarExpression::Unary { expr, evaluator, .. @@ -148,13 +144,13 @@ impl ScalarExpression { value.partial_cmp(&right).map(Ordering::is_le), ) { (Some(true), Some(true)) => true, - (None, _) | (_, None) => return Ok(DataValue::Boolean(None)), + (None, _) | (_, None) => return Ok(DataValue::Null), _ => false, }; if *negated { is_between = !is_between; } - Ok(DataValue::Boolean(Some(is_between))) + Ok(DataValue::Boolean(is_between)) } ScalarExpression::SubString { expr, @@ -165,6 +161,7 @@ impl ScalarExpression { .eval(tuple)? .cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))? .utf8() + .map(String::from) { if let Some(from_expr) = from_expr { let mut from = eval_to_num!(from_expr, tuple).saturating_sub(1); @@ -174,11 +171,7 @@ impl ScalarExpression { from += len_i + 1; } if from > len_i { - return Ok(DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }); + return Ok(DataValue::Null); } string = string.split_off(from as usize); } @@ -188,16 +181,12 @@ impl ScalarExpression { } Ok(DataValue::Utf8 { - value: Some(string), + value: string, ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }) } else { - Ok(DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }) + Ok(DataValue::Null) } } ScalarExpression::Position { expr, in_expr } => { @@ -206,20 +195,20 @@ impl ScalarExpression { .eval(tuple)? .cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))? .utf8() + .map(String::from) .unwrap_or("".to_owned())) }; let pattern = unpack(expr)?; let str = unpack(in_expr)?; - Ok(DataValue::Int32(Some( + Ok(DataValue::Int32( str.find(&pattern).map(|pos| pos as i32 + 1).unwrap_or(0), - ))) + )) } ScalarExpression::Trim { expr, trim_what_expr, trim_where, } => { - let mut value = None; if let Some(string) = expr .eval(tuple)? .cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))? @@ -231,6 +220,7 @@ impl ScalarExpression { .eval(tuple)? .cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))? .utf8() + .map(String::from) .unwrap_or_default(); } let trim_regex = match trim_where { @@ -248,15 +238,16 @@ impl ScalarExpression { .unwrap() } }; - let string_trimmed = trim_regex.replace_all(&string, "$1").to_string(); + let string_trimmed = trim_regex.replace_all(string, "$1").to_string(); - value = Some(string_trimmed) + Ok(DataValue::Utf8 { + value: string_trimmed, + ty: Utf8Type::Variable(None), + unit: CharLengthUnits::Characters, + }) + } else { + Ok(DataValue::Null) } - Ok(DataValue::Utf8 { - value, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }) } ScalarExpression::Reference { pos, .. } => { let Some((tuple, _)) = tuple else { @@ -270,9 +261,7 @@ impl ScalarExpression { for expr in exprs { values.push(expr.eval(tuple)?); } - Ok(DataValue::Tuple( - (!values.is_empty()).then_some((values, false)), - )) + Ok(DataValue::Tuple(values, false)) } ScalarExpression::ScalaFunction(ScalarFunction { inner, args, .. }) => { inner.eval(args, tuple)?.cast(inner.return_type()) diff --git a/src/expression/mod.rs b/src/expression/mod.rs index 4b1b5249..3e30b2a5 100644 --- a/src/expression/mod.rs +++ b/src/expression/mod.rs @@ -1182,13 +1182,15 @@ pub enum UnaryOperator { Not, } -impl From for UnaryOperator { - fn from(value: SqlUnaryOperator) -> Self { +impl TryFrom for UnaryOperator { + type Error = DatabaseError; + + fn try_from(value: SqlUnaryOperator) -> Result { match value { - SqlUnaryOperator::Plus => UnaryOperator::Plus, - SqlUnaryOperator::Minus => UnaryOperator::Minus, - SqlUnaryOperator::Not => UnaryOperator::Not, - _ => unimplemented!("not support!"), + SqlUnaryOperator::Plus => Ok(UnaryOperator::Plus), + SqlUnaryOperator::Minus => Ok(UnaryOperator::Minus), + SqlUnaryOperator::Not => Ok(UnaryOperator::Not), + op => Err(DatabaseError::UnsupportedStmt(format!("{}", op))), } } } @@ -1215,7 +1217,6 @@ pub enum BinaryOperator { And, Or, - Xor, } impl fmt::Display for ScalarExpression { @@ -1249,7 +1250,6 @@ impl fmt::Display for BinaryOperator { BinaryOperator::NotEq => write!(f, "!="), BinaryOperator::And => write!(f, "&&"), BinaryOperator::Or => write!(f, "||"), - BinaryOperator::Xor => write!(f, "^"), BinaryOperator::Like(escape_char) => { write!(f, "like")?; like_op(f, escape_char) @@ -1272,26 +1272,27 @@ impl fmt::Display for UnaryOperator { } } -impl From for BinaryOperator { - fn from(value: SqlBinaryOperator) -> Self { +impl TryFrom for BinaryOperator { + type Error = DatabaseError; + + fn try_from(value: SqlBinaryOperator) -> Result { match value { - SqlBinaryOperator::Plus => BinaryOperator::Plus, - SqlBinaryOperator::Minus => BinaryOperator::Minus, - SqlBinaryOperator::Multiply => BinaryOperator::Multiply, - SqlBinaryOperator::Divide => BinaryOperator::Divide, - SqlBinaryOperator::Modulo => BinaryOperator::Modulo, - SqlBinaryOperator::StringConcat => BinaryOperator::StringConcat, - SqlBinaryOperator::Gt => BinaryOperator::Gt, - SqlBinaryOperator::Lt => BinaryOperator::Lt, - SqlBinaryOperator::GtEq => BinaryOperator::GtEq, - SqlBinaryOperator::LtEq => BinaryOperator::LtEq, - SqlBinaryOperator::Spaceship => BinaryOperator::Spaceship, - SqlBinaryOperator::Eq => BinaryOperator::Eq, - SqlBinaryOperator::NotEq => BinaryOperator::NotEq, - SqlBinaryOperator::And => BinaryOperator::And, - SqlBinaryOperator::Or => BinaryOperator::Or, - SqlBinaryOperator::Xor => BinaryOperator::Xor, - _ => unimplemented!("not support!"), + SqlBinaryOperator::Plus => Ok(BinaryOperator::Plus), + SqlBinaryOperator::Minus => Ok(BinaryOperator::Minus), + SqlBinaryOperator::Multiply => Ok(BinaryOperator::Multiply), + SqlBinaryOperator::Divide => Ok(BinaryOperator::Divide), + SqlBinaryOperator::Modulo => Ok(BinaryOperator::Modulo), + SqlBinaryOperator::StringConcat => Ok(BinaryOperator::StringConcat), + SqlBinaryOperator::Gt => Ok(BinaryOperator::Gt), + SqlBinaryOperator::Lt => Ok(BinaryOperator::Lt), + SqlBinaryOperator::GtEq => Ok(BinaryOperator::GtEq), + SqlBinaryOperator::LtEq => Ok(BinaryOperator::LtEq), + SqlBinaryOperator::Spaceship => Ok(BinaryOperator::Spaceship), + SqlBinaryOperator::Eq => Ok(BinaryOperator::Eq), + SqlBinaryOperator::NotEq => Ok(BinaryOperator::NotEq), + SqlBinaryOperator::And => Ok(BinaryOperator::And), + SqlBinaryOperator::Or => Ok(BinaryOperator::Or), + op => Err(DatabaseError::UnsupportedStmt(format!("{}", op))), } } } @@ -1360,20 +1361,20 @@ mod test { fn_assert( &mut cursor, - ScalarExpression::Constant(DataValue::Int32(None)), + ScalarExpression::Constant(DataValue::Null), Some((&transaction, &table_cache)), &mut reference_tables, )?; fn_assert( &mut cursor, - ScalarExpression::Constant(DataValue::Int32(Some(42))), + ScalarExpression::Constant(DataValue::Int32(42)), Some((&transaction, &table_cache)), &mut reference_tables, )?; fn_assert( &mut cursor, ScalarExpression::Constant(DataValue::Utf8 { - value: Some("hello".to_string()), + value: "hello".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }), diff --git a/src/expression/range_detacher.rs b/src/expression/range_detacher.rs index 2f15d9c2..1590be82 100644 --- a/src/expression/range_detacher.rs +++ b/src/expression/range_detacher.rs @@ -114,7 +114,7 @@ impl Range { } merge_tuple.push(value); - DataValue::Tuple(Some((merge_tuple, is_upper))) + DataValue::Tuple(merge_tuple, is_upper) } fn collect_tuple_range(result_ranges: &mut Vec, tuple: &[&DataValue], range: Range) { fn merge_value_on_bound( @@ -130,7 +130,7 @@ impl Range { return Bound::Unbounded; } let values = tuple.iter().map(|v| (*v).clone()).collect_vec(); - Bound::Excluded(DataValue::Tuple(Some((values, is_upper)))) + Bound::Excluded(DataValue::Tuple(values, is_upper)) } } } @@ -286,7 +286,6 @@ impl<'a> RangeDetacher<'a> { (Range::Dummy, binary) | (binary, Range::Dummy) => match op { BinaryOperator::And => Some(Range::Dummy), BinaryOperator::Or => Some(binary), - BinaryOperator::Xor => todo!(), _ => None, }, // e.g. c1 > 1 ? c1 < 2 @@ -306,7 +305,6 @@ impl<'a> RangeDetacher<'a> { BinaryOperator::Or => Some(Self::or_scope_merge( left_min, left_max, right_min, right_max, )), - BinaryOperator::Xor => todo!(), _ => None, }, // e.g. c1 > 1 ? c1 = 1 @@ -380,7 +378,6 @@ impl<'a> RangeDetacher<'a> { }; Some(range) } - BinaryOperator::Xor => todo!(), _ => None, } } @@ -414,7 +411,6 @@ impl<'a> RangeDetacher<'a> { ranges.push(Range::Eq(val_2)); Some(Range::SortedRanges(ranges)) } - BinaryOperator::Xor => todo!(), _ => None, } } @@ -550,7 +546,6 @@ impl<'a> RangeDetacher<'a> { binary = match op { BinaryOperator::And => return vec![], BinaryOperator::Or => Some(ranges.remove(*idx)), - BinaryOperator::Xor => todo!(), _ => None, }; } @@ -814,7 +809,7 @@ mod test { .detach(&op.predicate) .unwrap(); println!("c1 = 1 => {}", range); - assert_eq!(range, Range::Eq(DataValue::Int32(Some(1)))) + assert_eq!(range, Range::Eq(DataValue::Int32(1))) } { let plan = table_state.plan("select * from t1 where c1 != 1")?; @@ -834,7 +829,7 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), + min: Bound::Excluded(DataValue::Int32(1)), max: Bound::Unbounded, } ) @@ -849,7 +844,7 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Included(DataValue::Int32(Some(1))), + min: Bound::Included(DataValue::Int32(1)), max: Bound::Unbounded, } ) @@ -865,7 +860,7 @@ mod test { range, Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(1))), + max: Bound::Excluded(DataValue::Int32(1)), } ) } @@ -880,7 +875,7 @@ mod test { range, Range::Scope { min: Bound::Unbounded, - max: Bound::Included(DataValue::Int32(Some(1))), + max: Bound::Included(DataValue::Int32(1)), } ) } @@ -894,8 +889,8 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Included(DataValue::Int32(Some(0))), - max: Bound::Excluded(DataValue::Int32(Some(1))), + min: Bound::Included(DataValue::Int32(0)), + max: Bound::Excluded(DataValue::Int32(1)), } ) } @@ -934,8 +929,8 @@ mod test { assert_eq!( range, Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(Some(0))), - Range::Eq(DataValue::Int32(Some(1))), + Range::Eq(DataValue::Int32(0)), + Range::Eq(DataValue::Int32(1)), ]) ) } @@ -946,7 +941,7 @@ mod test { .detach(&op.predicate) .unwrap(); println!("c1 = 1 and c1 = 1 => c1: {}", range); - assert_eq!(range, Range::Eq(DataValue::Int32(Some(1)))) + assert_eq!(range, Range::Eq(DataValue::Int32(1))) } { let plan = table_state.plan("select * from t1 where c1 = 1 or c1 = 1")?; @@ -955,7 +950,7 @@ mod test { .detach(&op.predicate) .unwrap(); println!("c1 = 1 or c1 = 1 => c1: {}", range); - assert_eq!(range, Range::Eq(DataValue::Int32(Some(1)))) + assert_eq!(range, Range::Eq(DataValue::Int32(1))) } { @@ -974,7 +969,7 @@ mod test { .detach(&op.predicate) .unwrap(); println!("c1 >= 1 and c1 = 1 => c1: {}", range); - assert_eq!(range, Range::Eq(DataValue::Int32(Some(1)))) + assert_eq!(range, Range::Eq(DataValue::Int32(1))) } { let plan = table_state.plan("select * from t1 where c1 > 1 or c1 = 1")?; @@ -986,7 +981,7 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Included(DataValue::Int32(Some(1))), + min: Bound::Included(DataValue::Int32(1)), max: Bound::Unbounded, } ) @@ -1001,7 +996,7 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Included(DataValue::Int32(Some(1))), + min: Bound::Included(DataValue::Int32(1)), max: Bound::Unbounded, } ) @@ -1021,8 +1016,8 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), - max: Bound::Excluded(DataValue::Int32(Some(3))), + min: Bound::Excluded(DataValue::Int32(1)), + max: Bound::Excluded(DataValue::Int32(3)), } ) } @@ -1040,8 +1035,8 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(0))), - max: Bound::Excluded(DataValue::Int32(Some(4))), + min: Bound::Excluded(DataValue::Int32(0)), + max: Bound::Excluded(DataValue::Int32(4)), } ) } @@ -1089,10 +1084,10 @@ mod test { assert_eq!( range, Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(Some(0))), + Range::Eq(DataValue::Int32(0)), Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), - max: Bound::Excluded(DataValue::Int32(Some(3))), + min: Bound::Excluded(DataValue::Int32(1)), + max: Bound::Excluded(DataValue::Int32(3)), } ]) ) @@ -1112,8 +1107,8 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Included(DataValue::Int32(Some(0))), - max: Bound::Excluded(DataValue::Int32(Some(4))), + min: Bound::Included(DataValue::Int32(0)), + max: Bound::Excluded(DataValue::Int32(4)), } ) } @@ -1137,8 +1132,8 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Included(DataValue::Int32(Some(0))), - max: Bound::Included(DataValue::Int32(Some(2))), + min: Bound::Included(DataValue::Int32(0)), + max: Bound::Included(DataValue::Int32(2)), } ) } @@ -1154,12 +1149,12 @@ mod test { range, Range::SortedRanges(vec![ Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), - max: Bound::Excluded(DataValue::Int32(Some(2))), + min: Bound::Excluded(DataValue::Int32(1)), + max: Bound::Excluded(DataValue::Int32(2)), }, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(5))), - max: Bound::Excluded(DataValue::Int32(Some(6))), + min: Bound::Excluded(DataValue::Int32(5)), + max: Bound::Excluded(DataValue::Int32(6)), }, ]) ) @@ -1175,12 +1170,12 @@ mod test { range, Range::SortedRanges(vec![ Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(0))), - max: Bound::Excluded(DataValue::Int32(Some(3))), + min: Bound::Excluded(DataValue::Int32(0)), + max: Bound::Excluded(DataValue::Int32(3)), }, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(4))), - max: Bound::Excluded(DataValue::Int32(Some(7))), + min: Bound::Excluded(DataValue::Int32(4)), + max: Bound::Excluded(DataValue::Int32(7)), }, ]) ) @@ -1235,8 +1230,8 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Included(DataValue::Int32(Some(5))), - max: Bound::Excluded(DataValue::Int32(Some(12))), + min: Bound::Included(DataValue::Int32(5)), + max: Bound::Excluded(DataValue::Int32(12)), } ) } @@ -1258,10 +1253,10 @@ mod test { Range::SortedRanges(vec![ Range::Scope { min: Bound::Unbounded, - max: Bound::Included(DataValue::Int32(Some(-4))), + max: Bound::Included(DataValue::Int32(-4)), }, Range::Scope { - min: Bound::Included(DataValue::Int32(Some(0))), + min: Bound::Included(DataValue::Int32(0)), max: Bound::Unbounded, } ]) @@ -1283,7 +1278,7 @@ mod test { .detach(&op.predicate) .unwrap(); println!("c1 = null => c1: {}", range); - assert_eq!(range, Range::Eq(DataValue::Int32(None))) + assert_eq!(range, Range::Eq(DataValue::Null)) } { let plan = table_state.plan("select * from t1 where c1 = null or c1 = 1")?; @@ -1295,8 +1290,8 @@ mod test { assert_eq!( range, Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(None)), - Range::Eq(DataValue::Int32(Some(1))) + Range::Eq(DataValue::Null), + Range::Eq(DataValue::Int32(1)) ]) ) } @@ -1311,7 +1306,7 @@ mod test { range, Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(5))), + max: Bound::Excluded(DataValue::Int32(5)), } ) } @@ -1326,10 +1321,10 @@ mod test { assert_eq!( range, Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(None)), + Range::Eq(DataValue::Null), Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), - max: Bound::Excluded(DataValue::Int32(Some(5))), + min: Bound::Excluded(DataValue::Int32(1)), + max: Bound::Excluded(DataValue::Int32(5)), }, ]) ) @@ -1341,7 +1336,7 @@ mod test { .detach(&op.predicate) .unwrap(); println!("c1 = null and c1 < 5 => c1: {}", range); - assert_eq!(range, Range::Eq(DataValue::Int32(None))) + assert_eq!(range, Range::Eq(DataValue::Null)) } { let plan = @@ -1398,7 +1393,7 @@ mod test { range, Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(5))), + max: Bound::Excluded(DataValue::Int32(5)), } ) } @@ -1413,8 +1408,8 @@ mod test { assert_eq!( range, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), - max: Bound::Excluded(DataValue::Int32(Some(5))), + min: Bound::Excluded(DataValue::Int32(1)), + max: Bound::Excluded(DataValue::Int32(5)), } ) } @@ -1428,14 +1423,14 @@ mod test { assert_eq!( range, Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(None)), + Range::Eq(DataValue::Null), Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(0))), - max: Bound::Excluded(DataValue::Int32(Some(3))), + min: Bound::Excluded(DataValue::Int32(0)), + max: Bound::Excluded(DataValue::Int32(3)), }, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(4))), - max: Bound::Excluded(DataValue::Int32(Some(7))), + min: Bound::Excluded(DataValue::Int32(4)), + max: Bound::Excluded(DataValue::Int32(7)), } ]) ) @@ -1450,14 +1445,14 @@ mod test { assert_eq!( range, Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(None)), + Range::Eq(DataValue::Null), Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(0))), - max: Bound::Excluded(DataValue::Int32(Some(3))), + min: Bound::Excluded(DataValue::Int32(0)), + max: Bound::Excluded(DataValue::Int32(3)), }, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(4))), - max: Bound::Excluded(DataValue::Int32(Some(7))), + min: Bound::Excluded(DataValue::Int32(4)), + max: Bound::Excluded(DataValue::Int32(7)), } ]) ) @@ -1473,12 +1468,12 @@ mod test { range, Range::SortedRanges(vec![ Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), - max: Bound::Excluded(DataValue::Int32(Some(2))), + min: Bound::Excluded(DataValue::Int32(1)), + max: Bound::Excluded(DataValue::Int32(2)), }, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(5))), - max: Bound::Excluded(DataValue::Int32(Some(6))), + min: Bound::Excluded(DataValue::Int32(5)), + max: Bound::Excluded(DataValue::Int32(6)), } ]) ) @@ -1494,12 +1489,12 @@ mod test { range, Range::SortedRanges(vec![ Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), - max: Bound::Excluded(DataValue::Int32(Some(2))), + min: Bound::Excluded(DataValue::Int32(1)), + max: Bound::Excluded(DataValue::Int32(2)), }, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(5))), - max: Bound::Excluded(DataValue::Int32(Some(6))), + min: Bound::Excluded(DataValue::Int32(5)), + max: Bound::Excluded(DataValue::Int32(6)), } ]) ) @@ -1511,20 +1506,20 @@ mod test { #[test] fn test_to_tuple_range_some() { let eqs_ranges = vec![ - Range::Eq(DataValue::Int32(Some(1))), + Range::Eq(DataValue::Int32(1)), Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(None)), - Range::Eq(DataValue::Int32(Some(1))), - Range::Eq(DataValue::Int32(Some(2))), + Range::Eq(DataValue::Null), + Range::Eq(DataValue::Int32(1)), + Range::Eq(DataValue::Int32(2)), ]), Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(Some(1))), - Range::Eq(DataValue::Int32(Some(2))), + Range::Eq(DataValue::Int32(1)), + Range::Eq(DataValue::Int32(2)), ]), ]; let range = Range::Scope { - min: Bound::Included(DataValue::Int32(Some(1))), + min: Bound::Included(DataValue::Int32(1)), max: Bound::Unbounded, } .combining_eqs(&eqs_ranges); @@ -1533,125 +1528,117 @@ mod test { range, Some(Range::SortedRanges(vec![ Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Null, + DataValue::Int32(1), + DataValue::Int32(1), ], false - )))), - max: Bound::Excluded(DataValue::Tuple(Some(( - vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(1)), - ], + )), + max: Bound::Excluded(DataValue::Tuple( + vec![DataValue::Int32(1), DataValue::Null, DataValue::Int32(1),], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Null, + DataValue::Int32(2), + DataValue::Int32(1), ], false - )))), - max: Bound::Excluded(DataValue::Tuple(Some(( - vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(2)), - ], + )), + max: Bound::Excluded(DataValue::Tuple( + vec![DataValue::Int32(1), DataValue::Null, DataValue::Int32(2),], true - )))), + )) }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), ], false - )))), - max: Bound::Excluded(DataValue::Tuple(Some(( + )), + max: Bound::Excluded(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), ], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), ], false - )))), - max: Bound::Excluded(DataValue::Tuple(Some(( + )), + max: Bound::Excluded(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(2), ], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), + DataValue::Int32(1), ], false - )))), - max: Bound::Excluded(DataValue::Tuple(Some(( + )), + max: Bound::Excluded(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), ], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(2), + DataValue::Int32(1), ], false - )))), - max: Bound::Excluded(DataValue::Tuple(Some(( + )), + max: Bound::Excluded(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(2), ], true - )))), + )), }, ])) ); let range = Range::Scope { min: Bound::Unbounded, - max: Bound::Included(DataValue::Int32(Some(1))), + max: Bound::Included(DataValue::Int32(1)), } .combining_eqs(&eqs_ranges); @@ -1659,125 +1646,117 @@ mod test { range, Some(Range::SortedRanges(vec![ Range::Scope { - min: Bound::Excluded(DataValue::Tuple(Some(( - vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(1)), - ], + min: Bound::Excluded(DataValue::Tuple( + vec![DataValue::Int32(1), DataValue::Null, DataValue::Int32(1),], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Null, + DataValue::Int32(1), + DataValue::Int32(1), ], true - )))), + )), }, Range::Scope { - min: Bound::Excluded(DataValue::Tuple(Some(( - vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(2)), - ], + min: Bound::Excluded(DataValue::Tuple( + vec![DataValue::Int32(1), DataValue::Null, DataValue::Int32(2),], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Null, + DataValue::Int32(2), + DataValue::Int32(1), ], true - )))), + )), }, Range::Scope { - min: Bound::Excluded(DataValue::Tuple(Some(( + min: Bound::Excluded(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), ], true - )))), + )), }, Range::Scope { - min: Bound::Excluded(DataValue::Tuple(Some(( + min: Bound::Excluded(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(2), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), ], true - )))), + )), }, Range::Scope { - min: Bound::Excluded(DataValue::Tuple(Some(( + min: Bound::Excluded(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), + DataValue::Int32(1), ], true - )))), + )), }, Range::Scope { - min: Bound::Excluded(DataValue::Tuple(Some(( + min: Bound::Excluded(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(2), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(2), + DataValue::Int32(1), ], true - )))), + )), }, ])) ); let range = Range::Scope { - min: Bound::Included(DataValue::Int32(Some(1))), - max: Bound::Included(DataValue::Int32(Some(2))), + min: Bound::Included(DataValue::Int32(1)), + max: Bound::Included(DataValue::Int32(2)), } .combining_eqs(&eqs_ranges); @@ -1785,124 +1764,124 @@ mod test { range, Some(Range::SortedRanges(vec![ Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Null, + DataValue::Int32(1), + DataValue::Int32(1), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Null, + DataValue::Int32(1), + DataValue::Int32(2), ], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Null, + DataValue::Int32(2), + DataValue::Int32(1), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(None), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Null, + DataValue::Int32(2), + DataValue::Int32(2), ], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(2), ], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(2), ], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), + DataValue::Int32(1), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(1), + DataValue::Int32(2), ], true - )))), + )), }, Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(2), + DataValue::Int32(1), ], false - )))), - max: Bound::Included(DataValue::Tuple(Some(( + )), + max: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(1)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(2)), + DataValue::Int32(1), + DataValue::Int32(2), + DataValue::Int32(2), + DataValue::Int32(2), ], true - )))), + )), }, ])) ) @@ -1911,28 +1890,28 @@ mod test { #[test] fn test_to_tuple_range_none() { let range = Range::Scope { - min: Bound::Included(DataValue::Int32(Some(2))), + min: Bound::Included(DataValue::Int32(2)), max: Bound::Unbounded, } .combining_eqs(&[ - Range::Eq(DataValue::Int32(Some(7))), - Range::Eq(DataValue::Int32(Some(10))), + Range::Eq(DataValue::Int32(7)), + Range::Eq(DataValue::Int32(10)), ]); assert_eq!( range, Some(Range::Scope { - min: Bound::Included(DataValue::Tuple(Some(( + min: Bound::Included(DataValue::Tuple( vec![ - DataValue::Int32(Some(7)), - DataValue::Int32(Some(10)), - DataValue::Int32(Some(2)) + DataValue::Int32(7), + DataValue::Int32(10), + DataValue::Int32(2) ], false - )))), - max: Bound::Excluded(DataValue::Tuple(Some(( - vec![DataValue::Int32(Some(7)), DataValue::Int32(Some(10))], + )), + max: Bound::Excluded(DataValue::Tuple( + vec![DataValue::Int32(7), DataValue::Int32(10)], true - )))), + )), }) ); let Range::Scope { @@ -1944,7 +1923,7 @@ mod test { }; assert_eq!( TupleLtBinaryEvaluator.binary_eval(&min, &max), - DataValue::Boolean(Some(true)) + DataValue::Boolean(true) ) } } diff --git a/src/expression/simplify.rs b/src/expression/simplify.rs index 5b1ac50e..9db3d0de 100644 --- a/src/expression/simplify.rs +++ b/src/expression/simplify.rs @@ -156,11 +156,9 @@ impl ScalarExpression { ScalarExpression::TypeCast { expr, ty, .. } => { expr.unpack_val().and_then(|val| val.cast(ty).ok()) } - ScalarExpression::IsNull { expr, .. } => { - let is_null = expr.unpack_val().map(|val| val.is_null()); - - Some(DataValue::Boolean(is_null)) - } + ScalarExpression::IsNull { expr, .. } => expr + .unpack_val() + .map(|val| DataValue::Boolean(val.is_null())), ScalarExpression::Unary { expr, op, @@ -474,7 +472,7 @@ impl ScalarExpression { if let Some(val) = expr.unpack_val() { let _ = mem::replace( self, - ScalarExpression::Constant(DataValue::Boolean(Some(val.is_null()))), + ScalarExpression::Constant(DataValue::Boolean(val.is_null())), ); } } diff --git a/src/function/char_length.rs b/src/function/char_length.rs index dd5b7693..6cf0c100 100644 --- a/src/function/char_length.rs +++ b/src/function/char_length.rs @@ -42,15 +42,10 @@ impl ScalarFunctionImpl for CharLength { value = value.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?; } let mut length: u64 = 0; - if let DataValue::Utf8 { - value: Some(value), - ty, - unit, - } = &mut value - { + if let DataValue::Utf8 { value, ty, unit } = &mut value { length = value.len() as u64; } - Ok(DataValue::UInt64(Some(length))) + Ok(DataValue::UInt64(length)) } fn monotonicity(&self) -> Option { diff --git a/src/function/current_date.rs b/src/function/current_date.rs index f1519a93..f48e128b 100644 --- a/src/function/current_date.rs +++ b/src/function/current_date.rs @@ -39,7 +39,7 @@ impl ScalarFunctionImpl for CurrentDate { _: &[ScalarExpression], _: Option<(&Tuple, &[ColumnRef])>, ) -> Result { - Ok(DataValue::Date32(Some(Local::now().num_days_from_ce()))) + Ok(DataValue::Date32(Local::now().num_days_from_ce())) } fn monotonicity(&self) -> Option { diff --git a/src/function/lower.rs b/src/function/lower.rs index 57aa83fc..91bcae26 100644 --- a/src/function/lower.rs +++ b/src/function/lower.rs @@ -43,12 +43,7 @@ impl ScalarFunctionImpl for Lower { if !matches!(value.logical_type(), LogicalType::Varchar(_, _)) { value = value.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?; } - if let DataValue::Utf8 { - value: Some(value), - ty, - unit, - } = &mut value - { + if let DataValue::Utf8 { value, ty, unit } = &mut value { *value = value.to_lowercase(); } Ok(value) diff --git a/src/function/numbers.rs b/src/function/numbers.rs index d5e7cfd5..c0847dc1 100644 --- a/src/function/numbers.rs +++ b/src/function/numbers.rs @@ -60,7 +60,7 @@ impl TableFunctionImpl for Numbers { let num = value.i32().ok_or(DatabaseError::NotNull)?; Ok( - Box::new((0..num).map(|i| Ok(Tuple::new(None, vec![DataValue::Int32(Some(i))])))) + Box::new((0..num).map(|i| Ok(Tuple::new(None, vec![DataValue::Int32(i)])))) as Box>>, ) } diff --git a/src/function/upper.rs b/src/function/upper.rs index 29a3e9b5..d41200b8 100644 --- a/src/function/upper.rs +++ b/src/function/upper.rs @@ -43,12 +43,7 @@ impl ScalarFunctionImpl for Upper { if !matches!(value.logical_type(), LogicalType::Varchar(_, _)) { value = value.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?; } - if let DataValue::Utf8 { - value: Some(value), - ty, - unit, - } = &mut value - { + if let DataValue::Utf8 { value, ty, unit } = &mut value { *value = value.to_uppercase(); } Ok(value) diff --git a/src/optimizer/core/cm_sketch.rs b/src/optimizer/core/cm_sketch.rs index bb009b31..2dc78435 100644 --- a/src/optimizer/core/cm_sketch.rs +++ b/src/optimizer/core/cm_sketch.rs @@ -230,11 +230,11 @@ mod tests { fn test_collect_count() { let mut cms = CountMinSketch::::new(100, 0.95, 10.0); for _ in 0..300 { - cms.increment(&DataValue::Int32(Some(300))); + cms.increment(&DataValue::Int32(300)); } assert_eq!( cms.collect_count(&vec![ - Range::Eq(DataValue::Int32(Some(300))), + Range::Eq(DataValue::Int32(300)), Range::Scope { min: Bound::Unbounded, max: Bound::Unbounded, diff --git a/src/optimizer/core/histogram.rs b/src/optimizer/core/histogram.rs index fb66ae21..37c03395 100644 --- a/src/optimizer/core/histogram.rs +++ b/src/optimizer/core/histogram.rs @@ -216,7 +216,7 @@ fn is_under( }, )?; let value = evaluator.0.binary_eval(value, target); - Ok::(matches!(value, DataValue::Boolean(Some(true)))) + Ok::(matches!(value, DataValue::Boolean(true))) }; Ok(match target { @@ -241,7 +241,7 @@ fn is_above( }, )?; let value = evaluator.0.binary_eval(value, target); - Ok::(matches!(value, DataValue::Boolean(Some(true)))) + Ok::(matches!(value, DataValue::Boolean(true))) }; Ok(match target { Bound::Included(target) => _is_above(value, target, is_min)?, @@ -306,27 +306,27 @@ impl Histogram { let float_value = |value: &DataValue, prefix_len: usize| { let value = match value.logical_type() { LogicalType::Varchar(..) | LogicalType::Char(..) => match value { - DataValue::Utf8 { value, .. } => value.as_ref().map(|string| { - if prefix_len > string.len() { - return 0.0; + DataValue::Utf8 { value, .. } => { + if prefix_len > value.len() { + return Ok(0.0); } let mut val = 0u64; - for (i, char) in string + for (i, char) in value .get(prefix_len..prefix_len + 8) .unwrap() .chars() .enumerate() { - if string.len() - prefix_len > i { + if value.len() - prefix_len > i { val += (val << 8) + char as u64; } else { val += val << 8; } } - val as f64 - }), + Some(val as f64) + } _ => unreachable!(), }, LogicalType::Date | LogicalType::DateTime | LogicalType::Time => match value { @@ -357,7 +357,7 @@ impl Histogram { | LogicalType::Double | LogicalType::Decimal(_, _) => value.clone().cast(&LogicalType::Double)?.double(), LogicalType::Tuple(_) => match value { - DataValue::Tuple(Some((values, _))) => { + DataValue::Tuple(values, _) => { let mut float = 0.0; for (i, value) in values.iter().enumerate() { @@ -372,7 +372,7 @@ impl Histogram { } Some(float) } - DataValue::Tuple(None) => None, + DataValue::Null => None, _ => unreachable!(), }, } @@ -392,6 +392,11 @@ impl Histogram { match &ranges[*binary_i] { Range::Scope { min, max } => { let bucket = &self.buckets[*bucket_i]; + let mut bucket_count = bucket.count as usize; + if *bucket_i == 0 { + bucket_count += self.null_count; + } + let mut temp_count = 0; let is_eq = |value: &DataValue, target: &Bound| match target { @@ -419,7 +424,7 @@ impl Histogram { Bound::Unbounded => unreachable!(), }; let ratio = *distinct_1.max(OrderedFloat(temp_ratio).min(OrderedFloat(1.0))); - temp_count += (bucket.count as f64 * ratio).ceil() as usize; + temp_count += (bucket_count as f64 * ratio).ceil() as usize; if let Some(count) = option { temp_count = temp_count.saturating_sub(count); } @@ -436,7 +441,7 @@ impl Histogram { Bound::Unbounded => unreachable!(), }; let ratio = *distinct_1.max(OrderedFloat(temp_ratio).min(OrderedFloat(1.0))); - temp_count += (bucket.count as f64 * (1.0 - ratio)).ceil() as usize; + temp_count += (bucket_count as f64 * (1.0 - ratio)).ceil() as usize; if let Some(count) = option { temp_count = temp_count.saturating_sub(count); } @@ -464,7 +469,7 @@ impl Histogram { }; let ratio = *distinct_1 .max(OrderedFloat(temp_ratio_max - temp_ratio_min).min(OrderedFloat(1.0))); - temp_count += (bucket.count as f64 * ratio).ceil() as usize; + temp_count += (bucket_count as f64 * ratio).ceil() as usize; if let Some(count) = option_max { temp_count = temp_count.saturating_sub(count); } @@ -527,26 +532,26 @@ mod tests { fn test_sort_tuples_on_histogram() -> Result<(), DatabaseError> { let mut builder = HistogramBuilder::new(&index_meta(), Some(15)); - builder.append(&DataValue::Int32(Some(0)))?; - builder.append(&DataValue::Int32(Some(1)))?; - builder.append(&DataValue::Int32(Some(2)))?; - builder.append(&DataValue::Int32(Some(3)))?; - builder.append(&DataValue::Int32(Some(4)))?; + builder.append(&DataValue::Int32(0))?; + builder.append(&DataValue::Int32(1))?; + builder.append(&DataValue::Int32(2))?; + builder.append(&DataValue::Int32(3))?; + builder.append(&DataValue::Int32(4))?; - builder.append(&DataValue::Int32(Some(5)))?; - builder.append(&DataValue::Int32(Some(6)))?; - builder.append(&DataValue::Int32(Some(7)))?; - builder.append(&DataValue::Int32(Some(8)))?; - builder.append(&DataValue::Int32(Some(9)))?; + builder.append(&DataValue::Int32(5))?; + builder.append(&DataValue::Int32(6))?; + builder.append(&DataValue::Int32(7))?; + builder.append(&DataValue::Int32(8))?; + builder.append(&DataValue::Int32(9))?; - builder.append(&DataValue::Int32(Some(10)))?; - builder.append(&DataValue::Int32(Some(11)))?; - builder.append(&DataValue::Int32(Some(12)))?; - builder.append(&DataValue::Int32(Some(13)))?; - builder.append(&DataValue::Int32(Some(14)))?; + builder.append(&DataValue::Int32(10))?; + builder.append(&DataValue::Int32(11))?; + builder.append(&DataValue::Int32(12))?; + builder.append(&DataValue::Int32(13))?; + builder.append(&DataValue::Int32(14))?; builder.append(&DataValue::Null)?; - builder.append(&DataValue::Int32(None))?; + builder.append(&DataValue::Null)?; // assert!(matches!(builder.build(10), Err(DataBaseError::TooManyBuckets))); @@ -559,28 +564,28 @@ mod tests { histogram.buckets, vec![ Bucket { - lower: DataValue::Int32(Some(0)), - upper: DataValue::Int32(Some(2)), + lower: DataValue::Int32(0), + upper: DataValue::Int32(2), count: 3, }, Bucket { - lower: DataValue::Int32(Some(3)), - upper: DataValue::Int32(Some(5)), + lower: DataValue::Int32(3), + upper: DataValue::Int32(5), count: 3, }, Bucket { - lower: DataValue::Int32(Some(6)), - upper: DataValue::Int32(Some(8)), + lower: DataValue::Int32(6), + upper: DataValue::Int32(8), count: 3, }, Bucket { - lower: DataValue::Int32(Some(9)), - upper: DataValue::Int32(Some(11)), + lower: DataValue::Int32(9), + upper: DataValue::Int32(11), count: 3, }, Bucket { - lower: DataValue::Int32(Some(12)), - upper: DataValue::Int32(Some(14)), + lower: DataValue::Int32(12), + upper: DataValue::Int32(14), count: 3, }, ] @@ -593,26 +598,26 @@ mod tests { fn test_rev_sort_tuples_on_histogram() -> Result<(), DatabaseError> { let mut builder = HistogramBuilder::new(&index_meta(), Some(15)); - builder.append(&DataValue::Int32(Some(14)))?; - builder.append(&DataValue::Int32(Some(13)))?; - builder.append(&DataValue::Int32(Some(12)))?; - builder.append(&DataValue::Int32(Some(11)))?; - builder.append(&DataValue::Int32(Some(10)))?; + builder.append(&DataValue::Int32(14))?; + builder.append(&DataValue::Int32(13))?; + builder.append(&DataValue::Int32(12))?; + builder.append(&DataValue::Int32(11))?; + builder.append(&DataValue::Int32(10))?; - builder.append(&DataValue::Int32(Some(9)))?; - builder.append(&DataValue::Int32(Some(8)))?; - builder.append(&DataValue::Int32(Some(7)))?; - builder.append(&DataValue::Int32(Some(6)))?; - builder.append(&DataValue::Int32(Some(5)))?; + builder.append(&DataValue::Int32(9))?; + builder.append(&DataValue::Int32(8))?; + builder.append(&DataValue::Int32(7))?; + builder.append(&DataValue::Int32(6))?; + builder.append(&DataValue::Int32(5))?; - builder.append(&DataValue::Int32(Some(4)))?; - builder.append(&DataValue::Int32(Some(3)))?; - builder.append(&DataValue::Int32(Some(2)))?; - builder.append(&DataValue::Int32(Some(1)))?; - builder.append(&DataValue::Int32(Some(0)))?; + builder.append(&DataValue::Int32(4))?; + builder.append(&DataValue::Int32(3))?; + builder.append(&DataValue::Int32(2))?; + builder.append(&DataValue::Int32(1))?; + builder.append(&DataValue::Int32(0))?; builder.append(&DataValue::Null)?; - builder.append(&DataValue::Int32(None))?; + builder.append(&DataValue::Null)?; let (histogram, _) = builder.build(5)?; @@ -623,28 +628,28 @@ mod tests { histogram.buckets, vec![ Bucket { - lower: DataValue::Int32(Some(0)), - upper: DataValue::Int32(Some(2)), + lower: DataValue::Int32(0), + upper: DataValue::Int32(2), count: 3, }, Bucket { - lower: DataValue::Int32(Some(3)), - upper: DataValue::Int32(Some(5)), + lower: DataValue::Int32(3), + upper: DataValue::Int32(5), count: 3, }, Bucket { - lower: DataValue::Int32(Some(6)), - upper: DataValue::Int32(Some(8)), + lower: DataValue::Int32(6), + upper: DataValue::Int32(8), count: 3, }, Bucket { - lower: DataValue::Int32(Some(9)), - upper: DataValue::Int32(Some(11)), + lower: DataValue::Int32(9), + upper: DataValue::Int32(11), count: 3, }, Bucket { - lower: DataValue::Int32(Some(12)), - upper: DataValue::Int32(Some(14)), + lower: DataValue::Int32(12), + upper: DataValue::Int32(14), count: 3, }, ] @@ -657,26 +662,26 @@ mod tests { fn test_non_average_on_histogram() -> Result<(), DatabaseError> { let mut builder = HistogramBuilder::new(&index_meta(), Some(15)); - builder.append(&DataValue::Int32(Some(14)))?; - builder.append(&DataValue::Int32(Some(13)))?; - builder.append(&DataValue::Int32(Some(12)))?; - builder.append(&DataValue::Int32(Some(11)))?; - builder.append(&DataValue::Int32(Some(10)))?; + builder.append(&DataValue::Int32(14))?; + builder.append(&DataValue::Int32(13))?; + builder.append(&DataValue::Int32(12))?; + builder.append(&DataValue::Int32(11))?; + builder.append(&DataValue::Int32(10))?; - builder.append(&DataValue::Int32(Some(4)))?; - builder.append(&DataValue::Int32(Some(3)))?; - builder.append(&DataValue::Int32(Some(2)))?; - builder.append(&DataValue::Int32(Some(1)))?; - builder.append(&DataValue::Int32(Some(0)))?; + builder.append(&DataValue::Int32(4))?; + builder.append(&DataValue::Int32(3))?; + builder.append(&DataValue::Int32(2))?; + builder.append(&DataValue::Int32(1))?; + builder.append(&DataValue::Int32(0))?; - builder.append(&DataValue::Int32(Some(9)))?; - builder.append(&DataValue::Int32(Some(8)))?; - builder.append(&DataValue::Int32(Some(7)))?; - builder.append(&DataValue::Int32(Some(6)))?; - builder.append(&DataValue::Int32(Some(5)))?; + builder.append(&DataValue::Int32(9))?; + builder.append(&DataValue::Int32(8))?; + builder.append(&DataValue::Int32(7))?; + builder.append(&DataValue::Int32(6))?; + builder.append(&DataValue::Int32(5))?; builder.append(&DataValue::Null)?; - builder.append(&DataValue::Int32(None))?; + builder.append(&DataValue::Null)?; let (histogram, _) = builder.build(4)?; @@ -687,23 +692,23 @@ mod tests { histogram.buckets, vec![ Bucket { - lower: DataValue::Int32(Some(0)), - upper: DataValue::Int32(Some(3)), + lower: DataValue::Int32(0), + upper: DataValue::Int32(3), count: 4, }, Bucket { - lower: DataValue::Int32(Some(4)), - upper: DataValue::Int32(Some(7)), + lower: DataValue::Int32(4), + upper: DataValue::Int32(7), count: 4, }, Bucket { - lower: DataValue::Int32(Some(8)), - upper: DataValue::Int32(Some(11)), + lower: DataValue::Int32(8), + upper: DataValue::Int32(11), count: 4, }, Bucket { - lower: DataValue::Int32(Some(12)), - upper: DataValue::Int32(Some(14)), + lower: DataValue::Int32(12), + upper: DataValue::Int32(14), count: 3, }, ] @@ -716,35 +721,34 @@ mod tests { fn test_collect_count() -> Result<(), DatabaseError> { let mut builder = HistogramBuilder::new(&index_meta(), Some(15)); - builder.append(&DataValue::Int32(Some(14)))?; - builder.append(&DataValue::Int32(Some(13)))?; - builder.append(&DataValue::Int32(Some(12)))?; - builder.append(&DataValue::Int32(Some(11)))?; - builder.append(&DataValue::Int32(Some(10)))?; + builder.append(&DataValue::Int32(14))?; + builder.append(&DataValue::Int32(13))?; + builder.append(&DataValue::Int32(12))?; + builder.append(&DataValue::Int32(11))?; + builder.append(&DataValue::Int32(10))?; - builder.append(&DataValue::Int32(Some(4)))?; - builder.append(&DataValue::Int32(Some(3)))?; - builder.append(&DataValue::Int32(Some(2)))?; - builder.append(&DataValue::Int32(Some(1)))?; - builder.append(&DataValue::Int32(Some(0)))?; + builder.append(&DataValue::Int32(4))?; + builder.append(&DataValue::Int32(3))?; + builder.append(&DataValue::Int32(2))?; + builder.append(&DataValue::Int32(1))?; + builder.append(&DataValue::Int32(0))?; - builder.append(&DataValue::Int32(Some(9)))?; - builder.append(&DataValue::Int32(Some(8)))?; - builder.append(&DataValue::Int32(Some(7)))?; - builder.append(&DataValue::Int32(Some(6)))?; - builder.append(&DataValue::Int32(Some(5)))?; + builder.append(&DataValue::Int32(9))?; + builder.append(&DataValue::Int32(8))?; + builder.append(&DataValue::Int32(7))?; + builder.append(&DataValue::Int32(6))?; + builder.append(&DataValue::Int32(5))?; builder.append(&DataValue::Null)?; - builder.append(&DataValue::Int32(None))?; let (histogram, sketch) = builder.build(4)?; let count_1 = histogram.collect_count( &vec![ - Range::Eq(DataValue::Int32(Some(2))), + Range::Eq(DataValue::Int32(2)), Range::Scope { - min: Bound::Included(DataValue::Int32(Some(4))), - max: Bound::Excluded(DataValue::Int32(Some(12))), + min: Bound::Included(DataValue::Int32(4)), + max: Bound::Excluded(DataValue::Int32(12)), }, ], &sketch, @@ -754,7 +758,7 @@ mod tests { let count_2 = histogram.collect_count( &vec![Range::Scope { - min: Bound::Included(DataValue::Int32(Some(4))), + min: Bound::Included(DataValue::Int32(4)), max: Bound::Unbounded, }], &sketch, @@ -764,7 +768,7 @@ mod tests { let count_3 = histogram.collect_count( &vec![Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(7))), + min: Bound::Excluded(DataValue::Int32(7)), max: Bound::Unbounded, }], &sketch, @@ -775,7 +779,7 @@ mod tests { let count_4 = histogram.collect_count( &vec![Range::Scope { min: Bound::Unbounded, - max: Bound::Included(DataValue::Int32(Some(11))), + max: Bound::Included(DataValue::Int32(11)), }], &sketch, )?; @@ -785,7 +789,7 @@ mod tests { let count_5 = histogram.collect_count( &vec![Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(8))), + max: Bound::Excluded(DataValue::Int32(8)), }], &sketch, )?; @@ -794,7 +798,7 @@ mod tests { let count_6 = histogram.collect_count( &vec![Range::Scope { - min: Bound::Included(DataValue::Int32(Some(2))), + min: Bound::Included(DataValue::Int32(2)), max: Bound::Unbounded, }], &sketch, @@ -804,7 +808,7 @@ mod tests { let count_7 = histogram.collect_count( &vec![Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), + min: Bound::Excluded(DataValue::Int32(1)), max: Bound::Unbounded, }], &sketch, @@ -815,7 +819,7 @@ mod tests { let count_8 = histogram.collect_count( &vec![Range::Scope { min: Bound::Unbounded, - max: Bound::Included(DataValue::Int32(Some(12))), + max: Bound::Included(DataValue::Int32(12)), }], &sketch, )?; @@ -825,7 +829,7 @@ mod tests { let count_9 = histogram.collect_count( &vec![Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(13))), + max: Bound::Excluded(DataValue::Int32(13)), }], &sketch, )?; @@ -834,18 +838,18 @@ mod tests { let count_10 = histogram.collect_count( &vec![Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(0))), - max: Bound::Excluded(DataValue::Int32(Some(3))), + min: Bound::Excluded(DataValue::Int32(0)), + max: Bound::Excluded(DataValue::Int32(3)), }], &sketch, )?; - assert_eq!(count_10, 2); + assert_eq!(count_10, 3); let count_11 = histogram.collect_count( &vec![Range::Scope { - min: Bound::Included(DataValue::Int32(Some(1))), - max: Bound::Included(DataValue::Int32(Some(2))), + min: Bound::Included(DataValue::Int32(1)), + max: Bound::Included(DataValue::Int32(2)), }], &sketch, )?; diff --git a/src/optimizer/core/memo.rs b/src/optimizer/core/memo.rs index 43dbe26f..5324b1e5 100644 --- a/src/optimizer/core/memo.rs +++ b/src/optimizer/core/memo.rs @@ -206,9 +206,9 @@ mod tests { ty: IndexType::PrimaryKey { is_multiple: false }, }), range: Some(Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(Some(2))), + Range::Eq(DataValue::Int32(2)), Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(40))), + min: Bound::Excluded(DataValue::Int32(40)), max: Bound::Unbounded, } ])), diff --git a/src/optimizer/core/statistics_meta.rs b/src/optimizer/core/statistics_meta.rs index ab2b3285..37a03194 100644 --- a/src/optimizer/core/statistics_meta.rs +++ b/src/optimizer/core/statistics_meta.rs @@ -130,26 +130,26 @@ mod tests { let mut builder = HistogramBuilder::new(&index, Some(15)); - builder.append(&Arc::new(DataValue::Int32(Some(14))))?; - builder.append(&Arc::new(DataValue::Int32(Some(13))))?; - builder.append(&Arc::new(DataValue::Int32(Some(12))))?; - builder.append(&Arc::new(DataValue::Int32(Some(11))))?; - builder.append(&Arc::new(DataValue::Int32(Some(10))))?; - - builder.append(&Arc::new(DataValue::Int32(Some(4))))?; - builder.append(&Arc::new(DataValue::Int32(Some(3))))?; - builder.append(&Arc::new(DataValue::Int32(Some(2))))?; - builder.append(&Arc::new(DataValue::Int32(Some(1))))?; - builder.append(&Arc::new(DataValue::Int32(Some(0))))?; - - builder.append(&Arc::new(DataValue::Int32(Some(9))))?; - builder.append(&Arc::new(DataValue::Int32(Some(8))))?; - builder.append(&Arc::new(DataValue::Int32(Some(7))))?; - builder.append(&Arc::new(DataValue::Int32(Some(6))))?; - builder.append(&Arc::new(DataValue::Int32(Some(5))))?; + builder.append(&Arc::new(DataValue::Int32(14)))?; + builder.append(&Arc::new(DataValue::Int32(13)))?; + builder.append(&Arc::new(DataValue::Int32(12)))?; + builder.append(&Arc::new(DataValue::Int32(11)))?; + builder.append(&Arc::new(DataValue::Int32(10)))?; + + builder.append(&Arc::new(DataValue::Int32(4)))?; + builder.append(&Arc::new(DataValue::Int32(3)))?; + builder.append(&Arc::new(DataValue::Int32(2)))?; + builder.append(&Arc::new(DataValue::Int32(1)))?; + builder.append(&Arc::new(DataValue::Int32(0)))?; + + builder.append(&Arc::new(DataValue::Int32(9)))?; + builder.append(&Arc::new(DataValue::Int32(8)))?; + builder.append(&Arc::new(DataValue::Int32(7)))?; + builder.append(&Arc::new(DataValue::Int32(6)))?; + builder.append(&Arc::new(DataValue::Int32(5)))?; builder.append(&Arc::new(DataValue::Null))?; - builder.append(&Arc::new(DataValue::Int32(None)))?; + builder.append(&Arc::new(DataValue::Null))?; let (histogram, sketch) = builder.build(4)?; let path = temp_dir.path().join("meta"); diff --git a/src/optimizer/rule/normalization/column_pruning.rs b/src/optimizer/rule/normalization/column_pruning.rs index d573e0bb..06cd94c1 100644 --- a/src/optimizer/rule/normalization/column_pruning.rs +++ b/src/optimizer/rule/normalization/column_pruning.rs @@ -58,7 +58,7 @@ impl ColumnPruning { if op.agg_calls.is_empty() && op.groupby_exprs.is_empty() { let value = DataValue::Utf8 { - value: Some("*".to_string()), + value: "*".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }; diff --git a/src/optimizer/rule/normalization/combine_operators.rs b/src/optimizer/rule/normalization/combine_operators.rs index 56db7d12..9690112a 100644 --- a/src/optimizer/rule/normalization/combine_operators.rs +++ b/src/optimizer/rule/normalization/combine_operators.rs @@ -208,8 +208,8 @@ mod tests { if let Operator::Filter(op) = &mut new_filter_op { op.predicate = ScalarExpression::Binary { op: BinaryOperator::Eq, - left_expr: Box::new(Constant(DataValue::Int8(Some(1)))), - right_expr: Box::new(Constant(DataValue::Int8(Some(1)))), + left_expr: Box::new(Constant(DataValue::Int8(1))), + right_expr: Box::new(Constant(DataValue::Int8(1))), evaluator: None, ty: LogicalType::Boolean, } diff --git a/src/optimizer/rule/normalization/pushdown_predicates.rs b/src/optimizer/rule/normalization/pushdown_predicates.rs index d2d1a51a..0a3851a5 100644 --- a/src/optimizer/rule/normalization/pushdown_predicates.rs +++ b/src/optimizer/rule/normalization/pushdown_predicates.rs @@ -270,10 +270,9 @@ impl PushPredicateIntoScan { if range.only_eq() && apply_column_count != meta.column_ids.len() { fn eq_to_scope(range: Range) -> Range { match range { - Range::Eq(DataValue::Tuple(Some((values, _)))) => { - let min = - Bound::Excluded(DataValue::Tuple(Some((values.clone(), false)))); - let max = Bound::Excluded(DataValue::Tuple(Some((values, true)))); + Range::Eq(DataValue::Tuple(values, _)) => { + let min = Bound::Excluded(DataValue::Tuple(values.clone(), false)); + let max = Bound::Excluded(DataValue::Tuple(values, true)); Range::Scope { min, max } } @@ -331,7 +330,7 @@ mod tests { let scan_op = best_plan.childrens.pop_only().childrens.pop_only(); if let Operator::TableScan(op) = &scan_op.operator { let mock_range = Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), + min: Bound::Excluded(DataValue::Int32(1)), max: Bound::Unbounded, }; diff --git a/src/optimizer/rule/normalization/simplification.rs b/src/optimizer/rule/normalization/simplification.rs index 48bd8074..294cf2bb 100644 --- a/src/optimizer/rule/normalization/simplification.rs +++ b/src/optimizer/rule/normalization/simplification.rs @@ -148,7 +148,7 @@ mod test { ) .find_best::(None)?; if let Operator::Project(project_op) = best_plan.clone().operator { - let constant_expr = ScalarExpression::Constant(DataValue::Int32(Some(3))); + let constant_expr = ScalarExpression::Constant(DataValue::Int32(3)); if let ScalarExpression::Binary { right_expr, .. } = &project_op.exprs[0] { assert_eq!(right_expr.as_ref(), &constant_expr); } else { @@ -167,7 +167,7 @@ mod test { range, Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(-2))), + max: Bound::Excluded(DataValue::Int32(-2)), } ); } else { @@ -297,9 +297,7 @@ mod test { left_expr: Box::new(ScalarExpression::ColumnRef(ColumnRef::from( c1_col ))), - right_expr: Box::new(ScalarExpression::Constant(DataValue::Int32( - Some(1) - ))), + right_expr: Box::new(ScalarExpression::Constant(DataValue::Int32(1))), evaluator: None, ty: LogicalType::Integer, }), @@ -366,20 +364,20 @@ mod test { range_1_c1, Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(-2))) + max: Bound::Excluded(DataValue::Int32(-2)) } ); assert_eq!( range_1_c2, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(2))), + min: Bound::Excluded(DataValue::Int32(2)), max: Bound::Unbounded } ); assert_eq!( range_2_c1, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(2))), + min: Bound::Excluded(DataValue::Int32(2)), max: Bound::Unbounded } ); @@ -387,27 +385,27 @@ mod test { range_2_c2, Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(-2))) + max: Bound::Excluded(DataValue::Int32(-2)) } ); assert_eq!( range_3_c1, Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(-1))) + max: Bound::Excluded(DataValue::Int32(-1)) } ); assert_eq!( range_3_c2, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(0))), + min: Bound::Excluded(DataValue::Int32(0)), max: Bound::Unbounded } ); assert_eq!( range_4_c1, Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(0))), + min: Bound::Excluded(DataValue::Int32(0)), max: Bound::Unbounded } ); @@ -415,7 +413,7 @@ mod test { range_4_c2, Range::Scope { min: Bound::Unbounded, - max: Bound::Excluded(DataValue::Int32(Some(-1))) + max: Bound::Excluded(DataValue::Int32(-1)) } ); @@ -444,7 +442,7 @@ mod test { assert_eq!( plan_filter(&plan_1, table_state.column_id_by_name("c1"))?, Some(Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(1))), + min: Bound::Excluded(DataValue::Int32(1)), max: Bound::Unbounded, }) ); @@ -486,9 +484,9 @@ mod test { assert_eq!( plan_filter(&plan_1, table_state.column_id_by_name("c1"))?, Some(Range::SortedRanges(vec![ - Range::Eq(DataValue::Int32(Some(1))), - Range::Eq(DataValue::Int32(Some(2))), - Range::Eq(DataValue::Int32(Some(3))), + Range::Eq(DataValue::Int32(1)), + Range::Eq(DataValue::Int32(2)), + Range::Eq(DataValue::Int32(3)), ])) ); diff --git a/src/serdes/column.rs b/src/serdes/column.rs index 7a7670e7..0fad7d86 100644 --- a/src/serdes/column.rs +++ b/src/serdes/column.rs @@ -227,7 +227,7 @@ pub(crate) mod test { LogicalType::Integer, None, false, - Some(ScalarExpression::Constant(DataValue::UInt64(Some(42)))), + Some(ScalarExpression::Constant(DataValue::UInt64(42))), )?, false, ))); @@ -315,7 +315,7 @@ pub(crate) mod test { LogicalType::Integer, None, false, - Some(ScalarExpression::Constant(DataValue::UInt64(Some(42)))), + Some(ScalarExpression::Constant(DataValue::UInt64(42))), )?; desc.encode(&mut cursor, false, &mut reference_tables)?; cursor.seek(SeekFrom::Start(0))?; diff --git a/src/serdes/data_value.rs b/src/serdes/data_value.rs index 2a023c2f..c36a37ca 100644 --- a/src/serdes/data_value.rs +++ b/src/serdes/data_value.rs @@ -8,29 +8,17 @@ pub(crate) mod test { use crate::errors::DatabaseError; use crate::serdes::{ReferenceSerialization, ReferenceTables}; use crate::storage::rocksdb::RocksTransaction; - use crate::types::value::{DataValue, Utf8Type}; - use sqlparser::ast::CharLengthUnits; + use crate::types::value::DataValue; use std::io::{Cursor, Seek, SeekFrom}; #[test] fn test_serialization() -> Result<(), DatabaseError> { - let source_0 = DataValue::Int32(None); - let source_1 = DataValue::Int32(Some(32)); - let source_2 = DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }; - let source_3 = DataValue::Utf8 { - value: Some("hello".to_string()), - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }; - let source_4 = DataValue::Tuple(None); - let source_5 = DataValue::Tuple(Some(( - vec![DataValue::Int32(None), DataValue::Int32(Some(42))], - false, - ))); + let source_0 = DataValue::Null; + let source_1 = DataValue::Int32(32); + let source_2 = DataValue::Null; + let source_3 = DataValue::Null; + let source_4 = DataValue::Null; + let source_5 = DataValue::Tuple(vec![DataValue::Null, DataValue::Int32(42)], false); let mut reference_tables = ReferenceTables::new(); let mut bytes = Vec::new(); diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 37b0afda..7802ab8c 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1233,25 +1233,25 @@ mod test { Tuple::new( Some(Arc::new(vec![0])), vec![ - DataValue::Int32(Some(0)), - DataValue::Boolean(Some(true)), - DataValue::Int32(Some(0)), + DataValue::Int32(0), + DataValue::Boolean(true), + DataValue::Int32(0), ], ), Tuple::new( Some(Arc::new(vec![0])), vec![ - DataValue::Int32(Some(1)), - DataValue::Boolean(Some(true)), - DataValue::Int32(Some(1)), + DataValue::Int32(1), + DataValue::Boolean(true), + DataValue::Int32(1), ], ), Tuple::new( Some(Arc::new(vec![0])), vec![ - DataValue::Int32(Some(2)), - DataValue::Boolean(Some(false)), - DataValue::Int32(Some(0)), + DataValue::Int32(2), + DataValue::Boolean(false), + DataValue::Int32(0), ], ), ] @@ -1563,15 +1563,15 @@ mod test { let tuples = build_tuples(); let indexes = vec![ ( - Arc::new(DataValue::Int32(Some(0))), + Arc::new(DataValue::Int32(0)), Index::new(1, &tuples[0].values[2], IndexType::Normal), ), ( - Arc::new(DataValue::Int32(Some(1))), + Arc::new(DataValue::Int32(1)), Index::new(1, &tuples[1].values[2], IndexType::Normal), ), ( - Arc::new(DataValue::Int32(Some(2))), + Arc::new(DataValue::Int32(2)), Index::new(1, &tuples[2].values[2], IndexType::Normal), ), ]; diff --git a/src/storage/rocksdb.rs b/src/storage/rocksdb.rs index 1b1d4c4a..3e8a4f12 100644 --- a/src/storage/rocksdb.rs +++ b/src/storage/rocksdb.rs @@ -215,7 +215,7 @@ mod test { &"test".to_string(), Tuple::new( Some(Arc::new(vec![0])), - vec![DataValue::Int32(Some(1)), DataValue::Boolean(Some(true))], + vec![DataValue::Int32(1), DataValue::Boolean(true)], ), &[LogicalType::Integer, LogicalType::Boolean], false, @@ -224,7 +224,7 @@ mod test { &"test".to_string(), Tuple::new( Some(Arc::new(vec![0])), - vec![DataValue::Int32(Some(2)), DataValue::Boolean(Some(true))], + vec![DataValue::Int32(2), DataValue::Boolean(true)], ), &[LogicalType::Integer, LogicalType::Boolean], false, @@ -266,10 +266,10 @@ mod test { .clone(); let a_column_id = table.get_column_id_by_name("a").unwrap(); let tuple_ids = vec![ - DataValue::Int32(Some(0)), - DataValue::Int32(Some(2)), - DataValue::Int32(Some(3)), - DataValue::Int32(Some(4)), + DataValue::Int32(0), + DataValue::Int32(2), + DataValue::Int32(3), + DataValue::Int32(4), ]; let pk_indices = Arc::new(vec![0]); let mut iter = IndexIter { @@ -293,10 +293,10 @@ mod test { tx: &transaction, }, ranges: vec![ - Range::Eq(DataValue::Int32(Some(0))), + Range::Eq(DataValue::Int32(0)), Range::Scope { - min: Bound::Included(DataValue::Int32(Some(2))), - max: Bound::Included(DataValue::Int32(Some(4))), + min: Bound::Included(DataValue::Int32(2)), + max: Bound::Included(DataValue::Int32(4)), }, ] .into_iter(), @@ -339,7 +339,7 @@ mod test { columns, table.indexes[0].clone(), vec![Range::Scope { - min: Bound::Excluded(DataValue::Int32(Some(0))), + min: Bound::Excluded(DataValue::Int32(0)), max: Bound::Unbounded, }], ) @@ -347,10 +347,7 @@ mod test { while let Some(tuple) = iter.next_tuple()? { assert_eq!(tuple.pk_indices, Some(Arc::new(vec![0]))); - assert_eq!( - tuple.values, - vec![DataValue::Int32(Some(1)), DataValue::Int32(Some(1))] - ) + assert_eq!(tuple.values, vec![DataValue::Int32(1), DataValue::Int32(1)]) } Ok(()) diff --git a/src/storage/table_codec.rs b/src/storage/table_codec.rs index 8ea890f8..7d2e5911 100644 --- a/src/storage/table_codec.rs +++ b/src/storage/table_codec.rs @@ -56,7 +56,7 @@ impl TableCodec { return Err(DatabaseError::NotNull); } - if let DataValue::Tuple(Some((values, _))) = &value { + if let DataValue::Tuple(values, _) = &value { for value in values { Self::check_primary_key(value, indentation + 1)? } @@ -569,10 +569,7 @@ mod tests { let mut tuple = Tuple::new( Some(Arc::new(vec![0])), - vec![ - DataValue::Int32(Some(0)), - DataValue::Decimal(Some(Decimal::new(1, 0))), - ], + vec![DataValue::Int32(0), DataValue::Decimal(Decimal::new(1, 0))], ); let (_, bytes) = table_codec.encode_tuple( &table_catalog.name, @@ -650,9 +647,9 @@ mod tests { arena: Default::default(), }; let table_catalog = build_table_codec(); - let value = Arc::new(DataValue::Int32(Some(0))); + let value = Arc::new(DataValue::Int32(0)); let index = Index::new(0, &value, IndexType::PrimaryKey { is_multiple: false }); - let tuple_id = DataValue::Int32(Some(0)); + let tuple_id = DataValue::Int32(0); let (_, bytes) = table_codec.encode_index(&table_catalog.name, &index, &tuple_id)?; assert_eq!(TableCodec::decode_index(&bytes)?, tuple_id); @@ -881,17 +878,17 @@ mod tests { .unwrap() }; - set.insert(op(DataValue::Int32(Some(0)), 0, &table_catalog.name)); - set.insert(op(DataValue::Int32(Some(1)), 0, &table_catalog.name)); - set.insert(op(DataValue::Int32(Some(2)), 0, &table_catalog.name)); + set.insert(op(DataValue::Int32(0), 0, &table_catalog.name)); + set.insert(op(DataValue::Int32(1), 0, &table_catalog.name)); + set.insert(op(DataValue::Int32(2), 0, &table_catalog.name)); - set.insert(op(DataValue::Int32(Some(0)), 1, &table_catalog.name)); - set.insert(op(DataValue::Int32(Some(1)), 1, &table_catalog.name)); - set.insert(op(DataValue::Int32(Some(2)), 1, &table_catalog.name)); + set.insert(op(DataValue::Int32(0), 1, &table_catalog.name)); + set.insert(op(DataValue::Int32(1), 1, &table_catalog.name)); + set.insert(op(DataValue::Int32(2), 1, &table_catalog.name)); - set.insert(op(DataValue::Int32(Some(0)), 2, &table_catalog.name)); - set.insert(op(DataValue::Int32(Some(1)), 2, &table_catalog.name)); - set.insert(op(DataValue::Int32(Some(2)), 2, &table_catalog.name)); + set.insert(op(DataValue::Int32(0), 2, &table_catalog.name)); + set.insert(op(DataValue::Int32(1), 2, &table_catalog.name)); + set.insert(op(DataValue::Int32(2), 2, &table_catalog.name)); println!("{:#?}", set); @@ -909,18 +906,9 @@ mod tests { assert_eq!(vec.len(), 3); - assert_eq!( - vec[0], - &op(DataValue::Int32(Some(0)), 1, &table_catalog.name) - ); - assert_eq!( - vec[1], - &op(DataValue::Int32(Some(1)), 1, &table_catalog.name) - ); - assert_eq!( - vec[2], - &op(DataValue::Int32(Some(2)), 1, &table_catalog.name) - ); + assert_eq!(vec[0], &op(DataValue::Int32(0), 1, &table_catalog.name)); + assert_eq!(vec[1], &op(DataValue::Int32(1), 1, &table_catalog.name)); + assert_eq!(vec[2], &op(DataValue::Int32(2), 1, &table_catalog.name)); } #[test] @@ -942,17 +930,17 @@ mod tests { .unwrap() }; - set.insert(op(DataValue::Int32(Some(0)), 0, "T0")); - set.insert(op(DataValue::Int32(Some(1)), 0, "T0")); - set.insert(op(DataValue::Int32(Some(2)), 0, "T0")); + set.insert(op(DataValue::Int32(0), 0, "T0")); + set.insert(op(DataValue::Int32(1), 0, "T0")); + set.insert(op(DataValue::Int32(2), 0, "T0")); - set.insert(op(DataValue::Int32(Some(0)), 0, "T1")); - set.insert(op(DataValue::Int32(Some(1)), 0, "T1")); - set.insert(op(DataValue::Int32(Some(2)), 0, "T1")); + set.insert(op(DataValue::Int32(0), 0, "T1")); + set.insert(op(DataValue::Int32(1), 0, "T1")); + set.insert(op(DataValue::Int32(2), 0, "T1")); - set.insert(op(DataValue::Int32(Some(0)), 0, "T2")); - set.insert(op(DataValue::Int32(Some(1)), 0, "T2")); - set.insert(op(DataValue::Int32(Some(2)), 0, "T2")); + set.insert(op(DataValue::Int32(0), 0, "T2")); + set.insert(op(DataValue::Int32(1), 0, "T2")); + set.insert(op(DataValue::Int32(2), 0, "T2")); let (min, max) = table_codec.all_index_bound(&"T1".to_string()); @@ -965,9 +953,9 @@ mod tests { assert_eq!(vec.len(), 3); - assert_eq!(vec[0], &op(DataValue::Int32(Some(0)), 0, "T1")); - assert_eq!(vec[1], &op(DataValue::Int32(Some(1)), 0, "T1")); - assert_eq!(vec[2], &op(DataValue::Int32(Some(2)), 0, "T1")); + assert_eq!(vec[0], &op(DataValue::Int32(0), 0, "T1")); + assert_eq!(vec[1], &op(DataValue::Int32(1), 0, "T1")); + assert_eq!(vec[2], &op(DataValue::Int32(2), 0, "T1")); } #[test] @@ -982,17 +970,17 @@ mod tests { .unwrap() }; - set.insert(op(DataValue::Int32(Some(0)), "T0")); - set.insert(op(DataValue::Int32(Some(1)), "T0")); - set.insert(op(DataValue::Int32(Some(2)), "T0")); + set.insert(op(DataValue::Int32(0), "T0")); + set.insert(op(DataValue::Int32(1), "T0")); + set.insert(op(DataValue::Int32(2), "T0")); - set.insert(op(DataValue::Int32(Some(0)), "T1")); - set.insert(op(DataValue::Int32(Some(1)), "T1")); - set.insert(op(DataValue::Int32(Some(2)), "T1")); + set.insert(op(DataValue::Int32(0), "T1")); + set.insert(op(DataValue::Int32(1), "T1")); + set.insert(op(DataValue::Int32(2), "T1")); - set.insert(op(DataValue::Int32(Some(0)), "T2")); - set.insert(op(DataValue::Int32(Some(1)), "T2")); - set.insert(op(DataValue::Int32(Some(2)), "T2")); + set.insert(op(DataValue::Int32(0), "T2")); + set.insert(op(DataValue::Int32(1), "T2")); + set.insert(op(DataValue::Int32(2), "T2")); let (min, max) = table_codec.tuple_bound(&"T1".to_string()); @@ -1005,9 +993,9 @@ mod tests { assert_eq!(vec.len(), 3); - assert_eq!(vec[0], &op(DataValue::Int32(Some(0)), "T1")); - assert_eq!(vec[1], &op(DataValue::Int32(Some(1)), "T1")); - assert_eq!(vec[2], &op(DataValue::Int32(Some(2)), "T1")); + assert_eq!(vec[0], &op(DataValue::Int32(0), "T1")); + assert_eq!(vec[1], &op(DataValue::Int32(1), "T1")); + assert_eq!(vec[2], &op(DataValue::Int32(2), "T1")); } #[test] diff --git a/src/types/evaluator/boolean.rs b/src/types/evaluator/boolean.rs index 900f2581..fb9d8574 100644 --- a/src/types/evaluator/boolean.rs +++ b/src/types/evaluator/boolean.rs @@ -17,96 +17,65 @@ pub struct BooleanNotEqBinaryEvaluator; #[typetag::serde] impl UnaryEvaluator for BooleanNotUnaryEvaluator { fn unary_eval(&self, value: &DataValue) -> DataValue { - let value = match value { - DataValue::Boolean(value) => value, - DataValue::Null => &None, + match value { + DataValue::Boolean(value) => DataValue::Boolean(!value), + DataValue::Null => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - DataValue::Boolean(value.map(|v| !v)) + } } } #[typetag::serde] impl BinaryEvaluator for BooleanAndBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Boolean(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Boolean(v1), DataValue::Boolean(v2)) => DataValue::Boolean(*v1 && *v2), + (DataValue::Boolean(false), DataValue::Null) + | (DataValue::Null, DataValue::Boolean(false)) => DataValue::Boolean(false), + (DataValue::Null, DataValue::Null) + | (DataValue::Boolean(true), DataValue::Null) + | (DataValue::Null, DataValue::Boolean(true)) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Boolean(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => Some(*v1 && *v2), - (Some(false), _) | (_, Some(false)) => Some(false), - _ => None, - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for BooleanOrBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Boolean(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Boolean(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Boolean(v1), DataValue::Boolean(v2)) => DataValue::Boolean(*v1 || *v2), + (DataValue::Boolean(true), DataValue::Null) + | (DataValue::Null, DataValue::Boolean(true)) => DataValue::Boolean(true), + (DataValue::Null, DataValue::Null) + | (DataValue::Boolean(false), DataValue::Null) + | (DataValue::Null, DataValue::Boolean(false)) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => Some(*v1 || *v2), - (Some(true), _) | (_, Some(true)) => Some(true), - _ => None, - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for BooleanEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Boolean(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Boolean(v1), DataValue::Boolean(v2)) => DataValue::Boolean(*v1 == *v2), + (DataValue::Null, DataValue::Boolean(_)) + | (DataValue::Boolean(_), DataValue::Null) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Boolean(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => Some(v1 == v2), - (_, _) => None, - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for BooleanNotEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Boolean(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Boolean(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Boolean(v1), DataValue::Boolean(v2)) => DataValue::Boolean(*v1 != *v2), + (DataValue::Null, DataValue::Boolean(_)) + | (DataValue::Boolean(_), DataValue::Null) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => Some(v1 != v2), - (_, _) => None, - }; - DataValue::Boolean(value) + } } } diff --git a/src/types/evaluator/decimal.rs b/src/types/evaluator/decimal.rs index f2b47560..3828536c 100644 --- a/src/types/evaluator/decimal.rs +++ b/src/types/evaluator/decimal.rs @@ -29,231 +29,132 @@ pub struct DecimalModBinaryEvaluator; #[typetag::serde] impl BinaryEvaluator for DecimalPlusBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Decimal(v1 + v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 + v2) - } else { - None - }; - DataValue::Decimal(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalMinusBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Decimal(v1 - v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 - v2) - } else { - None - }; - DataValue::Decimal(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalMultiplyBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Decimal(v1 * v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 * v2) - } else { - None - }; - DataValue::Decimal(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalDivideBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Decimal(v1 / v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 / v2) - } else { - None - }; - DataValue::Decimal(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalGtBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Boolean(v1 > v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 > v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalGtEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Boolean(v1 >= v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 >= v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalLtBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Boolean(v1 < v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 < v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalLtEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Boolean(v1 <= v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 <= v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Boolean(v1 == v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 == v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalNotEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Boolean(v1 != v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 != v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for DecimalModBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Decimal(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Decimal(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Decimal(v1), DataValue::Decimal(v2)) => DataValue::Decimal(v1 % v2), + (DataValue::Decimal(_), DataValue::Null) + | (DataValue::Null, DataValue::Decimal(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 % v2) - } else { - None - }; - DataValue::Decimal(value) + } } } diff --git a/src/types/evaluator/float32.rs b/src/types/evaluator/float32.rs index 2328cae7..ad474c58 100644 --- a/src/types/evaluator/float32.rs +++ b/src/types/evaluator/float32.rs @@ -1,9 +1,184 @@ use crate::types::evaluator::DataValue; use crate::types::evaluator::{BinaryEvaluator, UnaryEvaluator}; -use crate::{numeric_binary_evaluator_definition, numeric_unary_evaluator_definition}; -use paste::paste; use serde::{Deserialize, Serialize}; use std::hint; -numeric_unary_evaluator_definition!(Float32, DataValue::Float32); -numeric_binary_evaluator_definition!(Float32, DataValue::Float32); +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32PlusUnaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32MinusUnaryEvaluator; + +#[typetag::serde] +impl UnaryEvaluator for Float32PlusUnaryEvaluator { + fn unary_eval(&self, value: &DataValue) -> DataValue { + value.clone() + } +} +#[typetag::serde] +impl UnaryEvaluator for Float32MinusUnaryEvaluator { + fn unary_eval(&self, value: &DataValue) -> DataValue { + match value { + DataValue::Float32(value) => DataValue::Float32(-value), + DataValue::Null => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32PlusBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32MinusBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32MultiplyBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32DivideBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32GtBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32GtEqBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32LtBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32LtEqBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32EqBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32NotEqBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float32ModBinaryEvaluator; + +#[typetag::serde] +impl BinaryEvaluator for Float32PlusBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Float32(*v1 + *v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32MinusBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Float32(*v1 - *v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32MultiplyBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Float32(*v1 * *v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32DivideBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => { + DataValue::Float64(ordered_float::OrderedFloat(**v1 as f64 / **v2 as f64)) + } + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32GtBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Boolean(v1 > v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32GtEqBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Boolean(v1 >= v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32LtBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Boolean(v1 < v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32LtEqBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Boolean(v1 <= v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32EqBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Boolean(v1 == v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32NotEqBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Boolean(v1 != v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float32ModBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float32(v1), DataValue::Float32(v2)) => DataValue::Float32(*v1 % *v2), + (DataValue::Float32(_), DataValue::Null) + | (DataValue::Null, DataValue::Float32(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} diff --git a/src/types/evaluator/float64.rs b/src/types/evaluator/float64.rs index 0dcb953d..8adf3e5d 100644 --- a/src/types/evaluator/float64.rs +++ b/src/types/evaluator/float64.rs @@ -1,9 +1,184 @@ use crate::types::evaluator::DataValue; use crate::types::evaluator::{BinaryEvaluator, UnaryEvaluator}; -use crate::{numeric_binary_evaluator_definition, numeric_unary_evaluator_definition}; -use paste::paste; use serde::{Deserialize, Serialize}; use std::hint; -numeric_unary_evaluator_definition!(Float64, DataValue::Float64); -numeric_binary_evaluator_definition!(Float64, DataValue::Float64); +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64PlusUnaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64MinusUnaryEvaluator; + +#[typetag::serde] +impl UnaryEvaluator for Float64PlusUnaryEvaluator { + fn unary_eval(&self, value: &DataValue) -> DataValue { + value.clone() + } +} +#[typetag::serde] +impl UnaryEvaluator for Float64MinusUnaryEvaluator { + fn unary_eval(&self, value: &DataValue) -> DataValue { + match value { + DataValue::Float64(value) => DataValue::Float64(-value), + DataValue::Null => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64PlusBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64MinusBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64MultiplyBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64DivideBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64GtBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64GtEqBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64LtBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64LtEqBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64EqBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64NotEqBinaryEvaluator; +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Float64ModBinaryEvaluator; + +#[typetag::serde] +impl BinaryEvaluator for Float64PlusBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Float64(*v1 + *v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64MinusBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Float64(*v1 - *v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64MultiplyBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Float64(*v1 * *v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64DivideBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => { + DataValue::Float64(ordered_float::OrderedFloat(**v1 / **v2)) + } + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64GtBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Boolean(v1 > v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64GtEqBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Boolean(v1 >= v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64LtBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Boolean(v1 < v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64LtEqBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Boolean(v1 <= v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64EqBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Boolean(v1 == v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64NotEqBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Boolean(v1 != v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} +#[typetag::serde] +impl BinaryEvaluator for Float64ModBinaryEvaluator { + fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { + match (left, right) { + (DataValue::Float64(v1), DataValue::Float64(v2)) => DataValue::Float64(*v1 % *v2), + (DataValue::Float64(_), DataValue::Null) + | (DataValue::Null, DataValue::Float64(_)) + | (DataValue::Null, DataValue::Null) => DataValue::Null, + _ => unsafe { hint::unreachable_unchecked() }, + } + } +} diff --git a/src/types/evaluator/mod.rs b/src/types/evaluator/mod.rs index ef0f6411..97e117cb 100644 --- a/src/types/evaluator/mod.rs +++ b/src/types/evaluator/mod.rs @@ -262,12 +262,11 @@ macro_rules! numeric_unary_evaluator_definition { #[typetag::serde] impl UnaryEvaluator for [<$value_type MinusUnaryEvaluator>] { fn unary_eval(&self, value: &DataValue) -> DataValue { - let value = match value { - $compute_type(value) => value, - DataValue::Null => &None, + match value { + $compute_type(value) => $compute_type(-value), + DataValue::Null => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - $compute_type(value.map(|v| -v)) + } } } } @@ -304,232 +303,111 @@ macro_rules! numeric_binary_evaluator_definition { #[typetag::serde] impl BinaryEvaluator for [<$value_type PlusBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => $compute_type(*v1 + *v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 + v2) - } else { - None - }; - $compute_type(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type MinusBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => $compute_type(*v1 - *v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 - v2) - } else { - None - }; - $compute_type(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type MultiplyBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => $compute_type(*v1 * *v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 * v2) - } else { - None - }; - $compute_type(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type DivideBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => DataValue::Float64(ordered_float::OrderedFloat(*v1 as f64 / *v2 as f64)), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(*v1 as f64 / *v2 as f64) - } else { - None - }; - DataValue::Float64(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type GtBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => DataValue::Boolean(v1 > v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 > v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type GtEqBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => DataValue::Boolean(v1 >= v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 >= v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type LtBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => DataValue::Boolean(v1 < v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 < v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type LtEqBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => DataValue::Boolean(v1 <= v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 <= v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type EqBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => DataValue::Boolean(v1 == v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 == v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type NotEqBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => DataValue::Boolean(v1 != v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 != v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for [<$value_type ModBinaryEvaluator>] { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - $compute_type(value) => value, - DataValue::Null => &None, + match (left, right) { + ($compute_type(v1), $compute_type(v2)) => $compute_type(*v1 % *v2), + ($compute_type(_), DataValue::Null) | (DataValue::Null, $compute_type(_)) | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - $compute_type(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 % v2) - } else { - None - }; - $compute_type(value) + } } } } @@ -546,6 +424,7 @@ mod test { use crate::types::evaluator::{BinaryEvaluatorBox, EvaluatorFactory, UnaryEvaluatorBox}; use crate::types::value::{DataValue, Utf8Type}; use crate::types::LogicalType; + use ordered_float::OrderedFloat; use sqlparser::ast::CharLengthUnits; use std::io::{Cursor, Seek, SeekFrom}; use std::sync::Arc; @@ -556,59 +435,59 @@ mod test { EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Plus)?; let plus_i32_1 = plus_evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let plus_i32_2 = plus_evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(None)); + .binary_eval(&DataValue::Int32(1), &DataValue::Null); let plus_i32_3 = plus_evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(1))); + .binary_eval(&DataValue::Null, &DataValue::Int32(1)); let plus_i32_4 = plus_evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(1))); + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(1)); assert_eq!(plus_i32_1, plus_i32_2); assert_eq!(plus_i32_2, plus_i32_3); - assert_eq!(plus_i32_4, DataValue::Int32(Some(2))); + assert_eq!(plus_i32_4, DataValue::Int32(2)); let plus_evaluator = EvaluatorFactory::binary_create(LogicalType::Bigint, BinaryOperator::Plus)?; let plus_i64_1 = plus_evaluator .0 - .binary_eval(&DataValue::Int64(None), &DataValue::Int64(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let plus_i64_2 = plus_evaluator .0 - .binary_eval(&DataValue::Int64(Some(1)), &DataValue::Int64(None)); + .binary_eval(&DataValue::Int64(1), &DataValue::Null); let plus_i64_3 = plus_evaluator .0 - .binary_eval(&DataValue::Int64(None), &DataValue::Int64(Some(1))); + .binary_eval(&DataValue::Null, &DataValue::Int64(1)); let plus_i64_4 = plus_evaluator .0 - .binary_eval(&DataValue::Int64(Some(1)), &DataValue::Int64(Some(1))); + .binary_eval(&DataValue::Int64(1), &DataValue::Int64(1)); assert_eq!(plus_i64_1, plus_i64_2); assert_eq!(plus_i64_2, plus_i64_3); - assert_eq!(plus_i64_4, DataValue::Int64(Some(2))); + assert_eq!(plus_i64_4, DataValue::Int64(2)); let plus_evaluator = EvaluatorFactory::binary_create(LogicalType::Double, BinaryOperator::Plus)?; let plus_f64_1 = plus_evaluator .0 - .binary_eval(&DataValue::Float64(None), &DataValue::Float64(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let plus_f64_2 = plus_evaluator .0 - .binary_eval(&DataValue::Float64(Some(1.0)), &DataValue::Float64(None)); + .binary_eval(&DataValue::Float64(OrderedFloat(1.0)), &DataValue::Null); let plus_f64_3 = plus_evaluator .0 - .binary_eval(&DataValue::Float64(None), &DataValue::Float64(Some(1.0))); + .binary_eval(&DataValue::Null, &DataValue::Float64(OrderedFloat(1.0))); let plus_f64_4 = plus_evaluator.0.binary_eval( - &DataValue::Float64(Some(1.0)), - &DataValue::Float64(Some(1.0)), + &DataValue::Float64(OrderedFloat(1.0)), + &DataValue::Float64(OrderedFloat(1.0)), ); assert_eq!(plus_f64_1, plus_f64_2); assert_eq!(plus_f64_2, plus_f64_3); - assert_eq!(plus_f64_4, DataValue::Float64(Some(2.0))); + assert_eq!(plus_f64_4, DataValue::Float64(OrderedFloat(2.0))); Ok(()) } @@ -619,59 +498,59 @@ mod test { EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Minus)?; let minus_i32_1 = minus_evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let minus_i32_2 = minus_evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(None)); + .binary_eval(&DataValue::Int32(1), &DataValue::Null); let minus_i32_3 = minus_evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(1))); + .binary_eval(&DataValue::Null, &DataValue::Int32(1)); let minus_i32_4 = minus_evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(1))); + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(1)); assert_eq!(minus_i32_1, minus_i32_2); assert_eq!(minus_i32_2, minus_i32_3); - assert_eq!(minus_i32_4, DataValue::Int32(Some(0))); + assert_eq!(minus_i32_4, DataValue::Int32(0)); let minus_evaluator = EvaluatorFactory::binary_create(LogicalType::Bigint, BinaryOperator::Minus)?; let minus_i64_1 = minus_evaluator .0 - .binary_eval(&DataValue::Int64(None), &DataValue::Int64(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let minus_i64_2 = minus_evaluator .0 - .binary_eval(&DataValue::Int64(Some(1)), &DataValue::Int64(None)); + .binary_eval(&DataValue::Int64(1), &DataValue::Null); let minus_i64_3 = minus_evaluator .0 - .binary_eval(&DataValue::Int64(None), &DataValue::Int64(Some(1))); + .binary_eval(&DataValue::Null, &DataValue::Int64(1)); let minus_i64_4 = minus_evaluator .0 - .binary_eval(&DataValue::Int64(Some(1)), &DataValue::Int64(Some(1))); + .binary_eval(&DataValue::Int64(1), &DataValue::Int64(1)); assert_eq!(minus_i64_1, minus_i64_2); assert_eq!(minus_i64_2, minus_i64_3); - assert_eq!(minus_i64_4, DataValue::Int64(Some(0))); + assert_eq!(minus_i64_4, DataValue::Int64(0)); let minus_evaluator = EvaluatorFactory::binary_create(LogicalType::Double, BinaryOperator::Minus)?; let minus_f64_1 = minus_evaluator .0 - .binary_eval(&DataValue::Float64(None), &DataValue::Float64(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let minus_f64_2 = minus_evaluator .0 - .binary_eval(&DataValue::Float64(Some(1.0)), &DataValue::Float64(None)); + .binary_eval(&DataValue::Float64(OrderedFloat(1.0)), &DataValue::Null); let minus_f64_3 = minus_evaluator .0 - .binary_eval(&DataValue::Float64(None), &DataValue::Float64(Some(1.0))); + .binary_eval(&DataValue::Null, &DataValue::Float64(OrderedFloat(1.0))); let minus_f64_4 = minus_evaluator.0.binary_eval( - &DataValue::Float64(Some(1.0)), - &DataValue::Float64(Some(1.0)), + &DataValue::Float64(OrderedFloat(1.0)), + &DataValue::Float64(OrderedFloat(1.0)), ); assert_eq!(minus_f64_1, minus_f64_2); assert_eq!(minus_f64_2, minus_f64_3); - assert_eq!(minus_f64_4, DataValue::Float64(Some(0.0))); + assert_eq!(minus_f64_4, DataValue::Float64(OrderedFloat(0.0))); Ok(()) } @@ -682,59 +561,59 @@ mod test { EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Multiply)?; let multiply_i32_1 = multiply_evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let multiply_i32_2 = multiply_evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(None)); + .binary_eval(&DataValue::Int32(1), &DataValue::Null); let multiply_i32_3 = multiply_evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(1))); + .binary_eval(&DataValue::Null, &DataValue::Int32(1)); let multiply_i32_4 = multiply_evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(1))); + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(1)); assert_eq!(multiply_i32_1, multiply_i32_2); assert_eq!(multiply_i32_2, multiply_i32_3); - assert_eq!(multiply_i32_4, DataValue::Int32(Some(1))); + assert_eq!(multiply_i32_4, DataValue::Int32(1)); let multiply_evaluator = EvaluatorFactory::binary_create(LogicalType::Bigint, BinaryOperator::Multiply)?; let multiply_i64_1 = multiply_evaluator .0 - .binary_eval(&DataValue::Int64(None), &DataValue::Int64(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let multiply_i64_2 = multiply_evaluator .0 - .binary_eval(&DataValue::Int64(Some(1)), &DataValue::Int64(None)); + .binary_eval(&DataValue::Int64(1), &DataValue::Null); let multiply_i64_3 = multiply_evaluator .0 - .binary_eval(&DataValue::Int64(None), &DataValue::Int64(Some(1))); + .binary_eval(&DataValue::Null, &DataValue::Int64(1)); let multiply_i64_4 = multiply_evaluator .0 - .binary_eval(&DataValue::Int64(Some(1)), &DataValue::Int64(Some(1))); + .binary_eval(&DataValue::Int64(1), &DataValue::Int64(1)); assert_eq!(multiply_i64_1, multiply_i64_2); assert_eq!(multiply_i64_2, multiply_i64_3); - assert_eq!(multiply_i64_4, DataValue::Int64(Some(1))); + assert_eq!(multiply_i64_4, DataValue::Int64(1)); let multiply_evaluator = EvaluatorFactory::binary_create(LogicalType::Double, BinaryOperator::Multiply)?; let multiply_f64_1 = multiply_evaluator .0 - .binary_eval(&DataValue::Float64(None), &DataValue::Float64(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let multiply_f64_2 = multiply_evaluator .0 - .binary_eval(&DataValue::Float64(Some(1.0)), &DataValue::Float64(None)); + .binary_eval(&DataValue::Float64(OrderedFloat(1.0)), &DataValue::Null); let multiply_f64_3 = multiply_evaluator .0 - .binary_eval(&DataValue::Float64(None), &DataValue::Float64(Some(1.0))); + .binary_eval(&DataValue::Null, &DataValue::Float64(OrderedFloat(1.0))); let multiply_f64_4 = multiply_evaluator.0.binary_eval( - &DataValue::Float64(Some(1.0)), - &DataValue::Float64(Some(1.0)), + &DataValue::Float64(OrderedFloat(1.0)), + &DataValue::Float64(OrderedFloat(1.0)), ); assert_eq!(multiply_f64_1, multiply_f64_2); assert_eq!(multiply_f64_2, multiply_f64_3); - assert_eq!(multiply_f64_4, DataValue::Float64(Some(1.0))); + assert_eq!(multiply_f64_4, DataValue::Float64(OrderedFloat(1.0))); Ok(()) } @@ -745,59 +624,59 @@ mod test { EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Divide)?; let divide_i32_1 = divide_evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let divide_i32_2 = divide_evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(None)); + .binary_eval(&DataValue::Int32(1), &DataValue::Null); let divide_i32_3 = divide_evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(1))); + .binary_eval(&DataValue::Null, &DataValue::Int32(1)); let divide_i32_4 = divide_evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(1))); + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(1)); assert_eq!(divide_i32_1, divide_i32_2); assert_eq!(divide_i32_2, divide_i32_3); - assert_eq!(divide_i32_4, DataValue::Float64(Some(1.0))); + assert_eq!(divide_i32_4, DataValue::Float64(OrderedFloat(1.0))); let divide_evaluator = EvaluatorFactory::binary_create(LogicalType::Bigint, BinaryOperator::Divide)?; let divide_i64_1 = divide_evaluator .0 - .binary_eval(&DataValue::Int64(None), &DataValue::Int64(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let divide_i64_2 = divide_evaluator .0 - .binary_eval(&DataValue::Int64(Some(1)), &DataValue::Int64(None)); + .binary_eval(&DataValue::Int64(1), &DataValue::Null); let divide_i64_3 = divide_evaluator .0 - .binary_eval(&DataValue::Int64(None), &DataValue::Int64(Some(1))); + .binary_eval(&DataValue::Null, &DataValue::Int64(1)); let divide_i64_4 = divide_evaluator .0 - .binary_eval(&DataValue::Int64(Some(1)), &DataValue::Int64(Some(1))); + .binary_eval(&DataValue::Int64(1), &DataValue::Int64(1)); assert_eq!(divide_i64_1, divide_i64_2); assert_eq!(divide_i64_2, divide_i64_3); - assert_eq!(divide_i64_4, DataValue::Float64(Some(1.0))); + assert_eq!(divide_i64_4, DataValue::Float64(OrderedFloat(1.0))); let divide_evaluator = EvaluatorFactory::binary_create(LogicalType::Double, BinaryOperator::Divide)?; let divide_f64_1 = divide_evaluator .0 - .binary_eval(&DataValue::Float64(None), &DataValue::Float64(None)); + .binary_eval(&DataValue::Null, &DataValue::Null); let divide_f64_2 = divide_evaluator .0 - .binary_eval(&DataValue::Float64(Some(1.0)), &DataValue::Float64(None)); + .binary_eval(&DataValue::Float64(OrderedFloat(1.0)), &DataValue::Null); let divide_f64_3 = divide_evaluator .0 - .binary_eval(&DataValue::Float64(None), &DataValue::Float64(Some(1.0))); + .binary_eval(&DataValue::Null, &DataValue::Float64(OrderedFloat(1.0))); let divide_f64_4 = divide_evaluator.0.binary_eval( - &DataValue::Float64(Some(1.0)), - &DataValue::Float64(Some(1.0)), + &DataValue::Float64(OrderedFloat(1.0)), + &DataValue::Float64(OrderedFloat(1.0)), ); assert_eq!(divide_f64_1, divide_f64_2); assert_eq!(divide_f64_2, divide_f64_3); - assert_eq!(divide_f64_4, DataValue::Float64(Some(1.0))); + assert_eq!(divide_f64_4, DataValue::Float64(OrderedFloat(1.0))); Ok(()) } @@ -808,98 +687,96 @@ mod test { assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(0)),), - DataValue::Boolean(Some(true)) + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(0),), + DataValue::Boolean(true) ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Lt)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(0)),), - DataValue::Boolean(Some(false)) + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(0),), + DataValue::Boolean(false) ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::GtEq)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(1)),), - DataValue::Boolean(Some(true)) + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(1),), + DataValue::Boolean(true) ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::LtEq)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(1)),), - DataValue::Boolean(Some(true)) + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(1),), + DataValue::Boolean(true) ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::NotEq)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(1)),), - DataValue::Boolean(Some(false)) + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(1),), + DataValue::Boolean(false) ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Eq)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(Some(1)), &DataValue::Int32(Some(1)),), - DataValue::Boolean(Some(true)) + .binary_eval(&DataValue::Int32(1), &DataValue::Int32(1),), + DataValue::Boolean(true) ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Gt)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(0)),), - DataValue::Boolean(None) + .binary_eval(&DataValue::Null, &DataValue::Int32(0),), + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Lt)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(0)),), - DataValue::Boolean(None) + .binary_eval(&DataValue::Null, &DataValue::Int32(0),), + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::GtEq)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(1)),), - DataValue::Boolean(None) + .binary_eval(&DataValue::Null, &DataValue::Int32(1),), + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::LtEq)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(1)),), - DataValue::Boolean(None) + .binary_eval(&DataValue::Null, &DataValue::Int32(1),), + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::NotEq)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(1)),), - DataValue::Boolean(None) + .binary_eval(&DataValue::Null, &DataValue::Int32(1),), + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Eq)?; assert_eq!( evaluator .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(Some(1)),), - DataValue::Boolean(None) + .binary_eval(&DataValue::Null, &DataValue::Int32(1),), + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Integer, BinaryOperator::Eq)?; assert_eq!( - evaluator - .0 - .binary_eval(&DataValue::Int32(None), &DataValue::Int32(None),), - DataValue::Boolean(None) + evaluator.0.binary_eval(&DataValue::Null, &DataValue::Null,), + DataValue::Null ); Ok(()) @@ -909,59 +786,53 @@ mod test { fn test_binary_op_bool_compare() -> Result<(), DatabaseError> { let evaluator = EvaluatorFactory::binary_create(LogicalType::Boolean, BinaryOperator::And)?; assert_eq!( - evaluator.0.binary_eval( - &DataValue::Boolean(Some(true)), - &DataValue::Boolean(Some(true)), - ), - DataValue::Boolean(Some(true)) + evaluator + .0 + .binary_eval(&DataValue::Boolean(true), &DataValue::Boolean(true),), + DataValue::Boolean(true) ); assert_eq!( - evaluator.0.binary_eval( - &DataValue::Boolean(Some(false)), - &DataValue::Boolean(Some(true)), - ), - DataValue::Boolean(Some(false)) + evaluator + .0 + .binary_eval(&DataValue::Boolean(false), &DataValue::Boolean(true),), + DataValue::Boolean(false) ); assert_eq!( - evaluator.0.binary_eval( - &DataValue::Boolean(Some(false)), - &DataValue::Boolean(Some(false)), - ), - DataValue::Boolean(Some(false)) + evaluator + .0 + .binary_eval(&DataValue::Boolean(false), &DataValue::Boolean(false),), + DataValue::Boolean(false) ); assert_eq!( evaluator .0 - .binary_eval(&DataValue::Boolean(None), &DataValue::Boolean(Some(true)),), - DataValue::Boolean(None) + .binary_eval(&DataValue::Null, &DataValue::Boolean(true),), + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create(LogicalType::Boolean, BinaryOperator::Or)?; assert_eq!( - evaluator.0.binary_eval( - &DataValue::Boolean(Some(true)), - &DataValue::Boolean(Some(true)), - ), - DataValue::Boolean(Some(true)) + evaluator + .0 + .binary_eval(&DataValue::Boolean(true), &DataValue::Boolean(true),), + DataValue::Boolean(true) ); assert_eq!( - evaluator.0.binary_eval( - &DataValue::Boolean(Some(false)), - &DataValue::Boolean(Some(true)), - ), - DataValue::Boolean(Some(true)) + evaluator + .0 + .binary_eval(&DataValue::Boolean(false), &DataValue::Boolean(true),), + DataValue::Boolean(true) ); assert_eq!( - evaluator.0.binary_eval( - &DataValue::Boolean(Some(false)), - &DataValue::Boolean(Some(false)), - ), - DataValue::Boolean(Some(false)) + evaluator + .0 + .binary_eval(&DataValue::Boolean(false), &DataValue::Boolean(false),), + DataValue::Boolean(false) ); assert_eq!( evaluator .0 - .binary_eval(&DataValue::Boolean(None), &DataValue::Boolean(Some(true)),), - DataValue::Boolean(Some(true)) + .binary_eval(&DataValue::Null, &DataValue::Boolean(true),), + DataValue::Boolean(true) ); Ok(()) @@ -976,17 +847,17 @@ mod test { assert_eq!( evaluator.0.binary_eval( &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, &DataValue::Utf8 { - value: Some("b".to_string()), + value: "b".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(Some(false)) + DataValue::Boolean(false) ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -995,17 +866,17 @@ mod test { assert_eq!( evaluator.0.binary_eval( &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, &DataValue::Utf8 { - value: Some("b".to_string()), + value: "b".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(Some(true)) + DataValue::Boolean(true) ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1014,17 +885,17 @@ mod test { assert_eq!( evaluator.0.binary_eval( &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(Some(true)) + DataValue::Boolean(true) ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1033,17 +904,17 @@ mod test { assert_eq!( evaluator.0.binary_eval( &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(Some(true)) + DataValue::Boolean(true) ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1052,17 +923,17 @@ mod test { assert_eq!( evaluator.0.binary_eval( &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(Some(false)) + DataValue::Boolean(false) ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1071,17 +942,17 @@ mod test { assert_eq!( evaluator.0.binary_eval( &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(Some(true)) + DataValue::Boolean(true) ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1089,18 +960,14 @@ mod test { )?; assert_eq!( evaluator.0.binary_eval( + &DataValue::Null, &DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }, - &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(None) + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1108,18 +975,14 @@ mod test { )?; assert_eq!( evaluator.0.binary_eval( + &DataValue::Null, &DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }, - &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(None) + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1127,18 +990,14 @@ mod test { )?; assert_eq!( evaluator.0.binary_eval( + &DataValue::Null, &DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }, - &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(None) + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1146,18 +1005,14 @@ mod test { )?; assert_eq!( evaluator.0.binary_eval( + &DataValue::Null, &DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }, - &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(None) + DataValue::Null ); let evaluator = EvaluatorFactory::binary_create( LogicalType::Varchar(None, CharLengthUnits::Characters), @@ -1165,18 +1020,14 @@ mod test { )?; assert_eq!( evaluator.0.binary_eval( + &DataValue::Null, &DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, - }, - &DataValue::Utf8 { - value: Some("a".to_string()), + value: "a".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, ), - DataValue::Boolean(None) + DataValue::Null ); Ok(()) diff --git a/src/types/evaluator/tuple.rs b/src/types/evaluator/tuple.rs index 57cc6935..6c19dfab 100644 --- a/src/types/evaluator/tuple.rs +++ b/src/types/evaluator/tuple.rs @@ -18,8 +18,8 @@ pub struct TupleLtBinaryEvaluator; pub struct TupleLtEqBinaryEvaluator; fn tuple_cmp( - (v1, v1_is_upper): &(Vec, bool), - (v2, v2_is_upper): &(Vec, bool), + (v1, v1_is_upper): (&Vec, &bool), + (v2, v2_is_upper): (&Vec, &bool), ) -> Option { let mut order = Ordering::Equal; let mut v1_iter = v1.iter(); @@ -51,120 +51,88 @@ fn tuple_cmp( #[typetag::serde] impl BinaryEvaluator for TupleEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Tuple(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Tuple(v1, ..), DataValue::Tuple(v2, ..)) => DataValue::Boolean(*v1 == *v2), + (DataValue::Null, DataValue::Boolean(_)) + | (DataValue::Boolean(_), DataValue::Null) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Tuple(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => Some(v1 == v2), - (_, _) => None, - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for TupleNotEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Tuple(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Tuple(v1, ..), DataValue::Tuple(v2, ..)) => DataValue::Boolean(*v1 != *v2), + (DataValue::Null, DataValue::Boolean(_)) + | (DataValue::Boolean(_), DataValue::Null) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Tuple(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => Some(v1 != v2), - (_, _) => None, - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for TupleGtBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Tuple(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Tuple(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Tuple(v1, is_upper1), DataValue::Tuple(v2, is_upper2)) => { + tuple_cmp((v1, is_upper1), (v2, is_upper2)) + .map(|order| DataValue::Boolean(order.is_gt())) + .unwrap_or(DataValue::Null) + } + (DataValue::Null, DataValue::Boolean(_)) + | (DataValue::Boolean(_), DataValue::Null) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => tuple_cmp(v1, v2).map(|order| order.is_gt()), - (_, _) => None, - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for TupleGtEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Tuple(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Tuple(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Tuple(v1, is_upper1), DataValue::Tuple(v2, is_upper2)) => { + tuple_cmp((v1, is_upper1), (v2, is_upper2)) + .map(|order| DataValue::Boolean(order.is_ge())) + .unwrap_or(DataValue::Null) + } + (DataValue::Null, DataValue::Boolean(_)) + | (DataValue::Boolean(_), DataValue::Null) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => tuple_cmp(v1, v2).map(|order| order.is_ge()), - (_, _) => None, - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for TupleLtBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Tuple(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Tuple(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Tuple(v1, is_upper1), DataValue::Tuple(v2, is_upper2)) => { + tuple_cmp((v1, is_upper1), (v2, is_upper2)) + .map(|order| DataValue::Boolean(order.is_lt())) + .unwrap_or(DataValue::Null) + } + (DataValue::Null, DataValue::Boolean(_)) + | (DataValue::Boolean(_), DataValue::Null) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => tuple_cmp(v1, v2).map(|order| order.is_lt()), - (_, _) => None, - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for TupleLtEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Tuple(value) => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Tuple(value) => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Tuple(v1, is_upper1), DataValue::Tuple(v2, is_upper2)) => { + tuple_cmp((v1, is_upper1), (v2, is_upper2)) + .map(|order| DataValue::Boolean(order.is_le())) + .unwrap_or(DataValue::Null) + } + (DataValue::Null, DataValue::Boolean(_)) + | (DataValue::Boolean(_), DataValue::Null) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => tuple_cmp(v1, v2).map(|order| order.is_le()), - (_, _) => None, - }; - DataValue::Boolean(value) + } } } diff --git a/src/types/evaluator/utf8.rs b/src/types/evaluator/utf8.rs index 7ca9ce09..a262e575 100644 --- a/src/types/evaluator/utf8.rs +++ b/src/types/evaluator/utf8.rs @@ -32,195 +32,131 @@ pub struct Utf8NotLikeBinaryEvaluator { #[typetag::serde] impl BinaryEvaluator for Utf8GtBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value: v1, .. }, DataValue::Utf8 { value: v2, .. }) => { + DataValue::Boolean(v1 > v2) + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 > v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for Utf8GtEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value: v1, .. }, DataValue::Utf8 { value: v2, .. }) => { + DataValue::Boolean(v1 >= v2) + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 >= v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for Utf8LtBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value: v1, .. }, DataValue::Utf8 { value: v2, .. }) => { + DataValue::Boolean(v1 < v2) + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 < v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for Utf8LtEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value: v1, .. }, DataValue::Utf8 { value: v2, .. }) => { + DataValue::Boolean(v1 <= v2) + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 <= v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for Utf8EqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value: v1, .. }, DataValue::Utf8 { value: v2, .. }) => { + DataValue::Boolean(v1 == v2) + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 == v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for Utf8NotEqBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value: v1, .. }, DataValue::Utf8 { value: v2, .. }) => { + DataValue::Boolean(v1 != v2) + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = if let (Some(v1), Some(v2)) = (left, right) { - Some(v1 != v2) - } else { - None - }; - DataValue::Boolean(value) + } } } #[typetag::serde] impl BinaryEvaluator for Utf8StringConcatBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let left = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let right = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value: v1, .. }, DataValue::Utf8 { value: v2, .. }) => { + DataValue::Utf8 { + value: v1.clone() + v2, + ty: Utf8Type::Variable(None), + unit: CharLengthUnits::Characters, + } + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let value = match (left, right) { - (Some(v1), Some(v2)) => Some(v1.clone() + v2), - _ => None, - }; - DataValue::Utf8 { - value, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, } } } #[typetag::serde] impl BinaryEvaluator for Utf8LikeBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let value = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let pattern = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value, .. }, DataValue::Utf8 { value: pattern, .. }) => { + DataValue::Boolean(string_like(value, pattern, self.escape_char)) + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let is_match = if let (Some(value), Some(pattern)) = (value, pattern) { - string_like(value, pattern, self.escape_char) - } else { - return DataValue::Boolean(None); - }; - - DataValue::Boolean(Some(is_match)) + } } } #[typetag::serde] impl BinaryEvaluator for Utf8NotLikeBinaryEvaluator { fn binary_eval(&self, left: &DataValue, right: &DataValue) -> DataValue { - let value = match left { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, - _ => unsafe { hint::unreachable_unchecked() }, - }; - let pattern = match right { - DataValue::Utf8 { value, .. } => value, - DataValue::Null => &None, + match (left, right) { + (DataValue::Utf8 { value, .. }, DataValue::Utf8 { value: pattern, .. }) => { + DataValue::Boolean(!string_like(value, pattern, self.escape_char)) + } + (DataValue::Utf8 { .. }, DataValue::Null) + | (DataValue::Null, DataValue::Utf8 { .. }) + | (DataValue::Null, DataValue::Null) => DataValue::Null, _ => unsafe { hint::unreachable_unchecked() }, - }; - let is_match = if let (Some(value), Some(pattern)) = (value, pattern) { - string_like(value, pattern, self.escape_char) - } else { - return DataValue::Boolean(None); - }; - - DataValue::Boolean(Some(!is_match)) + } } } diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 3b7ceaf4..364247fb 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -51,7 +51,7 @@ impl Tuple { for i in pk_indices.iter() { values.push(self.values[*i].clone()); } - DataValue::Tuple(Some((values, false))) + DataValue::Tuple(values, false) } }) }) @@ -174,6 +174,7 @@ mod tests { use crate::types::LogicalType; use bumpalo::Bump; use itertools::Itertools; + use ordered_float::OrderedFloat; use rust_decimal::Decimal; use sqlparser::ast::CharLengthUnits; use std::sync::Arc; @@ -291,35 +292,35 @@ mod tests { Tuple::new( Some(Arc::new(vec![0])), vec![ - DataValue::Int32(Some(0)), - DataValue::UInt32(Some(1)), + DataValue::Int32(0), + DataValue::UInt32(1), DataValue::Utf8 { - value: Some("LOL".to_string()), + value: "LOL".to_string(), ty: Utf8Type::Variable(Some(2)), unit: CharLengthUnits::Characters, }, - DataValue::Int16(Some(1)), - DataValue::UInt16(Some(1)), - DataValue::Float32(Some(0.1)), - DataValue::Float64(Some(0.1)), - DataValue::Int8(Some(1)), - DataValue::UInt8(Some(1)), - DataValue::Boolean(Some(true)), - DataValue::Date64(Some(0)), - DataValue::Date32(Some(0)), - DataValue::Decimal(Some(Decimal::new(0, 3))), + DataValue::Int16(1), + DataValue::UInt16(1), + DataValue::Float32(OrderedFloat(0.1)), + DataValue::Float64(OrderedFloat(0.1)), + DataValue::Int8(1), + DataValue::UInt8(1), + DataValue::Boolean(true), + DataValue::Date64(0), + DataValue::Date32(0), + DataValue::Decimal(Decimal::new(0, 3)), DataValue::Utf8 { - value: Some("K".to_string()), + value: "K".to_string(), ty: Utf8Type::Fixed(1), unit: CharLengthUnits::Characters, }, DataValue::Utf8 { - value: Some("LOL".to_string()), + value: "LOL".to_string(), ty: Utf8Type::Variable(Some(2)), unit: CharLengthUnits::Octets, }, DataValue::Utf8 { - value: Some("K".to_string()), + value: "K".to_string(), ty: Utf8Type::Fixed(10), unit: CharLengthUnits::Octets, }, @@ -328,38 +329,22 @@ mod tests { Tuple::new( Some(Arc::new(vec![0])), vec![ - DataValue::Int32(Some(1)), - DataValue::UInt32(None), - DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(Some(2)), - unit: CharLengthUnits::Characters, - }, - DataValue::Int16(None), - DataValue::UInt16(None), - DataValue::Float32(None), - DataValue::Float64(None), - DataValue::Int8(None), - DataValue::UInt8(None), - DataValue::Boolean(None), - DataValue::Date64(None), - DataValue::Date32(None), - DataValue::Decimal(None), - DataValue::Utf8 { - value: None, - ty: Utf8Type::Fixed(1), - unit: CharLengthUnits::Characters, - }, - DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(Some(2)), - unit: CharLengthUnits::Octets, - }, - DataValue::Utf8 { - value: None, - ty: Utf8Type::Fixed(10), - unit: CharLengthUnits::Octets, - }, + DataValue::Int32(1), + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, + DataValue::Null, ], ), ]; diff --git a/src/types/tuple_builder.rs b/src/types/tuple_builder.rs index 9bf6b186..da6acbec 100644 --- a/src/types/tuple_builder.rs +++ b/src/types/tuple_builder.rs @@ -16,7 +16,7 @@ impl<'a> TupleBuilder<'a> { pub fn build_result(message: String) -> Tuple { let values = vec![DataValue::Utf8 { - value: Some(message), + value: message, ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }]; @@ -33,7 +33,7 @@ impl<'a> TupleBuilder<'a> { for (i, value) in row.into_iter().enumerate() { values.push( DataValue::Utf8 { - value: Some(value.to_string()), + value: value.to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, } diff --git a/src/types/value.rs b/src/types/value.rs index 7fedc236..9851bcbc 100644 --- a/src/types/value.rs +++ b/src/types/value.rs @@ -40,30 +40,30 @@ pub enum Utf8Type { #[derive(Clone, serde::Serialize, serde::Deserialize)] pub enum DataValue { Null, - Boolean(Option), - Float32(Option), - Float64(Option), - Int8(Option), - Int16(Option), - Int32(Option), - Int64(Option), - UInt8(Option), - UInt16(Option), - UInt32(Option), - UInt64(Option), + Boolean(bool), + Float32(OrderedFloat), + Float64(OrderedFloat), + Int8(i8), + Int16(i16), + Int32(i32), + Int64(i64), + UInt8(u8), + UInt16(u16), + UInt32(u32), + UInt64(u64), Utf8 { - value: Option, + value: String, ty: Utf8Type, unit: CharLengthUnits, }, /// Date stored as a signed 32bit int days since UNIX epoch 1970-01-01 - Date32(Option), + Date32(i32), /// Date stored as a signed 64bit int timestamp since UNIX epoch 1970-01-01 - Date64(Option), - Time(Option), - Decimal(Option), + Date64(i64), + Time(u32), + Decimal(Decimal), /// (values, is_upper) - Tuple(Option<(Vec, bool)>), + Tuple(Vec, bool), } macro_rules! generate_get_option { @@ -71,7 +71,7 @@ macro_rules! generate_get_option { impl $data_value { $( pub fn $prefix(&self) -> $field { - if let $data_value::$variant(Some(val)) = self { + if let $data_value::$variant(val) = self { Some(val.clone()) } else { None @@ -84,8 +84,6 @@ macro_rules! generate_get_option { generate_get_option!(DataValue, bool : Boolean(Option), - float : Float32(Option), - double : Float64(Option), i8 : Int8(Option), i16 : Int16(Option), i32 : Int32(Option), @@ -108,17 +106,9 @@ impl PartialEq for DataValue { match (self, other) { (Boolean(v1), Boolean(v2)) => v1.eq(v2), (Boolean(_), _) => false, - (Float32(v1), Float32(v2)) => { - let v1 = v1.map(OrderedFloat); - let v2 = v2.map(OrderedFloat); - v1.eq(&v2) - } + (Float32(v1), Float32(v2)) => v1.eq(v2), (Float32(_), _) => false, - (Float64(v1), Float64(v2)) => { - let v1 = v1.map(OrderedFloat); - let v2 = v2.map(OrderedFloat); - v1.eq(&v2) - } + (Float64(v1), Float64(v2)) => v1.eq(v2), (Float64(_), _) => false, (Int8(v1), Int8(v2)) => v1.eq(v2), (Int8(_), _) => false, @@ -148,8 +138,10 @@ impl PartialEq for DataValue { (Time(_), _) => false, (Decimal(v1), Decimal(v2)) => v1.eq(v2), (Decimal(_), _) => false, - (Tuple(values_1), Tuple(values_2)) => values_1.eq(values_2), - (Tuple(_), _) => false, + (Tuple(values_1, is_upper_1), Tuple(values_2, is_upper_2)) => { + values_1.eq(values_2) && is_upper_1.eq(is_upper_2) + } + (Tuple(..), _) => false, } } } @@ -160,17 +152,9 @@ impl PartialOrd for DataValue { match (self, other) { (Boolean(v1), Boolean(v2)) => v1.partial_cmp(v2), (Boolean(_), _) => None, - (Float32(v1), Float32(v2)) => { - let v1 = v1.map(OrderedFloat); - let v2 = v2.map(OrderedFloat); - v1.partial_cmp(&v2) - } + (Float32(v1), Float32(v2)) => v1.partial_cmp(v2), (Float32(_), _) => None, - (Float64(v1), Float64(v2)) => { - let v1 = v1.map(OrderedFloat); - let v2 = v2.map(OrderedFloat); - v1.partial_cmp(&v2) - } + (Float64(v1), Float64(v2)) => v1.partial_cmp(v2), (Float64(_), _) => None, (Int8(v1), Int8(v2)) => v1.partial_cmp(v2), (Int8(_), _) => None, @@ -200,7 +184,7 @@ impl PartialOrd for DataValue { (Time(_), _) => None, (Decimal(v1), Decimal(v2)) => v1.partial_cmp(v2), (Decimal(_), _) => None, - (Tuple(_), _) => None, + (Tuple(..), _) => None, } } } @@ -218,14 +202,8 @@ impl Hash for DataValue { use DataValue::*; match self { Boolean(v) => v.hash(state), - Float32(v) => { - let v = v.map(OrderedFloat); - v.hash(state) - } - Float64(v) => { - let v = v.map(OrderedFloat); - v.hash(state) - } + Float32(v) => v.hash(state), + Float64(v) => v.hash(state), Int8(v) => v.hash(state), Int16(v) => v.hash(state), Int32(v) => v.hash(state), @@ -240,58 +218,66 @@ impl Hash for DataValue { Date64(v) => v.hash(state), Time(v) => v.hash(state), Decimal(v) => v.hash(state), - Tuple(values) => values.hash(state), + Tuple(values, is_upper) => { + values.hash(state); + is_upper.hash(state); + } } } } macro_rules! varchar_cast { - ($value:expr, $len:expr, $ty:expr, $unit:expr) => { - $value - .map(|v| { - let string_value = format!("{}", v); - if let Some(len) = $len { - if Self::check_string_len(&string_value, *len as usize, $unit) { - return Err(DatabaseError::TooLong); - } - } - Ok(DataValue::Utf8 { - value: Some(string_value), - ty: $ty, - unit: $unit, - }) - }) - .unwrap_or(Ok(DataValue::Utf8 { - value: None, - ty: $ty, - unit: $unit, - })) - }; + ($value:expr, $len:expr, $ty:expr, $unit:expr) => {{ + let s_value = $value.to_string(); + if let Some(len) = $len { + if Self::check_string_len(&s_value, *len as usize, $unit) { + return Err(DatabaseError::TooLong); + } + } + Ok(DataValue::Utf8 { + value: s_value, + ty: $ty, + unit: $unit, + }) + }}; } macro_rules! numeric_to_boolean { ($value:expr) => { match $value { - Some(0) => Ok(DataValue::Boolean(Some(false))), - Some(1) => Ok(DataValue::Boolean(Some(true))), + 0 => Ok(DataValue::Boolean(false)), + 1 => Ok(DataValue::Boolean(true)), _ => Err(DatabaseError::CastFail), } }; } impl DataValue { - pub fn utf8(&self) -> Option { - if let DataValue::Utf8 { - value: Some(val), .. - } = self - { - Some(val.clone()) + pub fn float(&self) -> Option { + if let DataValue::Float32(val) = self { + Some(val.0) + } else { + None + } + } + + pub fn double(&self) -> Option { + if let DataValue::Float64(val) = self { + Some(val.0) + } else { + None + } + } + + pub fn utf8(&self) -> Option<&str> { + if let DataValue::Utf8 { value, .. } = self { + Some(value) } else { None } } pub fn date(&self) -> Option { - if let DataValue::Date32(Some(val)) = self { + if let DataValue::Date32(val) = self { NaiveDate::from_num_days_from_ce_opt(*val) } else { None @@ -299,7 +285,7 @@ impl DataValue { } pub fn datetime(&self) -> Option { - if let DataValue::Date64(Some(val)) = self { + if let DataValue::Date64(val) = self { DateTime::from_timestamp(*val, 0).map(|dt| dt.naive_utc()) } else { None @@ -307,7 +293,7 @@ impl DataValue { } pub fn time(&self) -> Option { - if let DataValue::Time(Some(val)) = self { + if let DataValue::Time(val) = self { NaiveTime::from_num_seconds_from_midnight_opt(*val, 0) } else { None @@ -329,7 +315,7 @@ impl DataValue { ( LogicalType::Varchar(Some(len), CharLengthUnits::Characters), DataValue::Utf8 { - value: Some(val), + value: val, ty: Utf8Type::Variable(_), unit: CharLengthUnits::Characters, }, @@ -337,7 +323,7 @@ impl DataValue { | ( LogicalType::Char(len, CharLengthUnits::Characters), DataValue::Utf8 { - value: Some(val), + value: val, ty: Utf8Type::Fixed(_), unit: CharLengthUnits::Characters, }, @@ -345,7 +331,7 @@ impl DataValue { ( LogicalType::Varchar(Some(len), CharLengthUnits::Octets), DataValue::Utf8 { - value: Some(val), + value: val, ty: Utf8Type::Variable(_), unit: CharLengthUnits::Octets, }, @@ -353,12 +339,12 @@ impl DataValue { | ( LogicalType::Char(len, CharLengthUnits::Octets), DataValue::Utf8 { - value: Some(val), + value: val, ty: Utf8Type::Fixed(_), unit: CharLengthUnits::Octets, }, ) => Self::check_string_len(val, *len as usize, CharLengthUnits::Octets), - (LogicalType::Decimal(full_len, scale_len), DataValue::Decimal(Some(val))) => { + (LogicalType::Decimal(full_len, scale_len), DataValue::Decimal(val)) => { if let Some(len) = full_len { let mantissa = val.mantissa().abs(); if mantissa != 0 && mantissa.ilog10() + 1 > *len as u32 { @@ -382,74 +368,21 @@ impl DataValue { Ok(()) } - fn format_date(value: Option) -> Option { - value.and_then(|v| Self::date_format(v).map(|fmt| format!("{}", fmt))) + fn format_date(value: i32) -> Option { + Self::date_format(value).map(|fmt| format!("{}", fmt)) } - fn format_datetime(value: Option) -> Option { - value.and_then(|v| Self::date_time_format(v).map(|fmt| format!("{}", fmt))) + fn format_datetime(value: i64) -> Option { + Self::date_time_format(value).map(|fmt| format!("{}", fmt)) } - fn format_time(value: Option) -> Option { - value.and_then(|v| Self::time_format(v).map(|fmt| format!("{}", fmt))) + fn format_time(value: u32) -> Option { + Self::time_format(value).map(|fmt| format!("{}", fmt)) } #[inline] pub fn is_null(&self) -> bool { - match self { - DataValue::Null => true, - DataValue::Boolean(value) => value.is_none(), - DataValue::Float32(value) => value.is_none(), - DataValue::Float64(value) => value.is_none(), - DataValue::Int8(value) => value.is_none(), - DataValue::Int16(value) => value.is_none(), - DataValue::Int32(value) => value.is_none(), - DataValue::Int64(value) => value.is_none(), - DataValue::UInt8(value) => value.is_none(), - DataValue::UInt16(value) => value.is_none(), - DataValue::UInt32(value) => value.is_none(), - DataValue::UInt64(value) => value.is_none(), - DataValue::Utf8 { value, .. } => value.is_none(), - DataValue::Date32(value) => value.is_none(), - DataValue::Date64(value) => value.is_none(), - DataValue::Time(value) => value.is_none(), - DataValue::Decimal(value) => value.is_none(), - DataValue::Tuple(value) => value.is_none(), - } - } - - #[inline] - pub fn none(logic_type: &LogicalType) -> DataValue { - match logic_type { - LogicalType::Invalid => panic!("invalid logical type"), - LogicalType::SqlNull => DataValue::Null, - LogicalType::Boolean => DataValue::Boolean(None), - LogicalType::Tinyint => DataValue::Int8(None), - LogicalType::UTinyint => DataValue::UInt8(None), - LogicalType::Smallint => DataValue::Int16(None), - LogicalType::USmallint => DataValue::UInt16(None), - LogicalType::Integer => DataValue::Int32(None), - LogicalType::UInteger => DataValue::UInt32(None), - LogicalType::Bigint => DataValue::Int64(None), - LogicalType::UBigint => DataValue::UInt64(None), - LogicalType::Float => DataValue::Float32(None), - LogicalType::Double => DataValue::Float64(None), - LogicalType::Char(len, unit) => DataValue::Utf8 { - value: None, - ty: Utf8Type::Fixed(*len), - unit: *unit, - }, - LogicalType::Varchar(len, unit) => DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(*len), - unit: *unit, - }, - LogicalType::Date => DataValue::Date32(None), - LogicalType::DateTime => DataValue::Date64(None), - LogicalType::Time => DataValue::Time(None), - LogicalType::Decimal(_, _) => DataValue::Decimal(None), - LogicalType::Tuple(_) => DataValue::Tuple(None), - } + matches!(self, DataValue::Null) } #[inline] @@ -457,35 +390,35 @@ impl DataValue { match logic_type { LogicalType::Invalid => panic!("invalid logical type"), LogicalType::SqlNull => DataValue::Null, - LogicalType::Boolean => DataValue::Boolean(Some(false)), - LogicalType::Tinyint => DataValue::Int8(Some(0)), - LogicalType::UTinyint => DataValue::UInt8(Some(0)), - LogicalType::Smallint => DataValue::Int16(Some(0)), - LogicalType::USmallint => DataValue::UInt16(Some(0)), - LogicalType::Integer => DataValue::Int32(Some(0)), - LogicalType::UInteger => DataValue::UInt32(Some(0)), - LogicalType::Bigint => DataValue::Int64(Some(0)), - LogicalType::UBigint => DataValue::UInt64(Some(0)), - LogicalType::Float => DataValue::Float32(Some(0.0)), - LogicalType::Double => DataValue::Float64(Some(0.0)), + LogicalType::Boolean => DataValue::Boolean(false), + LogicalType::Tinyint => DataValue::Int8(0), + LogicalType::UTinyint => DataValue::UInt8(0), + LogicalType::Smallint => DataValue::Int16(0), + LogicalType::USmallint => DataValue::UInt16(0), + LogicalType::Integer => DataValue::Int32(0), + LogicalType::UInteger => DataValue::UInt32(0), + LogicalType::Bigint => DataValue::Int64(0), + LogicalType::UBigint => DataValue::UInt64(0), + LogicalType::Float => DataValue::Float32(OrderedFloat(0.0)), + LogicalType::Double => DataValue::Float64(OrderedFloat(0.0)), LogicalType::Char(len, unit) => DataValue::Utf8 { - value: Some(String::new()), + value: String::new(), ty: Utf8Type::Fixed(*len), unit: *unit, }, LogicalType::Varchar(len, unit) => DataValue::Utf8 { - value: Some(String::new()), + value: String::new(), ty: Utf8Type::Variable(*len), unit: *unit, }, - LogicalType::Date => DataValue::Date32(Some(UNIX_DATETIME.num_days_from_ce())), - LogicalType::DateTime => DataValue::Date64(Some(UNIX_DATETIME.and_utc().timestamp())), - LogicalType::Time => DataValue::Time(Some(UNIX_TIME.num_seconds_from_midnight())), - LogicalType::Decimal(_, _) => DataValue::Decimal(Some(Decimal::new(0, 0))), + LogicalType::Date => DataValue::Date32(UNIX_DATETIME.num_days_from_ce()), + LogicalType::DateTime => DataValue::Date64(UNIX_DATETIME.and_utc().timestamp()), + LogicalType::Time => DataValue::Time(UNIX_TIME.num_seconds_from_midnight()), + LogicalType::Decimal(_, _) => DataValue::Decimal(Decimal::new(0, 0)), LogicalType::Tuple(types) => { let values = types.iter().map(DataValue::init).collect_vec(); - DataValue::Tuple(Some((values, false))) + DataValue::Tuple(values, false) } } } @@ -495,131 +428,97 @@ impl DataValue { match self { DataValue::Null => (), DataValue::Boolean(v) => { - if let Some(v) = v { - writer.write_u8(*v as u8)?; - return Ok(()); - } + writer.write_u8(*v as u8)?; + return Ok(()); } DataValue::Float32(v) => { - if let Some(v) = v { - writer.write_f32::(*v)?; - return Ok(()); - } + writer.write_f32::(v.0)?; + return Ok(()); } DataValue::Float64(v) => { - if let Some(v) = v { - writer.write_f64::(*v)?; - return Ok(()); - } + writer.write_f64::(v.0)?; + return Ok(()); } DataValue::Int8(v) => { - if let Some(v) = v { - writer.write_i8(*v)?; - return Ok(()); - } + writer.write_i8(*v)?; + return Ok(()); } DataValue::Int16(v) => { - if let Some(v) = v { - writer.write_i16::(*v)?; - return Ok(()); - } + writer.write_i16::(*v)?; + return Ok(()); } DataValue::Int32(v) => { - if let Some(v) = v { - writer.write_i32::(*v)?; - return Ok(()); - } + writer.write_i32::(*v)?; + return Ok(()); } DataValue::Int64(v) => { - if let Some(v) = v { - writer.write_i64::(*v)?; - return Ok(()); - } + writer.write_i64::(*v)?; + return Ok(()); } DataValue::UInt8(v) => { - if let Some(v) = v { - writer.write_u8(*v)?; - return Ok(()); - } + writer.write_u8(*v)?; + return Ok(()); } DataValue::UInt16(v) => { - if let Some(v) = v { - writer.write_u16::(*v)?; - return Ok(()); - } + writer.write_u16::(*v)?; + return Ok(()); } DataValue::UInt32(v) => { - if let Some(v) = v { - writer.write_u32::(*v)?; - return Ok(()); - } + writer.write_u32::(*v)?; + return Ok(()); } DataValue::UInt64(v) => { - if let Some(v) = v { - writer.write_u64::(*v)?; + writer.write_u64::(*v)?; + return Ok(()); + } + DataValue::Utf8 { value: v, ty, unit } => match ty { + Utf8Type::Variable(_) => { + let bytes = v.as_bytes(); + + writer.write_u32::(bytes.len() as u32)?; + writer.write_all(bytes)?; return Ok(()); } - } - DataValue::Utf8 { value: v, ty, unit } => { - if let Some(v) = v { - match ty { - Utf8Type::Variable(_) => { - let bytes = v.as_bytes(); - - writer.write_u32::(bytes.len() as u32)?; - writer.write_all(bytes)?; - return Ok(()); + Utf8Type::Fixed(len) => match unit { + CharLengthUnits::Characters => { + let chars_len = *len as usize; + let v = format!("{:len$}", v, len = chars_len); + let bytes = v.as_bytes(); + + writer.write_u32::(bytes.len() as u32)?; + writer.write_all(bytes)?; + return Ok(()); + } + CharLengthUnits::Octets => { + let octets_len = *len as usize; + let bytes = v.as_bytes(); + debug_assert!(octets_len >= bytes.len()); + + writer.write_all(bytes)?; + for _ in 0..octets_len - bytes.len() { + writer.write_u8(b' ')?; } - Utf8Type::Fixed(len) => match unit { - CharLengthUnits::Characters => { - let chars_len = *len as usize; - let v = format!("{:len$}", v, len = chars_len); - let bytes = v.as_bytes(); - - writer.write_u32::(bytes.len() as u32)?; - writer.write_all(bytes)?; - return Ok(()); - } - CharLengthUnits::Octets => { - let octets_len = *len as usize; - let bytes = v.as_bytes(); - debug_assert!(octets_len >= bytes.len()); - - writer.write_all(bytes)?; - for _ in 0..octets_len - bytes.len() { - writer.write_u8(b' ')?; - } - return Ok(()); - } - }, + return Ok(()); } - } - } + }, + }, DataValue::Date32(v) => { - if let Some(v) = v { - writer.write_i32::(*v)?; - return Ok(()); - } + writer.write_i32::(*v)?; + return Ok(()); } DataValue::Date64(v) => { - if let Some(v) = v { - writer.write_i64::(*v)?; - return Ok(()); - } + writer.write_i64::(*v)?; + return Ok(()); } DataValue::Time(v) => { - if let Some(v) = v { - writer.write_u32::(*v)?; - return Ok(()); - } + writer.write_u32::(*v)?; + return Ok(()); } DataValue::Decimal(v) => { - if let Some(v) = v { - writer.write_all(&v.serialize())?; - return Ok(()); - } + writer.write_all(&v.serialize())?; + return Ok(()); } - DataValue::Tuple(_) => unreachable!(), + DataValue::Tuple(..) => unreachable!(), } Ok(()) } @@ -643,77 +542,77 @@ impl DataValue { reader.seek(SeekFrom::Current(1))?; return Ok(None); } - DataValue::Boolean(Some(reader.read_u8()? != 0)) + DataValue::Boolean(reader.read_u8()? != 0) } LogicalType::Tinyint => { if !is_projection { reader.seek(SeekFrom::Current(1))?; return Ok(None); } - DataValue::Int8(Some(reader.read_i8()?)) + DataValue::Int8(reader.read_i8()?) } LogicalType::UTinyint => { if !is_projection { reader.seek(SeekFrom::Current(1))?; return Ok(None); } - DataValue::UInt8(Some(reader.read_u8()?)) + DataValue::UInt8(reader.read_u8()?) } LogicalType::Smallint => { if !is_projection { reader.seek(SeekFrom::Current(2))?; return Ok(None); } - DataValue::Int16(Some(reader.read_i16::()?)) + DataValue::Int16(reader.read_i16::()?) } LogicalType::USmallint => { if !is_projection { reader.seek(SeekFrom::Current(2))?; return Ok(None); } - DataValue::UInt16(Some(reader.read_u16::()?)) + DataValue::UInt16(reader.read_u16::()?) } LogicalType::Integer => { if !is_projection { reader.seek(SeekFrom::Current(4))?; return Ok(None); } - DataValue::Int32(Some(reader.read_i32::()?)) + DataValue::Int32(reader.read_i32::()?) } LogicalType::UInteger => { if !is_projection { reader.seek(SeekFrom::Current(4))?; return Ok(None); } - DataValue::UInt32(Some(reader.read_u32::()?)) + DataValue::UInt32(reader.read_u32::()?) } LogicalType::Bigint => { if !is_projection { reader.seek(SeekFrom::Current(8))?; return Ok(None); } - DataValue::Int64(Some(reader.read_i64::()?)) + DataValue::Int64(reader.read_i64::()?) } LogicalType::UBigint => { if !is_projection { reader.seek(SeekFrom::Current(8))?; return Ok(None); } - DataValue::UInt64(Some(reader.read_u64::()?)) + DataValue::UInt64(reader.read_u64::()?) } LogicalType::Float => { if !is_projection { reader.seek(SeekFrom::Current(4))?; return Ok(None); } - DataValue::Float32(Some(reader.read_f32::()?)) + DataValue::Float32(OrderedFloat(reader.read_f32::()?)) } LogicalType::Double => { if !is_projection { reader.seek(SeekFrom::Current(8))?; return Ok(None); } - DataValue::Float64(Some(reader.read_f64::()?)) + DataValue::Float64(OrderedFloat(reader.read_f64::()?)) } LogicalType::Char(ty_len, unit) => { // https://dev.mysql.com/doc/refman/8.0/en/char.html#:~:text=If%20a%20given%20value%20is%20stored%20into%20the%20CHAR(4)%20and%20VARCHAR(4)%20columns%2C%20the%20values%20retrieved%20from%20the%20columns%20are%20not%20always%20the%20same%20because%20trailing%20spaces%20are%20removed%20from%20CHAR%20columns%20upon%20retrieval.%20The%20following%20example%20illustrates%20this%20difference%3A @@ -734,7 +633,7 @@ impl DataValue { bytes.truncate(last_non_zero_index); DataValue::Utf8 { - value: Some(String::from_utf8(bytes)?), + value: String::from_utf8(bytes)?, ty: Utf8Type::Fixed(*ty_len), unit: *unit, } @@ -749,7 +648,7 @@ impl DataValue { reader.read_exact(&mut bytes)?; DataValue::Utf8 { - value: Some(String::from_utf8(bytes)?), + value: String::from_utf8(bytes)?, ty: Utf8Type::Variable(*ty_len), unit: *unit, } @@ -759,21 +658,21 @@ impl DataValue { reader.seek(SeekFrom::Current(4))?; return Ok(None); } - DataValue::Date32(Some(reader.read_i32::()?)) + DataValue::Date32(reader.read_i32::()?) } LogicalType::DateTime => { if !is_projection { reader.seek(SeekFrom::Current(8))?; return Ok(None); } - DataValue::Date64(Some(reader.read_i64::()?)) + DataValue::Date64(reader.read_i64::()?) } LogicalType::Time => { if !is_projection { reader.seek(SeekFrom::Current(4))?; return Ok(None); } - DataValue::Time(Some(reader.read_u32::()?)) + DataValue::Time(reader.read_u32::()?) } LogicalType::Decimal(_, _) => { if !is_projection { @@ -783,7 +682,7 @@ impl DataValue { let mut bytes = [0u8; 16]; reader.read_exact(&mut bytes)?; - DataValue::Decimal(Some(Decimal::deserialize(bytes))) + DataValue::Decimal(Decimal::deserialize(bytes)) } LogicalType::Tuple(_) => unreachable!(), }; @@ -819,13 +718,9 @@ impl DataValue { DataValue::Date64(_) => LogicalType::DateTime, DataValue::Time(_) => LogicalType::Time, DataValue::Decimal(_) => LogicalType::Decimal(None, None), - DataValue::Tuple(values) => { - if let Some((values, _)) = values { - let types = values.iter().map(|v| v.logical_type()).collect_vec(); - LogicalType::Tuple(types) - } else { - LogicalType::Tuple(vec![]) - } + DataValue::Tuple(values, ..) => { + let types = values.iter().map(|v| v.logical_type()).collect_vec(); + LogicalType::Tuple(types) } } } @@ -883,24 +778,24 @@ impl DataValue { #[inline] pub fn memcomparable_encode(&self, b: &mut BumpBytes) -> Result<(), DatabaseError> { match self { - DataValue::Int8(Some(v)) => encode_u!(b, *v as u8 ^ 0x80_u8), - DataValue::Int16(Some(v)) => encode_u!(b, *v as u16 ^ 0x8000_u16), - DataValue::Int32(Some(v)) | DataValue::Date32(Some(v)) => { + DataValue::Int8(v) => encode_u!(b, *v as u8 ^ 0x80_u8), + DataValue::Int16(v) => encode_u!(b, *v as u16 ^ 0x8000_u16), + DataValue::Int32(v) | DataValue::Date32(v) => { encode_u!(b, *v as u32 ^ 0x80000000_u32) } - DataValue::Int64(Some(v)) | DataValue::Date64(Some(v)) => { + DataValue::Int64(v) | DataValue::Date64(v) => { encode_u!(b, *v as u64 ^ 0x8000000000000000_u64) } - DataValue::UInt8(Some(v)) => encode_u!(b, v), - DataValue::UInt16(Some(v)) => encode_u!(b, v), - DataValue::UInt32(Some(v)) | DataValue::Time(Some(v)) => encode_u!(b, v), - DataValue::UInt64(Some(v)) => encode_u!(b, v), - DataValue::Utf8 { value: Some(v), .. } => Self::encode_bytes(b, v.as_bytes()), - DataValue::Boolean(Some(v)) => b.push(if *v { b'1' } else { b'0' }), - DataValue::Float32(Some(f)) => { + DataValue::UInt8(v) => encode_u!(b, v), + DataValue::UInt16(v) => encode_u!(b, v), + DataValue::UInt32(v) | DataValue::Time(v) => encode_u!(b, v), + DataValue::UInt64(v) => encode_u!(b, v), + DataValue::Utf8 { value: v, .. } => Self::encode_bytes(b, v.as_bytes()), + DataValue::Boolean(v) => b.push(if *v { b'1' } else { b'0' }), + DataValue::Float32(f) => { let mut u = f.to_bits(); - if *f >= 0_f32 { + if f.0 >= 0_f32 { u |= 0x80000000_u32; } else { u = !u; @@ -908,10 +803,10 @@ impl DataValue { encode_u!(b, u); } - DataValue::Float64(Some(f)) => { + DataValue::Float64(f) => { let mut u = f.to_bits(); - if *f >= 0_f64 { + if f.0 >= 0_f64 { u |= 0x8000000000000000_u64; } else { u = !u; @@ -920,8 +815,8 @@ impl DataValue { encode_u!(b, u); } DataValue::Null => (), - DataValue::Decimal(Some(v)) => Self::serialize_decimal(*v, b)?, - DataValue::Tuple(Some((values, is_upper))) => { + DataValue::Decimal(v) => Self::serialize_decimal(*v, b)?, + DataValue::Tuple(values, is_upper) => { let last = values.len() - 1; for (i, v) in values.iter().enumerate() { @@ -933,11 +828,6 @@ impl DataValue { } } } - value => { - if !value.is_null() { - return Err(DatabaseError::InvalidType); - } - } } Ok(()) @@ -1067,8 +957,8 @@ impl DataValue { if self.is_null() { return Ok(false); } - if let DataValue::Boolean(option) = self { - Ok(matches!(option, Some(true))) + if let DataValue::Boolean(is_true) = self { + Ok(*is_true) } else { Err(DatabaseError::InvalidType) } @@ -1078,47 +968,21 @@ impl DataValue { let value = match self { DataValue::Null => match to { LogicalType::Invalid => Err(DatabaseError::CastFail), - LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::Boolean => Ok(DataValue::Boolean(None)), - LogicalType::Tinyint => Ok(DataValue::Int8(None)), - LogicalType::UTinyint => Ok(DataValue::UInt8(None)), - LogicalType::Smallint => Ok(DataValue::Int16(None)), - LogicalType::USmallint => Ok(DataValue::UInt16(None)), - LogicalType::Integer => Ok(DataValue::Int32(None)), - LogicalType::UInteger => Ok(DataValue::UInt32(None)), - LogicalType::Bigint => Ok(DataValue::Int64(None)), - LogicalType::UBigint => Ok(DataValue::UInt64(None)), - LogicalType::Float => Ok(DataValue::Float32(None)), - LogicalType::Double => Ok(DataValue::Float64(None)), - LogicalType::Char(len, unit) => Ok(DataValue::Utf8 { - value: None, - ty: Utf8Type::Fixed(*len), - unit: *unit, - }), - LogicalType::Varchar(len, unit) => Ok(DataValue::Utf8 { - value: None, - ty: Utf8Type::Variable(*len), - unit: *unit, - }), - LogicalType::Date => Ok(DataValue::Date32(None)), - LogicalType::DateTime => Ok(DataValue::Date64(None)), - LogicalType::Time => Ok(DataValue::Time(None)), - LogicalType::Decimal(_, _) => Ok(DataValue::Decimal(None)), - LogicalType::Tuple(_) => Ok(DataValue::Tuple(None)), + _ => Ok(DataValue::Null), }, DataValue::Boolean(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Boolean => Ok(DataValue::Boolean(value)), - LogicalType::Tinyint => Ok(DataValue::Int8(value.map(|v| v.into()))), - LogicalType::UTinyint => Ok(DataValue::UInt8(value.map(|v| v.into()))), - LogicalType::Smallint => Ok(DataValue::Int16(value.map(|v| v.into()))), - LogicalType::USmallint => Ok(DataValue::UInt16(value.map(|v| v.into()))), - LogicalType::Integer => Ok(DataValue::Int32(value.map(|v| v.into()))), - LogicalType::UInteger => Ok(DataValue::UInt32(value.map(|v| v.into()))), - LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), - LogicalType::UBigint => Ok(DataValue::UInt64(value.map(|v| v.into()))), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), + LogicalType::Tinyint => Ok(DataValue::Int8(value.into())), + LogicalType::UTinyint => Ok(DataValue::UInt8(value.into())), + LogicalType::Smallint => Ok(DataValue::Int16(value.into())), + LogicalType::USmallint => Ok(DataValue::UInt16(value.into())), + LogicalType::Integer => Ok(DataValue::Int32(value.into())), + LogicalType::UInteger => Ok(DataValue::UInt32(value.into())), + LogicalType::Bigint => Ok(DataValue::Int64(value.into())), + LogicalType::UBigint => Ok(DataValue::UInt64(value.into())), + LogicalType::Float => Ok(DataValue::Float32(value.into())), + LogicalType::Double => Ok(DataValue::Float64(value.into())), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } @@ -1130,29 +994,24 @@ impl DataValue { DataValue::Float32(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Float => Ok(DataValue::Float32(value)), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), + LogicalType::Double => Ok(DataValue::Float64(OrderedFloat(value.0.into()))), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal( - value - .map(|v| { - let mut decimal = - Decimal::from_f32(v).ok_or(DatabaseError::CastFail)?; - Self::decimal_round_f(option, &mut decimal); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from_f32(value.0).ok_or(DatabaseError::CastFail)?; + Self::decimal_round_f(option, &mut decimal); - Ok::(decimal) - }) - .transpose()?, - )), + Ok(DataValue::Decimal(decimal)) + } _ => Err(DatabaseError::CastFail), }, DataValue::Float64(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v as f32))), + LogicalType::Float => Ok(DataValue::Float32(OrderedFloat(value.0 as f32))), LogicalType::Double => Ok(DataValue::Float64(value)), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) @@ -1160,311 +1019,244 @@ impl DataValue { LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal( - value - .map(|v| { - let mut decimal = - Decimal::from_f64(v).ok_or(DatabaseError::CastFail)?; - Self::decimal_round_f(option, &mut decimal); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from_f64(value.0).ok_or(DatabaseError::CastFail)?; + Self::decimal_round_f(option, &mut decimal); - Ok::(decimal) - }) - .transpose()?, - )), + Ok(DataValue::Decimal(decimal)) + } _ => Err(DatabaseError::CastFail), }, DataValue::Int8(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Tinyint => Ok(DataValue::Int8(value)), - LogicalType::UTinyint => Ok(DataValue::UInt8(value.map(u8::try_from).transpose()?)), - LogicalType::USmallint => { - Ok(DataValue::UInt16(value.map(u16::try_from).transpose()?)) - } - LogicalType::UInteger => { - Ok(DataValue::UInt32(value.map(u32::try_from).transpose()?)) - } - LogicalType::UBigint => { - Ok(DataValue::UInt64(value.map(u64::try_from).transpose()?)) - } - LogicalType::Smallint => Ok(DataValue::Int16(value.map(|v| v.into()))), - LogicalType::Integer => Ok(DataValue::Int32(value.map(|v| v.into()))), - LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), + LogicalType::UTinyint => Ok(DataValue::UInt8(u8::try_from(value)?)), + LogicalType::USmallint => Ok(DataValue::UInt16(u16::try_from(value)?)), + LogicalType::UInteger => Ok(DataValue::UInt32(u32::try_from(value)?)), + LogicalType::UBigint => Ok(DataValue::UInt64(u64::try_from(value)?)), + LogicalType::Smallint => Ok(DataValue::Int16(value.into())), + LogicalType::Integer => Ok(DataValue::Int32(value.into())), + LogicalType::Bigint => Ok(DataValue::Int64(value.into())), + LogicalType::Float => Ok(DataValue::Float32(value.into())), + LogicalType::Double => Ok(DataValue::Float64(value.into())), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { - let mut decimal = Decimal::from(v); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from(value); Self::decimal_round_i(option, &mut decimal); - decimal - }))), + Ok(DataValue::Decimal(decimal)) + } LogicalType::Boolean => numeric_to_boolean!(value), _ => Err(DatabaseError::CastFail), }, DataValue::Int16(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::UTinyint => Ok(DataValue::UInt8(value.map(u8::try_from).transpose()?)), - LogicalType::USmallint => { - Ok(DataValue::UInt16(value.map(u16::try_from).transpose()?)) - } - LogicalType::UInteger => { - Ok(DataValue::UInt32(value.map(u32::try_from).transpose()?)) - } - LogicalType::UBigint => { - Ok(DataValue::UInt64(value.map(u64::try_from).transpose()?)) - } - LogicalType::Tinyint => Ok(DataValue::Int8(value.map(i8::try_from).transpose()?)), + LogicalType::UTinyint => Ok(DataValue::UInt8(u8::try_from(value)?)), + LogicalType::USmallint => Ok(DataValue::UInt16(u16::try_from(value)?)), + LogicalType::UInteger => Ok(DataValue::UInt32(u32::try_from(value)?)), + LogicalType::UBigint => Ok(DataValue::UInt64(u64::try_from(value)?)), + LogicalType::Tinyint => Ok(DataValue::Int8(i8::try_from(value)?)), LogicalType::Smallint => Ok(DataValue::Int16(value)), - LogicalType::Integer => Ok(DataValue::Int32(value.map(|v| v.into()))), - LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), + LogicalType::Integer => Ok(DataValue::Int32(value.into())), + LogicalType::Bigint => Ok(DataValue::Int64(value.into())), + LogicalType::Float => Ok(DataValue::Float32(value.into())), + LogicalType::Double => Ok(DataValue::Float64(value.into())), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { - let mut decimal = Decimal::from(v); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from(value); Self::decimal_round_i(option, &mut decimal); - decimal - }))), + Ok(DataValue::Decimal(decimal)) + } LogicalType::Boolean => numeric_to_boolean!(value), _ => Err(DatabaseError::CastFail), }, DataValue::Int32(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::UTinyint => Ok(DataValue::UInt8(value.map(u8::try_from).transpose()?)), - LogicalType::USmallint => { - Ok(DataValue::UInt16(value.map(u16::try_from).transpose()?)) - } - LogicalType::UInteger => { - Ok(DataValue::UInt32(value.map(u32::try_from).transpose()?)) - } - LogicalType::UBigint => { - Ok(DataValue::UInt64(value.map(u64::try_from).transpose()?)) - } - LogicalType::Tinyint => Ok(DataValue::Int8(value.map(i8::try_from).transpose()?)), - LogicalType::Smallint => { - Ok(DataValue::Int16(value.map(i16::try_from).transpose()?)) - } + LogicalType::UTinyint => Ok(DataValue::UInt8(u8::try_from(value)?)), + LogicalType::USmallint => Ok(DataValue::UInt16(u16::try_from(value)?)), + LogicalType::UInteger => Ok(DataValue::UInt32(u32::try_from(value)?)), + LogicalType::UBigint => Ok(DataValue::UInt64(u64::try_from(value)?)), + LogicalType::Tinyint => Ok(DataValue::Int8(i8::try_from(value)?)), + LogicalType::Smallint => Ok(DataValue::Int16(i16::try_from(value)?)), LogicalType::Integer => Ok(DataValue::Int32(value)), - LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v as f32))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), + LogicalType::Bigint => Ok(DataValue::Int64(value.into())), + LogicalType::Float => Ok(DataValue::Float32(OrderedFloat(value as f32))), + LogicalType::Double => Ok(DataValue::Float64(value.into())), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { - let mut decimal = Decimal::from(v); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from(value); Self::decimal_round_i(option, &mut decimal); - decimal - }))), + Ok(DataValue::Decimal(decimal)) + } LogicalType::Boolean => numeric_to_boolean!(value), _ => Err(DatabaseError::CastFail), }, DataValue::Int64(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::UTinyint => Ok(DataValue::UInt8(value.map(u8::try_from).transpose()?)), - LogicalType::USmallint => { - Ok(DataValue::UInt16(value.map(u16::try_from).transpose()?)) - } - LogicalType::UInteger => { - Ok(DataValue::UInt32(value.map(u32::try_from).transpose()?)) - } - LogicalType::UBigint => { - Ok(DataValue::UInt64(value.map(u64::try_from).transpose()?)) - } - LogicalType::Tinyint => Ok(DataValue::Int8(value.map(i8::try_from).transpose()?)), - LogicalType::Smallint => { - Ok(DataValue::Int16(value.map(i16::try_from).transpose()?)) - } - LogicalType::Integer => Ok(DataValue::Int32(value.map(i32::try_from).transpose()?)), + LogicalType::UTinyint => Ok(DataValue::UInt8(u8::try_from(value)?)), + LogicalType::USmallint => Ok(DataValue::UInt16(u16::try_from(value)?)), + LogicalType::UInteger => Ok(DataValue::UInt32(u32::try_from(value)?)), + LogicalType::UBigint => Ok(DataValue::UInt64(u64::try_from(value)?)), + LogicalType::Tinyint => Ok(DataValue::Int8(i8::try_from(value)?)), + LogicalType::Smallint => Ok(DataValue::Int16(i16::try_from(value)?)), + LogicalType::Integer => Ok(DataValue::Int32(i32::try_from(value)?)), LogicalType::Bigint => Ok(DataValue::Int64(value)), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v as f32))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v as f64))), + LogicalType::Float => Ok(DataValue::Float32(OrderedFloat(value as f32))), + LogicalType::Double => Ok(DataValue::Float64(OrderedFloat(value as f64))), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { - let mut decimal = Decimal::from(v); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from(value); Self::decimal_round_i(option, &mut decimal); - decimal - }))), + Ok(DataValue::Decimal(decimal)) + } LogicalType::Boolean => numeric_to_boolean!(value), _ => Err(DatabaseError::CastFail), }, DataValue::UInt8(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::Tinyint => Ok(DataValue::Int8(value.map(i8::try_from).transpose()?)), + LogicalType::Tinyint => Ok(DataValue::Int8(i8::try_from(value)?)), LogicalType::UTinyint => Ok(DataValue::UInt8(value)), - LogicalType::Smallint => Ok(DataValue::Int16(value.map(|v| v.into()))), - LogicalType::USmallint => Ok(DataValue::UInt16(value.map(|v| v.into()))), - LogicalType::Integer => Ok(DataValue::Int32(value.map(|v| v.into()))), - LogicalType::UInteger => Ok(DataValue::UInt32(value.map(|v| v.into()))), - LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), - LogicalType::UBigint => Ok(DataValue::UInt64(value.map(|v| v.into()))), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), + LogicalType::Smallint => Ok(DataValue::Int16(value.into())), + LogicalType::USmallint => Ok(DataValue::UInt16(value.into())), + LogicalType::Integer => Ok(DataValue::Int32(value.into())), + LogicalType::UInteger => Ok(DataValue::UInt32(value.into())), + LogicalType::Bigint => Ok(DataValue::Int64(value.into())), + LogicalType::UBigint => Ok(DataValue::UInt64(value.into())), + LogicalType::Float => Ok(DataValue::Float32(value.into())), + LogicalType::Double => Ok(DataValue::Float64(value.into())), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { - let mut decimal = Decimal::from(v); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from(value); Self::decimal_round_i(option, &mut decimal); - decimal - }))), + Ok(DataValue::Decimal(decimal)) + } LogicalType::Boolean => numeric_to_boolean!(value), _ => Err(DatabaseError::CastFail), }, DataValue::UInt16(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::Tinyint => Ok(DataValue::Int8(value.map(i8::try_from).transpose()?)), - LogicalType::UTinyint => Ok(DataValue::UInt8(value.map(u8::try_from).transpose()?)), - LogicalType::Smallint => { - Ok(DataValue::Int16(value.map(i16::try_from).transpose()?)) - } + LogicalType::Tinyint => Ok(DataValue::Int8(i8::try_from(value)?)), + LogicalType::UTinyint => Ok(DataValue::UInt8(u8::try_from(value)?)), + LogicalType::Smallint => Ok(DataValue::Int16(i16::try_from(value)?)), LogicalType::USmallint => Ok(DataValue::UInt16(value)), - LogicalType::Integer => Ok(DataValue::Int32(value.map(|v| v.into()))), - LogicalType::UInteger => Ok(DataValue::UInt32(value.map(|v| v.into()))), - LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), - LogicalType::UBigint => Ok(DataValue::UInt64(value.map(|v| v.into()))), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), + LogicalType::Integer => Ok(DataValue::Int32(value.into())), + LogicalType::UInteger => Ok(DataValue::UInt32(value.into())), + LogicalType::Bigint => Ok(DataValue::Int64(value.into())), + LogicalType::UBigint => Ok(DataValue::UInt64(value.into())), + LogicalType::Float => Ok(DataValue::Float32(value.into())), + LogicalType::Double => Ok(DataValue::Float64(value.into())), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { - let mut decimal = Decimal::from(v); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from(value); Self::decimal_round_i(option, &mut decimal); - decimal - }))), + Ok(DataValue::Decimal(decimal)) + } LogicalType::Boolean => numeric_to_boolean!(value), _ => Err(DatabaseError::CastFail), }, DataValue::UInt32(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::Tinyint => Ok(DataValue::Int8(value.map(i8::try_from).transpose()?)), - LogicalType::UTinyint => Ok(DataValue::UInt8(value.map(u8::try_from).transpose()?)), - LogicalType::Smallint => { - Ok(DataValue::Int16(value.map(i16::try_from).transpose()?)) - } - LogicalType::USmallint => { - Ok(DataValue::UInt16(value.map(u16::try_from).transpose()?)) - } - LogicalType::Integer => Ok(DataValue::Int32(value.map(i32::try_from).transpose()?)), + LogicalType::Tinyint => Ok(DataValue::Int8(i8::try_from(value)?)), + LogicalType::UTinyint => Ok(DataValue::UInt8(u8::try_from(value)?)), + LogicalType::Smallint => Ok(DataValue::Int16(i16::try_from(value)?)), + LogicalType::USmallint => Ok(DataValue::UInt16(u16::try_from(value)?)), + LogicalType::Integer => Ok(DataValue::Int32(i32::try_from(value)?)), LogicalType::UInteger => Ok(DataValue::UInt32(value)), - LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), - LogicalType::UBigint => Ok(DataValue::UInt64(value.map(|v| v.into()))), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v as f32))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), + LogicalType::Bigint => Ok(DataValue::Int64(value.into())), + LogicalType::UBigint => Ok(DataValue::UInt64(value.into())), + LogicalType::Float => Ok(DataValue::Float32(OrderedFloat(value as f32))), + LogicalType::Double => Ok(DataValue::Float64(OrderedFloat(value.into()))), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { - let mut decimal = Decimal::from(v); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from(value); Self::decimal_round_i(option, &mut decimal); - decimal - }))), + Ok(DataValue::Decimal(decimal)) + } LogicalType::Boolean => numeric_to_boolean!(value), _ => Err(DatabaseError::CastFail), }, DataValue::UInt64(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::Tinyint => Ok(DataValue::Int8(value.map(i8::try_from).transpose()?)), - LogicalType::UTinyint => Ok(DataValue::UInt8(value.map(u8::try_from).transpose()?)), - LogicalType::Smallint => { - Ok(DataValue::Int16(value.map(i16::try_from).transpose()?)) - } - LogicalType::USmallint => { - Ok(DataValue::UInt16(value.map(u16::try_from).transpose()?)) - } - LogicalType::Integer => Ok(DataValue::Int32(value.map(i32::try_from).transpose()?)), - LogicalType::UInteger => { - Ok(DataValue::UInt32(value.map(u32::try_from).transpose()?)) - } - LogicalType::Bigint => Ok(DataValue::Int64(value.map(i64::try_from).transpose()?)), + LogicalType::Tinyint => Ok(DataValue::Int8(i8::try_from(value)?)), + LogicalType::UTinyint => Ok(DataValue::UInt8(u8::try_from(value)?)), + LogicalType::Smallint => Ok(DataValue::Int16(i16::try_from(value)?)), + LogicalType::USmallint => Ok(DataValue::UInt16(u16::try_from(value)?)), + LogicalType::Integer => Ok(DataValue::Int32(i32::try_from(value)?)), + LogicalType::UInteger => Ok(DataValue::UInt32(u32::try_from(value)?)), + LogicalType::Bigint => Ok(DataValue::Int64(i64::try_from(value)?)), LogicalType::UBigint => Ok(DataValue::UInt64(value)), - LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v as f32))), - LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v as f64))), + LogicalType::Float => Ok(DataValue::Float32(OrderedFloat(value as f32))), + LogicalType::Double => Ok(DataValue::Float64(OrderedFloat(value as f64))), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } LogicalType::Varchar(len, unit) => { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } - LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { - let mut decimal = Decimal::from(v); + LogicalType::Decimal(_, option) => { + let mut decimal = Decimal::from(value); Self::decimal_round_i(option, &mut decimal); - decimal - }))), + Ok(DataValue::Decimal(decimal)) + } LogicalType::Boolean => numeric_to_boolean!(value), _ => Err(DatabaseError::CastFail), }, DataValue::Utf8 { value, .. } => match to { LogicalType::Invalid => Err(DatabaseError::CastFail), LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::Boolean => Ok(DataValue::Boolean( - value.map(|v| bool::from_str(&v)).transpose()?, - )), - LogicalType::Tinyint => Ok(DataValue::Int8( - value.map(|v| i8::from_str(&v)).transpose()?, - )), - LogicalType::UTinyint => Ok(DataValue::UInt8( - value.map(|v| u8::from_str(&v)).transpose()?, - )), - LogicalType::Smallint => Ok(DataValue::Int16( - value.map(|v| i16::from_str(&v)).transpose()?, - )), - LogicalType::USmallint => Ok(DataValue::UInt16( - value.map(|v| u16::from_str(&v)).transpose()?, - )), - LogicalType::Integer => Ok(DataValue::Int32( - value.map(|v| i32::from_str(&v)).transpose()?, - )), - LogicalType::UInteger => Ok(DataValue::UInt32( - value.map(|v| u32::from_str(&v)).transpose()?, - )), - LogicalType::Bigint => Ok(DataValue::Int64( - value.map(|v| i64::from_str(&v)).transpose()?, - )), - LogicalType::UBigint => Ok(DataValue::UInt64( - value.map(|v| u64::from_str(&v)).transpose()?, - )), - LogicalType::Float => Ok(DataValue::Float32( - value.map(|v| f32::from_str(&v)).transpose()?, - )), - LogicalType::Double => Ok(DataValue::Float64( - value.map(|v| f64::from_str(&v)).transpose()?, - )), + LogicalType::Boolean => Ok(DataValue::Boolean(bool::from_str(&value)?)), + LogicalType::Tinyint => Ok(DataValue::Int8(i8::from_str(&value)?)), + LogicalType::UTinyint => Ok(DataValue::UInt8(u8::from_str(&value)?)), + LogicalType::Smallint => Ok(DataValue::Int16(i16::from_str(&value)?)), + LogicalType::USmallint => Ok(DataValue::UInt16(u16::from_str(&value)?)), + LogicalType::Integer => Ok(DataValue::Int32(i32::from_str(&value)?)), + LogicalType::UInteger => Ok(DataValue::UInt32(u32::from_str(&value)?)), + LogicalType::Bigint => Ok(DataValue::Int64(i64::from_str(&value)?)), + LogicalType::UBigint => Ok(DataValue::UInt64(u64::from_str(&value)?)), + LogicalType::Float => Ok(DataValue::Float32(OrderedFloat(f32::from_str(&value)?))), + LogicalType::Double => Ok(DataValue::Float64(OrderedFloat(f64::from_str(&value)?))), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) } @@ -1472,49 +1264,34 @@ impl DataValue { varchar_cast!(value, len, Utf8Type::Variable(*len), *unit) } LogicalType::Date => { - let option = value - .map(|v| { - NaiveDate::parse_from_str(&v, DATE_FMT) - .map(|date| date.num_days_from_ce()) - }) - .transpose()?; - - Ok(DataValue::Date32(option)) + let value = NaiveDate::parse_from_str(&value, DATE_FMT) + .map(|date| date.num_days_from_ce())?; + Ok(DataValue::Date32(value)) } LogicalType::DateTime => { - let option = value - .map(|v| { - NaiveDateTime::parse_from_str(&v, DATE_TIME_FMT) - .or_else(|_| { - NaiveDate::parse_from_str(&v, DATE_FMT) - .map(|date| date.and_hms_opt(0, 0, 0).unwrap()) - }) - .map(|date_time| date_time.and_utc().timestamp()) + let value = NaiveDateTime::parse_from_str(&value, DATE_TIME_FMT) + .or_else(|_| { + NaiveDate::parse_from_str(&value, DATE_FMT) + .map(|date| date.and_hms_opt(0, 0, 0).unwrap()) }) - .transpose()?; + .map(|date_time| date_time.and_utc().timestamp())?; - Ok(DataValue::Date64(option)) + Ok(DataValue::Date64(value)) } LogicalType::Time => { - let option = value - .map(|v| { - NaiveTime::parse_from_str(&v, TIME_FMT) - .map(|time| time.num_seconds_from_midnight()) - }) - .transpose()?; + let value = NaiveTime::parse_from_str(&value, TIME_FMT) + .map(|time| time.num_seconds_from_midnight())?; - Ok(DataValue::Time(option)) + Ok(DataValue::Time(value)) } - LogicalType::Decimal(_, _) => Ok(DataValue::Decimal( - value.map(|v| Decimal::from_str(&v)).transpose()?, - )), + LogicalType::Decimal(_, _) => Ok(DataValue::Decimal(Decimal::from_str(&value)?)), _ => Err(DatabaseError::CastFail), }, DataValue::Date32(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Char(len, unit) => { varchar_cast!( - Self::format_date(value), + Self::format_date(value).ok_or(DatabaseError::CastFail)?, Some(len), Utf8Type::Fixed(*len), *unit @@ -1522,7 +1299,7 @@ impl DataValue { } LogicalType::Varchar(len, unit) => { varchar_cast!( - Self::format_date(value), + Self::format_date(value).ok_or(DatabaseError::CastFail)?, len, Utf8Type::Variable(*len), *unit @@ -1530,13 +1307,14 @@ impl DataValue { } LogicalType::Date => Ok(DataValue::Date32(value)), LogicalType::DateTime => { - let option = value.and_then(|v| { - NaiveDate::from_num_days_from_ce_opt(v) - .and_then(|date| date.and_hms_opt(0, 0, 0)) - .map(|date_time| date_time.and_utc().timestamp()) - }); + let value = NaiveDate::from_num_days_from_ce_opt(value) + .ok_or(DatabaseError::CastFail)? + .and_hms_opt(0, 0, 0) + .ok_or(DatabaseError::CastFail)? + .and_utc() + .timestamp(); - Ok(DataValue::Date64(option)) + Ok(DataValue::Date64(value)) } _ => Err(DatabaseError::CastFail), }, @@ -1544,7 +1322,7 @@ impl DataValue { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Char(len, unit) => { varchar_cast!( - Self::format_datetime(value), + Self::format_datetime(value).ok_or(DatabaseError::CastFail)?, Some(len), Utf8Type::Fixed(*len), *unit @@ -1552,29 +1330,28 @@ impl DataValue { } LogicalType::Varchar(len, unit) => { varchar_cast!( - Self::format_datetime(value), + Self::format_datetime(value).ok_or(DatabaseError::CastFail)?, len, Utf8Type::Variable(*len), *unit ) } LogicalType::Date => { - let option = value.and_then(|v| { - DateTime::from_timestamp(v, 0) - .map(|dt| dt.naive_utc()) - .map(|date_time| date_time.date().num_days_from_ce()) - }); + let value = DateTime::from_timestamp(value, 0) + .ok_or(DatabaseError::CastFail)? + .naive_utc() + .date() + .num_days_from_ce(); - Ok(DataValue::Date32(option)) + Ok(DataValue::Date32(value)) } LogicalType::DateTime => Ok(DataValue::Date64(value)), LogicalType::Time => { - let option = value.and_then(|v| { - DateTime::from_timestamp(v, 0) - .map(|date_time| date_time.time().num_seconds_from_midnight()) - }); + let value = DateTime::from_timestamp(value, 0) + .map(|date_time| date_time.time().num_seconds_from_midnight()) + .ok_or(DatabaseError::CastFail)?; - Ok(DataValue::Time(option)) + Ok(DataValue::Time(value)) } _ => Err(DatabaseError::CastFail), }, @@ -1582,7 +1359,7 @@ impl DataValue { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Char(len, unit) => { varchar_cast!( - Self::format_time(value), + Self::format_time(value).ok_or(DatabaseError::CastFail)?, Some(len), Utf8Type::Fixed(*len), *unit @@ -1590,7 +1367,7 @@ impl DataValue { } LogicalType::Varchar(len, unit) => { varchar_cast!( - Self::format_time(value), + Self::format_time(value).ok_or(DatabaseError::CastFail)?, len, Utf8Type::Variable(*len), *unit @@ -1600,8 +1377,12 @@ impl DataValue { }, DataValue::Decimal(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), - LogicalType::Float => Ok(DataValue::Float32(value.and_then(|v| v.to_f32()))), - LogicalType::Double => Ok(DataValue::Float64(value.and_then(|v| v.to_f64()))), + LogicalType::Float => Ok(DataValue::Float32(OrderedFloat( + value.to_f32().ok_or(DatabaseError::CastFail)?, + ))), + LogicalType::Double => Ok(DataValue::Float64(OrderedFloat( + value.to_f64().ok_or(DatabaseError::CastFail)?, + ))), LogicalType::Decimal(_, _) => Ok(DataValue::Decimal(value)), LogicalType::Char(len, unit) => { varchar_cast!(value, Some(len), Utf8Type::Fixed(*len), *unit) @@ -1611,17 +1392,15 @@ impl DataValue { } _ => Err(DatabaseError::CastFail), }, - DataValue::Tuple(values) => match to { - LogicalType::Tuple(types) => Ok(if let Some((mut values, is_upper)) = values { + DataValue::Tuple(mut values, is_upper) => match to { + LogicalType::Tuple(types) => { for (i, value) in values.iter_mut().enumerate() { if types[i] != value.logical_type() { *value = mem::replace(value, DataValue::Null).cast(&types[i])?; } } - DataValue::Tuple(Some((values, is_upper))) - } else { - DataValue::Tuple(None) - }), + Ok(DataValue::Tuple(values, is_upper)) + } _ => Err(DatabaseError::CastFail), }, }?; @@ -1638,14 +1417,8 @@ impl DataValue { return None; } - if let ( - DataValue::Utf8 { - value: Some(v1), .. - }, - DataValue::Utf8 { - value: Some(v2), .. - }, - ) = (self, target) + if let (DataValue::Utf8 { value: v1, .. }, DataValue::Utf8 { value: v2, .. }) = + (self, target) { let min_len = cmp::min(v1.len(), v2.len()); @@ -1666,7 +1439,7 @@ impl DataValue { #[inline] pub(crate) fn values_to_tuple(mut values: Vec) -> Option { if values.len() > 1 { - Some(DataValue::Tuple(Some((values, false)))) + Some(DataValue::Tuple(values, false)) } else { values.pop() } @@ -1710,20 +1483,22 @@ macro_rules! impl_scalar { ($ty:ty, $scalar:tt) => { impl From<$ty> for DataValue { fn from(value: $ty) -> Self { - DataValue::$scalar(Some(value)) + DataValue::$scalar(value) } } impl From> for DataValue { fn from(value: Option<$ty>) -> Self { - DataValue::$scalar(value) + if let Some(value) = value { + DataValue::$scalar(value) + } else { + DataValue::Null + } } } }; } -impl_scalar!(f64, Float64); -impl_scalar!(f32, Float32); impl_scalar!(i8, Int8); impl_scalar!(i16, Int16); impl_scalar!(i32, Int32); @@ -1735,10 +1510,42 @@ impl_scalar!(u32, UInt32); impl_scalar!(u64, UInt64); impl_scalar!(Decimal, Decimal); +impl From for DataValue { + fn from(value: f32) -> Self { + DataValue::Float32(OrderedFloat(value)) + } +} + +impl From> for DataValue { + fn from(value: Option) -> Self { + if let Some(value) = value { + DataValue::Float32(OrderedFloat(value)) + } else { + DataValue::Null + } + } +} + +impl From for DataValue { + fn from(value: f64) -> Self { + DataValue::Float64(OrderedFloat(value)) + } +} + +impl From> for DataValue { + fn from(value: Option) -> Self { + if let Some(value) = value { + DataValue::Float64(OrderedFloat(value)) + } else { + DataValue::Null + } + } +} + impl From for DataValue { fn from(value: String) -> Self { DataValue::Utf8 { - value: Some(value), + value, ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, } @@ -1747,47 +1554,63 @@ impl From for DataValue { impl From> for DataValue { fn from(value: Option) -> Self { - DataValue::Utf8 { - value, - ty: Utf8Type::Variable(None), - unit: CharLengthUnits::Characters, + if let Some(value) = value { + DataValue::Utf8 { + value, + ty: Utf8Type::Variable(None), + unit: CharLengthUnits::Characters, + } + } else { + DataValue::Null } } } impl From<&NaiveDate> for DataValue { fn from(value: &NaiveDate) -> Self { - DataValue::Date32(Some(value.num_days_from_ce())) + DataValue::Date32(value.num_days_from_ce()) } } impl From> for DataValue { fn from(value: Option<&NaiveDate>) -> Self { - DataValue::Date32(value.map(|d| d.num_days_from_ce())) + if let Some(value) = value { + DataValue::Date32(value.num_days_from_ce()) + } else { + DataValue::Null + } } } impl From<&NaiveDateTime> for DataValue { fn from(value: &NaiveDateTime) -> Self { - DataValue::Date64(Some(value.and_utc().timestamp())) + DataValue::Date64(value.and_utc().timestamp()) } } impl From> for DataValue { fn from(value: Option<&NaiveDateTime>) -> Self { - DataValue::Date64(value.map(|d| d.and_utc().timestamp())) + if let Some(value) = value { + DataValue::Date64(value.and_utc().timestamp()) + } else { + DataValue::Null + } } } impl From<&NaiveTime> for DataValue { fn from(value: &NaiveTime) -> Self { - DataValue::Time(Some(value.num_seconds_from_midnight())) + DataValue::Time(value.num_seconds_from_midnight()) } } impl From> for DataValue { fn from(value: Option<&NaiveTime>) -> Self { - DataValue::Time(value.map(|d| d.num_seconds_from_midnight())) + if let Some(value) = value { + DataValue::Time(value.num_seconds_from_midnight()) + } else { + DataValue::Null + } } } @@ -1819,62 +1642,47 @@ impl TryFrom<&sqlparser::ast::Value> for DataValue { } } -macro_rules! format_option { - ($F:expr, $EXPR:expr) => { - match $EXPR { - Some(e) => write!($F, "{}", e), - None => write!($F, "null"), - } - }; -} macro_rules! format_float_option { - ($F:expr, $EXPR:expr) => { - match $EXPR { - Some(e) => { - let formatted_string = format!("{:?}", e); - let formatted_result = if let Some(i) = formatted_string.find('.') { - format!("{:.1$}", e, formatted_string.len() - i - 1) - } else { - format!("{:.1}", e) - }; + ($F:expr, $EXPR:expr) => {{ + let formatted_string = format!("{:?}", $EXPR); + let formatted_result = if let Some(i) = formatted_string.find('.') { + format!("{:.1$}", $EXPR, formatted_string.len() - i - 1) + } else { + format!("{:.1}", $EXPR) + }; - write!($F, "{}", formatted_result) - } - None => write!($F, "null"), - } - }; + write!($F, "{}", formatted_result) + }}; } impl fmt::Display for DataValue { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - DataValue::Boolean(e) => format_option!(f, e)?, + DataValue::Boolean(e) => write!(f, "{}", e)?, DataValue::Float32(e) => format_float_option!(f, e)?, DataValue::Float64(e) => format_float_option!(f, e)?, - DataValue::Int8(e) => format_option!(f, e)?, - DataValue::Int16(e) => format_option!(f, e)?, - DataValue::Int32(e) => format_option!(f, e)?, - DataValue::Int64(e) => format_option!(f, e)?, - DataValue::UInt8(e) => format_option!(f, e)?, - DataValue::UInt16(e) => format_option!(f, e)?, - DataValue::UInt32(e) => format_option!(f, e)?, - DataValue::UInt64(e) => format_option!(f, e)?, - DataValue::Utf8 { value: e, .. } => format_option!(f, e)?, + DataValue::Int8(e) => write!(f, "{}", e)?, + DataValue::Int16(e) => write!(f, "{}", e)?, + DataValue::Int32(e) => write!(f, "{}", e)?, + DataValue::Int64(e) => write!(f, "{}", e)?, + DataValue::UInt8(e) => write!(f, "{}", e)?, + DataValue::UInt16(e) => write!(f, "{}", e)?, + DataValue::UInt32(e) => write!(f, "{}", e)?, + DataValue::UInt64(e) => write!(f, "{}", e)?, + DataValue::Utf8 { value: e, .. } => write!(f, "{}", e)?, DataValue::Null => write!(f, "null")?, - DataValue::Date32(e) => format_option!(f, e.and_then(DataValue::date_format))?, - DataValue::Date64(e) => format_option!(f, e.and_then(DataValue::date_time_format))?, - DataValue::Time(e) => format_option!(f, e.and_then(DataValue::time_format))?, - DataValue::Decimal(e) => format_option!(f, e.as_ref().map(DataValue::decimal_format))?, - DataValue::Tuple(e) => { + DataValue::Date32(e) => write!(f, "{}", DataValue::date_format(*e).unwrap())?, + DataValue::Date64(e) => write!(f, "{}", DataValue::date_time_format(*e).unwrap())?, + DataValue::Time(e) => write!(f, "{}", DataValue::time_format(*e).unwrap())?, + DataValue::Decimal(e) => write!(f, "{}", DataValue::decimal_format(e))?, + DataValue::Tuple(values, ..) => { write!(f, "(")?; - if let Some((values, _)) = e { - let len = values.len(); + let len = values.len(); - for (i, value) in values.iter().enumerate() { - value.fmt(f)?; - if len != i + 1 { - write!(f, ", ")?; - } + for (i, value) in values.iter().enumerate() { + value.fmt(f)?; + if len != i + 1 { + write!(f, ", ")?; } } write!(f, ")")?; @@ -1898,16 +1706,15 @@ impl fmt::Debug for DataValue { DataValue::UInt16(_) => write!(f, "UInt16({})", self), DataValue::UInt32(_) => write!(f, "UInt32({})", self), DataValue::UInt64(_) => write!(f, "UInt64({})", self), - DataValue::Utf8 { value: None, .. } => write!(f, "Utf8({})", self), - DataValue::Utf8 { value: Some(_), .. } => write!(f, "Utf8(\"{}\")", self), + DataValue::Utf8 { .. } => write!(f, "Utf8(\"{}\")", self), DataValue::Null => write!(f, "null"), DataValue::Date32(_) => write!(f, "Date32({})", self), DataValue::Date64(_) => write!(f, "Date64({})", self), DataValue::Time(_) => write!(f, "Time({})", self), DataValue::Decimal(_) => write!(f, "Decimal({})", self), - DataValue::Tuple(_) => { + DataValue::Tuple(..) => { write!(f, "Tuple({}", self)?; - if matches!(self, DataValue::Tuple(Some((_, true)))) { + if matches!(self, DataValue::Tuple(_, true)) { write!(f, " [is upper]")?; } write!(f, ")") @@ -1922,8 +1729,32 @@ mod test { use crate::storage::table_codec::BumpBytes; use crate::types::value::DataValue; use bumpalo::Bump; + use ordered_float::OrderedFloat; use rust_decimal::Decimal; + #[test] + fn test_mem_comparable_null() -> Result<(), DatabaseError> { + let arena = Bump::new(); + let mut key_i8_0 = BumpBytes::new_in(&arena); + let mut key_i8_1 = BumpBytes::new_in(&arena); + let mut key_i8_2 = BumpBytes::new_in(&arena); + let mut key_i8_3 = BumpBytes::new_in(&arena); + + DataValue::Null.memcomparable_encode(&mut key_i8_0)?; + DataValue::Int8(i8::MIN).memcomparable_encode(&mut key_i8_1)?; + DataValue::Int8(-1_i8).memcomparable_encode(&mut key_i8_2)?; + DataValue::Int8(i8::MAX).memcomparable_encode(&mut key_i8_3)?; + + println!("{:?} < {:?}", key_i8_0, key_i8_1); + println!("{:?} < {:?}", key_i8_1, key_i8_2); + println!("{:?} < {:?}", key_i8_2, key_i8_3); + assert!(key_i8_0 < key_i8_1); + assert!(key_i8_1 < key_i8_2); + assert!(key_i8_2 < key_i8_3); + + Ok(()) + } + #[test] fn test_mem_comparable_int() -> Result<(), DatabaseError> { let arena = Bump::new(); @@ -1931,9 +1762,9 @@ mod test { let mut key_i8_2 = BumpBytes::new_in(&arena); let mut key_i8_3 = BumpBytes::new_in(&arena); - DataValue::Int8(Some(i8::MIN)).memcomparable_encode(&mut key_i8_1)?; - DataValue::Int8(Some(-1_i8)).memcomparable_encode(&mut key_i8_2)?; - DataValue::Int8(Some(i8::MAX)).memcomparable_encode(&mut key_i8_3)?; + DataValue::Int8(i8::MIN).memcomparable_encode(&mut key_i8_1)?; + DataValue::Int8(-1_i8).memcomparable_encode(&mut key_i8_2)?; + DataValue::Int8(i8::MAX).memcomparable_encode(&mut key_i8_3)?; println!("{:?} < {:?}", key_i8_1, key_i8_2); println!("{:?} < {:?}", key_i8_2, key_i8_3); @@ -1944,9 +1775,9 @@ mod test { let mut key_i16_2 = BumpBytes::new_in(&arena); let mut key_i16_3 = BumpBytes::new_in(&arena); - DataValue::Int16(Some(i16::MIN)).memcomparable_encode(&mut key_i16_1)?; - DataValue::Int16(Some(-1_i16)).memcomparable_encode(&mut key_i16_2)?; - DataValue::Int16(Some(i16::MAX)).memcomparable_encode(&mut key_i16_3)?; + DataValue::Int16(i16::MIN).memcomparable_encode(&mut key_i16_1)?; + DataValue::Int16(-1_i16).memcomparable_encode(&mut key_i16_2)?; + DataValue::Int16(i16::MAX).memcomparable_encode(&mut key_i16_3)?; println!("{:?} < {:?}", key_i16_1, key_i16_2); println!("{:?} < {:?}", key_i16_2, key_i16_3); @@ -1957,9 +1788,9 @@ mod test { let mut key_i32_2 = BumpBytes::new_in(&arena); let mut key_i32_3 = BumpBytes::new_in(&arena); - DataValue::Int32(Some(i32::MIN)).memcomparable_encode(&mut key_i32_1)?; - DataValue::Int32(Some(-1_i32)).memcomparable_encode(&mut key_i32_2)?; - DataValue::Int32(Some(i32::MAX)).memcomparable_encode(&mut key_i32_3)?; + DataValue::Int32(i32::MIN).memcomparable_encode(&mut key_i32_1)?; + DataValue::Int32(-1_i32).memcomparable_encode(&mut key_i32_2)?; + DataValue::Int32(i32::MAX).memcomparable_encode(&mut key_i32_3)?; println!("{:?} < {:?}", key_i32_1, key_i32_2); println!("{:?} < {:?}", key_i32_2, key_i32_3); @@ -1970,9 +1801,9 @@ mod test { let mut key_i64_2 = BumpBytes::new_in(&arena); let mut key_i64_3 = BumpBytes::new_in(&arena); - DataValue::Int64(Some(i64::MIN)).memcomparable_encode(&mut key_i64_1)?; - DataValue::Int64(Some(-1_i64)).memcomparable_encode(&mut key_i64_2)?; - DataValue::Int64(Some(i64::MAX)).memcomparable_encode(&mut key_i64_3)?; + DataValue::Int64(i64::MIN).memcomparable_encode(&mut key_i64_1)?; + DataValue::Int64(-1_i64).memcomparable_encode(&mut key_i64_2)?; + DataValue::Int64(i64::MAX).memcomparable_encode(&mut key_i64_3)?; println!("{:?} < {:?}", key_i64_1, key_i64_2); println!("{:?} < {:?}", key_i64_2, key_i64_3); @@ -1989,9 +1820,9 @@ mod test { let mut key_f32_2 = BumpBytes::new_in(&arena); let mut key_f32_3 = BumpBytes::new_in(&arena); - DataValue::Float32(Some(f32::MIN)).memcomparable_encode(&mut key_f32_1)?; - DataValue::Float32(Some(-1_f32)).memcomparable_encode(&mut key_f32_2)?; - DataValue::Float32(Some(f32::MAX)).memcomparable_encode(&mut key_f32_3)?; + DataValue::Float32(OrderedFloat(f32::MIN)).memcomparable_encode(&mut key_f32_1)?; + DataValue::Float32(OrderedFloat(-1_f32)).memcomparable_encode(&mut key_f32_2)?; + DataValue::Float32(OrderedFloat(f32::MAX)).memcomparable_encode(&mut key_f32_3)?; println!("{:?} < {:?}", key_f32_1, key_f32_2); println!("{:?} < {:?}", key_f32_2, key_f32_3); @@ -2002,9 +1833,9 @@ mod test { let mut key_f64_2 = BumpBytes::new_in(&arena); let mut key_f64_3 = BumpBytes::new_in(&arena); - DataValue::Float64(Some(f64::MIN)).memcomparable_encode(&mut key_f64_1)?; - DataValue::Float64(Some(-1_f64)).memcomparable_encode(&mut key_f64_2)?; - DataValue::Float64(Some(f64::MAX)).memcomparable_encode(&mut key_f64_3)?; + DataValue::Float64(OrderedFloat(f64::MIN)).memcomparable_encode(&mut key_f64_1)?; + DataValue::Float64(OrderedFloat(-1_f64)).memcomparable_encode(&mut key_f64_2)?; + DataValue::Float64(OrderedFloat(f64::MAX)).memcomparable_encode(&mut key_f64_3)?; println!("{:?} < {:?}", key_f64_1, key_f64_2); println!("{:?} < {:?}", key_f64_2, key_f64_3); @@ -2021,9 +1852,9 @@ mod test { let mut key_deciaml_2 = BumpBytes::new_in(&arena); let mut key_deciaml_3 = BumpBytes::new_in(&arena); - DataValue::Decimal(Some(Decimal::MIN)).memcomparable_encode(&mut key_deciaml_1)?; - DataValue::Decimal(Some(Decimal::new(-1, 0))).memcomparable_encode(&mut key_deciaml_2)?; - DataValue::Decimal(Some(Decimal::MAX)).memcomparable_encode(&mut key_deciaml_3)?; + DataValue::Decimal(Decimal::MIN).memcomparable_encode(&mut key_deciaml_1)?; + DataValue::Decimal(Decimal::new(-1, 0)).memcomparable_encode(&mut key_deciaml_2)?; + DataValue::Decimal(Decimal::MAX).memcomparable_encode(&mut key_deciaml_3)?; println!("{:?} < {:?}", key_deciaml_1, key_deciaml_2); println!("{:?} < {:?}", key_deciaml_2, key_deciaml_3); @@ -2040,32 +1871,20 @@ mod test { let mut key_tuple_2 = BumpBytes::new_in(&arena); let mut key_tuple_3 = BumpBytes::new_in(&arena); - DataValue::Tuple(Some(( - vec![ - DataValue::Int8(None), - DataValue::Int8(Some(0)), - DataValue::Int8(Some(1)), - ], + DataValue::Tuple( + vec![DataValue::Null, DataValue::Int8(0), DataValue::Int8(1)], false, - ))) + ) .memcomparable_encode(&mut key_tuple_1)?; - DataValue::Tuple(Some(( - vec![ - DataValue::Int8(Some(0)), - DataValue::Int8(Some(0)), - DataValue::Int8(Some(1)), - ], + DataValue::Tuple( + vec![DataValue::Int8(0), DataValue::Int8(0), DataValue::Int8(1)], false, - ))) + ) .memcomparable_encode(&mut key_tuple_2)?; - DataValue::Tuple(Some(( - vec![ - DataValue::Int8(Some(0)), - DataValue::Int8(Some(0)), - DataValue::Int8(Some(2)), - ], + DataValue::Tuple( + vec![DataValue::Int8(0), DataValue::Int8(0), DataValue::Int8(2)], false, - ))) + ) .memcomparable_encode(&mut key_tuple_3)?; println!("{:?} < {:?}", key_tuple_1, key_tuple_2); @@ -2083,32 +1902,20 @@ mod test { let mut key_tuple_2 = BumpBytes::new_in(&arena); let mut key_tuple_3 = BumpBytes::new_in(&arena); - DataValue::Tuple(Some(( - vec![ - DataValue::Int8(None), - DataValue::Int8(Some(0)), - DataValue::Int8(Some(1)), - ], + DataValue::Tuple( + vec![DataValue::Null, DataValue::Int8(0), DataValue::Int8(1)], true, - ))) + ) .memcomparable_encode(&mut key_tuple_1)?; - DataValue::Tuple(Some(( - vec![ - DataValue::Int8(Some(0)), - DataValue::Int8(Some(0)), - DataValue::Int8(Some(1)), - ], + DataValue::Tuple( + vec![DataValue::Int8(0), DataValue::Int8(0), DataValue::Int8(1)], true, - ))) + ) .memcomparable_encode(&mut key_tuple_2)?; - DataValue::Tuple(Some(( - vec![ - DataValue::Int8(Some(0)), - DataValue::Int8(Some(0)), - DataValue::Int8(Some(2)), - ], + DataValue::Tuple( + vec![DataValue::Int8(0), DataValue::Int8(0), DataValue::Int8(2)], true, - ))) + ) .memcomparable_encode(&mut key_tuple_3)?; println!("{:?} < {:?}", key_tuple_2, key_tuple_3); diff --git a/tests/macros-test/src/main.rs b/tests/macros-test/src/main.rs index 1db6317d..be75734d 100644 --- a/tests/macros-test/src/main.rs +++ b/tests/macros-test/src/main.rs @@ -37,9 +37,9 @@ mod test { )), ]); let values = vec![ - DataValue::Int32(Some(9)), + DataValue::Int32(9), DataValue::Utf8 { - value: Some("LOL".to_string()), + value: "LOL".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }, @@ -57,13 +57,13 @@ mod test { implement_from_tuple!( MyStruct, ( c1: i32 => |inner: &mut MyStruct, value| { - if let DataValue::Int32(Some(val)) = value { + if let DataValue::Int32(val) = value { inner.c1 = val; } }, c2: String => |inner: &mut MyStruct, value| { - if let DataValue::Utf8 { value: Some(val), .. } = value { - inner.c2 = val; + if let DataValue::Utf8 { value, .. } = value { + inner.c2 = value; } } ) @@ -92,8 +92,8 @@ mod test { Ok(Box::new((0..num) .into_iter() .map(|i| Ok(Tuple::new(None, vec![ - DataValue::Int32(Some(i)), - DataValue::Int32(Some(i)), + DataValue::Int32(i), + DataValue::Int32(i), ])))) as Box>>) })); @@ -102,9 +102,9 @@ mod test { let function = MyScalaFunction::new(); let sum = function.eval( &[ - ScalarExpression::Constant(DataValue::Int8(Some(1))), + ScalarExpression::Constant(DataValue::Int8(1)), ScalarExpression::Constant(DataValue::Utf8 { - value: Some("1".to_string()), + value: "1".to_string(), ty: Utf8Type::Variable(None), unit: CharLengthUnits::Characters, }), @@ -121,14 +121,14 @@ mod test { arg_types: vec![LogicalType::Integer, LogicalType::Integer], } ); - assert_eq!(sum, DataValue::Int32(Some(2))); + assert_eq!(sum, DataValue::Int32(2)); Ok(()) } #[test] fn test_table_function() -> Result<(), DatabaseError> { let function = MyTableFunction::new(); - let mut numbers = function.eval(&[ScalarExpression::Constant(DataValue::Int8(Some(2)))])?; + let mut numbers = function.eval(&[ScalarExpression::Constant(DataValue::Int8(2))])?; println!("{:?}", function); @@ -141,17 +141,11 @@ mod test { ); assert_eq!( numbers.next().unwrap().unwrap(), - Tuple::new( - None, - vec![DataValue::Int32(Some(0)), DataValue::Int32(Some(0)),] - ) + Tuple::new(None, vec![DataValue::Int32(0), DataValue::Int32(0),]) ); assert_eq!( numbers.next().unwrap().unwrap(), - Tuple::new( - None, - vec![DataValue::Int32(Some(1)), DataValue::Int32(Some(1)),] - ) + Tuple::new(None, vec![DataValue::Int32(1), DataValue::Int32(1),]) ); assert!(numbers.next().is_none()); diff --git a/tests/slt/describe.slt b/tests/slt/describe.slt index 5bcc9403..39fc34b6 100644 --- a/tests/slt/describe.slt +++ b/tests/slt/describe.slt @@ -6,7 +6,7 @@ describe t9; ---- c1 Integer 4 false PRIMARY null c2 Integer 4 true EMPTY 0 -c3 Varchar(None, CHARACTERS) null true UNIQUE null +c3 Varchar(None, CHARACTERS) variable true UNIQUE null statement ok drop table t9; @@ -19,7 +19,7 @@ describe t9_m; ---- c1 Integer 4 false PRIMARY null c2 Integer 4 false PRIMARY null -c3 Varchar(None, CHARACTERS) null true UNIQUE null +c3 Varchar(None, CHARACTERS) variable true UNIQUE null statement ok drop table t9_m; diff --git a/tests/slt/sql_2016/E091_01.slt b/tests/slt/sql_2016/E091_01.slt index f3c72249..341d7935 100644 --- a/tests/slt/sql_2016/E091_01.slt +++ b/tests/slt/sql_2016/E091_01.slt @@ -6,4 +6,4 @@ CREATE TABLE TABLE_E091_01_01_01 ( ID INT PRIMARY KEY, A FLOAT ); query F SELECT AVG ( A ) FROM TABLE_E091_01_01_01 ---- -0.0 +null diff --git a/tests/slt/sql_2016/E091_06.slt b/tests/slt/sql_2016/E091_06.slt index cbc91b63..a01f31b4 100644 --- a/tests/slt/sql_2016/E091_06.slt +++ b/tests/slt/sql_2016/E091_06.slt @@ -6,7 +6,7 @@ CREATE TABLE TABLE_E091_06_01_01 ( ID INT PRIMARY KEY, A FLOAT ); query F SELECT AVG ( ALL A ) FROM TABLE_E091_06_01_01 ---- -0.0 +null statement ok CREATE TABLE TABLE_E091_06_02_01 ( ID INT PRIMARY KEY, A FLOAT ); diff --git a/tests/slt/sql_2016/E091_07.slt b/tests/slt/sql_2016/E091_07.slt index 278cd385..98efe265 100644 --- a/tests/slt/sql_2016/E091_07.slt +++ b/tests/slt/sql_2016/E091_07.slt @@ -6,7 +6,7 @@ CREATE TABLE TABLE_E091_07_01_01 ( ID INT PRIMARY KEY, A FLOAT ); query F SELECT AVG ( DISTINCT A ) FROM TABLE_E091_07_01_01 ---- -0.0 +null statement ok CREATE TABLE TABLE_E091_07_01_02 ( ID INT PRIMARY KEY, A FLOAT ); diff --git a/tpcc/src/delivery.rs b/tpcc/src/delivery.rs index 0e137100..4403e120 100644 --- a/tpcc/src/delivery.rs +++ b/tpcc/src/delivery.rs @@ -38,8 +38,8 @@ impl TpccTransaction for Delivery { .execute( &statements[0], &[ - ("?1", DataValue::Int8(Some(d_id as i8))), - ("?2", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int8(d_id as i8)), + ("?2", DataValue::Int16(args.w_id as i16)), ], )? .next() @@ -53,9 +53,9 @@ impl TpccTransaction for Delivery { tx.execute( &statements[1], &[ - ("?1", DataValue::Int32(Some(no_o_id))), - ("?2", DataValue::Int8(Some(d_id as i8))), - ("?3", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int32(no_o_id)), + ("?2", DataValue::Int8(d_id as i8)), + ("?3", DataValue::Int16(args.w_id as i16)), ], )? .done()?; @@ -64,9 +64,9 @@ impl TpccTransaction for Delivery { .execute( &statements[2], &[ - ("?1", DataValue::Int32(Some(no_o_id))), - ("?2", DataValue::Int8(Some(d_id as i8))), - ("?3", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int32(no_o_id)), + ("?2", DataValue::Int8(d_id as i8)), + ("?3", DataValue::Int16(args.w_id as i16)), ], )? .next() @@ -76,10 +76,10 @@ impl TpccTransaction for Delivery { tx.execute( &statements[3], &[ - ("?1", DataValue::Int8(Some(args.o_carrier_id as i8))), - ("?2", DataValue::Int32(Some(no_o_id))), - ("?3", DataValue::Int8(Some(d_id as i8))), - ("?4", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int8(args.o_carrier_id as i8)), + ("?2", DataValue::Int32(no_o_id)), + ("?3", DataValue::Int8(d_id as i8)), + ("?4", DataValue::Int16(args.w_id as i16)), ], )? .done()?; @@ -88,9 +88,9 @@ impl TpccTransaction for Delivery { &statements[4], &[ ("?1", DataValue::from(&now)), - ("?2", DataValue::Int32(Some(no_o_id))), - ("?3", DataValue::Int8(Some(d_id as i8))), - ("?4", DataValue::Int16(Some(args.w_id as i16))), + ("?2", DataValue::Int32(no_o_id)), + ("?3", DataValue::Int8(d_id as i8)), + ("?4", DataValue::Int16(args.w_id as i16)), ], )? .done()?; @@ -99,9 +99,9 @@ impl TpccTransaction for Delivery { .execute( &statements[5], &[ - ("?1", DataValue::Int32(Some(no_o_id))), - ("?2", DataValue::Int8(Some(d_id as i8))), - ("?3", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int32(no_o_id)), + ("?2", DataValue::Int8(d_id as i8)), + ("?3", DataValue::Int16(args.w_id as i16)), ], )? .next() @@ -111,10 +111,10 @@ impl TpccTransaction for Delivery { tx.execute( &statements[6], &[ - ("?1", DataValue::Decimal(Some(ol_total))), - ("?2", DataValue::Int32(Some(c_id))), - ("?3", DataValue::Int8(Some(d_id as i8))), - ("?4", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Decimal(ol_total)), + ("?2", DataValue::Int32(c_id)), + ("?3", DataValue::Int8(d_id as i8)), + ("?4", DataValue::Int16(args.w_id as i16)), ], )? .done()?; diff --git a/tpcc/src/new_ord.rs b/tpcc/src/new_ord.rs index b1ece09e..e036a3c4 100644 --- a/tpcc/src/new_ord.rs +++ b/tpcc/src/new_ord.rs @@ -72,17 +72,17 @@ impl TpccTransaction for NewOrd { .execute( &statements[0], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int16(Some(args.w_id as i16))), - ("?3", DataValue::Int8(Some(args.d_id as i8))), - ("?4", DataValue::Int64(Some(args.c_id as i64))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int16(args.w_id as i16)), + ("?3", DataValue::Int8(args.d_id as i8)), + ("?4", DataValue::Int64(args.c_id as i64)), ], )? .next() .unwrap()?; let c_discount = tuple.values[0].decimal().unwrap(); - let c_last = tuple.values[1].utf8().unwrap(); - let c_credit = tuple.values[2].utf8().unwrap(); + let c_last = tuple.values[1].utf8().unwrap().to_string(); + let c_credit = tuple.values[2].utf8().unwrap().to_string(); let w_tax = tuple.values[3].decimal().unwrap(); (c_discount, c_last, c_credit, w_tax) @@ -92,21 +92,21 @@ impl TpccTransaction for NewOrd { .execute( &statements[1], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int32(Some(args.c_id as i32))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int32(args.c_id as i32)), ], )? .next() .unwrap()?; let c_discount = tuple.values[0].decimal().unwrap(); - let c_last = tuple.values[1].utf8().unwrap(); - let c_credit = tuple.values[2].utf8().unwrap(); + let c_last = tuple.values[1].utf8().unwrap().to_string(); + let c_credit = tuple.values[2].utf8().unwrap().to_string(); // "SELECT w_tax FROM warehouse WHERE w_id = ?" let tuple = tx .execute( &statements[2], - &[("?1", DataValue::Int16(Some(args.w_id as i16)))], + &[("?1", DataValue::Int16(args.w_id as i16))], )? .next() .unwrap()?; @@ -119,8 +119,8 @@ impl TpccTransaction for NewOrd { .execute( &statements[3], &[ - ("?1", DataValue::Int8(Some(args.d_id as i8))), - ("?2", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int8(args.d_id as i8)), + ("?2", DataValue::Int16(args.w_id as i16)), ], )? .next() @@ -131,9 +131,9 @@ impl TpccTransaction for NewOrd { tx.execute( &statements[4], &[ - ("?1", DataValue::Int32(Some(d_next_o_id))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int32(d_next_o_id)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int16(args.w_id as i16)), ], )? .done()?; @@ -142,13 +142,13 @@ impl TpccTransaction for NewOrd { tx.execute( &statements[5], &[ - ("?1", DataValue::Int32(Some(o_id))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int16(Some(args.w_id as i16))), - ("?4", DataValue::Int32(Some(args.c_id as i32))), + ("?1", DataValue::Int32(o_id)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int16(args.w_id as i16)), + ("?4", DataValue::Int32(args.c_id as i32)), ("?5", DataValue::from(&now)), - ("?6", DataValue::Int8(Some(args.o_ol_cnt as i8))), - ("?7", DataValue::Int8(Some(args.o_all_local as i8))), + ("?6", DataValue::Int8(args.o_ol_cnt as i8)), + ("?7", DataValue::Int8(args.o_all_local as i8)), ], )? .done()?; @@ -156,9 +156,9 @@ impl TpccTransaction for NewOrd { tx.execute( &statements[6], &[ - ("?1", DataValue::Int32(Some(o_id))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int32(o_id)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int16(args.w_id as i16)), ], )? .done()?; @@ -193,7 +193,7 @@ impl TpccTransaction for NewOrd { let tuple = tx .execute( &statements[7], - vec![("?1", DataValue::Int32(Some(ol_i_id as i32)))], + vec![("?1", DataValue::Int32(ol_i_id as i32))], )? .next(); let Some(tuple) = tuple else { @@ -205,15 +205,15 @@ impl TpccTransaction for NewOrd { let i_data = tuple.values[2].utf8().unwrap(); price[ol_num_seq[ol_number - 1]] = i_price; - iname[ol_num_seq[ol_number - 1]] = i_name; + iname[ol_num_seq[ol_number - 1]] = i_name.to_string(); // "SELECT s_quantity, s_data, s_dist_01, s_dist_02, s_dist_03, s_dist_04, s_dist_05, s_dist_06, s_dist_07, s_dist_08, s_dist_09, s_dist_10 FROM stock WHERE s_i_id = ? AND s_w_id = ? FOR UPDATE" let tuple = tx .execute( &statements[8], vec![ - ("?1", DataValue::Int32(Some(ol_i_id as i32))), - ("?2", DataValue::Int16(Some(ol_supply_w_id as i16))), + ("?1", DataValue::Int32(ol_i_id as i32)), + ("?2", DataValue::Int16(ol_supply_w_id as i16)), ], )? .next() @@ -252,9 +252,9 @@ impl TpccTransaction for NewOrd { tx.execute( &statements[9], vec![ - ("?1", DataValue::Int16(Some(s_quantity))), - ("?2", DataValue::Int32(Some(ol_i_id as i32))), - ("?3", DataValue::Int16(Some(ol_supply_w_id as i16))), + ("?1", DataValue::Int16(s_quantity)), + ("?2", DataValue::Int32(ol_i_id as i32)), + ("?3", DataValue::Int16(ol_supply_w_id as i16)), ], )? .done()?; @@ -273,14 +273,14 @@ impl TpccTransaction for NewOrd { tx.execute( &statements[10], vec![ - ("?1", DataValue::Int32(Some(o_id))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int16(Some(args.w_id as i16))), - ("?4", DataValue::Int8(Some(ol_number as i8))), - ("?5", DataValue::Int32(Some(ol_i_id as i32))), - ("?6", DataValue::Int16(Some(ol_supply_w_id as i16))), - ("?7", DataValue::Int8(Some(ol_quantity as i8))), - ("?8", DataValue::Decimal(Some(ol_amount.round_dp(2)))), + ("?1", DataValue::Int32(o_id)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int16(args.w_id as i16)), + ("?4", DataValue::Int8(ol_number as i8)), + ("?5", DataValue::Int32(ol_i_id as i32)), + ("?6", DataValue::Int16(ol_supply_w_id as i16)), + ("?7", DataValue::Int8(ol_quantity as i8)), + ("?8", DataValue::Decimal(ol_amount.round_dp(2))), ("?9", DataValue::from(ol_dist_info)), ], )? @@ -345,16 +345,16 @@ impl TpccTest for NewOrdTest { fn pick_dist_info( ol_supply_w_id: usize, - s_dist_01: String, - s_dist_02: String, - s_dist_03: String, - s_dist_04: String, - s_dist_05: String, - s_dist_06: String, - s_dist_07: String, - s_dist_08: String, - s_dist_09: String, - s_dist_10: String, + s_dist_01: &str, + s_dist_02: &str, + s_dist_03: &str, + s_dist_04: &str, + s_dist_05: &str, + s_dist_06: &str, + s_dist_07: &str, + s_dist_08: &str, + s_dist_09: &str, + s_dist_10: &str, ) -> String { match ol_supply_w_id { 1 => s_dist_01, @@ -369,4 +369,5 @@ fn pick_dist_info( 10 => s_dist_10, _ => unreachable!(), } + .to_string() } diff --git a/tpcc/src/order_stat.rs b/tpcc/src/order_stat.rs index 47f3e027..a086790f 100644 --- a/tpcc/src/order_stat.rs +++ b/tpcc/src/order_stat.rs @@ -51,8 +51,8 @@ impl TpccTransaction for OrderStat { .execute( &statements[0], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(args.d_id as i8)), ("?3", DataValue::from(args.c_last.clone())), ], )? @@ -63,8 +63,8 @@ impl TpccTransaction for OrderStat { let mut tuple_iter = tx.execute( &statements[1], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(args.d_id as i8)), ("?3", DataValue::from(args.c_last.clone())), ], )?; @@ -81,9 +81,9 @@ impl TpccTransaction for OrderStat { let tuple = tuple_iter.next().unwrap()?; c_balance = tuple.values[0].decimal().unwrap(); - c_first = tuple.values[1].utf8().unwrap(); - c_middle = tuple.values[2].utf8().unwrap(); - c_last = tuple.values[3].utf8().unwrap(); + c_first = tuple.values[1].utf8().unwrap().to_string(); + c_middle = tuple.values[2].utf8().unwrap().to_string(); + c_last = tuple.values[3].utf8().unwrap().to_string(); } (c_balance, c_first, c_middle, c_last) } else { @@ -92,17 +92,17 @@ impl TpccTransaction for OrderStat { .execute( &statements[2], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int32(Some(args.c_id as i32))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int32(args.c_id as i32)), ], )? .next() .unwrap()?; let c_balance = tuple.values[0].decimal().unwrap(); - let c_first = tuple.values[1].utf8().unwrap(); - let c_middle = tuple.values[2].utf8().unwrap(); - let c_last = tuple.values[3].utf8().unwrap(); + let c_first = tuple.values[1].utf8().unwrap().to_string(); + let c_middle = tuple.values[2].utf8().unwrap().to_string(); + let c_last = tuple.values[3].utf8().unwrap().to_string(); (c_balance, c_first, c_middle, c_last) }; // TODO: Join Eq @@ -111,12 +111,12 @@ impl TpccTransaction for OrderStat { .execute( &statements[3], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int32(Some(args.c_id as i32))), - ("?4", DataValue::Int16(Some(args.w_id as i16))), - ("?5", DataValue::Int8(Some(args.d_id as i8))), - ("?6", DataValue::Int32(Some(args.c_id as i32))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int32(args.c_id as i32)), + ("?4", DataValue::Int16(args.w_id as i16)), + ("?5", DataValue::Int8(args.d_id as i8)), + ("?6", DataValue::Int32(args.c_id as i32)), ], )? .next(); @@ -132,9 +132,9 @@ impl TpccTransaction for OrderStat { .execute( &statements[4], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int32(Some(o_id))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int32(o_id)), ], )? .next() diff --git a/tpcc/src/payment.rs b/tpcc/src/payment.rs index f1edf102..cdce47d5 100644 --- a/tpcc/src/payment.rs +++ b/tpcc/src/payment.rs @@ -62,8 +62,8 @@ impl TpccTransaction for Payment { tx.execute( &statements[0], &[ - ("?1", DataValue::Decimal(Some(args.h_amount))), - ("?2", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Decimal(args.h_amount)), + ("?2", DataValue::Int16(args.w_id as i16)), ], )? .done()?; @@ -71,7 +71,7 @@ impl TpccTransaction for Payment { let tuple = tx .execute( &statements[1], - &[("?1", DataValue::Int16(Some(args.w_id as i16)))], + &[("?1", DataValue::Int16(args.w_id as i16))], )? .next() .unwrap()?; @@ -86,9 +86,9 @@ impl TpccTransaction for Payment { tx.execute( &statements[2], &[ - ("?1", DataValue::Decimal(Some(args.h_amount))), - ("?2", DataValue::Int16(Some(args.w_id as i16))), - ("?3", DataValue::Int8(Some(args.d_id as i8))), + ("?1", DataValue::Decimal(args.h_amount)), + ("?2", DataValue::Int16(args.w_id as i16)), + ("?3", DataValue::Int8(args.d_id as i8)), ], )? .done()?; @@ -98,8 +98,8 @@ impl TpccTransaction for Payment { .execute( &statements[3], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(args.d_id as i8)), ], )? .next() @@ -118,8 +118,8 @@ impl TpccTransaction for Payment { .execute( &statements[4], &[ - ("?1", DataValue::Int16(Some(args.c_w_id as i16))), - ("?2", DataValue::Int8(Some(args.c_d_id as i8))), + ("?1", DataValue::Int16(args.c_w_id as i16)), + ("?2", DataValue::Int8(args.c_d_id as i8)), ("?3", DataValue::from(args.c_last.clone())), ], )? @@ -131,8 +131,8 @@ impl TpccTransaction for Payment { let mut tuple_iter = tx.execute( &statements[5], &[ - ("?1", DataValue::Int16(Some(args.c_w_id as i16))), - ("?2", DataValue::Int8(Some(args.c_d_id as i8))), + ("?1", DataValue::Int16(args.c_w_id as i16)), + ("?2", DataValue::Int8(args.c_d_id as i8)), ("?3", DataValue::from(args.c_last.clone())), ], )?; @@ -149,9 +149,9 @@ impl TpccTransaction for Payment { .execute( &statements[6], &[ - ("?1", DataValue::Int16(Some(args.c_w_id as i16))), - ("?2", DataValue::Int8(Some(args.c_d_id as i8))), - ("?3", DataValue::Int32(Some(c_id))), + ("?1", DataValue::Int16(args.c_w_id as i16)), + ("?2", DataValue::Int8(args.c_d_id as i8)), + ("?3", DataValue::Int32(c_id)), ], )? .next() @@ -179,9 +179,9 @@ impl TpccTransaction for Payment { .execute( &statements[7], &[ - ("?1", DataValue::Int16(Some(args.c_w_id as i16))), - ("?2", DataValue::Int8(Some(args.c_d_id as i8))), - ("?3", DataValue::Int32(Some(c_id))), + ("?1", DataValue::Int16(args.c_w_id as i16)), + ("?2", DataValue::Int8(args.c_d_id as i8)), + ("?3", DataValue::Int32(c_id)), ], )? .next() @@ -195,11 +195,11 @@ impl TpccTransaction for Payment { tx.execute( &statements[8], &[ - ("?1", DataValue::Decimal(Some(c_balance))), - ("?2", DataValue::from(c_data)), - ("?3", DataValue::Int16(Some(args.c_w_id as i16))), - ("?4", DataValue::Int8(Some(args.c_d_id as i8))), - ("?5", DataValue::Int32(Some(c_id))), + ("?1", DataValue::Decimal(c_balance)), + ("?2", DataValue::from(c_data.to_string())), + ("?3", DataValue::Int16(args.c_w_id as i16)), + ("?4", DataValue::Int8(args.c_d_id as i8)), + ("?5", DataValue::Int32(c_id)), ], )? .done()?; @@ -208,10 +208,10 @@ impl TpccTransaction for Payment { tx.execute( &statements[9], &[ - ("?1", DataValue::Decimal(Some(c_balance))), - ("?2", DataValue::Int16(Some(args.c_w_id as i16))), - ("?3", DataValue::Int8(Some(args.c_d_id as i8))), - ("?4", DataValue::Int32(Some(c_id))), + ("?1", DataValue::Decimal(c_balance)), + ("?2", DataValue::Int16(args.c_w_id as i16)), + ("?3", DataValue::Int8(args.c_d_id as i8)), + ("?4", DataValue::Int32(c_id)), ], )? .done()?; @@ -221,10 +221,10 @@ impl TpccTransaction for Payment { tx.execute( &statements[9], &[ - ("?1", DataValue::Decimal(Some(c_balance))), - ("?2", DataValue::Int16(Some(args.c_w_id as i16))), - ("?3", DataValue::Int8(Some(args.c_d_id as i8))), - ("?4", DataValue::Int32(Some(c_id))), + ("?1", DataValue::Decimal(c_balance)), + ("?2", DataValue::Int16(args.c_w_id as i16)), + ("?3", DataValue::Int8(args.c_d_id as i8)), + ("?4", DataValue::Int32(c_id)), ], )? .done()?; @@ -234,13 +234,13 @@ impl TpccTransaction for Payment { tx.execute( &statements[10], &[ - ("?1", DataValue::Int8(Some(args.c_d_id as i8))), - ("?2", DataValue::Int16(Some(args.c_w_id as i16))), - ("?3", DataValue::Int32(Some(c_id))), - ("?4", DataValue::Int8(Some(args.d_id as i8))), - ("?5", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int8(args.c_d_id as i8)), + ("?2", DataValue::Int16(args.c_w_id as i16)), + ("?3", DataValue::Int32(c_id)), + ("?4", DataValue::Int8(args.d_id as i8)), + ("?5", DataValue::Int16(args.w_id as i16)), ("?6", DataValue::from(&now.naive_utc())), - ("?7", DataValue::Decimal(Some(args.h_amount))), + ("?7", DataValue::Decimal(args.h_amount)), ("?8", DataValue::from(h_data)), ], )? diff --git a/tpcc/src/slev.rs b/tpcc/src/slev.rs index 76d69a8e..70e4e190 100644 --- a/tpcc/src/slev.rs +++ b/tpcc/src/slev.rs @@ -35,8 +35,8 @@ impl TpccTransaction for Slev { .execute( &statements[0], &[ - ("?1", DataValue::Int8(Some(args.d_id as i8))), - ("?2", DataValue::Int16(Some(args.w_id as i16))), + ("?1", DataValue::Int8(args.d_id as i8)), + ("?2", DataValue::Int16(args.w_id as i16)), ], )? .next() @@ -47,10 +47,10 @@ impl TpccTransaction for Slev { .execute( &statements[1], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(args.d_id as i8))), - ("?3", DataValue::Int32(Some(d_next_o_id))), - ("?4", DataValue::Int32(Some(d_next_o_id))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(args.d_id as i8)), + ("?3", DataValue::Int32(d_next_o_id)), + ("?4", DataValue::Int32(d_next_o_id)), ], )? .next() @@ -61,9 +61,9 @@ impl TpccTransaction for Slev { .execute( &statements[2], &[ - ("?1", DataValue::Int16(Some(args.w_id as i16))), - ("?2", DataValue::Int8(Some(ol_i_id as i8))), - ("?3", DataValue::Int16(Some(args.level as i16))), + ("?1", DataValue::Int16(args.w_id as i16)), + ("?2", DataValue::Int8(ol_i_id as i8)), + ("?3", DataValue::Int16(args.level as i16)), ], )? .next() From a220375a4a4a98e8c0e082239e28aba3a62c1c97 Mon Sep 17 00:00:00 2001 From: Kould Date: Sun, 29 Dec 2024 01:53:26 +0800 Subject: [PATCH 2/2] config: version up --- Cargo.toml | 2 +- tpcc/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e47f4ad7..8573e33f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "fnck_sql" -version = "0.0.9" +version = "0.0.10" edition = "2021" authors = ["Kould ", "Xwg "] description = "SQL as a Function for Rust" diff --git a/tpcc/Cargo.toml b/tpcc/Cargo.toml index 7bba2487..9b32f95a 100644 --- a/tpcc/Cargo.toml +++ b/tpcc/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] clap = { version = "4", features = ["derive"] } chrono = { version = "0.4" } -fnck_sql = { version = "0.0.9", path = "..", package = "fnck_sql" } +fnck_sql = { version = "0.0.10", path = "..", package = "fnck_sql" } indicatif = { version = "0.17" } ordered-float = { version = "4" } rand = { version = "0.8" }