mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-27 13:04:20 +01:00
Merge pull request #183 from JeanArhancet/feat/add-random-function
This commit is contained in:
@@ -90,7 +90,7 @@ This document describes the SQLite compatibility status of Limbo:
|
||||
| octet_length(X) | No | |
|
||||
| printf(FORMAT,...) | No | |
|
||||
| quote(X) | No | |
|
||||
| random() | No | |
|
||||
| random() | Yes | |
|
||||
| randomblob(N) | No | |
|
||||
| replace(X,Y,Z) | No | |
|
||||
| round(X) | No | |
|
||||
|
||||
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -737,8 +737,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -997,6 +999,7 @@ dependencies = [
|
||||
"cfg_block",
|
||||
"criterion",
|
||||
"fallible-iterator 0.3.0",
|
||||
"getrandom",
|
||||
"io-uring",
|
||||
"libc",
|
||||
"log",
|
||||
|
||||
@@ -38,6 +38,7 @@ ordered-multimap = "0.7.1"
|
||||
sieve-cache = "0.1.4"
|
||||
sqlite3-parser = "0.11.0"
|
||||
thiserror = "1.0.61"
|
||||
getrandom = { version = "0.2.15", features = ["js"] }
|
||||
regex = "1.10.5"
|
||||
|
||||
[target.'cfg(not(target_family = "windows"))'.dev-dependencies]
|
||||
|
||||
14
core/expr.rs
14
core/expr.rs
@@ -353,6 +353,20 @@ pub fn translate_expr(
|
||||
func: SingleRowFunc::Lower,
|
||||
});
|
||||
|
||||
Ok(target_register)
|
||||
}
|
||||
SingleRowFunc::Random => {
|
||||
if args.is_some() {
|
||||
anyhow::bail!("Parse error: random function with arguments");
|
||||
}
|
||||
let regs = program.alloc_register();
|
||||
|
||||
program.emit_insn(Insn::Function {
|
||||
start_reg: regs,
|
||||
dest: target_register,
|
||||
func: SingleRowFunc::Random,
|
||||
});
|
||||
|
||||
Ok(target_register)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ pub enum SingleRowFunc {
|
||||
Abs,
|
||||
Upper,
|
||||
Lower,
|
||||
Random,
|
||||
}
|
||||
|
||||
impl ToString for SingleRowFunc {
|
||||
@@ -44,6 +45,7 @@ impl ToString for SingleRowFunc {
|
||||
SingleRowFunc::Abs => "abs".to_string(),
|
||||
SingleRowFunc::Upper => "upper".to_string(),
|
||||
SingleRowFunc::Lower => "lower".to_string(),
|
||||
SingleRowFunc::Random => "random".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,6 +73,7 @@ impl FromStr for Func {
|
||||
"abs" => Ok(Func::SingleRow(SingleRowFunc::Abs)),
|
||||
"upper" => Ok(Func::SingleRow(SingleRowFunc::Upper)),
|
||||
"lower" => Ok(Func::SingleRow(SingleRowFunc::Lower)),
|
||||
"random" => Ok(Func::SingleRow(SingleRowFunc::Random)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
27
core/vdbe.rs
27
core/vdbe.rs
@@ -1289,6 +1289,10 @@ impl Program {
|
||||
}
|
||||
state.pc += 1;
|
||||
}
|
||||
SingleRowFunc::Random => {
|
||||
state.registers[*dest] = exec_random();
|
||||
state.pc += 1;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1861,6 +1865,13 @@ fn exec_abs(reg: &OwnedValue) -> Option<OwnedValue> {
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_random() -> OwnedValue {
|
||||
let mut buf = [0u8; 8];
|
||||
getrandom::getrandom(&mut buf).unwrap();
|
||||
let random_number = i64::from_ne_bytes(buf);
|
||||
OwnedValue::Integer(random_number)
|
||||
}
|
||||
|
||||
// Implements LIKE pattern matching.
|
||||
fn exec_like(pattern: &str, text: &str) -> bool {
|
||||
let re = Regex::new(&pattern.replace('%', ".*").replace('_', ".").to_string()).unwrap();
|
||||
@@ -1883,7 +1894,7 @@ fn exec_if(reg: &OwnedValue, null_reg: &OwnedValue, not: bool) -> bool {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{exec_abs, exec_if, exec_like, exec_lower, exec_upper, OwnedValue};
|
||||
use super::{exec_abs, exec_if, exec_like, exec_lower, exec_random, exec_upper, OwnedValue};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[test]
|
||||
@@ -1935,6 +1946,20 @@ mod tests {
|
||||
assert!(!exec_like("%a.ab", "aaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random() {
|
||||
match exec_random() {
|
||||
OwnedValue::Integer(value) => {
|
||||
// Check that the value is within the range of i64
|
||||
assert!(
|
||||
value >= i64::MIN && value <= i64::MAX,
|
||||
"Random number out of range"
|
||||
);
|
||||
}
|
||||
_ => panic!("exec_random did not return an Integer variant"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exec_if() {
|
||||
let reg = OwnedValue::Integer(0);
|
||||
|
||||
Reference in New Issue
Block a user