for op_compare reuse compare_immutable

This commit is contained in:
pedrocarlo
2025-11-05 12:57:11 -03:00
parent b1f4554420
commit e5e97a5b0a
2 changed files with 27 additions and 36 deletions

View File

@@ -1638,10 +1638,10 @@ where
V2: AsValueRef,
E1: ExactSizeIterator<Item = V1>,
E2: ExactSizeIterator<Item = V2>,
I1: IntoIterator<IntoIter = E1>,
I2: IntoIterator<IntoIter = E2>,
I1: IntoIterator<IntoIter = E1, Item = E1::Item>,
I2: IntoIterator<IntoIter = E2, Item = E2::Item>,
{
let (l, r) = (l.into_iter(), r.into_iter());
let (l, r): (E1, E2) = (l.into_iter(), r.into_iter());
assert!(
l.len() >= column_info.len(),
"{} < {}",
@@ -1656,17 +1656,9 @@ where
);
let (l, r) = (l.take(column_info.len()), r.take(column_info.len()));
for (i, (l, r)) in l.zip(r).enumerate() {
let l = l.as_value_ref();
let r = r.as_value_ref();
let column_order = column_info[i].sort_order;
let collation = column_info[i].collation;
let cmp = match (l, r) {
(ValueRef::Text(left, _), ValueRef::Text(right, _)) => collation.compare_strings(
&String::from_utf8_lossy(left),
&String::from_utf8_lossy(right),
),
_ => l.partial_cmp(&r).unwrap(),
};
let cmp = compare_immutable_single(l, r, collation);
if !cmp.is_eq() {
return match column_order {
SortOrder::Asc => cmp,
@@ -1677,6 +1669,22 @@ where
std::cmp::Ordering::Equal
}
pub fn compare_immutable_single<V1, V2>(l: V1, r: V2, collation: CollationSeq) -> std::cmp::Ordering
where
V1: AsValueRef,
V2: AsValueRef,
{
let l = l.as_value_ref();
let r = r.as_value_ref();
match (l, r) {
(ValueRef::Text(left, _), ValueRef::Text(right, _)) => collation.compare_strings(
&String::from_utf8_lossy(left),
&String::from_utf8_lossy(right),
),
_ => l.partial_cmp(&r).unwrap(),
}
}
#[derive(Debug, Clone, Copy)]
pub enum RecordCompare {
Int,

View File

@@ -75,7 +75,7 @@ use super::{
CommitState,
};
use parking_lot::RwLock;
use turso_parser::ast::{self, ForeignKeyClause, Name, SortOrder};
use turso_parser::ast::{self, ForeignKeyClause, Name};
use turso_parser::parser::Parser;
use super::{
@@ -537,29 +537,12 @@ pub fn op_compare(
));
}
let mut cmp = std::cmp::Ordering::Equal;
for (i, key_col) in key_info.iter().enumerate().take(count) {
// TODO (https://github.com/tursodatabase/turso/issues/2304): this logic is almost the same as compare_immutable()
// but that one works on RefValue and this works on Value. There are tons of cases like this where we could reuse
// functionality if we had a trait that both RefValue and Value implement.
let a = state.registers[start_reg_a + i].get_value();
let b = state.registers[start_reg_b + i].get_value();
let column_order = key_col.sort_order;
let collation = key_col.collation;
cmp = match (a, b) {
(Value::Text(left), Value::Text(right)) => {
collation.compare_strings(left.as_str(), right.as_str())
}
_ => a.partial_cmp(b).unwrap(),
};
if !cmp.is_eq() {
cmp = match column_order {
SortOrder::Asc => cmp,
SortOrder::Desc => cmp.reverse(),
};
break;
}
}
// (https://github.com/tursodatabase/turso/issues/2304): reusing logic from compare_immutable().
// TODO: There are tons of cases like this where we could reuse this in a similar vein
let a_range = (start_reg_a..start_reg_a + count + 1).map(|idx| state.registers[idx].get_value());
let b_range = (start_reg_b..start_reg_b + count + 1).map(|idx| state.registers[idx].get_value());
let cmp = compare_immutable(a_range, b_range, key_info);
state.last_compare = Some(cmp);
state.pc += 1;
Ok(InsnFunctionStepResult::Step)