Skip to content

Commit

Permalink
fix: expand DataValue::Utf8 so that it can correspond to Char and…
Browse files Browse the repository at this point in the history
… `VarChar` respectively.
  • Loading branch information
KKould committed Mar 26, 2024
1 parent faf27fe commit 54846fd
Show file tree
Hide file tree
Showing 13 changed files with 289 additions and 121 deletions.
13 changes: 10 additions & 3 deletions src/binder/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::expression::function::{FunctionSummary, ScalarFunction};
use crate::expression::{AliasType, ScalarExpression};
use crate::planner::LogicalPlan;
use crate::storage::Transaction;
use crate::types::value::DataValue;
use crate::types::value::{DataValue, Utf8Type};
use crate::types::LogicalType;

macro_rules! try_alias {
Expand Down Expand Up @@ -67,7 +67,11 @@ impl<'a, T: Transaction> Binder<'a, T> {
} => self.bind_cast(expr, data_type),
Expr::TypedString { data_type, value } => {
let logical_type = LogicalType::try_from(data_type.clone())?;
let value = DataValue::Utf8(Some(value.to_string())).cast(&logical_type)?;
let value = DataValue::Utf8 {
value: Some(value.to_string()),
ty: Utf8Type::Variable,
}
.cast(&logical_type)?;

Ok(ScalarExpression::Constant(Arc::new(value)))
}
Expand Down Expand Up @@ -597,6 +601,9 @@ impl<'a, T: Transaction> Binder<'a, T> {
}

fn wildcard_expr() -> ScalarExpression {
ScalarExpression::Constant(Arc::new(DataValue::Utf8(Some("*".to_string()))))
ScalarExpression::Constant(Arc::new(DataValue::Utf8 {
value: Some("*".to_string()),
ty: Utf8Type::Variable,
}))
}
}
7 changes: 5 additions & 2 deletions src/execution/volcano/dml/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::planner::LogicalPlan;
use crate::storage::Transaction;
use crate::types::index::IndexMetaRef;
use crate::types::tuple::Tuple;
use crate::types::value::DataValue;
use crate::types::value::{DataValue, Utf8Type};
use futures_async_stream::try_stream;
use itertools::Itertools;
use std::fmt::Formatter;
Expand Down Expand Up @@ -106,7 +106,10 @@ impl Analyze {
let meta = StatisticsMeta::new(histogram, sketch);

meta.to_file(&path)?;
values.push(Arc::new(DataValue::Utf8(Some(path.clone()))));
values.push(Arc::new(DataValue::Utf8 {
value: Some(path.clone()),
ty: Utf8Type::Variable,
}));
transaction.save_table_meta(&table_name, path, meta)?;
}
yield Tuple { id: None, values };
Expand Down
48 changes: 33 additions & 15 deletions src/execution/volcano/dql/describe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@ use crate::execution::volcano::{BoxedExecutor, ReadExecutor};
use crate::planner::operator::describe::DescribeOperator;
use crate::storage::Transaction;
use crate::types::tuple::Tuple;
use crate::types::value::{DataValue, ValueRef};
use crate::types::value::{DataValue, Utf8Type, ValueRef};
use futures_async_stream::try_stream;
use lazy_static::lazy_static;
use std::sync::Arc;

lazy_static! {
static ref PRIMARY_KEY_TYPE: ValueRef =
Arc::new(DataValue::Utf8(Some(String::from("PRIMARY"))));
static ref UNIQUE_KEY_TYPE: ValueRef = Arc::new(DataValue::Utf8(Some(String::from("UNIQUE"))));
static ref EMPTY_KEY_TYPE: ValueRef = Arc::new(DataValue::Utf8(Some(String::from("EMPTY"))));
static ref PRIMARY_KEY_TYPE: ValueRef = Arc::new(DataValue::Utf8 {
value: Some(String::from("PRIMARY")),
ty: Utf8Type::Variable
});
static ref UNIQUE_KEY_TYPE: ValueRef = Arc::new(DataValue::Utf8 {
value: Some(String::from("UNIQUE")),
ty: Utf8Type::Variable
});
static ref EMPTY_KEY_TYPE: ValueRef = Arc::new(DataValue::Utf8 {
value: Some(String::from("EMPTY")),
ty: Utf8Type::Variable
});
}

pub struct Describe {
Expand Down Expand Up @@ -59,17 +67,27 @@ impl Describe {
.map(|expr| format!("{}", expr))
.unwrap_or_else(|| "null".to_string());
let values = vec![
Arc::new(DataValue::Utf8(Some(column.name().to_string()))),
Arc::new(DataValue::Utf8(Some(datatype.to_string()))),
Arc::new(DataValue::Utf8(Some(
datatype
.raw_len()
.map(|len| len.to_string())
.unwrap_or_else(|| "DYNAMIC".to_string()),
))),
Arc::new(DataValue::Utf8(Some(column.nullable.to_string()))),
Arc::new(DataValue::Utf8 {
value: Some(column.name().to_string()),
ty: Utf8Type::Variable,
}),
Arc::new(DataValue::Utf8 {
value: Some(datatype.to_string()),
ty: Utf8Type::Variable,
}),
Arc::new(DataValue::Utf8 {
value: datatype.raw_len().map(|len| len.to_string()),
ty: Utf8Type::Variable,
}),
Arc::new(DataValue::Utf8 {
value: Some(column.nullable.to_string()),
ty: Utf8Type::Variable,
}),
key_fn(column),
Arc::new(DataValue::Utf8(Some(default))),
Arc::new(DataValue::Utf8 {
value: Some(default),
ty: Utf8Type::Variable,
}),
];
yield Tuple { id: None, values };
}
Expand Down
7 changes: 5 additions & 2 deletions src/execution/volcano/dql/explain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::execution::volcano::{BoxedExecutor, ReadExecutor};
use crate::planner::LogicalPlan;
use crate::storage::Transaction;
use crate::types::tuple::Tuple;
use crate::types::value::DataValue;
use crate::types::value::{DataValue, Utf8Type};
use futures_async_stream::try_stream;
use std::sync::Arc;

Expand All @@ -26,7 +26,10 @@ impl<T: Transaction> ReadExecutor<T> for Explain {
impl Explain {
#[try_stream(boxed, ok = Tuple, error = DatabaseError)]
pub async fn _execute(self) {
let values = vec![Arc::new(DataValue::Utf8(Some(self.plan.explain(0))))];
let values = vec![Arc::new(DataValue::Utf8 {
value: Some(self.plan.explain(0)),
ty: Utf8Type::Variable,
})];

yield Tuple { id: None, values };
}
Expand Down
7 changes: 5 additions & 2 deletions src/execution/volcano/dql/show_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::errors::DatabaseError;
use crate::execution::volcano::{BoxedExecutor, ReadExecutor};
use crate::storage::Transaction;
use crate::types::tuple::Tuple;
use crate::types::value::DataValue;
use crate::types::value::{DataValue, Utf8Type};
use futures_async_stream::try_stream;
use std::sync::Arc;

Expand All @@ -21,7 +21,10 @@ impl ShowTables {
let metas = transaction.table_metas()?;

for TableMeta { table_name } in metas {
let values = vec![Arc::new(DataValue::Utf8(Some(table_name.to_string())))];
let values = vec![Arc::new(DataValue::Utf8 {
value: Some(table_name.to_string()),
ty: Utf8Type::Variable,
})];

yield Tuple { id: None, values };
}
Expand Down
22 changes: 17 additions & 5 deletions src/expression/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::errors::DatabaseError;
use crate::expression::function::ScalarFunction;
use crate::expression::{AliasType, BinaryOperator, ScalarExpression};
use crate::types::tuple::Tuple;
use crate::types::value::{DataValue, ValueRef};
use crate::types::value::{DataValue, Utf8Type, ValueRef};
use crate::types::LogicalType;
use itertools::Itertools;
use lazy_static::lazy_static;
Expand All @@ -23,7 +23,10 @@ macro_rules! eval_to_num {
{
num_i32
} else {
return Ok(Arc::new(DataValue::Utf8(None)));
return Ok(Arc::new(DataValue::Utf8 {
value: None,
ty: Utf8Type::Variable,
}));
}
};
}
Expand Down Expand Up @@ -164,7 +167,10 @@ impl ScalarExpression {
from += len_i + 1;
}
if from > len_i {
return Ok(Arc::new(DataValue::Utf8(None)));
return Ok(Arc::new(DataValue::Utf8 {
value: None,
ty: Utf8Type::Variable,
}));
}
string = string.split_off(from as usize);
}
Expand All @@ -174,9 +180,15 @@ impl ScalarExpression {
let _ = string.split_off(for_i);
}

Ok(Arc::new(DataValue::Utf8(Some(string))))
Ok(Arc::new(DataValue::Utf8 {
value: Some(string),
ty: Utf8Type::Variable,
}))
} else {
Ok(Arc::new(DataValue::Utf8(None)))
Ok(Arc::new(DataValue::Utf8 {
value: None,
ty: Utf8Type::Variable,
}))
}
}
ScalarExpression::Position { expr, in_expr } => {
Expand Down
9 changes: 6 additions & 3 deletions src/expression/value_compute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::errors::DatabaseError;
use crate::expression::{BinaryOperator, UnaryOperator};
use crate::types::value::{DataValue, ValueRef};
use crate::types::value::{DataValue, Utf8Type, ValueRef};
use crate::types::LogicalType;
use regex::Regex;
use std::cmp::Ordering;
Expand All @@ -14,7 +14,7 @@ fn unpack_bool(value: DataValue) -> Option<bool> {

fn unpack_utf8(value: DataValue) -> Option<String> {
match value {
DataValue::Utf8(inner) => inner,
DataValue::Utf8 { value: inner, .. } => inner,
_ => None,
}
}
Expand Down Expand Up @@ -574,7 +574,10 @@ impl DataValue {
_ => None,
};

DataValue::Utf8(value)
DataValue::Utf8 {
value,
ty: Utf8Type::Variable,
}
}
_ => return Err(DatabaseError::UnsupportedBinaryOperator(unified_type, *op)),
}
Expand Down
2 changes: 1 addition & 1 deletion src/optimizer/core/histogram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ 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| {
DataValue::Utf8 { value, .. } => value.as_ref().map(|string| {
if prefix_len > string.len() {
return 0.0;
}
Expand Down
7 changes: 5 additions & 2 deletions src/optimizer/rule/normalization/column_pruning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::optimizer::core::pattern::{Pattern, PatternChildrenPredicate};
use crate::optimizer::core::rule::{MatchPattern, NormalizationRule};
use crate::optimizer::heuristic::graph::{HepGraph, HepNodeId};
use crate::planner::operator::Operator;
use crate::types::value::DataValue;
use crate::types::value::{DataValue, Utf8Type};
use crate::types::LogicalType;
use itertools::Itertools;
use lazy_static::lazy_static;
Expand Down Expand Up @@ -61,7 +61,10 @@ impl ColumnPruning {
Self::clear_exprs(&column_references, &mut op.agg_calls);

if op.agg_calls.is_empty() && op.groupby_exprs.is_empty() {
let value = Arc::new(DataValue::Utf8(Some("*".to_string())));
let value = Arc::new(DataValue::Utf8 {
value: Some("*".to_string()),
ty: Utf8Type::Variable,
});
// only single COUNT(*) is not depend on any column
// removed all expressions from the aggregate: push a COUNT(*)
op.agg_calls.push(ScalarExpression::AggCall {
Expand Down
4 changes: 2 additions & 2 deletions src/storage/table_codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl TableCodec {
) -> Result<(Bytes, Bytes), DatabaseError> {
let key = TableCodec::encode_index_key(name, index, Some(tuple_id))?;
let mut bytes = Vec::new();
tuple_id.to_raw(&mut bytes, None)?;
tuple_id.to_raw(&mut bytes)?;

Ok((Bytes::from(key), Bytes::from(bytes)))
}
Expand Down Expand Up @@ -269,7 +269,7 @@ impl TableCodec {

if let Some(tuple_id) = tuple_id {
if matches!(index.ty, IndexType::Normal | IndexType::Composite) {
tuple_id.to_raw(&mut key_prefix, None)?;
tuple_id.to_raw(&mut key_prefix)?;
}
}
Ok(key_prefix)
Expand Down
2 changes: 1 addition & 1 deletion src/types/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl Tuple {
bytes[i / BITS_MAX_INDEX] = flip_bit(bytes[i / BITS_MAX_INDEX], i % BITS_MAX_INDEX);
} else {
let logical_type = types[i];
let value_len = value.to_raw(&mut bytes, Some(logical_type))?;
let value_len = value.to_raw(&mut bytes)?;

if logical_type.raw_len().is_none() {
let index = bytes.len() - value_len;
Expand Down
16 changes: 12 additions & 4 deletions src/types/tuple_builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::errors::DatabaseError;
use crate::types::tuple::{Schema, Tuple};
use crate::types::value::DataValue;
use crate::types::value::{DataValue, Utf8Type};
use std::sync::Arc;

pub struct TupleBuilder<'a> {
Expand All @@ -13,7 +13,10 @@ impl<'a> TupleBuilder<'a> {
}

pub fn build_result(message: String) -> Tuple {
let values = vec![Arc::new(DataValue::Utf8(Some(message)))];
let values = vec![Arc::new(DataValue::Utf8 {
value: Some(message),
ty: Utf8Type::Variable,
})];

Tuple { id: None, values }
}
Expand All @@ -26,8 +29,13 @@ impl<'a> TupleBuilder<'a> {
let mut primary_key = None;

for (i, value) in row.into_iter().enumerate() {
let data_value =
Arc::new(DataValue::Utf8(Some(value.to_string())).cast(self.schema[i].datatype())?);
let data_value = Arc::new(
DataValue::Utf8 {
value: Some(value.to_string()),
ty: Utf8Type::Variable,
}
.cast(self.schema[i].datatype())?,
);

if primary_key.is_none() && self.schema[i].desc.is_primary {
primary_key = Some(data_value.clone());
Expand Down
Loading

0 comments on commit 54846fd

Please sign in to comment.