mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-18 17:14:20 +01:00
Add unhex(X) scalar function
This commit adds `unhex(X)` scalar function. Function with `unhex(X,Y)` two arguments is not implemented yet. Relates to issue #144
This commit is contained in:
@@ -112,7 +112,7 @@ This document describes the SQLite compatibility status of Limbo:
|
||||
| trim(X) | Yes | |
|
||||
| trim(X,Y) | Yes | |
|
||||
| typeof(X) | Yes | |
|
||||
| unhex(X) | No | |
|
||||
| unhex(X) | Yes | |
|
||||
| unhex(X,Y) | No | |
|
||||
| unicode(X) | Yes | |
|
||||
| unlikely(X) | No | |
|
||||
|
||||
@@ -77,6 +77,7 @@ pub enum ScalarFunc {
|
||||
SqliteVersion,
|
||||
UnixEpoch,
|
||||
Hex,
|
||||
Unhex,
|
||||
}
|
||||
|
||||
impl Display for ScalarFunc {
|
||||
@@ -112,6 +113,7 @@ impl Display for ScalarFunc {
|
||||
ScalarFunc::SqliteVersion => "sqlite_version".to_string(),
|
||||
ScalarFunc::UnixEpoch => "unixepoch".to_string(),
|
||||
ScalarFunc::Hex => "hex".to_string(),
|
||||
ScalarFunc::Unhex => "unhex".to_string(),
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
@@ -182,6 +184,7 @@ impl Func {
|
||||
"json" => Ok(Func::Json(JsonFunc::Json)),
|
||||
"unixepoch" => Ok(Func::Scalar(ScalarFunc::UnixEpoch)),
|
||||
"hex" => Ok(Func::Scalar(ScalarFunc::Hex)),
|
||||
"unhex" => Ok(Func::Scalar(ScalarFunc::Unhex)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1215,7 +1215,8 @@ pub fn translate_expr(
|
||||
ScalarFunc::Trim
|
||||
| ScalarFunc::LTrim
|
||||
| ScalarFunc::RTrim
|
||||
| ScalarFunc::Round => {
|
||||
| ScalarFunc::Round
|
||||
| ScalarFunc::Unhex => {
|
||||
let args = if let Some(args) = args {
|
||||
if args.len() > 2 {
|
||||
crate::bail_parse_error!(
|
||||
|
||||
@@ -1551,6 +1551,12 @@ impl Program {
|
||||
let result = exec_hex(reg_value);
|
||||
state.registers[*dest] = result;
|
||||
}
|
||||
ScalarFunc::Unhex => {
|
||||
let reg_value = state.registers[*start_reg].clone();
|
||||
let ignored_chars = state.registers.get(*start_reg + 1);
|
||||
let result = exec_unhex(®_value, ignored_chars);
|
||||
state.registers[*dest] = result;
|
||||
}
|
||||
ScalarFunc::Random => {
|
||||
state.registers[*dest] = exec_random();
|
||||
}
|
||||
@@ -2171,6 +2177,20 @@ fn exec_hex(reg: &OwnedValue) -> OwnedValue {
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_unhex(reg: &OwnedValue, ignored_chars: Option<&OwnedValue>) -> OwnedValue {
|
||||
if ignored_chars.is_some() {
|
||||
unimplemented!("unhex(X,Y) is not implemented");
|
||||
}
|
||||
|
||||
match reg {
|
||||
OwnedValue::Null => OwnedValue::Null,
|
||||
_ => match hex::decode(reg.to_string()) {
|
||||
Ok(bytes) => OwnedValue::Blob(Rc::new(bytes)),
|
||||
Err(_) => OwnedValue::Null,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_unicode(reg: &OwnedValue) -> OwnedValue {
|
||||
match reg {
|
||||
OwnedValue::Text(_)
|
||||
@@ -2292,7 +2312,7 @@ mod tests {
|
||||
use super::{
|
||||
exec_abs, exec_char, exec_hex, exec_if, exec_length, exec_like, exec_lower, exec_ltrim,
|
||||
exec_max, exec_min, exec_nullif, exec_quote, exec_random, exec_round, exec_rtrim,
|
||||
exec_sign, exec_substring, exec_trim, exec_typeof, exec_unicode, exec_upper,
|
||||
exec_sign, exec_substring, exec_trim, exec_typeof, exec_unhex, exec_unicode, exec_upper,
|
||||
execute_sqlite_version, get_new_rowid, AggContext, Cursor, CursorResult, LimboError,
|
||||
OwnedRecord, OwnedValue, Result,
|
||||
};
|
||||
@@ -2644,6 +2664,33 @@ mod tests {
|
||||
assert_eq!(exec_hex(&input_float), expected_val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unhex() {
|
||||
let input = OwnedValue::Text(Rc::new(String::from("6F")));
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![0x6f]));
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::Text(Rc::new(String::from("6f")));
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![0x6f]));
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::Text(Rc::new(String::from("611")));
|
||||
let expected = OwnedValue::Null;
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::Text(Rc::new(String::from("")));
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![]));
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::Text(Rc::new(String::from("61x")));
|
||||
let expected = OwnedValue::Null;
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::Null;
|
||||
let expected = OwnedValue::Null;
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_abs() {
|
||||
let int_positive_reg = OwnedValue::Integer(10);
|
||||
|
||||
@@ -119,6 +119,30 @@ do_execsql_test hex-null {
|
||||
select hex(null)
|
||||
} {}
|
||||
|
||||
do_execsql_test unhex-str-ab {
|
||||
SELECT unhex('6162');
|
||||
} {ab}
|
||||
|
||||
do_execsql_test unhex-int-ab {
|
||||
SELECT unhex(6162);
|
||||
} {ab}
|
||||
|
||||
do_execsql_test unhex-dot-uppercase {
|
||||
SELECT unhex('2E');
|
||||
} {.}
|
||||
|
||||
do_execsql_test unhex-dot-lowercase {
|
||||
SELECT unhex('2e');
|
||||
} {.}
|
||||
|
||||
do_execsql_test unhex-no-hex {
|
||||
SELECT unhex('x');
|
||||
} {}
|
||||
|
||||
do_execsql_test unhex-null {
|
||||
SELECT unhex(NULL);
|
||||
} {}
|
||||
|
||||
do_execsql_test trim {
|
||||
SELECT trim(' Limbo ');
|
||||
} {Limbo}
|
||||
|
||||
Reference in New Issue
Block a user