diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 363d96a99..94a61beaa 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -4,7 +4,7 @@ use sqlite3_parser::ast::{self, UnaryOperator}; use crate::function::JsonFunc; use crate::function::{AggFunc, Func, FuncCtx, MathFuncArity, ScalarFunc}; use crate::schema::Type; -use crate::util::normalize_ident; +use crate::util::{exprs_are_equivalent, normalize_ident}; use crate::vdbe::{builder::ProgramBuilder, BranchOffset, Insn}; use crate::Result; @@ -554,10 +554,7 @@ pub fn translate_expr( ) -> Result { if let Some(precomputed_exprs_to_registers) = precomputed_exprs_to_registers { for (precomputed_expr, reg) in precomputed_exprs_to_registers.iter() { - // TODO: implement a custom equality check for expressions - // there are lots of examples where this breaks, even simple ones like - // sum(x) != SUM(x) - if expr == *precomputed_expr { + if exprs_are_equivalent(expr, precomputed_expr) { program.emit_insn(Insn::Copy { src_reg: *reg, dst_reg: target_register, diff --git a/core/translate/planner.rs b/core/translate/planner.rs index 14757e00a..0bdc447f3 100644 --- a/core/translate/planner.rs +++ b/core/translate/planner.rs @@ -4,7 +4,12 @@ use super::{ Aggregate, BTreeTableReference, Direction, GroupBy, Plan, ResultSetColumn, SourceOperator, }, }; -use crate::{function::Func, schema::Schema, util::normalize_ident, Result}; +use crate::{ + function::Func, + schema::Schema, + util::{exprs_are_equivalent, normalize_ident}, + Result, +}; use sqlite3_parser::ast::{self, FromClause, JoinType, ResultColumn}; pub struct OperatorIdCounter { @@ -23,7 +28,10 @@ impl OperatorIdCounter { } fn resolve_aggregates(expr: &ast::Expr, aggs: &mut Vec) -> bool { - if aggs.iter().any(|a| a.original_expr == *expr) { + if aggs + .iter() + .any(|a| exprs_are_equivalent(&a.original_expr, expr)) + { return true; } match expr {