Skip to content

Commit

Permalink
Add REVERSE function (gluesql#327)
Browse files Browse the repository at this point in the history
  • Loading branch information
zmrdltl authored Aug 26, 2021
1 parent b9d9d69 commit 23e0e87
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/ast/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ pub enum Function {
Ltrim { expr: Expr, chars: Option<Expr> },
#[strum(to_string = "RTRIM")]
Rtrim { expr: Expr, chars: Option<Expr> },
#[strum(to_string = "REVERSE")]
Reverse(Expr),
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
Expand Down
7 changes: 7 additions & 0 deletions src/executor/evaluate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,13 @@ async fn evaluate_function<'a, T: 'static + Debug>(
}
.map(Evaluated::from)
}
Function::Reverse(expr) => {
match eval_to_str(expr).await? {
Nullable::Value(v) => Ok(Value::Str(v.chars().rev().collect::<String>())),
Nullable::Null => Ok(Value::Null),
}
}
.map(Evaluated::from),
}
}

Expand Down
1 change: 1 addition & 0 deletions src/tests/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod ltrim_rtrim;
pub mod math_function;
pub mod pi;
pub mod radians;
pub mod reverse;
pub mod round;
pub mod sqrt_power;
pub mod trim;
Expand Down
38 changes: 38 additions & 0 deletions src/tests/function/reverse.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::*;

test_case!(reverse, async move {
let test_cases = vec![
("CREATE TABLE Item (name TEXT)", Ok(Payload::Create)),
(
r#"INSERT INTO Item VALUES ("Let's meet")"#,
Ok(Payload::Insert(1)),
),
(
"SELECT REVERSE(name) AS test FROM Item;",
Ok(select!(
"test"
Value::Str;
"teem s'teL".to_owned()
)),
),
(
r#"SELECT REVERSE(1) AS test FROM Item"#,
Err(EvaluateError::FunctionRequiresStringValue("REVERSE".to_owned()).into()),
),
(
"CREATE TABLE NullTest (name TEXT null)",
Ok(Payload::Create),
),
(
r#"INSERT INTO NullTest VALUES (null)"#,
Ok(Payload::Insert(1)),
),
(
r#"SELECT REVERSE(name) AS test FROM NullTest"#,
Ok(select_with_null!(test; Value::Null)),
),
];
for (sql, expected) in test_cases.into_iter() {
test!(expected, sql);
}
});
1 change: 1 addition & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ macro_rules! generate_tests {
glue!(function_radians, function::radians::radians);
glue!(function_degrees, function::degrees::degrees);
glue!(function_pi, function::pi::pi);
glue!(function_reverse, function::reverse::reverse);

#[cfg(feature = "index")]
macro_rules! glue_index {
Expand Down
1 change: 1 addition & 0 deletions src/translate/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ pub fn translate_function(sql_function: &SqlFunction) -> Result<Expr> {
divisor,
})))
}
"REVERSE" => func_with_one_arg!(Function::Reverse),
_ => Err(TranslateError::UnsupportedFunction(name).into()),
}
}

0 comments on commit 23e0e87

Please sign in to comment.