From d572089b80fa25bd05527578dcac81957370b771 Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Sun, 29 Dec 2024 16:56:43 -0500 Subject: [PATCH 1/3] Refactor out repetitive agg_func code in vdbe --- core/vdbe/insn.rs | 142 ++++++++++- core/vdbe/mod.rs | 635 +++++----------------------------------------- 2 files changed, 198 insertions(+), 579 deletions(-) diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index b0eba79d..c37babd2 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -1,5 +1,5 @@ use super::{AggFunc, BranchOffset, CursorID, FuncCtx, PageIdx}; -use crate::types::OwnedRecord; +use crate::types::{OwnedRecord, OwnedValue}; use limbo_macros::Description; #[derive(Description, Debug)] @@ -488,3 +488,143 @@ pub enum Insn { where_clause: String, }, } + +impl Insn { + pub fn math_binary_eval(&self) -> fn(&OwnedValue, &OwnedValue) -> OwnedValue { + match self { + Self::Add { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Integer(lhs + rhs) + } + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(lhs + rhs) + } + (OwnedValue::Float(f), OwnedValue::Integer(i)) + | (OwnedValue::Integer(i), OwnedValue::Float(f)) => { + OwnedValue::Float(*f + *i as f64) + } + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => { + todo!("{:?} {:?}", lhs, rhs); + } + } + }, + Self::Subtract { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Integer(lhs - rhs) + } + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(lhs - rhs) + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Float(lhs - *rhs as f64) + } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(*lhs as f64 - rhs) + } + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => unimplemented!(), + } + }, + Self::Multiply { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Integer(lhs * rhs) + } + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(lhs * rhs) + } + (OwnedValue::Integer(i), OwnedValue::Float(f)) + | (OwnedValue::Float(f), OwnedValue::Integer(i)) => { + OwnedValue::Float(*i as f64 * { *f }) + } + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } + }, + Self::Divide { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { + match (lhs, rhs) { + (_, OwnedValue::Integer(0)) | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Integer(lhs / rhs) + } + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(lhs / rhs) + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Float(lhs / *rhs as f64) + } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(*lhs as f64 / rhs) + } + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } + }, + Self::BitAnd { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { + match (lhs, rhs) { + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + (_, OwnedValue::Integer(0)) + | (OwnedValue::Integer(0), _) + | (_, OwnedValue::Float(0.0)) + | (OwnedValue::Float(0.0), _) => OwnedValue::Integer(0), + (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { + OwnedValue::Integer(lh & rh) + } + (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { + OwnedValue::Integer(*lh as i64 & *rh as i64) + } + (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { + OwnedValue::Integer(*lh as i64 & rh) + } + (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { + OwnedValue::Integer(lh & *rh as i64) + } + _ => todo!(), + } + }, + Self::BitOr { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { + match (lhs, rhs) { + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { + OwnedValue::Integer(lh | rh) + } + (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { + OwnedValue::Integer(*lh as i64 | rh) + } + (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { + OwnedValue::Integer(lh | *rh as i64) + } + (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { + OwnedValue::Integer(*lh as i64 | *rh as i64) + } + _ => todo!(), + } + }, + Self::Remainder { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { + match (lhs, rhs) { + (OwnedValue::Null, _) + | (_, OwnedValue::Null) + | (_, OwnedValue::Integer(0)) + | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Integer(lhs % rhs) + } + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(((*lhs as i64) % (*rhs as i64)) as f64) + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Float(((*lhs as i64) % rhs) as f64) + } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float((lhs % *rhs as i64) as f64) + } + _ => todo!(), + } + }, + _ => todo!(), + } + } +} diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index 20b5e39c..0847980d 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -189,529 +189,90 @@ impl Program { let lhs = *lhs; let rhs = *rhs; let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Integer(lhs + rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs + rhs); - } - (OwnedValue::Float(f), OwnedValue::Integer(i)) - | (OwnedValue::Integer(i), OwnedValue::Float(f)) => { - state.registers[dest] = OwnedValue::Float(*f + *i as f64); - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Agg(aggctx), other) | (other, OwnedValue::Agg(aggctx)) => { - match other { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc + *i as f64); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(acc + i); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc + f); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(*acc as f64 + f); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Agg(aggctx2) => { - let acc = aggctx.final_value(); - let acc2 = aggctx2.final_value(); - match (acc, acc2) { - (OwnedValue::Integer(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = OwnedValue::Integer(acc + acc2); - } - (OwnedValue::Float(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = OwnedValue::Float(acc + acc2); - } - (OwnedValue::Integer(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = - OwnedValue::Float(*acc as f64 + acc2); - } - (OwnedValue::Float(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = - OwnedValue::Float(acc + *acc2 as f64); - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - rest => unimplemented!("{:?}", rest), - } - } - _ => { - todo!(); - } + let mut lhs = &state.registers[lhs]; + let mut rhs = &state.registers[rhs]; + if let OwnedValue::Agg(aggctx) = &lhs { + lhs = aggctx.final_value(); + } + if let OwnedValue::Agg(aggctx) = &rhs { + rhs = aggctx.final_value(); } + state.registers[dest] = insn.math_binary_eval()(lhs, rhs); state.pc += 1; } Insn::Subtract { lhs, rhs, dest } => { let lhs = *lhs; let rhs = *rhs; let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Integer(lhs - rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs - rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs - *rhs as f64); - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(*lhs as f64 - rhs); - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Agg(aggctx), rhs) => match rhs { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc - *i as f64); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(acc - i); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc - f); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(*acc as f64 - f); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Agg(aggctx2) => { - let acc = aggctx.final_value(); - let acc2 = aggctx2.final_value(); - match (acc, acc2) { - (OwnedValue::Integer(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = OwnedValue::Integer(acc - acc2); - } - (OwnedValue::Float(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = OwnedValue::Float(acc - acc2); - } - (OwnedValue::Integer(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = - OwnedValue::Float(*acc as f64 - acc2); - } - (OwnedValue::Float(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = - OwnedValue::Float(acc - *acc2 as f64); - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - rest => unimplemented!("{:?}", rest), - }, - (lhs, OwnedValue::Agg(aggctx)) => match lhs { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(*i as f64 - acc); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(i - acc); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(f - acc); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(f - *acc as f64); - } - _ => { - todo!("{:?}", aggctx); - } - }, - rest => unimplemented!("{:?}", rest), - }, - others => { - todo!("{:?}", others); - } + let mut lhs = &state.registers[lhs]; + let mut rhs = &state.registers[rhs]; + if let OwnedValue::Agg(aggctx) = &lhs { + lhs = aggctx.final_value(); + } + if let OwnedValue::Agg(aggctx) = &rhs { + rhs = aggctx.final_value(); } + state.registers[dest] = insn.math_binary_eval()(lhs, rhs); state.pc += 1; } Insn::Multiply { lhs, rhs, dest } => { let lhs = *lhs; let rhs = *rhs; let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Integer(lhs * rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs * rhs); - } - (OwnedValue::Integer(i), OwnedValue::Float(f)) - | (OwnedValue::Float(f), OwnedValue::Integer(i)) => { - state.registers[dest] = OwnedValue::Float(*i as f64 * { *f }); - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Agg(aggctx), other) | (other, OwnedValue::Agg(aggctx)) => { - match other { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc * *i as f64); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(acc * i); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc * f); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(*acc as f64 * f); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Agg(aggctx2) => { - let acc = aggctx.final_value(); - let acc2 = aggctx2.final_value(); - match (acc, acc2) { - (OwnedValue::Integer(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = OwnedValue::Integer(acc * acc2); - } - (OwnedValue::Float(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = OwnedValue::Float(acc * acc2); - } - (OwnedValue::Integer(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = - OwnedValue::Float(*acc as f64 * acc2); - } - (OwnedValue::Float(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = - OwnedValue::Float(acc * *acc2 as f64); - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - rest => unimplemented!("{:?}", rest), - } - } - others => { - todo!("{:?}", others); - } + let mut lhs = &state.registers[lhs]; + let mut rhs = &state.registers[rhs]; + if let OwnedValue::Agg(aggctx) = &lhs { + lhs = aggctx.final_value(); + } + if let OwnedValue::Agg(aggctx) = &rhs { + rhs = aggctx.final_value(); } + state.registers[dest] = insn.math_binary_eval()(lhs, rhs); state.pc += 1; } Insn::Divide { lhs, rhs, dest } => { let lhs = *lhs; let rhs = *rhs; let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - // If the divisor is zero, the result is NULL. - (_, OwnedValue::Integer(0)) | (_, OwnedValue::Float(0.0)) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Integer(lhs / rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs / rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs / *rhs as f64); - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(*lhs as f64 / rhs); - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Agg(aggctx), rhs) => match rhs { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc / *i as f64); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(acc / i); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc / f); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(*acc as f64 / f); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Agg(aggctx2) => { - let acc = aggctx.final_value(); - let acc2 = aggctx2.final_value(); - match (acc, acc2) { - (OwnedValue::Integer(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = OwnedValue::Integer(acc / acc2); - } - (OwnedValue::Float(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = OwnedValue::Float(acc / acc2); - } - (OwnedValue::Integer(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = - OwnedValue::Float(*acc as f64 / acc2); - } - (OwnedValue::Float(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = - OwnedValue::Float(acc / *acc2 as f64); - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - rest => unimplemented!("{:?}", rest), - }, - (lhs, OwnedValue::Agg(aggctx)) => match lhs { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(*i as f64 / acc); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(i / acc); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(f / acc); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(f / *acc as f64); - } - _ => { - todo!("{:?}", aggctx); - } - }, - rest => unimplemented!("{:?}", rest), - }, - others => { - todo!("{:?}", others); - } + let mut lhs = &state.registers[lhs]; + let mut rhs = &state.registers[rhs]; + if let OwnedValue::Agg(aggctx) = &lhs { + lhs = aggctx.final_value(); + } + if let OwnedValue::Agg(aggctx) = &rhs { + rhs = aggctx.final_value(); } + state.registers[dest] = insn.math_binary_eval()(lhs, rhs); state.pc += 1; } Insn::BitAnd { lhs, rhs, dest } => { let lhs = *lhs; let rhs = *rhs; let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - // handle 0 and null cases - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (_, OwnedValue::Integer(0)) - | (OwnedValue::Integer(0), _) - | (_, OwnedValue::Float(0.0)) - | (OwnedValue::Float(0.0), _) => { - state.registers[dest] = OwnedValue::Integer(0); - } - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh & rh); - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = OwnedValue::Integer(*lh as i64 & *rh as i64); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(*lh as i64 & rh); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh & *rh as i64); - } - (OwnedValue::Agg(aggctx), other) | (other, OwnedValue::Agg(aggctx)) => { - match other { - OwnedValue::Agg(aggctx2) => { - match (aggctx.final_value(), aggctx2.final_value()) { - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh & rh); - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 & *rh as i64); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(lh & *rh as i64); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 & rh); - } - _ => { - unimplemented!( - "{:?} {:?}", - aggctx.final_value(), - aggctx2.final_value() - ); - } - } - } - other => match (aggctx.final_value(), other) { - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (_, OwnedValue::Integer(0)) - | (OwnedValue::Integer(0), _) - | (_, OwnedValue::Float(0.0)) - | (OwnedValue::Float(0.0), _) => { - state.registers[dest] = OwnedValue::Integer(0); - } - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh & rh); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 & rh); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(lh & *rh as i64); - } - _ => { - unimplemented!("{:?} {:?}", aggctx.final_value(), other); - } - }, - } - } - _ => { - unimplemented!("{:?} {:?}", state.registers[lhs], state.registers[rhs]); - } + let mut lhs = &state.registers[lhs]; + let mut rhs = &state.registers[rhs]; + if let OwnedValue::Agg(aggctx) = &lhs { + lhs = aggctx.final_value(); + } + if let OwnedValue::Agg(aggctx) = &rhs { + rhs = aggctx.final_value(); } + state.registers[dest] = insn.math_binary_eval()(lhs, rhs); state.pc += 1; } Insn::BitOr { lhs, rhs, dest } => { let lhs = *lhs; let rhs = *rhs; let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh | rh); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(*lh as i64 | rh); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh | *rh as i64); - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = OwnedValue::Integer(*lh as i64 | *rh as i64); - } - (OwnedValue::Agg(aggctx), other) | (other, OwnedValue::Agg(aggctx)) => { - match other { - OwnedValue::Agg(aggctx2) => { - let final_lhs = aggctx.final_value(); - let final_rhs = aggctx2.final_value(); - match (final_lhs, final_rhs) { - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh | rh); - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 | *rh as i64); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(lh | *rh as i64); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 | rh); - } - _ => { - unimplemented!("{:?} {:?}", final_lhs, final_rhs); - } - } - } - other => match (aggctx.final_value(), other) { - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh | rh); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 | rh); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(lh | *rh as i64); - } - _ => { - unimplemented!("{:?} {:?}", aggctx.final_value(), other); - } - }, - } - } - _ => { - unimplemented!("{:?} {:?}", state.registers[lhs], state.registers[rhs]); - } + let mut lhs = &state.registers[lhs]; + let mut rhs = &state.registers[rhs]; + if let OwnedValue::Agg(aggctx) = &lhs { + lhs = aggctx.final_value(); + } + if let OwnedValue::Agg(aggctx) = &rhs { + rhs = aggctx.final_value(); } + state.registers[dest] = insn.math_binary_eval()(lhs, rhs); state.pc += 1; } Insn::BitNot { reg, dest } => { @@ -747,97 +308,15 @@ impl Program { let lhs = *lhs; let rhs = *rhs; let dest = *dest; - state.registers[dest] = match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Null, _) - | (_, OwnedValue::Null) - | (_, OwnedValue::Integer(0)) - | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Integer(lhs % rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(((*lhs as i64) % (*rhs as i64)) as f64) - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Float(((*lhs as i64) % rhs) as f64) - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float((lhs % *rhs as i64) as f64) - } - (lhs, OwnedValue::Agg(agg_rhs)) => match lhs { - OwnedValue::Agg(agg_lhs) => { - let acc = agg_lhs.final_value(); - let acc2 = agg_rhs.final_value(); - match (acc, acc2) { - (_, OwnedValue::Integer(0)) - | (_, OwnedValue::Float(0.0)) - | (_, OwnedValue::Null) - | (OwnedValue::Null, _) => OwnedValue::Null, - (OwnedValue::Integer(l), OwnedValue::Integer(r)) => { - OwnedValue::Integer(l % r) - } - (OwnedValue::Float(lh_f), OwnedValue::Float(rh_f)) => { - OwnedValue::Float(((*lh_f as i64) % (*rh_f as i64)) as f64) - } - (OwnedValue::Integer(lh_i), OwnedValue::Float(rh_f)) => { - OwnedValue::Float((lh_i % (*rh_f as i64)) as f64) - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - OwnedValue::Integer(lh_i) => match agg_rhs.final_value() { - OwnedValue::Null => OwnedValue::Null, - OwnedValue::Float(rh_f) => { - OwnedValue::Float((lh_i % (*rh_f as i64)) as f64) - } - OwnedValue::Integer(rh_i) => OwnedValue::Integer(lh_i % rh_i), - _ => { - todo!("{:?}", agg_rhs); - } - }, - OwnedValue::Float(lh_f) => match agg_rhs.final_value() { - OwnedValue::Null => OwnedValue::Null, - OwnedValue::Float(rh_f) => { - OwnedValue::Float(((*lh_f as i64) % (*rh_f as i64)) as f64) - } - OwnedValue::Integer(rh_i) => { - OwnedValue::Float(((*lh_f as i64) % rh_i) as f64) - } - _ => { - todo!("{:?}", agg_rhs); - } - }, - _ => todo!("{:?}", rhs), - }, - (OwnedValue::Agg(aggctx), rhs) => match rhs { - OwnedValue::Integer(rh_i) => match aggctx.final_value() { - OwnedValue::Null => OwnedValue::Null, - OwnedValue::Float(lh_f) => { - OwnedValue::Float(((*lh_f as i64) % rh_i) as f64) - } - OwnedValue::Integer(lh_i) => OwnedValue::Integer(lh_i % rh_i), - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(rh_f) => match aggctx.final_value() { - OwnedValue::Null => OwnedValue::Null, - OwnedValue::Float(lh_f) => { - OwnedValue::Float(((*lh_f as i64) % (*rh_f as i64)) as f64) - } - OwnedValue::Integer(lh_i) => { - OwnedValue::Float((lh_i % (*rh_f as i64)) as f64) - } - _ => { - todo!("{:?}", aggctx); - } - }, - _ => todo!("{:?}", rhs), - }, - _ => todo!("{:?} {:?}", state.registers[lhs], state.registers[rhs]), - }; + let mut lhs = &state.registers[lhs]; + let mut rhs = &state.registers[rhs]; + if let OwnedValue::Agg(aggctx) = &lhs { + lhs = aggctx.final_value(); + } + if let OwnedValue::Agg(aggctx) = &rhs { + rhs = aggctx.final_value(); + } + state.registers[dest] = insn.math_binary_eval()(lhs, rhs); state.pc += 1; } Insn::Null { dest, dest_end } => { From 45eeee15893062c54093f441ed0d96c9e953cda1 Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Sun, 29 Dec 2024 17:14:42 -0500 Subject: [PATCH 2/3] Add comment and match case for improperly called values --- core/vdbe/insn.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index c37babd2..a68807f5 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -490,6 +490,8 @@ pub enum Insn { } impl Insn { + // returns a function that evaluates a binary expression of final values + // do not use on unresolved AggFunc values not in their .final_state() pub fn math_binary_eval(&self) -> fn(&OwnedValue, &OwnedValue) -> OwnedValue { match self { Self::Add { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { @@ -505,9 +507,10 @@ impl Insn { OwnedValue::Float(*f + *i as f64) } (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, - _ => { - todo!("{:?} {:?}", lhs, rhs); + (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { + unimplemented!("unresolved values {:?}", (lhs, rhs)) } + _ => todo!(), } }, Self::Subtract { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { @@ -525,7 +528,10 @@ impl Insn { OwnedValue::Float(*lhs as f64 - rhs) } (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, - _ => unimplemented!(), + (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { + unimplemented!("unresolved values {:?}", (lhs, rhs)) + } + _ => todo!(), } }, Self::Multiply { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { @@ -541,6 +547,9 @@ impl Insn { OwnedValue::Float(*i as f64 * { *f }) } (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { + unimplemented!("unresolved values {:?}", (lhs, rhs)) + } _ => todo!(), } }, @@ -560,6 +569,9 @@ impl Insn { OwnedValue::Float(*lhs as f64 / rhs) } (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { + unimplemented!("unresolved values {:?}", (lhs, rhs)) + } _ => todo!(), } }, @@ -582,6 +594,9 @@ impl Insn { (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { OwnedValue::Integer(lh & *rh as i64) } + (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { + unimplemented!("unresolved values {:?}", (lhs, rhs)) + } _ => todo!(), } }, @@ -600,6 +615,9 @@ impl Insn { (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { OwnedValue::Integer(*lh as i64 | *rh as i64) } + (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { + unimplemented!("unresolved values {:?}", (lhs, rhs)) + } _ => todo!(), } }, @@ -621,10 +639,13 @@ impl Insn { (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { OwnedValue::Float((lhs % *rhs as i64) as f64) } + (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { + unimplemented!("unresolved values {:?}", (lhs, rhs)) + } _ => todo!(), } }, - _ => todo!(), + _ => unimplemented!("Not a binary operation instruction {:?}", self), } } } From ed950072981f8dfb0cdfc50be365591519a3f70f Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Mon, 30 Dec 2024 08:47:55 -0500 Subject: [PATCH 3/3] Separate exec insns to individual functions --- core/vdbe/insn.rs | 300 ++++++++++++++++++++++------------------------ core/vdbe/mod.rs | 135 ++++----------------- 2 files changed, 165 insertions(+), 270 deletions(-) diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index a68807f5..439a3ff2 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -489,163 +489,149 @@ pub enum Insn { }, } -impl Insn { - // returns a function that evaluates a binary expression of final values - // do not use on unresolved AggFunc values not in their .final_state() - pub fn math_binary_eval(&self) -> fn(&OwnedValue, &OwnedValue) -> OwnedValue { - match self { - Self::Add { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { - match (lhs, rhs) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Integer(lhs + rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(lhs + rhs) - } - (OwnedValue::Float(f), OwnedValue::Integer(i)) - | (OwnedValue::Integer(i), OwnedValue::Float(f)) => { - OwnedValue::Float(*f + *i as f64) - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, - (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { - unimplemented!("unresolved values {:?}", (lhs, rhs)) - } - _ => todo!(), - } - }, - Self::Subtract { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { - match (lhs, rhs) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Integer(lhs - rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(lhs - rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Float(lhs - *rhs as f64) - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(*lhs as f64 - rhs) - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, - (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { - unimplemented!("unresolved values {:?}", (lhs, rhs)) - } - _ => todo!(), - } - }, - Self::Multiply { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { - match (lhs, rhs) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Integer(lhs * rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(lhs * rhs) - } - (OwnedValue::Integer(i), OwnedValue::Float(f)) - | (OwnedValue::Float(f), OwnedValue::Integer(i)) => { - OwnedValue::Float(*i as f64 * { *f }) - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, - (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { - unimplemented!("unresolved values {:?}", (lhs, rhs)) - } - _ => todo!(), - } - }, - Self::Divide { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { - match (lhs, rhs) { - (_, OwnedValue::Integer(0)) | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Integer(lhs / rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(lhs / rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Float(lhs / *rhs as f64) - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(*lhs as f64 / rhs) - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, - (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { - unimplemented!("unresolved values {:?}", (lhs, rhs)) - } - _ => todo!(), - } - }, - Self::BitAnd { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { - match (lhs, rhs) { - (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, - (_, OwnedValue::Integer(0)) - | (OwnedValue::Integer(0), _) - | (_, OwnedValue::Float(0.0)) - | (OwnedValue::Float(0.0), _) => OwnedValue::Integer(0), - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - OwnedValue::Integer(lh & rh) - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - OwnedValue::Integer(*lh as i64 & *rh as i64) - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - OwnedValue::Integer(*lh as i64 & rh) - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - OwnedValue::Integer(lh & *rh as i64) - } - (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { - unimplemented!("unresolved values {:?}", (lhs, rhs)) - } - _ => todo!(), - } - }, - Self::BitOr { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { - match (lhs, rhs) { - (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - OwnedValue::Integer(lh | rh) - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - OwnedValue::Integer(*lh as i64 | rh) - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - OwnedValue::Integer(lh | *rh as i64) - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - OwnedValue::Integer(*lh as i64 | *rh as i64) - } - (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { - unimplemented!("unresolved values {:?}", (lhs, rhs)) - } - _ => todo!(), - } - }, - Self::Remainder { .. } => |lhs: &OwnedValue, rhs: &OwnedValue| -> OwnedValue { - match (lhs, rhs) { - (OwnedValue::Null, _) - | (_, OwnedValue::Null) - | (_, OwnedValue::Integer(0)) - | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Integer(lhs % rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(((*lhs as i64) % (*rhs as i64)) as f64) - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Float(((*lhs as i64) % rhs) as f64) - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float((lhs % *rhs as i64) as f64) - } - (OwnedValue::Agg(_), _) | (_, OwnedValue::Agg(_)) => { - unimplemented!("unresolved values {:?}", (lhs, rhs)) - } - _ => todo!(), - } - }, - _ => unimplemented!("Not a binary operation instruction {:?}", self), +pub fn exec_add(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs + rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(lhs + rhs), + (OwnedValue::Float(f), OwnedValue::Integer(i)) + | (OwnedValue::Integer(i), OwnedValue::Float(f)) => OwnedValue::Float(*f + *i as f64), + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } +} + +pub fn exec_subtract(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs - rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(lhs - rhs), + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Float(lhs - *rhs as f64), + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(*lhs as f64 - rhs), + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } +} +pub fn exec_multiply(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs * rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(lhs * rhs), + (OwnedValue::Integer(i), OwnedValue::Float(f)) + | (OwnedValue::Float(f), OwnedValue::Integer(i)) => OwnedValue::Float(*i as f64 * { *f }), + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } +} + +pub fn exec_divide(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (_, OwnedValue::Integer(0)) | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs / rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(lhs / rhs), + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Float(lhs / *rhs as f64), + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(*lhs as f64 / rhs), + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } +} + +pub fn exec_bit_and(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + (_, OwnedValue::Integer(0)) + | (OwnedValue::Integer(0), _) + | (_, OwnedValue::Float(0.0)) + | (OwnedValue::Float(0.0), _) => OwnedValue::Integer(0), + (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => OwnedValue::Integer(lh & rh), + (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { + OwnedValue::Integer(*lh as i64 & *rh as i64) + } + (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => OwnedValue::Integer(*lh as i64 & rh), + (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => OwnedValue::Integer(lh & *rh as i64), + _ => todo!(), + } +} +pub fn exec_bit_or(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => OwnedValue::Integer(lh | rh), + (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => OwnedValue::Integer(*lh as i64 | rh), + (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => OwnedValue::Integer(lh | *rh as i64), + (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { + OwnedValue::Integer(*lh as i64 | *rh as i64) } + _ => todo!(), + } +} + +pub fn exec_remainder(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Null, _) + | (_, OwnedValue::Null) + | (_, OwnedValue::Integer(0)) + | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs % rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(((*lhs as i64) % (*rhs as i64)) as f64) + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Float(((*lhs as i64) % rhs) as f64) + } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float((lhs % *rhs as i64) as f64) + } + _ => todo!(), + } +} + +pub fn exec_bit_not(mut reg: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = reg { + reg = agg.final_value(); + } + match reg { + OwnedValue::Null => OwnedValue::Null, + OwnedValue::Integer(i) => OwnedValue::Integer(!i), + OwnedValue::Float(f) => OwnedValue::Integer(!(*f as i64)), + _ => todo!(), } } diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index 0847980d..31193e60 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -42,6 +42,10 @@ use crate::vdbe::insn::Insn; use crate::{function::JsonFunc, json::get_json, json::json_array, json::json_array_length}; use crate::{Connection, Result, Rows, TransactionState, DATABASE_VERSION}; use datetime::{exec_date, exec_time, exec_unixepoch}; +use insn::{ + exec_add, exec_bit_and, exec_bit_not, exec_bit_or, exec_divide, exec_multiply, exec_remainder, + exec_subtract, +}; use likeop::{construct_like_escape_arg, exec_glob, exec_like_with_escape}; use rand::distributions::{Distribution, Uniform}; use rand::{thread_rng, Rng}; @@ -186,137 +190,42 @@ impl Program { state.pc = *target_pc; } Insn::Add { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - let mut lhs = &state.registers[lhs]; - let mut rhs = &state.registers[rhs]; - if let OwnedValue::Agg(aggctx) = &lhs { - lhs = aggctx.final_value(); - } - if let OwnedValue::Agg(aggctx) = &rhs { - rhs = aggctx.final_value(); - } - state.registers[dest] = insn.math_binary_eval()(lhs, rhs); + state.registers[*dest] = + exec_add(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::Subtract { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - let mut lhs = &state.registers[lhs]; - let mut rhs = &state.registers[rhs]; - if let OwnedValue::Agg(aggctx) = &lhs { - lhs = aggctx.final_value(); - } - if let OwnedValue::Agg(aggctx) = &rhs { - rhs = aggctx.final_value(); - } - state.registers[dest] = insn.math_binary_eval()(lhs, rhs); + state.registers[*dest] = + exec_subtract(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::Multiply { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - let mut lhs = &state.registers[lhs]; - let mut rhs = &state.registers[rhs]; - if let OwnedValue::Agg(aggctx) = &lhs { - lhs = aggctx.final_value(); - } - if let OwnedValue::Agg(aggctx) = &rhs { - rhs = aggctx.final_value(); - } - state.registers[dest] = insn.math_binary_eval()(lhs, rhs); + state.registers[*dest] = + exec_multiply(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::Divide { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - let mut lhs = &state.registers[lhs]; - let mut rhs = &state.registers[rhs]; - if let OwnedValue::Agg(aggctx) = &lhs { - lhs = aggctx.final_value(); - } - if let OwnedValue::Agg(aggctx) = &rhs { - rhs = aggctx.final_value(); - } - state.registers[dest] = insn.math_binary_eval()(lhs, rhs); + state.registers[*dest] = + exec_divide(&state.registers[*lhs], &state.registers[*rhs]); + state.pc += 1; + } + Insn::Remainder { lhs, rhs, dest } => { + state.registers[*dest] = + exec_remainder(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::BitAnd { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - let mut lhs = &state.registers[lhs]; - let mut rhs = &state.registers[rhs]; - if let OwnedValue::Agg(aggctx) = &lhs { - lhs = aggctx.final_value(); - } - if let OwnedValue::Agg(aggctx) = &rhs { - rhs = aggctx.final_value(); - } - state.registers[dest] = insn.math_binary_eval()(lhs, rhs); + state.registers[*dest] = + exec_bit_and(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::BitOr { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - let mut lhs = &state.registers[lhs]; - let mut rhs = &state.registers[rhs]; - if let OwnedValue::Agg(aggctx) = &lhs { - lhs = aggctx.final_value(); - } - if let OwnedValue::Agg(aggctx) = &rhs { - rhs = aggctx.final_value(); - } - state.registers[dest] = insn.math_binary_eval()(lhs, rhs); + state.registers[*dest] = + exec_bit_or(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::BitNot { reg, dest } => { - let reg = *reg; - let dest = *dest; - match &state.registers[reg] { - OwnedValue::Integer(i) => state.registers[dest] = OwnedValue::Integer(!i), - OwnedValue::Float(f) => { - state.registers[dest] = OwnedValue::Integer(!{ *f as i64 }) - } - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Agg(aggctx) => match aggctx.final_value() { - OwnedValue::Integer(i) => { - state.registers[dest] = OwnedValue::Integer(!i); - } - OwnedValue::Float(f) => { - state.registers[dest] = OwnedValue::Integer(!{ *f as i64 }); - } - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - _ => unimplemented!("{:?}", aggctx), - }, - _ => { - unimplemented!("{:?}", state.registers[reg]); - } - } - state.pc += 1; - } - Insn::Remainder { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - let mut lhs = &state.registers[lhs]; - let mut rhs = &state.registers[rhs]; - if let OwnedValue::Agg(aggctx) = &lhs { - lhs = aggctx.final_value(); - } - if let OwnedValue::Agg(aggctx) = &rhs { - rhs = aggctx.final_value(); - } - state.registers[dest] = insn.math_binary_eval()(lhs, rhs); + state.registers[*dest] = exec_bit_not(&state.registers[*reg]); state.pc += 1; } Insn::Null { dest, dest_end } => {