Skip to content

Commit 126c6c8

Browse files
authored
feat: support Octets for Char/Varchar (#184)
* feat: support `Octets` for `Char/Varchar` * style: code fmt & fix `Char/Varchar` on Server * docs: add ospp icon * docs: change icons place * style: while push -> resize on `src/types/values.rs`
1 parent 5ed5ce4 commit 126c6c8

25 files changed

+517
-195
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ regex = { version = "1.10.3" }
5858
rust_decimal = { version = "1.34.3" }
5959
serde = { version = "1.0.197", features = ["derive", "rc"] }
6060
siphasher = { version = "1.0.0", features = ["serde"] }
61-
sqlparser = { version = "0.34.0" }
61+
sqlparser = { version = "0.34.0", features = ["serde"] }
6262
strum_macros = { version = "0.26.2" }
6363
thiserror = { version = "1.0.58" }
6464
tokio = { version = "1.36.0", features = ["full"] }

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Built by @KipData
1717
</h3>
1818

1919
<p align="center">
20+
<a href="https://summer-ospp.ac.cn/org/orgdetail/0b09d23d-2510-4537-aa9d-45158bb6bdc2"><img src="https://img.shields.io/badge/OSPP-KipData-3DA639?logo=opensourceinitiative"></a>
2021
&nbsp;
2122
<a href="https://github.com/KipData/KipSQL/actions/workflows/ci.yml"><img src="https://github.com/KipData/KipSQL/actions/workflows/ci.yml/badge.svg" alt="CI"></img></a>
2223
&nbsp;

src/bin/server.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ 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::Char(_) | LogicalType::Varchar(_) => {
201+
LogicalType::Char(..) | LogicalType::Varchar(..) => {
202202
encoder.encode_field(&value.utf8())
203203
}
204204
LogicalType::Date => encoder.encode_field(&value.date()),
@@ -225,9 +225,9 @@ fn into_pg_type(data_type: &LogicalType) -> PgWireResult<Type> {
225225
LogicalType::Bigint | LogicalType::UBigint => Type::INT8,
226226
LogicalType::Float => Type::FLOAT4,
227227
LogicalType::Double => Type::FLOAT8,
228-
LogicalType::Varchar(_) => Type::VARCHAR,
228+
LogicalType::Varchar(..) => Type::VARCHAR,
229229
LogicalType::Date | LogicalType::DateTime => Type::DATE,
230-
LogicalType::Char(_) => Type::CHAR,
230+
LogicalType::Char(..) => Type::CHAR,
231231
LogicalType::Time => Type::TIME,
232232
LogicalType::Decimal(_, _) => todo!(),
233233
_ => {

src/binder/create_table.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ mod tests {
146146
use crate::storage::kip::KipStorage;
147147
use crate::storage::Storage;
148148
use crate::types::LogicalType;
149+
use sqlparser::ast::CharLengthUnits;
149150
use std::sync::atomic::AtomicUsize;
150151
use tempfile::TempDir;
151152

@@ -177,7 +178,12 @@ mod tests {
177178
assert_eq!(op.columns[1].nullable, true);
178179
assert_eq!(
179180
op.columns[1].desc,
180-
ColumnDesc::new(LogicalType::Varchar(Some(10)), false, false, None)
181+
ColumnDesc::new(
182+
LogicalType::Varchar(Some(10), CharLengthUnits::Characters),
183+
false,
184+
false,
185+
None
186+
)
181187
);
182188
}
183189
_ => unreachable!(),

src/binder/expr.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::expression;
44
use crate::expression::agg::AggKind;
55
use itertools::Itertools;
66
use sqlparser::ast::{
7-
BinaryOperator, DataType, Expr, Function, FunctionArg, FunctionArgExpr, Ident, Query,
8-
UnaryOperator,
7+
BinaryOperator, CharLengthUnits, DataType, Expr, Function, FunctionArg, FunctionArgExpr, Ident,
8+
Query, UnaryOperator,
99
};
1010
use std::slice;
1111
use std::sync::Arc;
@@ -69,7 +69,8 @@ impl<'a, T: Transaction> Binder<'a, T> {
6969
let logical_type = LogicalType::try_from(data_type.clone())?;
7070
let value = DataValue::Utf8 {
7171
value: Some(value.to_string()),
72-
ty: Utf8Type::Variable,
72+
ty: Utf8Type::Variable(None),
73+
unit: CharLengthUnits::Characters,
7374
}
7475
.cast(&logical_type)?;
7576

@@ -354,7 +355,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
354355
| BinaryOperator::And
355356
| BinaryOperator::Or
356357
| BinaryOperator::Xor => LogicalType::Boolean,
357-
BinaryOperator::StringConcat => LogicalType::Varchar(None),
358+
BinaryOperator::StringConcat => LogicalType::Varchar(None, CharLengthUnits::Characters),
358359
_ => todo!(),
359360
};
360361

@@ -603,7 +604,8 @@ impl<'a, T: Transaction> Binder<'a, T> {
603604
fn wildcard_expr() -> ScalarExpression {
604605
ScalarExpression::Constant(Arc::new(DataValue::Utf8 {
605606
value: Some("*".to_string()),
606-
ty: Utf8Type::Variable,
607+
ty: Utf8Type::Variable(None),
608+
unit: CharLengthUnits::Characters,
607609
}))
608610
}
609611
}

src/catalog/column.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::catalog::TableName;
22
use crate::errors::DatabaseError;
33
use crate::expression::ScalarExpression;
44
use serde::{Deserialize, Serialize};
5+
use sqlparser::ast::CharLengthUnits;
56
use std::hash::Hash;
67
use std::sync::Arc;
78

@@ -50,7 +51,12 @@ impl ColumnCatalog {
5051
table_name: None,
5152
},
5253
nullable: true,
53-
desc: ColumnDesc::new(LogicalType::Varchar(None), false, false, None),
54+
desc: ColumnDesc::new(
55+
LogicalType::Varchar(None, CharLengthUnits::Characters),
56+
false,
57+
false,
58+
None,
59+
),
5460
}
5561
}
5662

src/execution/volcano/dml/analyze.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::types::tuple::Tuple;
1212
use crate::types::value::{DataValue, Utf8Type};
1313
use futures_async_stream::try_stream;
1414
use itertools::Itertools;
15+
use sqlparser::ast::CharLengthUnits;
1516
use std::fmt::Formatter;
1617
use std::sync::Arc;
1718
use std::time::{SystemTime, UNIX_EPOCH};
@@ -108,7 +109,8 @@ impl Analyze {
108109
meta.to_file(&path)?;
109110
values.push(Arc::new(DataValue::Utf8 {
110111
value: Some(path.clone()),
111-
ty: Utf8Type::Variable,
112+
ty: Utf8Type::Variable(None),
113+
unit: CharLengthUnits::Characters,
112114
}));
113115
transaction.save_table_meta(&table_name, path, meta)?;
114116
}

src/execution/volcano/dml/copy_from_file.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ mod tests {
105105
use crate::catalog::{ColumnCatalog, ColumnDesc, ColumnSummary};
106106
use crate::db::DataBaseBuilder;
107107
use futures::StreamExt;
108+
use sqlparser::ast::CharLengthUnits;
108109
use std::io::Write;
109110
use std::sync::Arc;
110111
use tempfile::TempDir;
@@ -148,7 +149,12 @@ mod tests {
148149
table_name: None,
149150
},
150151
nullable: false,
151-
desc: ColumnDesc::new(LogicalType::Varchar(Some(10)), false, false, None),
152+
desc: ColumnDesc::new(
153+
LogicalType::Varchar(Some(10), CharLengthUnits::Characters),
154+
false,
155+
false,
156+
None,
157+
),
152158
}),
153159
];
154160

src/execution/volcano/dql/describe.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,24 @@ use crate::types::tuple::Tuple;
77
use crate::types::value::{DataValue, Utf8Type, ValueRef};
88
use futures_async_stream::try_stream;
99
use lazy_static::lazy_static;
10+
use sqlparser::ast::CharLengthUnits;
1011
use std::sync::Arc;
1112

1213
lazy_static! {
1314
static ref PRIMARY_KEY_TYPE: ValueRef = Arc::new(DataValue::Utf8 {
1415
value: Some(String::from("PRIMARY")),
15-
ty: Utf8Type::Variable
16+
ty: Utf8Type::Variable(None),
17+
unit: CharLengthUnits::Characters
1618
});
1719
static ref UNIQUE_KEY_TYPE: ValueRef = Arc::new(DataValue::Utf8 {
1820
value: Some(String::from("UNIQUE")),
19-
ty: Utf8Type::Variable
21+
ty: Utf8Type::Variable(None),
22+
unit: CharLengthUnits::Characters
2023
});
2124
static ref EMPTY_KEY_TYPE: ValueRef = Arc::new(DataValue::Utf8 {
2225
value: Some(String::from("EMPTY")),
23-
ty: Utf8Type::Variable
26+
ty: Utf8Type::Variable(None),
27+
unit: CharLengthUnits::Characters
2428
});
2529
}
2630

@@ -69,24 +73,29 @@ impl Describe {
6973
let values = vec![
7074
Arc::new(DataValue::Utf8 {
7175
value: Some(column.name().to_string()),
72-
ty: Utf8Type::Variable,
76+
ty: Utf8Type::Variable(None),
77+
unit: CharLengthUnits::Characters,
7378
}),
7479
Arc::new(DataValue::Utf8 {
7580
value: Some(datatype.to_string()),
76-
ty: Utf8Type::Variable,
81+
ty: Utf8Type::Variable(None),
82+
unit: CharLengthUnits::Characters,
7783
}),
7884
Arc::new(DataValue::Utf8 {
7985
value: datatype.raw_len().map(|len| len.to_string()),
80-
ty: Utf8Type::Variable,
86+
ty: Utf8Type::Variable(None),
87+
unit: CharLengthUnits::Characters,
8188
}),
8289
Arc::new(DataValue::Utf8 {
8390
value: Some(column.nullable.to_string()),
84-
ty: Utf8Type::Variable,
91+
ty: Utf8Type::Variable(None),
92+
unit: CharLengthUnits::Characters,
8593
}),
8694
key_fn(column),
8795
Arc::new(DataValue::Utf8 {
8896
value: Some(default),
89-
ty: Utf8Type::Variable,
97+
ty: Utf8Type::Variable(None),
98+
unit: CharLengthUnits::Characters,
9099
}),
91100
];
92101
yield Tuple { id: None, values };

src/execution/volcano/dql/explain.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::storage::Transaction;
55
use crate::types::tuple::Tuple;
66
use crate::types::value::{DataValue, Utf8Type};
77
use futures_async_stream::try_stream;
8+
use sqlparser::ast::CharLengthUnits;
89
use std::sync::Arc;
910

1011
pub struct Explain {
@@ -28,7 +29,8 @@ impl Explain {
2829
pub async fn _execute(self) {
2930
let values = vec![Arc::new(DataValue::Utf8 {
3031
value: Some(self.plan.explain(0)),
31-
ty: Utf8Type::Variable,
32+
ty: Utf8Type::Variable(None),
33+
unit: CharLengthUnits::Characters,
3234
})];
3335

3436
yield Tuple { id: None, values };

src/execution/volcano/dql/show_table.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::storage::Transaction;
55
use crate::types::tuple::Tuple;
66
use crate::types::value::{DataValue, Utf8Type};
77
use futures_async_stream::try_stream;
8+
use sqlparser::ast::CharLengthUnits;
89
use std::sync::Arc;
910

1011
pub struct ShowTables;
@@ -23,7 +24,8 @@ impl ShowTables {
2324
for TableMeta { table_name } in metas {
2425
let values = vec![Arc::new(DataValue::Utf8 {
2526
value: Some(table_name.to_string()),
26-
ty: Utf8Type::Variable,
27+
ty: Utf8Type::Variable(None),
28+
unit: CharLengthUnits::Characters,
2729
})];
2830

2931
yield Tuple { id: None, values };

src/expression/evaluator.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::types::value::{DataValue, Utf8Type, ValueRef};
77
use crate::types::LogicalType;
88
use itertools::Itertools;
99
use lazy_static::lazy_static;
10+
use sqlparser::ast::CharLengthUnits;
1011
use std::cmp;
1112
use std::cmp::Ordering;
1213
use std::sync::Arc;
@@ -25,7 +26,8 @@ macro_rules! eval_to_num {
2526
} else {
2627
return Ok(Arc::new(DataValue::Utf8 {
2728
value: None,
28-
ty: Utf8Type::Variable,
29+
ty: Utf8Type::Variable(None),
30+
unit: CharLengthUnits::Characters,
2931
}));
3032
}
3133
};
@@ -156,7 +158,7 @@ impl ScalarExpression {
156158
from_expr,
157159
} => {
158160
if let Some(mut string) = DataValue::clone(expr.eval(tuple, schema)?.as_ref())
159-
.cast(&LogicalType::Varchar(None))?
161+
.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?
160162
.utf8()
161163
{
162164
if let Some(from_expr) = from_expr {
@@ -169,7 +171,8 @@ impl ScalarExpression {
169171
if from > len_i {
170172
return Ok(Arc::new(DataValue::Utf8 {
171173
value: None,
172-
ty: Utf8Type::Variable,
174+
ty: Utf8Type::Variable(None),
175+
unit: CharLengthUnits::Characters,
173176
}));
174177
}
175178
string = string.split_off(from as usize);
@@ -182,19 +185,21 @@ impl ScalarExpression {
182185

183186
Ok(Arc::new(DataValue::Utf8 {
184187
value: Some(string),
185-
ty: Utf8Type::Variable,
188+
ty: Utf8Type::Variable(None),
189+
unit: CharLengthUnits::Characters,
186190
}))
187191
} else {
188192
Ok(Arc::new(DataValue::Utf8 {
189193
value: None,
190-
ty: Utf8Type::Variable,
194+
ty: Utf8Type::Variable(None),
195+
unit: CharLengthUnits::Characters,
191196
}))
192197
}
193198
}
194199
ScalarExpression::Position { expr, in_expr } => {
195200
let unpack = |expr: &ScalarExpression| -> Result<String, DatabaseError> {
196201
Ok(DataValue::clone(expr.eval(tuple, schema)?.as_ref())
197-
.cast(&LogicalType::Varchar(None))?
202+
.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?
198203
.utf8()
199204
.unwrap_or("".to_owned()))
200205
};

src/expression/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use std::hash::Hash;
55
use std::sync::Arc;
66
use std::{fmt, mem};
77

8-
use sqlparser::ast::{BinaryOperator as SqlBinaryOperator, UnaryOperator as SqlUnaryOperator};
8+
use sqlparser::ast::{
9+
BinaryOperator as SqlBinaryOperator, CharLengthUnits, UnaryOperator as SqlUnaryOperator,
10+
};
911

1012
use self::agg::AggKind;
1113
use crate::catalog::{ColumnCatalog, ColumnDesc, ColumnRef};
@@ -394,7 +396,9 @@ impl ScalarExpression {
394396
ScalarExpression::IsNull { .. }
395397
| ScalarExpression::In { .. }
396398
| ScalarExpression::Between { .. } => LogicalType::Boolean,
397-
ScalarExpression::SubString { .. } => LogicalType::Varchar(None),
399+
ScalarExpression::SubString { .. } => {
400+
LogicalType::Varchar(None, CharLengthUnits::Characters)
401+
}
398402
ScalarExpression::Position { .. } => LogicalType::Integer,
399403
ScalarExpression::Alias { expr, .. } | ScalarExpression::Reference { expr, .. } => {
400404
expr.return_type()

0 commit comments

Comments
 (0)