mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-27 20:04:23 +01:00
Merge pull request #246 from macroexpansion/feature/add-rtrim-scalar-function
This commit is contained in:
@@ -95,8 +95,8 @@ This document describes the SQLite compatibility status of Limbo:
|
||||
| replace(X,Y,Z) | No | |
|
||||
| round(X) | Yes | |
|
||||
| round(X,Y) | Yes | |
|
||||
| rtrim(X) | No | |
|
||||
| rtrim(X,Y) | No | |
|
||||
| rtrim(X) | Yes | |
|
||||
| rtrim(X,Y) | Yes | |
|
||||
| sign(X) | No | |
|
||||
| soundex(X) | No | |
|
||||
| sqlite_compileoption_get(N) | No | |
|
||||
|
||||
@@ -35,6 +35,7 @@ pub enum ScalarFunc {
|
||||
Random,
|
||||
Trim,
|
||||
LTrim,
|
||||
RTrim,
|
||||
Round,
|
||||
Length,
|
||||
Min,
|
||||
@@ -54,6 +55,7 @@ impl ToString for ScalarFunc {
|
||||
ScalarFunc::Random => "random".to_string(),
|
||||
ScalarFunc::Trim => "trim".to_string(),
|
||||
ScalarFunc::LTrim => "ltrim".to_string(),
|
||||
ScalarFunc::RTrim => "rtrim".to_string(),
|
||||
ScalarFunc::Round => "round".to_string(),
|
||||
ScalarFunc::Length => "length".to_string(),
|
||||
ScalarFunc::Min => "min".to_string(),
|
||||
@@ -91,6 +93,7 @@ impl Func {
|
||||
"random" => Ok(Func::Scalar(ScalarFunc::Random)),
|
||||
"trim" => Ok(Func::Scalar(ScalarFunc::Trim)),
|
||||
"ltrim" => Ok(Func::Scalar(ScalarFunc::LTrim)),
|
||||
"rtrim" => Ok(Func::Scalar(ScalarFunc::RTrim)),
|
||||
"round" => Ok(Func::Scalar(ScalarFunc::Round)),
|
||||
"length" => Ok(Func::Scalar(ScalarFunc::Length)),
|
||||
"date" => Ok(Func::Scalar(ScalarFunc::Date)),
|
||||
|
||||
@@ -275,7 +275,10 @@ pub fn translate_expr(
|
||||
});
|
||||
Ok(target_register)
|
||||
}
|
||||
ScalarFunc::Trim | ScalarFunc::LTrim | ScalarFunc::Round => {
|
||||
ScalarFunc::Trim
|
||||
| ScalarFunc::LTrim
|
||||
| ScalarFunc::RTrim
|
||||
| ScalarFunc::Round => {
|
||||
let args = if let Some(args) = args {
|
||||
if args.len() > 2 {
|
||||
crate::bail_parse_error!(
|
||||
|
||||
@@ -1125,6 +1125,16 @@ impl Program {
|
||||
state.registers[*dest] = result;
|
||||
state.pc += 1;
|
||||
}
|
||||
ScalarFunc::RTrim => {
|
||||
let start_reg = *start_reg;
|
||||
let reg_value = state.registers[start_reg].clone();
|
||||
let pattern_value = state.registers.get(start_reg + 1).cloned();
|
||||
|
||||
let result = exec_rtrim(®_value, pattern_value);
|
||||
|
||||
state.registers[*dest] = result;
|
||||
state.pc += 1;
|
||||
}
|
||||
ScalarFunc::Round => {
|
||||
let start_reg = *start_reg;
|
||||
let reg_value = state.registers[start_reg].clone();
|
||||
@@ -1379,6 +1389,25 @@ fn exec_ltrim(reg: &OwnedValue, pattern: Option<OwnedValue>) -> OwnedValue {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements RTRIM pattern matching.
|
||||
fn exec_rtrim(reg: &OwnedValue, pattern: Option<OwnedValue>) -> OwnedValue {
|
||||
match (reg, pattern) {
|
||||
(reg, Some(pattern)) => match reg {
|
||||
OwnedValue::Text(_) | OwnedValue::Integer(_) | OwnedValue::Float(_) => {
|
||||
let pattern_chars: Vec<char> = pattern.to_string().chars().collect();
|
||||
OwnedValue::Text(Rc::new(
|
||||
reg.to_string()
|
||||
.trim_end_matches(&pattern_chars[..])
|
||||
.to_string(),
|
||||
))
|
||||
}
|
||||
_ => reg.to_owned(),
|
||||
},
|
||||
(OwnedValue::Text(t), None) => OwnedValue::Text(Rc::new(t.trim_end().to_string())),
|
||||
(reg, _) => reg.to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
// exec_if returns whether you should jump
|
||||
fn exec_if(reg: &OwnedValue, null_reg: &OwnedValue, not: bool) -> bool {
|
||||
match reg {
|
||||
@@ -1397,7 +1426,7 @@ fn exec_if(reg: &OwnedValue, null_reg: &OwnedValue, not: bool) -> bool {
|
||||
mod tests {
|
||||
use super::{
|
||||
exec_abs, exec_if, exec_length, exec_like, exec_lower, exec_ltrim, exec_minmax,
|
||||
exec_random, exec_round, exec_trim, exec_unicode, exec_upper, OwnedValue,
|
||||
exec_random, exec_round, exec_rtrim, exec_trim, exec_unicode, exec_upper, OwnedValue,
|
||||
};
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -1518,6 +1547,23 @@ mod tests {
|
||||
assert_eq!(exec_ltrim(&input_str, Some(pattern_str)), expected_str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rtrim() {
|
||||
let input_str = OwnedValue::Text(Rc::new(String::from(" Bob and Alice ")));
|
||||
let expected_str = OwnedValue::Text(Rc::new(String::from(" Bob and Alice")));
|
||||
assert_eq!(exec_rtrim(&input_str, None), expected_str);
|
||||
|
||||
let input_str = OwnedValue::Text(Rc::new(String::from(" Bob and Alice ")));
|
||||
let pattern_str = OwnedValue::Text(Rc::new(String::from("Bob and")));
|
||||
let expected_str = OwnedValue::Text(Rc::new(String::from(" Bob and Alice")));
|
||||
assert_eq!(exec_rtrim(&input_str, Some(pattern_str)), expected_str);
|
||||
|
||||
let input_str = OwnedValue::Text(Rc::new(String::from(" Bob and Alice ")));
|
||||
let pattern_str = OwnedValue::Text(Rc::new(String::from("and Alice")));
|
||||
let expected_str = OwnedValue::Text(Rc::new(String::from(" Bob")));
|
||||
assert_eq!(exec_rtrim(&input_str, Some(pattern_str)), expected_str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_upper_case() {
|
||||
let input_str = OwnedValue::Text(Rc::new(String::from("Limbo")));
|
||||
|
||||
@@ -123,6 +123,42 @@ do_execsql_test ltrim-no-match-pattern {
|
||||
SELECT ltrim('Limbo', 'xyz');
|
||||
} {Limbo}
|
||||
|
||||
do_execsql_test rtrim {
|
||||
SELECT rtrim(' Limbo ');
|
||||
} {" Limbo"}
|
||||
|
||||
do_execsql_test rtrim-number {
|
||||
SELECT rtrim(1);
|
||||
} {1}
|
||||
|
||||
do_execsql_test rtrim-null {
|
||||
SELECT rtrim(null);
|
||||
} {}
|
||||
|
||||
do_execsql_test rtrim-trailing-whitespace {
|
||||
SELECT rtrim('Trailing ');
|
||||
} {Trailing}
|
||||
|
||||
do_execsql_test rtrim-no-trailing-whitespace {
|
||||
SELECT rtrim('Limbo');
|
||||
} {Limbo}
|
||||
|
||||
do_execsql_test rtrim-pattern {
|
||||
SELECT rtrim('Limbo', 'Limbo');
|
||||
} {}
|
||||
|
||||
do_execsql_test rtrim-pattern-number {
|
||||
SELECT rtrim(1, '1');
|
||||
} {}
|
||||
|
||||
do_execsql_test rtrim-pattern-null {
|
||||
SELECT rtrim(null, 'null');
|
||||
} {}
|
||||
|
||||
do_execsql_test rtrim-no-match-pattern {
|
||||
SELECT rtrim('Limbo', 'xyz');
|
||||
} {Limbo}
|
||||
|
||||
do_execsql_test round-float-no-precision {
|
||||
SELECT round(123.456);
|
||||
} {123.0}
|
||||
|
||||
Reference in New Issue
Block a user