Skip to content

Commit ae59a91

Browse files
wszhdshysNANASE
andauthored
feat: add function CharLength & CharacterLength (#235)
Co-authored-by: NANASE <wszhds@gmail.com>
1 parent 06824ec commit ae59a91

File tree

5 files changed

+84
-11
lines changed

5 files changed

+84
-11
lines changed

rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nightly-2024-04-27
1+
nightly-2024-10-18

src/db.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::execution::{build_write, try_collect};
55
use crate::expression::function::scala::ScalarFunctionImpl;
66
use crate::expression::function::table::TableFunctionImpl;
77
use crate::expression::function::FunctionSummary;
8+
use crate::function::char_length::CharLength;
89
use crate::function::current_date::CurrentDate;
910
use crate::function::lower::Lower;
1011
use crate::function::numbers::Numbers;
@@ -50,6 +51,9 @@ impl DataBaseBuilder {
5051
scala_functions: Default::default(),
5152
table_functions: Default::default(),
5253
};
54+
builder = builder.register_scala_function(CharLength::new("char_length".to_lowercase()));
55+
builder =
56+
builder.register_scala_function(CharLength::new("character_length".to_lowercase()));
5357
builder = builder.register_scala_function(CurrentDate::new());
5458
builder = builder.register_scala_function(Lower::new());
5559
builder = builder.register_scala_function(Upper::new());

src/function/char_length.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 CharLength {
17+
summary: FunctionSummary,
18+
}
19+
20+
impl CharLength {
21+
pub(crate) fn new(function_name: String) -> Arc<Self> {
22+
let arg_types = vec![LogicalType::Varchar(None, CharLengthUnits::Characters)];
23+
Arc::new(Self {
24+
summary: FunctionSummary {
25+
name: function_name,
26+
arg_types,
27+
},
28+
})
29+
}
30+
}
31+
32+
#[typetag::serde]
33+
impl ScalarFunctionImpl for CharLength {
34+
#[allow(unused_variables, clippy::redundant_closure_call)]
35+
fn eval(
36+
&self,
37+
exprs: &[ScalarExpression],
38+
tuples: &Tuple,
39+
columns: &[ColumnRef],
40+
) -> Result<DataValue, DatabaseError> {
41+
let value = exprs[0].eval(tuples, columns)?;
42+
let mut value = DataValue::clone(&value);
43+
if !matches!(value.logical_type(), LogicalType::Varchar(_, _)) {
44+
value = DataValue::clone(&value)
45+
.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?;
46+
}
47+
let mut length: u64 = 0;
48+
if let DataValue::Utf8 {
49+
value: Some(value),
50+
ty,
51+
unit,
52+
} = &mut value
53+
{
54+
length = value.len() as u64;
55+
}
56+
Ok(DataValue::UInt64(Some(length)))
57+
}
58+
59+
fn monotonicity(&self) -> Option<FuncMonotonicity> {
60+
todo!()
61+
}
62+
63+
fn return_type(&self) -> &LogicalType {
64+
&LogicalType::Varchar(None, CharLengthUnits::Characters)
65+
}
66+
67+
fn summary(&self) -> &FunctionSummary {
68+
&self.summary
69+
}
70+
}

src/function/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub(crate) mod char_length;
12
pub(crate) mod current_date;
23
pub(crate) mod lower;
34
pub(crate) mod numbers;

tests/slt/sql_2016/E021_04.slt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
# E021-04: CHARACTER_LENGTH function
22

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

5-
# query I
6-
# SELECT CHARACTER_LENGTH ( 'foo' )
7-
# ----
8-
# 3
98

10-
11-
# query I
12-
# SELECT CHAR_LENGTH ( 'foo' )
13-
# ----
14-
# 3
9+
query I
10+
SELECT CHAR_LENGTH ( 'foo' )
11+
----
12+
3

0 commit comments

Comments
 (0)