diff --git a/core/translate.rs b/core/translate.rs index cbfa4c404..63306a4dd 100644 --- a/core/translate.rs +++ b/core/translate.rs @@ -602,7 +602,15 @@ fn translate_condition_expr( let lhs_reg = program.alloc_register(); let rhs_reg = program.alloc_register(); let _ = translate_expr(program, select, lhs, lhs_reg); + match lhs.as_ref() { + ast::Expr::Literal(_) => program.mark_last_insn_constant(), + _ => {} + } let _ = translate_expr(program, select, rhs, rhs_reg); + match rhs.as_ref() { + ast::Expr::Literal(_) => program.mark_last_insn_constant(), + _ => {} + } match op { ast::Operator::Greater => { if jump_if_true { diff --git a/core/types.rs b/core/types.rs index 30fdf6d85..7c74fcad2 100644 --- a/core/types.rs +++ b/core/types.rs @@ -66,6 +66,33 @@ pub enum AggContext { GroupConcat(OwnedValue), } +impl std::cmp::PartialOrd for OwnedValue { + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (OwnedValue::Integer(int_left), OwnedValue::Integer(int_right)) => { + int_left.partial_cmp(int_right) + } + (OwnedValue::Integer(int_left), OwnedValue::Float(float_right)) => { + float_right.partial_cmp(&(*int_left as f64)) + } + (OwnedValue::Float(float_left), OwnedValue::Integer(int_right)) => { + float_left.partial_cmp(&(*int_right as f64)) + } + (OwnedValue::Float(float_left), OwnedValue::Float(float_right)) => { + float_left.partial_cmp(float_right) + } + (OwnedValue::Text(text_left), OwnedValue::Text(text_right)) => { + text_left.partial_cmp(text_right) + } + (OwnedValue::Blob(blob_left), OwnedValue::Blob(blob_right)) => { + blob_left.partial_cmp(blob_right) + } + (OwnedValue::Null, OwnedValue::Null) => Some(std::cmp::Ordering::Equal), + _ => None, + } + } +} + impl std::ops::Add for OwnedValue { type Output = OwnedValue; diff --git a/core/vdbe.rs b/core/vdbe.rs index 7acf5ea34..970d069e6 100644 --- a/core/vdbe.rs +++ b/core/vdbe.rs @@ -612,29 +612,15 @@ impl Program { let rhs = *rhs; let target_pc = *target_pc; match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - if lhs == rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - if lhs == rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Text(lhs), OwnedValue::Text(rhs)) => { - if lhs == rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; } _ => { - todo!(); + if &state.registers[lhs] == &state.registers[rhs] { + state.pc = target_pc; + } else { + state.pc += 1; + } } } } @@ -648,29 +634,15 @@ impl Program { let rhs = *rhs; let target_pc = *target_pc; match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - if lhs != rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - if lhs != rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Text(lhs), OwnedValue::Text(rhs)) => { - if lhs != rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; } _ => { - todo!(); + if &state.registers[lhs] != &state.registers[rhs] { + state.pc = target_pc; + } else { + state.pc += 1; + } } } } @@ -684,22 +656,15 @@ impl Program { let rhs = *rhs; let target_pc = *target_pc; match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - if lhs < rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - if lhs < rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; } _ => { - todo!(); + if &state.registers[lhs] < &state.registers[rhs] { + state.pc = target_pc; + } else { + state.pc += 1; + } } } } @@ -713,22 +678,15 @@ impl Program { let rhs = *rhs; let target_pc = *target_pc; match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - if lhs <= rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - if lhs <= rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; } _ => { - todo!(); + if &state.registers[lhs] <= &state.registers[rhs] { + state.pc = target_pc; + } else { + state.pc += 1; + } } } } @@ -742,22 +700,15 @@ impl Program { let rhs = *rhs; let target_pc = *target_pc; match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - if lhs > rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - if lhs > rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; } _ => { - todo!(); + if &state.registers[lhs] > &state.registers[rhs] { + state.pc = target_pc; + } else { + state.pc += 1; + } } } } @@ -771,22 +722,15 @@ impl Program { let rhs = *rhs; let target_pc = *target_pc; match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - if lhs >= rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - if lhs >= rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; } _ => { - todo!(); + if &state.registers[lhs] >= &state.registers[rhs] { + state.pc = target_pc; + } else { + state.pc += 1; + } } } } diff --git a/testing/where.test b/testing/where.test index 7b5fc9099..c47084fa2 100755 --- a/testing/where.test +++ b/testing/where.test @@ -96,3 +96,16 @@ Jamie|88 Jamie|41 Jamie|73 } + +do_execsql_test where-float-int { + select * from products where price > 50 and name != 'hat'; +} {2|cap|82.0 +5|sweatshirt|74.0 +6|shorts|70.0 +7|jeans|78.0 +8|sneakers|82.0 +11|accessories|81.0} + +do_execsql_test where-multiple-and { + select * from products where price > 50 and name != 'sweatshirt' and price < 75; +} {6|shorts|70.0}