Skip to content

Commit f7de8b9

Browse files
authored
feat: The octet function is implemented to calculate the number of bytes of the input value. And fixed the charlength function so that it correctly outputs the number of characters instead of bytes (#264)
1 parent 7348d79 commit f7de8b9

File tree

6 files changed

+86
-8
lines changed

6 files changed

+86
-8
lines changed

src/db.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::function::char_length::CharLength;
88
use crate::function::current_date::CurrentDate;
99
use crate::function::lower::Lower;
1010
use crate::function::numbers::Numbers;
11+
use crate::function::octet_length::OctetLength;
1112
use crate::function::upper::Upper;
1213
use crate::optimizer::heuristic::batch::HepBatchStrategy;
1314
use crate::optimizer::heuristic::optimizer::HepOptimizer;
@@ -61,6 +62,7 @@ impl DataBaseBuilder {
6162
builder.register_scala_function(CharLength::new("character_length".to_lowercase()));
6263
builder = builder.register_scala_function(CurrentDate::new());
6364
builder = builder.register_scala_function(Lower::new());
65+
builder = builder.register_scala_function(OctetLength::new());
6466
builder = builder.register_scala_function(Upper::new());
6567
builder = builder.register_table_function(Numbers::new());
6668
builder

src/function/char_length.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl ScalarFunctionImpl for CharLength {
4343
}
4444
let mut length: u64 = 0;
4545
if let DataValue::Utf8 { value, ty, unit } = &mut value {
46-
length = value.len() as u64;
46+
length = value.chars().count() as u64;
4747
}
4848
Ok(DataValue::UInt64(length))
4949
}

src/function/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ pub(crate) mod char_length;
22
pub(crate) mod current_date;
33
pub(crate) mod lower;
44
pub(crate) mod numbers;
5+
pub(crate) mod octet_length;
56
pub(crate) mod upper;

src/function/octet_length.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use crate::catalog::ColumnRef;
2+
use crate::errors::DatabaseError;
3+
use crate::expression::function::scala::FuncMonotonicity;
4+
use crate::expression::function::scala::ScalarFunctionImpl;
5+
use crate::expression::function::FunctionSummary;
6+
use crate::expression::ScalarExpression;
7+
use crate::types::tuple::Tuple;
8+
use crate::types::value::DataValue;
9+
use crate::types::LogicalType;
10+
use serde::Deserialize;
11+
use serde::Serialize;
12+
use sqlparser::ast::CharLengthUnits;
13+
use std::sync::Arc;
14+
15+
#[derive(Debug, Serialize, Deserialize)]
16+
pub(crate) struct OctetLength {
17+
summary: FunctionSummary,
18+
}
19+
20+
impl OctetLength {
21+
pub(crate) fn new() -> Arc<Self> {
22+
let function_name = "octet_length".to_lowercase();
23+
let arg_types = vec![LogicalType::Varchar(None, CharLengthUnits::Characters)];
24+
Arc::new(Self {
25+
summary: FunctionSummary {
26+
name: function_name,
27+
arg_types,
28+
},
29+
})
30+
}
31+
}
32+
33+
#[typetag::serde]
34+
impl ScalarFunctionImpl for OctetLength {
35+
#[allow(unused_variables, clippy::redundant_closure_call)]
36+
fn eval(
37+
&self,
38+
exprs: &[ScalarExpression],
39+
tuples: Option<(&Tuple, &[ColumnRef])>,
40+
) -> Result<DataValue, DatabaseError> {
41+
let mut value = exprs[0].eval(tuples)?;
42+
if !matches!(value.logical_type(), LogicalType::Varchar(_, _)) {
43+
value = value.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?;
44+
}
45+
let mut length: u64 = 0;
46+
if let DataValue::Utf8 { value, ty, unit } = &mut value {
47+
length = value.len() as u64;
48+
}
49+
Ok(DataValue::UInt64(length))
50+
}
51+
52+
fn monotonicity(&self) -> Option<FuncMonotonicity> {
53+
todo!()
54+
}
55+
56+
fn return_type(&self) -> &LogicalType {
57+
&LogicalType::Varchar(None, CharLengthUnits::Characters)
58+
}
59+
60+
fn summary(&self) -> &FunctionSummary {
61+
&self.summary
62+
}
63+
}

tests/slt/sql_2016/E021_04.slt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,17 @@ SELECT CHARACTER_LENGTH ( 'foo' )
55
----
66
3
77

8-
98
query I
109
SELECT CHAR_LENGTH ( 'foo' )
1110
----
1211
3
12+
13+
query I
14+
SELECT CHARACTER_LENGTH ( '测试' )
15+
----
16+
2
17+
18+
query I
19+
SELECT CHAR_LENGTH ( '测试' )
20+
----
21+
2

tests/slt/sql_2016/E021_05.slt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
# E021-05: OCTET_LENGTH function
1+
#E021-05: OCTET_LENGTH function
22

3-
# TODO: OCTET_LENGTH()
3+
query I
4+
SELECT OCTET_LENGTH ( 'foo' )
5+
----
6+
3
47

5-
# query I
6-
# SELECT OCTET_LENGTH ( 'foo' )
7-
# ----
8-
# 3
8+
query I
9+
SELECT OCTET_LENGTH ( '测试' )
10+
----
11+
6

0 commit comments

Comments
 (0)