mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-28 12:24:23 +01:00
Merge 'Add support for hex scalar function' from baishen
Add support for hex scalar function
```
limbo> SELECT hex('abc');
616263
limbo> EXPLAIN SELECT hex('abc');
addr opcode p1 p2 p3 p4 p5 comment
---- ----------------- ---- ---- ---- ------------- -- -------
0 Init 0 5 0 0 Start at 5
1 String8 0 2 0 abc 0 r[2]='abc'
2 Function 0 2 1 hex 0 r[1]=func(r[2])
3 ResultRow 1 1 0 0 output=r[1]
4 Halt 0 0 0 0
5 Transaction 0 0 0 0
6 Goto 0 1 0 0
```
Related issue #144
Closes #342
This commit is contained in:
@@ -69,7 +69,7 @@ This document describes the SQLite compatibility status of Limbo:
|
||||
| concat_ws(SEP,X,...) | Yes | |
|
||||
| format(FORMAT,...) | No | |
|
||||
| glob(X,Y) | Yes | |
|
||||
| hex(X) | No | |
|
||||
| hex(X) | Yes | |
|
||||
| ifnull(X,Y) | Yes | |
|
||||
| iif(X,Y,Z) | No | |
|
||||
| instr(X,Y) | No | |
|
||||
|
||||
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -893,6 +893,12 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
@@ -1117,6 +1123,7 @@ dependencies = [
|
||||
"criterion",
|
||||
"fallible-iterator 0.3.0",
|
||||
"getrandom",
|
||||
"hex",
|
||||
"indexmap",
|
||||
"io-uring",
|
||||
"jsonb",
|
||||
|
||||
@@ -30,6 +30,7 @@ mimalloc = { version = "*", default-features = false }
|
||||
[dependencies]
|
||||
cfg_block = "0.1.1"
|
||||
fallible-iterator = "0.3.0"
|
||||
hex = "0.4.3"
|
||||
libc = "0.2.155"
|
||||
log = "0.4.20"
|
||||
nix = { version = "0.29.0", features = ["fs"] }
|
||||
|
||||
@@ -76,6 +76,7 @@ pub enum ScalarFunc {
|
||||
Quote,
|
||||
SqliteVersion,
|
||||
UnixEpoch,
|
||||
Hex,
|
||||
}
|
||||
|
||||
impl Display for ScalarFunc {
|
||||
@@ -110,6 +111,7 @@ impl Display for ScalarFunc {
|
||||
ScalarFunc::Quote => "quote".to_string(),
|
||||
ScalarFunc::SqliteVersion => "sqlite_version".to_string(),
|
||||
ScalarFunc::UnixEpoch => "unixepoch".to_string(),
|
||||
ScalarFunc::Hex => "hex".to_string(),
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
@@ -179,6 +181,7 @@ impl Func {
|
||||
"sqlite_version" => Ok(Func::Scalar(ScalarFunc::SqliteVersion)),
|
||||
"json" => Ok(Func::Json(JsonFunc::Json)),
|
||||
"unixepoch" => Ok(Func::Scalar(ScalarFunc::UnixEpoch)),
|
||||
"hex" => Ok(Func::Scalar(ScalarFunc::Hex)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1133,6 +1133,34 @@ pub fn translate_expr(
|
||||
});
|
||||
Ok(target_register)
|
||||
}
|
||||
ScalarFunc::Hex => {
|
||||
let args = if let Some(args) = args {
|
||||
if args.len() != 1 {
|
||||
crate::bail_parse_error!(
|
||||
"hex function must have exactly 1 argument",
|
||||
);
|
||||
}
|
||||
args
|
||||
} else {
|
||||
crate::bail_parse_error!("hex function with no arguments",);
|
||||
};
|
||||
let regs = program.alloc_register();
|
||||
translate_expr(
|
||||
program,
|
||||
referenced_tables,
|
||||
&args[0],
|
||||
regs,
|
||||
cursor_hint,
|
||||
cached_results,
|
||||
)?;
|
||||
program.emit_insn(Insn::Function {
|
||||
constant_mask: 0,
|
||||
start_reg: regs,
|
||||
dest: target_register,
|
||||
func: func_ctx,
|
||||
});
|
||||
Ok(target_register)
|
||||
}
|
||||
ScalarFunc::UnixEpoch => {
|
||||
let mut start_reg = 0;
|
||||
match args {
|
||||
|
||||
@@ -1536,6 +1536,11 @@ impl Program {
|
||||
};
|
||||
state.registers[*dest] = result.unwrap_or(OwnedValue::Null);
|
||||
}
|
||||
ScalarFunc::Hex => {
|
||||
let reg_value = state.registers[*start_reg].borrow_mut();
|
||||
let result = exec_hex(reg_value);
|
||||
state.registers[*dest] = result;
|
||||
}
|
||||
ScalarFunc::Random => {
|
||||
state.registers[*dest] = exec_random();
|
||||
}
|
||||
@@ -2146,6 +2151,19 @@ fn exec_typeof(reg: &OwnedValue) -> OwnedValue {
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_hex(reg: &OwnedValue) -> OwnedValue {
|
||||
match reg {
|
||||
OwnedValue::Text(_)
|
||||
| OwnedValue::Integer(_)
|
||||
| OwnedValue::Float(_)
|
||||
| OwnedValue::Blob(_) => {
|
||||
let text = reg.to_string();
|
||||
OwnedValue::Text(Rc::new(hex::encode_upper(text)))
|
||||
}
|
||||
_ => OwnedValue::Null,
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_unicode(reg: &OwnedValue) -> OwnedValue {
|
||||
match reg {
|
||||
OwnedValue::Text(_)
|
||||
@@ -2265,7 +2283,7 @@ fn execute_sqlite_version(version_integer: i64) -> String {
|
||||
mod tests {
|
||||
|
||||
use super::{
|
||||
exec_abs, exec_char, exec_if, exec_length, exec_like, exec_lower, exec_ltrim, exec_minmax,
|
||||
exec_abs, exec_char, exec_hex, exec_if, exec_length, exec_like, exec_lower, exec_ltrim, exec_minmax,
|
||||
exec_nullif, exec_quote, exec_random, exec_round, exec_rtrim, exec_sign, exec_substring,
|
||||
exec_trim, exec_typeof, exec_unicode, exec_upper, execute_sqlite_version, get_new_rowid,
|
||||
AggContext, Cursor, CursorResult, LimboError, OwnedRecord, OwnedValue, Result,
|
||||
@@ -2610,6 +2628,21 @@ mod tests {
|
||||
assert_eq!(exec_lower(&OwnedValue::Null).unwrap(), OwnedValue::Null)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex() {
|
||||
let input_str = OwnedValue::Text(Rc::new("limbo".to_string()));
|
||||
let expected_val = OwnedValue::Text(Rc::new(String::from("6C696D626F")));
|
||||
assert_eq!(exec_hex(&input_str), expected_val);
|
||||
|
||||
let input_int = OwnedValue::Integer(100);
|
||||
let expected_val = OwnedValue::Text(Rc::new(String::from("313030")));
|
||||
assert_eq!(exec_hex(&input_int), expected_val);
|
||||
|
||||
let input_float = OwnedValue::Float(12.34);
|
||||
let expected_val = OwnedValue::Text(Rc::new(String::from("31322E3334")));
|
||||
assert_eq!(exec_hex(&input_float), expected_val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_abs() {
|
||||
let int_positive_reg = OwnedValue::Integer(10);
|
||||
|
||||
@@ -107,6 +107,18 @@ do_execsql_test lower-null {
|
||||
select lower(null)
|
||||
} {}
|
||||
|
||||
do_execsql_test hex {
|
||||
select hex('limbo')
|
||||
} {6C696D626F}
|
||||
|
||||
do_execsql_test hex-number {
|
||||
select hex(100)
|
||||
} {313030}
|
||||
|
||||
do_execsql_test hex-null {
|
||||
select hex(null)
|
||||
} {}
|
||||
|
||||
do_execsql_test trim {
|
||||
SELECT trim(' Limbo ');
|
||||
} {Limbo}
|
||||
|
||||
Reference in New Issue
Block a user