diff --git a/COMPAT.md b/COMPAT.md index b0cc85d83..f541c1f61 100644 --- a/COMPAT.md +++ b/COMPAT.md @@ -227,7 +227,7 @@ Feature support of [sqlite expr syntax](https://www.sqlite.org/lang_expr.html). | like(X,Y) | Yes | | | like(X,Y,Z) | Yes | | | likelihood(X,Y) | No | | -| likely(X) | No | | +| likely(X) | Yes | | | load_extension(X) | Yes | sqlite3 extensions not yet supported | | load_extension(X,Y) | No | | | lower(X) | Yes | | diff --git a/core/function.rs b/core/function.rs index 8f27b1a5b..4c235cca5 100644 --- a/core/function.rs +++ b/core/function.rs @@ -292,6 +292,7 @@ pub enum ScalarFunc { LoadExtension, StrfTime, Printf, + Likely, } impl Display for ScalarFunc { @@ -346,6 +347,7 @@ impl Display for ScalarFunc { Self::LoadExtension => "load_extension".to_string(), Self::StrfTime => "strftime".to_string(), Self::Printf => "printf".to_string(), + Self::Likely => "likely".to_string(), }; write!(f, "{}", str) } @@ -596,6 +598,7 @@ impl Func { "sqlite_version" => Ok(Self::Scalar(ScalarFunc::SqliteVersion)), "sqlite_source_id" => Ok(Self::Scalar(ScalarFunc::SqliteSourceId)), "replace" => Ok(Self::Scalar(ScalarFunc::Replace)), + "likely" => Ok(Self::Scalar(ScalarFunc::Likely)), #[cfg(feature = "json")] "json" => Ok(Self::Json(JsonFunc::Json)), #[cfg(feature = "json")] diff --git a/core/translate/expr.rs b/core/translate/expr.rs index cd384391a..7bb0dc228 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -1571,6 +1571,33 @@ pub fn translate_expr( target_register, func_ctx, ), + ScalarFunc::Likely => { + let args = if let Some(args) = args { + if args.len() != 1 { + crate::bail_parse_error!( + "likely function must have exactly 1 argument", + ); + } + args + } else { + crate::bail_parse_error!("likely function with no arguments",); + }; + let start_reg = program.alloc_register(); + translate_and_mark( + program, + referenced_tables, + &args[0], + start_reg, + resolver, + )?; + program.emit_insn(Insn::Function { + constant_mask: 0, + start_reg, + dest: target_register, + func: func_ctx, + }); + Ok(target_register) + } } } Func::Math(math_func) => match math_func.arity() { diff --git a/core/vdbe/execute.rs b/core/vdbe/execute.rs index d2c636bae..09c283ecd 100644 --- a/core/vdbe/execute.rs +++ b/core/vdbe/execute.rs @@ -3448,6 +3448,11 @@ pub fn op_function( let result = exec_printf(&state.registers[*start_reg..*start_reg + arg_count])?; state.registers[*dest] = Register::OwnedValue(result); } + ScalarFunc::Likely => { + let value = &state.registers[*start_reg].borrow_mut(); + let result = exec_likely(value.get_owned_value()); + state.registers[*dest] = Register::OwnedValue(result); + } }, crate::function::Func::Vector(vector_func) => match vector_func { VectorFunc::Vector => { @@ -5220,9 +5225,16 @@ fn exec_math_log(arg: &OwnedValue, base: Option<&OwnedValue>) -> OwnedValue { OwnedValue::Float(result) } +fn exec_likely(reg: &OwnedValue) -> OwnedValue { + reg.clone() +} + #[cfg(test)] mod tests { - use crate::vdbe::{execute::exec_replace, Bitfield, Register}; + use crate::vdbe::{ + execute::{exec_likely, exec_replace}, + Bitfield, Register, + }; use super::{ exec_abs, exec_char, exec_hex, exec_if, exec_instr, exec_length, exec_like, exec_lower, @@ -6114,6 +6126,29 @@ mod tests { ); } + #[test] + fn test_likely() { + let input = OwnedValue::build_text("limbo"); + let expected = OwnedValue::build_text("limbo"); + assert_eq!(exec_likely(&input), expected); + + let input = OwnedValue::Integer(100); + let expected = OwnedValue::Integer(100); + assert_eq!(exec_likely(&input), expected); + + let input = OwnedValue::Float(12.34); + let expected = OwnedValue::Float(12.34); + assert_eq!(exec_likely(&input), expected); + + let input = OwnedValue::Null; + let expected = OwnedValue::Null; + assert_eq!(exec_likely(&input), expected); + + let input = OwnedValue::Blob(vec![1, 2, 3, 4]); + let expected = OwnedValue::Blob(vec![1, 2, 3, 4]); + assert_eq!(exec_likely(&input), expected); + } + #[test] fn test_bitfield() { let mut bitfield = Bitfield::<4>::new(); diff --git a/testing/scalar-functions.test b/testing/scalar-functions.test index 01feb7c1b..09e99a8f3 100755 --- a/testing/scalar-functions.test +++ b/testing/scalar-functions.test @@ -195,6 +195,22 @@ do_execsql_test hex-null { select hex(null) } {} +do_execsql_test likely { + select likely('limbo') +} {limbo} + +do_execsql_test likely-int { + select likely(100) +} {100} + +do_execsql_test likely-decimal { + select likely(12.34) +} {12.34} + +do_execsql_test likely-null { + select likely(NULL) +} {} + do_execsql_test unhex-str-ab { SELECT unhex('6162'); } {ab}