mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-01 07:24:19 +01:00
Respect jump_if_true in like implementation
This commit is contained in:
@@ -788,7 +788,7 @@ fn translate_condition_expr(
|
||||
ast::LikeOperator::Match => todo!(),
|
||||
ast::LikeOperator::Regexp => todo!(),
|
||||
}
|
||||
if *not {
|
||||
if jump_if_true ^ *not {
|
||||
program.emit_insn_with_label_dependency(
|
||||
Insn::If {
|
||||
reg: cur_reg,
|
||||
|
||||
44
core/vdbe.rs
44
core/vdbe.rs
@@ -796,7 +796,7 @@ impl Program {
|
||||
null_reg,
|
||||
} => {
|
||||
assert!(*target_pc >= 0);
|
||||
if jump_if(&state.registers[*reg], &state.registers[*null_reg], false) {
|
||||
if exec_if(&state.registers[*reg], &state.registers[*null_reg], false) {
|
||||
state.pc = *target_pc;
|
||||
} else {
|
||||
state.pc += 1;
|
||||
@@ -808,7 +808,7 @@ impl Program {
|
||||
null_reg,
|
||||
} => {
|
||||
assert!(*target_pc >= 0);
|
||||
if jump_if(&state.registers[*reg], &state.registers[*null_reg], true) {
|
||||
if exec_if(&state.registers[*reg], &state.registers[*null_reg], true) {
|
||||
state.pc = *target_pc;
|
||||
} else {
|
||||
state.pc += 1;
|
||||
@@ -1242,7 +1242,7 @@ impl Program {
|
||||
let text = state.registers[start_reg + 1].clone();
|
||||
let result = match (pattern, text) {
|
||||
(OwnedValue::Text(pattern), OwnedValue::Text(text)) => {
|
||||
OwnedValue::Integer(like(&pattern, &text) as i64)
|
||||
OwnedValue::Integer(exec_like(&pattern, &text) as i64)
|
||||
}
|
||||
_ => {
|
||||
unreachable!("Like on non-text registers");
|
||||
@@ -1765,13 +1765,13 @@ fn get_indent_count(indent_count: usize, curr_insn: &Insn, prev_insn: Option<&In
|
||||
}
|
||||
|
||||
// Implements LIKE pattern matching.
|
||||
fn like(pattern: &str, text: &str) -> bool {
|
||||
fn exec_like(pattern: &str, text: &str) -> bool {
|
||||
let re = Regex::new(&format!("{}", pattern.replace("%", ".*").replace("_", "."))).unwrap();
|
||||
re.is_match(text)
|
||||
}
|
||||
|
||||
// step_if returns whether you should jump
|
||||
fn jump_if(reg: &OwnedValue, null_reg: &OwnedValue, not: bool) -> bool {
|
||||
// exec_if returns whether you should jump
|
||||
fn exec_if(reg: &OwnedValue, null_reg: &OwnedValue, not: bool) -> bool {
|
||||
match reg {
|
||||
OwnedValue::Integer(0) | OwnedValue::Float(0.0) => not,
|
||||
OwnedValue::Integer(_) | OwnedValue::Float(_) => !not,
|
||||
@@ -1789,38 +1789,38 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_like() {
|
||||
assert!(like("a%", "aaaa"));
|
||||
assert!(like("%a%a", "aaaa"));
|
||||
assert!(like("%a.a", "aaaa"));
|
||||
assert!(like("a.a%", "aaaa"));
|
||||
assert!(!like("%a.ab", "aaaa"));
|
||||
assert!(exec_like("a%", "aaaa"));
|
||||
assert!(exec_like("%a%a", "aaaa"));
|
||||
assert!(exec_like("%a.a", "aaaa"));
|
||||
assert!(exec_like("a.a%", "aaaa"));
|
||||
assert!(!exec_like("%a.ab", "aaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_jump_if() {
|
||||
fn test_exec_if() {
|
||||
let reg = OwnedValue::Integer(0);
|
||||
let null_reg = OwnedValue::Integer(0);
|
||||
assert_eq!(jump_if(®, &null_reg, false), false);
|
||||
assert_eq!(jump_if(®, &null_reg, true), true);
|
||||
assert_eq!(exec_if(®, &null_reg, false), false);
|
||||
assert_eq!(exec_if(®, &null_reg, true), true);
|
||||
|
||||
let reg = OwnedValue::Integer(1);
|
||||
let null_reg = OwnedValue::Integer(0);
|
||||
assert_eq!(jump_if(®, &null_reg, false), true);
|
||||
assert_eq!(jump_if(®, &null_reg, true), false);
|
||||
assert_eq!(exec_if(®, &null_reg, false), true);
|
||||
assert_eq!(exec_if(®, &null_reg, true), false);
|
||||
|
||||
let reg = OwnedValue::Null;
|
||||
let null_reg = OwnedValue::Integer(0);
|
||||
assert_eq!(jump_if(®, &null_reg, false), false);
|
||||
assert_eq!(jump_if(®, &null_reg, true), false);
|
||||
assert_eq!(exec_if(®, &null_reg, false), false);
|
||||
assert_eq!(exec_if(®, &null_reg, true), false);
|
||||
|
||||
let reg = OwnedValue::Null;
|
||||
let null_reg = OwnedValue::Integer(1);
|
||||
assert_eq!(jump_if(®, &null_reg, false), true);
|
||||
assert_eq!(jump_if(®, &null_reg, true), true);
|
||||
assert_eq!(exec_if(®, &null_reg, false), true);
|
||||
assert_eq!(exec_if(®, &null_reg, true), true);
|
||||
|
||||
let reg = OwnedValue::Null;
|
||||
let null_reg = OwnedValue::Null;
|
||||
assert_eq!(jump_if(®, &null_reg, false), false);
|
||||
assert_eq!(jump_if(®, &null_reg, true), false);
|
||||
assert_eq!(exec_if(®, &null_reg, false), false);
|
||||
assert_eq!(exec_if(®, &null_reg, true), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ do_execsql_test where-like {
|
||||
} {4|sweater|25.0
|
||||
5|sweatshirt|74.0}
|
||||
|
||||
do_execsql_test where-not-like {
|
||||
do_execsql_test where-not-like-and {
|
||||
select * from products where name not like 'sweat%' and price >= 70.0;
|
||||
} {1|hat|79.0
|
||||
2|cap|82.0
|
||||
@@ -30,3 +30,11 @@ do_execsql_test where-not-like {
|
||||
7|jeans|78.0
|
||||
8|sneakers|82.0
|
||||
11|accessories|81.0}
|
||||
|
||||
do_execsql_test where-like-or {
|
||||
select * from products where name like 'sweat%' or price >= 80.0;
|
||||
} {2|cap|82.0
|
||||
4|sweater|25.0
|
||||
5|sweatshirt|74.0
|
||||
8|sneakers|82.0
|
||||
11|accessories|81.0}
|
||||
|
||||
Reference in New Issue
Block a user