mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-27 13:04:20 +01:00
Merge 'Enhance robusteness of optimization for Binary expressions' from Diego Reis
fix #1318 Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com> Closes #1322
This commit is contained in:
@@ -4,7 +4,7 @@ use limbo_sqlite3_parser::ast::{self, UnaryOperator};
|
||||
use crate::function::JsonFunc;
|
||||
use crate::function::{Func, FuncCtx, MathFuncArity, ScalarFunc, VectorFunc};
|
||||
use crate::schema::{Table, Type};
|
||||
use crate::util::normalize_ident;
|
||||
use crate::util::{exprs_are_equivalent, normalize_ident};
|
||||
use crate::vdbe::{
|
||||
builder::ProgramBuilder,
|
||||
insn::{CmpInsFlags, Insn},
|
||||
@@ -494,8 +494,8 @@ pub fn translate_expr(
|
||||
match expr {
|
||||
ast::Expr::Between { .. } => todo!(),
|
||||
ast::Expr::Binary(e1, op, e2) => {
|
||||
// Check if both sides of the expression are identical and reuse the same register if so
|
||||
if e1 == e2 {
|
||||
// Check if both sides of the expression are equivalent and reuse the same register if so
|
||||
if exprs_are_equivalent(e1, e2) {
|
||||
let shared_reg = program.alloc_register();
|
||||
translate_expr(program, referenced_tables, e1, shared_reg, resolver)?;
|
||||
|
||||
|
||||
24
core/util.rs
24
core/util.rs
@@ -399,7 +399,11 @@ pub fn exprs_are_equivalent(expr1: &Expr, expr2: &Expr) -> bool {
|
||||
(Expr::Unary(op1, expr1), Expr::Unary(op2, expr2)) => {
|
||||
op1 == op2 && exprs_are_equivalent(expr1, expr2)
|
||||
}
|
||||
(Expr::Variable(var1), Expr::Variable(var2)) => var1 == var2,
|
||||
// Variables that are not bound to a specific value, are treated as NULL
|
||||
// https://sqlite.org/lang_expr.html#varparam
|
||||
(Expr::Variable(var), Expr::Variable(var2)) if var == "" && var2 == "" => false,
|
||||
// Named variables can be compared by their name
|
||||
(Expr::Variable(val), Expr::Variable(val2)) => val == val2,
|
||||
(Expr::Parenthesized(exprs1), Expr::Parenthesized(exprs2)) => {
|
||||
exprs1.len() == exprs2.len()
|
||||
&& exprs1
|
||||
@@ -945,6 +949,24 @@ pub mod tests {
|
||||
assert_eq!(normalize_ident("\"foo\""), "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_anonymous_variable_comparison() {
|
||||
let expr1 = Expr::Variable("".to_string());
|
||||
let expr2 = Expr::Variable("".to_string());
|
||||
assert!(!exprs_are_equivalent(&expr1, &expr2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_named_variable_comparison() {
|
||||
let expr1 = Expr::Variable("1".to_string());
|
||||
let expr2 = Expr::Variable("1".to_string());
|
||||
assert!(exprs_are_equivalent(&expr1, &expr2));
|
||||
|
||||
let expr1 = Expr::Variable("1".to_string());
|
||||
let expr2 = Expr::Variable("2".to_string());
|
||||
assert!(!exprs_are_equivalent(&expr1, &expr2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_addition_exprs_are_equivalent() {
|
||||
let expr1 = Expr::Binary(
|
||||
|
||||
Reference in New Issue
Block a user