From d1288cacef4accaaa33d40f9b75a163d21fff400 Mon Sep 17 00:00:00 2001 From: Bennett Clement Date: Mon, 15 Jul 2024 23:19:46 +0800 Subject: [PATCH 1/4] Implement where and --- core/translate.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/translate.rs b/core/translate.rs index 405d824eb..5e2afaa75 100644 --- a/core/translate.rs +++ b/core/translate.rs @@ -569,6 +569,25 @@ fn translate_condition_expr( select: &Select, expr: &ast::Expr, jump_target: BranchOffset, +) -> Result<()> { + match expr { + ast::Expr::Binary(e1, op, e2) => match op { + ast::Operator::And => { + let _ = translate_condition_expr(program, select, e1, jump_target)?; + let _ = translate_condition_expr(program, select, e2, jump_target)?; + Ok(()) + } + _ => translate_condition_expr_leaf(program, select, expr, jump_target), + }, + _ => translate_condition_expr_leaf(program, select, expr, jump_target), + } +} + +fn translate_condition_expr_leaf( + program: &mut ProgramBuilder, + select: &Select, + expr: &ast::Expr, + jump_target: BranchOffset, ) -> Result<()> { match expr { ast::Expr::Between { .. } => todo!(), From f955187b70d550494e0ae4a65d7dfaa9eef92e86 Mon Sep 17 00:00:00 2001 From: Bennett Clement Date: Mon, 15 Jul 2024 23:36:35 +0800 Subject: [PATCH 2/4] Implement where and --- core/vdbe.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++++ testing/all.test | 13 ++++++ 2 files changed, 115 insertions(+) diff --git a/core/vdbe.rs b/core/vdbe.rs index a00018301..e8c3d327f 100644 --- a/core/vdbe.rs +++ b/core/vdbe.rs @@ -603,6 +603,20 @@ impl Program { state.pc += 1; } } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + if (*lhs as f64) == *rhs { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + if *lhs == (*rhs as f64) { + state.pc = target_pc; + } else { + state.pc += 1; + } + } (OwnedValue::Text(lhs), OwnedValue::Text(rhs)) => { if lhs == rhs { state.pc = target_pc; @@ -610,6 +624,9 @@ impl Program { state.pc += 1; } } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; + } _ => { todo!(); } @@ -639,6 +656,20 @@ impl Program { state.pc += 1; } } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + if (*lhs as f64) != *rhs { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + if *lhs != (*rhs as f64) { + state.pc = target_pc; + } else { + state.pc += 1; + } + } (OwnedValue::Text(lhs), OwnedValue::Text(rhs)) => { if lhs != rhs { state.pc = target_pc; @@ -646,6 +677,9 @@ impl Program { state.pc += 1; } } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; + } _ => { todo!(); } @@ -675,6 +709,23 @@ impl Program { state.pc += 1; } } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + if (*lhs as f64) < *rhs { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + if *lhs < (*rhs as f64) { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; + } _ => { todo!(); } @@ -704,6 +755,23 @@ impl Program { state.pc += 1; } } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + if (*lhs as f64) <= *rhs { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + if *lhs <= (*rhs as f64) { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; + } _ => { todo!(); } @@ -733,6 +801,23 @@ impl Program { state.pc += 1; } } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + if (*lhs as f64) > *rhs { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + if *lhs > (*rhs as f64) { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; + } _ => { todo!(); } @@ -762,6 +847,23 @@ impl Program { state.pc += 1; } } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + if (*lhs as f64) >= *rhs { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + if *lhs >= (*rhs as f64) { + state.pc = target_pc; + } else { + state.pc += 1; + } + } + (_, OwnedValue::Null) | (OwnedValue::Null, _) => { + state.pc = target_pc; + } _ => { todo!(); } diff --git a/testing/all.test b/testing/all.test index f376f70a8..76ba2367f 100755 --- a/testing/all.test +++ b/testing/all.test @@ -108,6 +108,19 @@ do_execsql_test where-clause-lte { select count(1) from users where id <= 2000; } {2000} +do_execsql_test where-and { + 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 != 'boots' and price <= 70; +} {6|shorts|70.0} + do_execsql_test where-clause-unary-true { select count(1) from users where 1; } {10000} From 4d077cf3e56531eed4e53d4c35d944fc827ef657 Mon Sep 17 00:00:00 2001 From: Bennett Clement Date: Tue, 16 Jul 2024 08:32:10 +0800 Subject: [PATCH 3/4] Implement std::cmp::PartialOrd for OwnedValue --- core/translate.rs | 19 ---- core/types.rs | 27 ++++++ core/vdbe.rs | 218 +++++++--------------------------------------- testing/all.test | 26 +++--- 4 files changed, 70 insertions(+), 220 deletions(-) diff --git a/core/translate.rs b/core/translate.rs index 0d9d73b5d..fea1096d8 100644 --- a/core/translate.rs +++ b/core/translate.rs @@ -570,25 +570,6 @@ fn translate_condition_expr( expr: &ast::Expr, target_jump: BranchOffset, jump_if_true: bool, // if true jump to target on op == true, if false invert op -) -> Result<()> { - match expr { - ast::Expr::Binary(e1, op, e2) => match op { - ast::Operator::And => { - let _ = translate_condition_expr(program, select, e1, jump_target)?; - let _ = translate_condition_expr(program, select, e2, jump_target)?; - Ok(()) - } - _ => translate_condition_expr_leaf(program, select, expr, jump_target), - }, - _ => translate_condition_expr_leaf(program, select, expr, jump_target), - } -} - -fn translate_condition_expr_leaf( - program: &mut ProgramBuilder, - select: &Select, - expr: &ast::Expr, - jump_target: BranchOffset, ) -> Result<()> { match expr { ast::Expr::Between { .. } => todo!(), 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 d1651eba1..41726870d 100644 --- a/core/vdbe.rs +++ b/core/vdbe.rs @@ -585,46 +585,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::Integer(lhs), OwnedValue::Float(rhs)) => { - if (*lhs as f64) == *rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - if *lhs == (*rhs as f64) { - 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; + } } } } @@ -638,46 +607,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::Integer(lhs), OwnedValue::Float(rhs)) => { - if (*lhs as f64) != *rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - if *lhs != (*rhs as f64) { - 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; + } } } } @@ -691,39 +629,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::Integer(lhs), OwnedValue::Float(rhs)) => { - if (*lhs as f64) < *rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - if *lhs < (*rhs as f64) { - 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; + } } } } @@ -737,39 +651,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::Integer(lhs), OwnedValue::Float(rhs)) => { - if (*lhs as f64) <= *rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - if *lhs <= (*rhs as f64) { - 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; + } } } } @@ -783,39 +673,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::Integer(lhs), OwnedValue::Float(rhs)) => { - if (*lhs as f64) > *rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - if *lhs > (*rhs as f64) { - 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; + } } } } @@ -829,39 +695,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::Integer(lhs), OwnedValue::Float(rhs)) => { - if (*lhs as f64) >= *rhs { - state.pc = target_pc; - } else { - state.pc += 1; - } - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - if *lhs >= (*rhs as f64) { - 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/all.test b/testing/all.test index 55baa9653..119c60c7b 100755 --- a/testing/all.test +++ b/testing/all.test @@ -108,19 +108,6 @@ do_execsql_test where-clause-lte { select count(1) from users where id <= 2000; } {2000} -do_execsql_test where-and { - 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 != 'boots' and price <= 70; -} {6|shorts|70.0} - do_execsql_test where-clause-unary-true { select count(1) from users where 1; } {10000} @@ -253,3 +240,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} \ No newline at end of file From 7858c350c54eb3104112da6383daec1f72d36028 Mon Sep 17 00:00:00 2001 From: Bennett Clement Date: Tue, 16 Jul 2024 08:51:41 +0800 Subject: [PATCH 4/4] Reintroduce overwritten optimization --- core/translate.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/translate.rs b/core/translate.rs index fea1096d8..40ba17869 100644 --- a/core/translate.rs +++ b/core/translate.rs @@ -599,7 +599,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 {