From 71c6295111a870dfc1944a20df24ce4ca310d1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=9E=97=E4=BC=9F?= Date: Thu, 5 Oct 2023 14:35:30 +0800 Subject: [PATCH] Support text column creation (#77) --- README.md | 2 +- src/catalog/column.rs | 7 +++++++ src/expression/evaluator.rs | 2 +- src/expression/simplify.rs | 2 ++ src/optimizer/rule/simplification.rs | 4 ++++ src/storage/table_codec.rs | 2 +- src/types/mod.rs | 4 ++++ src/types/value.rs | 27 ++++++++++++++++++++++++++- tests/slt/create.slt | 2 +- 9 files changed, 47 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fd171985..62638a13 100755 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ cargo run ``` test command ```sql -create table t1 (a int, b int); +create table t1 (a int primary key, b int); insert into t1 (a, b) values (1, 1), (5, 3), (6, 2); diff --git a/src/catalog/column.rs b/src/catalog/column.rs index c3206160..44c04a11 100644 --- a/src/catalog/column.rs +++ b/src/catalog/column.rs @@ -16,6 +16,9 @@ pub struct ColumnCatalog { pub nullable: bool, pub desc: ColumnDesc, pub ref_expr: Option, + // absoulte file path, used to store text content + pub text_files: Vec, + pub deleted_text_files: Vec, } impl ColumnCatalog { @@ -32,6 +35,8 @@ impl ColumnCatalog { nullable, desc: column_desc, ref_expr, + text_files: Vec::new(), + deleted_text_files: Vec::new(), } } @@ -43,6 +48,8 @@ impl ColumnCatalog { nullable: false, desc: ColumnDesc::new(LogicalType::Varchar(None), false, false), ref_expr: None, + text_files: Vec::new(), + deleted_text_files: Vec::new(), } } diff --git a/src/expression/evaluator.rs b/src/expression/evaluator.rs index f30eba4f..c233ed23 100644 --- a/src/expression/evaluator.rs +++ b/src/expression/evaluator.rs @@ -8,7 +8,7 @@ use lazy_static::lazy_static; use std::sync::Arc; lazy_static! { - static ref NULL_VALUE: ValueRef = { Arc::new(DataValue::Null) }; + static ref NULL_VALUE: ValueRef = Arc::new(DataValue::Null); } impl ScalarExpression { diff --git a/src/expression/simplify.rs b/src/expression/simplify.rs index 25a7be94..614c6db7 100644 --- a/src/expression/simplify.rs +++ b/src/expression/simplify.rs @@ -728,6 +728,8 @@ mod test { is_unique: false, }, ref_expr: None, + text_files: Vec::new(), + deleted_text_files: Vec::new(), }); let val_1 = Arc::new(DataValue::Int32(Some(1))); diff --git a/src/optimizer/rule/simplification.rs b/src/optimizer/rule/simplification.rs index fc5e324d..918fce6b 100644 --- a/src/optimizer/rule/simplification.rs +++ b/src/optimizer/rule/simplification.rs @@ -147,6 +147,8 @@ mod test { is_unique: false, }, ref_expr: None, + text_files: Vec::new(), + deleted_text_files: Vec::new(), }; let c2_col = ColumnCatalog { id: Some(1), @@ -159,6 +161,8 @@ mod test { is_unique: true, }, ref_expr: None, + text_files: Vec::new(), + deleted_text_files: Vec::new(), }; // -(c1 + 1) > c2 => c1 < -c2 - 1 diff --git a/src/storage/table_codec.rs b/src/storage/table_codec.rs index a4b5098b..a2819dfc 100644 --- a/src/storage/table_codec.rs +++ b/src/storage/table_codec.rs @@ -8,7 +8,7 @@ use lazy_static::lazy_static; const BOUND_MIN_TAG: u8 = 0; const BOUND_MAX_TAG: u8 = 1; lazy_static! { - static ref ROOT_BYTES: Vec = { b"Root".to_vec() }; + static ref ROOT_BYTES: Vec = b"Root".to_vec(); } #[derive(Clone)] diff --git a/src/types/mod.rs b/src/types/mod.rs index de2d29f4..9ddbe5a5 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -36,6 +36,7 @@ pub enum LogicalType { Float, Double, Varchar(Option), + Text, Date, DateTime, // decimal (precision, scale) @@ -96,6 +97,7 @@ impl LogicalType { LogicalType::Double => Some(8), /// Note: The non-fixed length type's raw_len is None e.g. Varchar LogicalType::Varchar(_) => None, + LogicalType::Text => None, LogicalType::Decimal(_, _) => Some(16), LogicalType::Date => Some(4), LogicalType::DateTime => Some(8), @@ -294,6 +296,7 @@ impl LogicalType { LogicalType::Float => matches!(to, LogicalType::Double), LogicalType::Double => false, LogicalType::Varchar(_) => false, + LogicalType::Text => false, LogicalType::Date => matches!(to, LogicalType::DateTime | LogicalType::Varchar(_)), LogicalType::DateTime => matches!(to, LogicalType::Date | LogicalType::Varchar(_)), LogicalType::Decimal(_, _) => false, @@ -310,6 +313,7 @@ impl TryFrom for LogicalType { sqlparser::ast::DataType::Char(len) | sqlparser::ast::DataType::Varchar(len) => { Ok(LogicalType::Varchar(len.map(|len| len.length as u32))) } + sqlparser::ast::DataType::Text => Ok(LogicalType::Text), sqlparser::ast::DataType::Float(_) => Ok(LogicalType::Float), sqlparser::ast::DataType::Double => Ok(LogicalType::Double), sqlparser::ast::DataType::TinyInt(_) => Ok(LogicalType::Tinyint), diff --git a/src/types/value.rs b/src/types/value.rs index a5f0d962..aa8e32a5 100644 --- a/src/types/value.rs +++ b/src/types/value.rs @@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize}; use super::LogicalType; lazy_static! { - static ref UNIX_DATETIME: NaiveDateTime = { NaiveDateTime::from_timestamp_opt(0, 0).unwrap() }; + static ref UNIX_DATETIME: NaiveDateTime = NaiveDateTime::from_timestamp_opt(0, 0).unwrap(); } pub const DATE_FMT: &str = "%Y-%m-%d"; @@ -329,6 +329,7 @@ impl DataValue { LogicalType::Float => DataValue::Float32(None), LogicalType::Double => DataValue::Float64(None), LogicalType::Varchar(_) => DataValue::Utf8(None), + LogicalType::Text => DataValue::Utf8(None), LogicalType::Date => DataValue::Date32(None), LogicalType::DateTime => DataValue::Date64(None), LogicalType::Decimal(_, _) => DataValue::Decimal(None), @@ -351,6 +352,7 @@ impl DataValue { LogicalType::Float => DataValue::Float32(Some(0.0)), LogicalType::Double => DataValue::Float64(Some(0.0)), LogicalType::Varchar(_) => DataValue::Utf8(Some("".to_string())), + LogicalType::Text => DataValue::Utf8(Some("".to_string())), LogicalType::Date => DataValue::Date32(Some(UNIX_DATETIME.num_days_from_ce())), LogicalType::DateTime => DataValue::Date64(Some(UNIX_DATETIME.timestamp())), LogicalType::Decimal(_, _) => DataValue::Decimal(Some(Decimal::new(0, 0))), @@ -421,6 +423,9 @@ impl DataValue { LogicalType::Varchar(_) => DataValue::Utf8( (!bytes.is_empty()).then(|| String::from_utf8(bytes.to_owned()).unwrap()), ), + LogicalType::Text => DataValue::Utf8( + (!bytes.is_empty()).then(|| String::from_utf8(bytes.to_owned()).unwrap()), + ), LogicalType::Date => { DataValue::Date32((!bytes.is_empty()).then(|| i32::decode_fixed(bytes))) } @@ -594,6 +599,7 @@ impl DataValue { LogicalType::Float => Ok(DataValue::Float32(None)), LogicalType::Double => Ok(DataValue::Float64(None)), LogicalType::Varchar(_) => Ok(DataValue::Utf8(None)), + LogicalType::Text => Ok(DataValue::Utf8(None)), LogicalType::Date => Ok(DataValue::Date32(None)), LogicalType::DateTime => Ok(DataValue::Date64(None)), LogicalType::Decimal(_, _) => Ok(DataValue::Decimal(None)), @@ -612,6 +618,7 @@ impl DataValue { LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), _ => Err(TypeError::CastFail), }, DataValue::Float32(value) => match to { @@ -619,6 +626,7 @@ impl DataValue { LogicalType::Float => Ok(DataValue::Float32(value)), LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal( value .map(|v| { @@ -635,6 +643,7 @@ impl DataValue { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Double => Ok(DataValue::Float64(value)), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal( value .map(|v| { @@ -668,6 +677,7 @@ impl DataValue { LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { let mut decimal = Decimal::from(v); Self::decimal_round_i(option, &mut decimal); @@ -696,6 +706,7 @@ impl DataValue { LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { let mut decimal = Decimal::from(v); Self::decimal_round_i(option, &mut decimal); @@ -722,6 +733,7 @@ impl DataValue { LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { let mut decimal = Decimal::from(v); Self::decimal_round_i(option, &mut decimal); @@ -746,6 +758,7 @@ impl DataValue { )), LogicalType::Bigint => Ok(DataValue::Int64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { let mut decimal = Decimal::from(v); Self::decimal_round_i(option, &mut decimal); @@ -766,6 +779,7 @@ impl DataValue { LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { let mut decimal = Decimal::from(v); Self::decimal_round_i(option, &mut decimal); @@ -784,6 +798,7 @@ impl DataValue { LogicalType::Float => Ok(DataValue::Float32(value.map(|v| v.into()))), LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { let mut decimal = Decimal::from(v); Self::decimal_round_i(option, &mut decimal); @@ -799,6 +814,7 @@ impl DataValue { LogicalType::UBigint => Ok(DataValue::UInt64(value.map(|v| v.into()))), LogicalType::Double => Ok(DataValue::Float64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { let mut decimal = Decimal::from(v); Self::decimal_round_i(option, &mut decimal); @@ -811,6 +827,7 @@ impl DataValue { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::UBigint => Ok(DataValue::UInt64(value.map(|v| v.into()))), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Decimal(_, option) => Ok(DataValue::Decimal(value.map(|v| { let mut decimal = Decimal::from(v); Self::decimal_round_i(option, &mut decimal); @@ -856,6 +873,7 @@ impl DataValue { value.map(|v| f64::from_str(&v)).transpose()?, )), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), LogicalType::Date => { let option = value .map(|v| { @@ -887,6 +905,9 @@ impl DataValue { DataValue::Date32(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Varchar(len) => varchar_cast!(Self::format_date(value), len), + LogicalType::Text => Ok(DataValue::Utf8( + Self::format_date(value).map(|v| format!("{v}")), + )), LogicalType::Date => Ok(DataValue::Date32(value)), LogicalType::DateTime => { let option = value.and_then(|v| { @@ -902,6 +923,9 @@ impl DataValue { DataValue::Date64(value) => match to { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Varchar(len) => varchar_cast!(Self::format_datetime(value), len), + LogicalType::Text => Ok(DataValue::Utf8( + Self::format_datetime(value).map(|v| format!("{v}")), + )), LogicalType::Date => { let option = value.and_then(|v| { NaiveDateTime::from_timestamp_opt(v, 0) @@ -917,6 +941,7 @@ impl DataValue { LogicalType::SqlNull => Ok(DataValue::Null), LogicalType::Decimal(_, _) => Ok(DataValue::Decimal(value)), LogicalType::Varchar(len) => varchar_cast!(value, len), + LogicalType::Text => Ok(DataValue::Utf8(value.map(|v| format!("{v}")))), _ => Err(TypeError::CastFail), }, } diff --git a/tests/slt/create.slt b/tests/slt/create.slt index 741acc10..4ab6bcb5 100644 --- a/tests/slt/create.slt +++ b/tests/slt/create.slt @@ -1,2 +1,2 @@ statement ok -create table t(id int primary key, v1 int, v2 int, v3 int) \ No newline at end of file +create table t(id int primary key, v1 int, v2 int, v3 text) \ No newline at end of file