Merge 'Added 'likelihood' scalar function' from Sachin Kumar Singh

The `likelihood(X,Y)` function returns argument X unchanged. The value Y
in likelihood(X,Y) must be a floating point constant between 0.0 and
1.0, inclusive.
```
sqlite> explain SELECT likelihood(42, 0.0);
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     6     0                    0   Start at 6
1     Once           0     3     0                    0
2     Integer        42    2     0                    0   r[2]=42
3     Copy           2     1     0                    0   r[1]=r[2]
4     ResultRow      1     1     0                    0   output=r[1]
5     Halt           0     0     0                    0
6     Goto           0     1     0                    0
```
```
limbo> explain SELECT likelihood(42, 0.0);
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     4     0                    0   Start at 4
1     Copy               2     1     0                    0   r[1]=r[2]
2     ResultRow          1     1     0                    0   output=r[1]
3     Halt               0     0     0                    0
4     Integer            42    2     0                    0   r[2]=42
5     Goto               0     1     0                    0
```

Closes #1303
This commit is contained in:
Pekka Enberg 2025-04-11 09:34:36 +03:00
commit d67e1b604b
5 changed files with 134 additions and 2 deletions

View file

@ -3520,6 +3520,14 @@ pub fn op_function(
let result = exec_likely(value.get_owned_value());
state.registers[*dest] = Register::OwnedValue(result);
}
ScalarFunc::Likelihood => {
assert_eq!(arg_count, 2);
let value = &state.registers[*start_reg];
let probability = &state.registers[*start_reg + 1];
let result =
exec_likelihood(value.get_owned_value(), probability.get_owned_value());
state.registers[*dest] = Register::OwnedValue(result);
}
},
crate::function::Func::Vector(vector_func) => match vector_func {
VectorFunc::Vector => {
@ -5380,6 +5388,10 @@ fn exec_likely(reg: &OwnedValue) -> OwnedValue {
reg.clone()
}
fn exec_likelihood(reg: &OwnedValue, _probability: &OwnedValue) -> OwnedValue {
reg.clone()
}
pub fn exec_add(lhs: &OwnedValue, rhs: &OwnedValue) -> OwnedValue {
let result = match (lhs, rhs) {
(OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => {
@ -6263,7 +6275,7 @@ mod tests {
}
use crate::vdbe::{
execute::{exec_likely, exec_replace},
execute::{exec_likelihood, exec_likely, exec_replace},
Bitfield, Register,
};
@ -7180,6 +7192,39 @@ mod tests {
assert_eq!(exec_likely(&input), expected);
}
#[test]
fn test_likelihood() {
let value = OwnedValue::build_text("limbo");
let prob = OwnedValue::Float(0.5);
assert_eq!(exec_likelihood(&value, &prob), value);
let value = OwnedValue::build_text("database");
let prob = OwnedValue::Float(0.9375);
assert_eq!(exec_likelihood(&value, &prob), value);
let value = OwnedValue::Integer(100);
let prob = OwnedValue::Float(1.0);
assert_eq!(exec_likelihood(&value, &prob), value);
let value = OwnedValue::Float(12.34);
let prob = OwnedValue::Float(0.5);
assert_eq!(exec_likelihood(&value, &prob), value);
let value = OwnedValue::Null;
let prob = OwnedValue::Float(0.5);
assert_eq!(exec_likelihood(&value, &prob), value);
let value = OwnedValue::Blob(vec![1, 2, 3, 4]);
let prob = OwnedValue::Float(0.5);
assert_eq!(exec_likelihood(&value, &prob), value);
let prob = OwnedValue::build_text("0.5");
assert_eq!(exec_likelihood(&value, &prob), value);
let prob = OwnedValue::Null;
assert_eq!(exec_likelihood(&value, &prob), value);
}
#[test]
fn test_bitfield() {
let mut bitfield = Bitfield::<4>::new();