Skip to content

Commit 253daa8

Browse files
authored
feat: add DataType::Char and add LEN to Describe (#174)
* feat: add `DataType::Char` and add `LEN` to `Describe` * fix: `Tuple::serialize_to` & `Tuple::deserialize_from` for `LogicalType::Char` * fix: `DataValue::cast`'s Decimal\Date32\Date64 to Char * fix: replace fill symbol '\0' -> ' ' for `LogicalType::Char` * fix: fill symbol move to `DataValue::to_raw` * docs: add DataType::Char * style: code simplification * fix: `LogicalType::Char` on Server
1 parent e0de637 commit 253daa8

File tree

23 files changed

+248
-101
lines changed

23 files changed

+248
-101
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ let fnck_sql = DataBaseBuilder::path("./data")
124124
- UInteger
125125
- Bigint
126126
- UBigint
127+
- Char
127128
- Varchar
128129
- DDL
129130
- Begin (Server only)
@@ -177,6 +178,7 @@ let fnck_sql = DataBaseBuilder::path("./data")
177178
- UBigint
178179
- Float
179180
- Double
181+
- Char
180182
- Varchar
181183
- Date
182184
- DateTime

src/bin/server.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,9 @@ fn encode_tuples<'a>(schema: &Schema, tuples: Vec<Tuple>) -> PgWireResult<QueryR
198198
LogicalType::UBigint => encoder.encode_field(&value.u64().map(|v| v as i64)),
199199
LogicalType::Float => encoder.encode_field(&value.float()),
200200
LogicalType::Double => encoder.encode_field(&value.double()),
201-
LogicalType::Varchar(_) => encoder.encode_field(&value.utf8()),
201+
LogicalType::Char(_) | LogicalType::Varchar(_) => {
202+
encoder.encode_field(&value.utf8())
203+
}
202204
LogicalType::Date => encoder.encode_field(&value.date()),
203205
LogicalType::DateTime => encoder.encode_field(&value.datetime()),
204206
LogicalType::Decimal(_, _) => todo!(),
@@ -224,6 +226,7 @@ fn into_pg_type(data_type: &LogicalType) -> PgWireResult<Type> {
224226
LogicalType::Double => Type::FLOAT8,
225227
LogicalType::Varchar(_) => Type::VARCHAR,
226228
LogicalType::Date | LogicalType::DateTime => Type::DATE,
229+
LogicalType::Char(_) => Type::CHAR,
227230
LogicalType::Decimal(_, _) => todo!(),
228231
_ => {
229232
return Err(PgWireError::UserError(Box::new(ErrorInfo::new(

src/execution/volcano/ddl/add_column.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,21 @@ impl<T: Transaction> WriteExecutor<T> for AddColumn {
3030

3131
impl AddColumn {
3232
#[try_stream(boxed, ok = Tuple, error = DatabaseError)]
33-
async fn _execute<T: Transaction>(self, transaction: &mut T) {
33+
async fn _execute<T: Transaction>(mut self, transaction: &mut T) {
3434
let AddColumnOperator {
3535
table_name,
3636
column,
3737
if_not_exists,
3838
} = &self.op;
3939
let mut unique_values = column.desc().is_unique.then(Vec::new);
4040
let mut tuples = Vec::new();
41+
let schema = self.input.output_schema();
42+
let mut types = Vec::with_capacity(schema.len() + 1);
43+
44+
for column_ref in schema.iter() {
45+
types.push(*column_ref.datatype());
46+
}
47+
types.push(*column.datatype());
4148

4249
#[for_await]
4350
for tuple in build_read(self.input, transaction) {
@@ -54,7 +61,7 @@ impl AddColumn {
5461
tuples.push(tuple);
5562
}
5663
for tuple in tuples {
57-
transaction.append(table_name, tuple, true)?;
64+
transaction.append(table_name, tuple, &types, true)?;
5865
}
5966
let col_id = transaction.add_column(table_name, column, *if_not_exists)?;
6067

src/execution/volcano/ddl/drop_column.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,14 @@ impl DropColumn {
4646
))?;
4747
}
4848
let mut tuples = Vec::new();
49+
let mut types = Vec::with_capacity(tuple_columns.len() - 1);
4950

51+
for (i, column_ref) in tuple_columns.iter().enumerate() {
52+
if i == column_index {
53+
continue;
54+
}
55+
types.push(*column_ref.datatype());
56+
}
5057
#[for_await]
5158
for tuple in build_read(self.input, transaction) {
5259
let mut tuple: Tuple = tuple?;
@@ -55,7 +62,7 @@ impl DropColumn {
5562
tuples.push(tuple);
5663
}
5764
for tuple in tuples {
58-
transaction.append(&table_name, tuple, true)?;
65+
transaction.append(&table_name, tuple, &types, true)?;
5966
}
6067
transaction.drop_column(&table_name, &column_name)?;
6168

src/execution/volcano/dml/copy_from_file.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::errors::DatabaseError;
33
use crate::execution::volcano::{BoxedExecutor, WriteExecutor};
44
use crate::planner::operator::copy_from_file::CopyFromFileOperator;
55
use crate::storage::Transaction;
6-
use crate::types::tuple::Tuple;
6+
use crate::types::tuple::{types, Tuple};
77
use crate::types::tuple_builder::TupleBuilder;
88
use futures_async_stream::try_stream;
99
use std::fs::File;
@@ -30,6 +30,7 @@ impl<T: Transaction> WriteExecutor<T> for CopyFromFile {
3030
impl CopyFromFile {
3131
#[try_stream(boxed, ok = Tuple, error = DatabaseError)]
3232
pub async fn _execute<T: Transaction>(self, transaction: &mut T) {
33+
let types = types(&self.op.schema_ref);
3334
let (tx, mut rx) = tokio::sync::mpsc::channel(1);
3435
let (tx1, mut rx1) = tokio::sync::mpsc::channel(1);
3536
// # Cancellation
@@ -39,7 +40,7 @@ impl CopyFromFile {
3940
let handle = tokio::task::spawn_blocking(|| self.read_file_blocking(tx));
4041
let mut size = 0_usize;
4142
while let Some(chunk) = rx.recv().await {
42-
transaction.append(&table_name, chunk, false)?;
43+
transaction.append(&table_name, chunk, &types, false)?;
4344
size += 1;
4445
}
4546
handle.await??;

src/execution/volcano/dml/insert.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl Insert {
6060
.ok_or_else(|| DatabaseError::NotNull)?;
6161

6262
if let Some(table_catalog) = transaction.table(table_name.clone()).cloned() {
63+
let types = table_catalog.types();
6364
#[for_await]
6465
for tuple in build_read(input, transaction) {
6566
let Tuple { values, .. } = tuple?;
@@ -99,7 +100,7 @@ impl Insert {
99100
}
100101
}
101102
for tuple in tuples {
102-
transaction.append(&table_name, tuple, is_overwrite)?;
103+
transaction.append(&table_name, tuple, &types, is_overwrite)?;
103104
}
104105
}
105106
}

src/execution/volcano/dml/update.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::planner::operator::update::UpdateOperator;
66
use crate::planner::LogicalPlan;
77
use crate::storage::Transaction;
88
use crate::types::index::Index;
9+
use crate::types::tuple::types;
910
use crate::types::tuple::Tuple;
1011
use futures_async_stream::try_stream;
1112
use std::collections::HashMap;
@@ -44,6 +45,7 @@ impl Update {
4445
} = self;
4546
let values_schema = values.output_schema().clone();
4647
let input_schema = input.output_schema().clone();
48+
let types = types(&input_schema);
4749

4850
if let Some(table_catalog) = transaction.table(table_name.clone()).cloned() {
4951
let mut value_map = HashMap::new();
@@ -94,7 +96,7 @@ impl Update {
9496
transaction.add_index(&table_name, index, tuple.id.as_ref().unwrap())?;
9597
}
9698

97-
transaction.append(&table_name, tuple, is_overwrite)?;
99+
transaction.append(&table_name, tuple, &types, is_overwrite)?;
98100
}
99101
}
100102
}

src/execution/volcano/dql/describe.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,21 @@ impl Describe {
5151
};
5252

5353
for column in table.columns() {
54+
let datatype = column.datatype();
5455
let values = vec![
5556
Arc::new(DataValue::Utf8(Some(column.name().to_string()))),
56-
Arc::new(DataValue::Utf8(Some(column.datatype().to_string()))),
57+
Arc::new(DataValue::Utf8(Some(datatype.to_string()))),
58+
Arc::new(DataValue::Utf8(Some(
59+
datatype
60+
.raw_len()
61+
.map(|len| len.to_string())
62+
.unwrap_or_else(|| "DYNAMIC".to_string()),
63+
))),
5764
Arc::new(DataValue::Utf8(Some(column.nullable.to_string()))),
5865
key_fn(column),
5966
column
6067
.default_value()
61-
.unwrap_or_else(|| Arc::new(DataValue::none(column.datatype()))),
68+
.unwrap_or_else(|| Arc::new(DataValue::none(datatype))),
6269
];
6370
yield Tuple { id: None, values };
6471
}

src/expression/value_compute.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ impl DataValue {
502502
_ => return Err(DatabaseError::UnsupportedBinaryOperator(unified_type, *op)),
503503
}
504504
}
505-
LogicalType::Varchar(_) => {
505+
LogicalType::Varchar(_) | LogicalType::Char(_) => {
506506
let left_value = unpack_utf8(self.clone().cast(&unified_type)?);
507507
let right_value = unpack_utf8(right.clone().cast(&unified_type)?);
508508

src/optimizer/core/histogram.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ impl Histogram {
255255
) -> Result<bool, DatabaseError> {
256256
let float_value = |value: &DataValue, prefix_len: usize| {
257257
let value = match value.logical_type() {
258-
LogicalType::Varchar(_) => match value {
258+
LogicalType::Varchar(_) | LogicalType::Char(_) => match value {
259259
DataValue::Utf8(value) => value.as_ref().map(|string| {
260260
if prefix_len > string.len() {
261261
return 0.0;

0 commit comments

Comments
 (0)