Skip to content

Commit

Permalink
feat: add function Lower & Upper
Browse files Browse the repository at this point in the history
  • Loading branch information
NANASE committed Oct 19, 2024
1 parent bce7cd0 commit fb44809
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::expression::function::scala::ScalarFunctionImpl;
use crate::expression::function::table::TableFunctionImpl;
use crate::expression::function::FunctionSummary;
use crate::function::current_date::CurrentDate;
use crate::function::lower::Lower;
use crate::function::numbers::Numbers;
use crate::function::upper::Upper;
use crate::optimizer::heuristic::batch::HepBatchStrategy;
use crate::optimizer::heuristic::optimizer::HepOptimizer;
use crate::optimizer::rule::implementation::ImplementationRuleImpl;
Expand Down Expand Up @@ -49,6 +51,8 @@ impl DataBaseBuilder {
table_functions: Default::default(),
};
builder = builder.register_scala_function(CurrentDate::new());
builder = builder.register_scala_function(Lower::new());
builder = builder.register_scala_function(Upper::new());
builder = builder.register_table_function(Numbers::new());
builder
}
Expand Down
72 changes: 72 additions & 0 deletions src/function/lower.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use crate::catalog::ColumnRef;
use crate::errors::DatabaseError;
use crate::expression::function::scala::FuncMonotonicity;
use crate::expression::function::scala::ScalarFunctionImpl;
use crate::expression::function::FunctionSummary;
use crate::expression::ScalarExpression;
use crate::types::tuple::Tuple;
use crate::types::value::DataValue;
use crate::types::LogicalType;
use serde::Deserialize;
use serde::Serialize;
use sqlparser::ast::CharLengthUnits;
use std::sync::Arc;

#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct Lower {
summary: FunctionSummary,
}

impl Lower {
#[allow(unused_mut)]
pub(crate) fn new() -> Arc<Self> {
let function_name = "lower".to_lowercase();
let arg_types = vec![LogicalType::Varchar(None, CharLengthUnits::Characters)];
Arc::new(Self {
summary: FunctionSummary {
name: function_name,
arg_types,
},
})
}
}

#[typetag::serde]
impl ScalarFunctionImpl for Lower {
#[allow(unused_variables, clippy::redundant_closure_call)]
fn eval(
&self,
exprs: &[ScalarExpression],
tuples: &Tuple,
columns: &[ColumnRef],
) -> Result<DataValue, DatabaseError> {
let value = exprs[0].eval(tuples, columns)?;
let mut value = DataValue::clone(&value);
if !matches!(value.logical_type(), LogicalType::Varchar(_, _)) {
value = DataValue::clone(&value)
.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?;
}
if let DataValue::Utf8 {
value: Some(value),
ty,
unit,
} = &mut value
{
*value = value.to_lowercase();
}
Ok(value)

}

fn monotonicity(&self) -> Option<FuncMonotonicity> {
todo!()
}

fn return_type(&self) -> &LogicalType {
&LogicalType::Varchar(None, CharLengthUnits::Characters)
}

fn summary(&self) -> &FunctionSummary {
&self.summary
}
}
2 changes: 2 additions & 0 deletions src/function/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pub(crate) mod current_date;
pub(crate) mod numbers;
pub(crate) mod lower;
pub(crate) mod upper;
72 changes: 72 additions & 0 deletions src/function/upper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use crate::catalog::ColumnRef;
use crate::errors::DatabaseError;
use crate::expression::function::scala::FuncMonotonicity;
use crate::expression::function::scala::ScalarFunctionImpl;
use crate::expression::function::FunctionSummary;
use crate::expression::ScalarExpression;
use crate::types::tuple::Tuple;
use crate::types::value::DataValue;
use crate::types::LogicalType;
use serde::Deserialize;
use serde::Serialize;
use sqlparser::ast::CharLengthUnits;
use std::sync::Arc;

#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct Upper {
summary: FunctionSummary,
}

impl Upper {
#[allow(unused_mut)]
pub(crate) fn new() -> Arc<Self> {
let function_name = "upper".to_lowercase();
let arg_types = vec![LogicalType::Varchar(None, CharLengthUnits::Characters)];
Arc::new(Self {
summary: FunctionSummary {
name: function_name,
arg_types,
},
})
}
}

#[typetag::serde]
impl ScalarFunctionImpl for Upper {
#[allow(unused_variables, clippy::redundant_closure_call)]
fn eval(
&self,
exprs: &[ScalarExpression],
tuples: &Tuple,
columns: &[ColumnRef],
) -> Result<DataValue, DatabaseError> {
let value = exprs[0].eval(tuples, columns)?;
let mut value = DataValue::clone(&value);
if !matches!(value.logical_type(), LogicalType::Varchar(_, _)) {
value = DataValue::clone(&value)
.cast(&LogicalType::Varchar(None, CharLengthUnits::Characters))?;
}
if let DataValue::Utf8 {
value: Some(value),
ty,
unit,
} = &mut value
{
*value = value.to_uppercase();
}
Ok(value)

}

fn monotonicity(&self) -> Option<FuncMonotonicity> {
todo!()
}

fn return_type(&self) -> &LogicalType {
&LogicalType::Varchar(None, CharLengthUnits::Characters)
}

fn summary(&self) -> &FunctionSummary {
&self.summary
}
}
36 changes: 27 additions & 9 deletions tests/slt/sql_2016/E021_08.slt
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
# E021-08: UPPER and LOWER functions

# TODO: LOWER()/UPPER()
query T
SELECT LOWER ( 'FOO' )
----
foo

# query T
# SELECT LOWER ( 'foo' )
# ----
# 'foo'
query T
SELECT LOWER ( 'foo' )
----
foo

# query T
# SELECT UPPER ( 'foo' )
# ----
# 'FOO'
query T
SELECT UPPER ( 'foo' )
----
FOO

query T
SELECT UPPER ( 'FOO' )
----
FOO

query T
SELECT UPPER ( LOWER ( 'FOO' ) )
----
FOO

query T
SELECT LOWER ( UPPER ( 'foo' ) )
----
foo

0 comments on commit fb44809

Please sign in to comment.