From a72b75e193b3a8cd03f772f22e030c3c0c14d15c Mon Sep 17 00:00:00 2001 From: jachewz Date: Mon, 7 Apr 2025 21:45:49 +1000 Subject: [PATCH 1/3] fix: remainder operator rhs text --- core/vdbe/insn.rs | 7 +++++-- testing/math.test | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index 8d3a9afca..fa201079f 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -1001,9 +1001,12 @@ pub fn exec_remainder(lhs: &OwnedValue, rhs: &OwnedValue) -> OwnedValue { &cast_text_to_numeric(lhs.as_str()), &cast_text_to_numeric(rhs.as_str()), ), - (OwnedValue::Text(text), other) | (other, OwnedValue::Text(text)) => { + (OwnedValue::Text(text), other) => { exec_remainder(&cast_text_to_numeric(text.as_str()), other) } +(other, OwnedValue::Text(text)) => { + exec_remainder(other, &cast_text_to_numeric(text.as_str())) + } other => todo!("remainder not implemented for: {:?} {:?}", lhs, other), } } @@ -1699,7 +1702,7 @@ mod tests { ), ( OwnedValue::Float(12.0), - OwnedValue::Text(Text::from_str("12.0")), + OwnedValue::Text(Text::from_str("3.0")), ), ]; let outputs = vec![ diff --git a/testing/math.test b/testing/math.test index d1747f976..dcfaa97df 100755 --- a/testing/math.test +++ b/testing/math.test @@ -1357,6 +1357,19 @@ do_execsql_test mod-agg-float { SELECT count(*) % 2.43 from users } { 0.0 } +foreach {testnum lhs rhs ans} { + 1 'a' 'a' {} + 2 'a' 10 0 + 3 10 'a' {} + 4 'a' 11.0 0.0 + 5 11.0 'a' {} + 7 '10' '3' 1 + 8 '10.0' '3' 1.0 + 9 '10.0' -3 1.0 +} { + do_execsql_test mod-text-$testnum "SELECT $lhs % $rhs" $::ans +} + do_execsql_test comp-float-float { SELECT 0.0 = 0.0 } { 1 } From db15661b7ef9db6c1db1134fb7d876ab28345d6b Mon Sep 17 00:00:00 2001 From: jachewz Date: Mon, 7 Apr 2025 21:49:09 +1000 Subject: [PATCH 2/3] fix: i64 % -1 overflow panic --- core/vdbe/insn.rs | 20 +++++++++++++++----- testing/math.test | 8 ++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index fa201079f..7fffb9b22 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -971,7 +971,7 @@ pub fn exec_remainder(lhs: &OwnedValue, rhs: &OwnedValue) -> OwnedValue { if rhs == &0 { OwnedValue::Null } else { - OwnedValue::Integer(lhs % rhs) + OwnedValue::Integer(lhs % rhs.abs()) } } (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { @@ -979,14 +979,14 @@ pub fn exec_remainder(lhs: &OwnedValue, rhs: &OwnedValue) -> OwnedValue { if rhs_int == 0 { OwnedValue::Null } else { - OwnedValue::Float(((*lhs as i64) % rhs_int) as f64) + OwnedValue::Float(((*lhs as i64) % rhs_int.abs()) as f64) } } (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { if rhs == &0 { OwnedValue::Null } else { - OwnedValue::Float(((*lhs as i64) % rhs) as f64) + OwnedValue::Float(((*lhs as i64) % rhs.abs()) as f64) } } (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { @@ -994,7 +994,7 @@ pub fn exec_remainder(lhs: &OwnedValue, rhs: &OwnedValue) -> OwnedValue { if rhs_int == 0 { OwnedValue::Null } else { - OwnedValue::Float((lhs % rhs_int) as f64) + OwnedValue::Float((lhs % rhs_int.abs()) as f64) } } (OwnedValue::Text(lhs), OwnedValue::Text(rhs)) => exec_remainder( @@ -1004,7 +1004,7 @@ pub fn exec_remainder(lhs: &OwnedValue, rhs: &OwnedValue) -> OwnedValue { (OwnedValue::Text(text), other) => { exec_remainder(&cast_text_to_numeric(text.as_str()), other) } -(other, OwnedValue::Text(text)) => { + (other, OwnedValue::Text(text)) => { exec_remainder(other, &cast_text_to_numeric(text.as_str())) } other => todo!("remainder not implemented for: {:?} {:?}", lhs, other), @@ -1688,10 +1688,15 @@ mod tests { (OwnedValue::Float(12.0), OwnedValue::Float(0.0)), (OwnedValue::Float(12.0), OwnedValue::Integer(0)), (OwnedValue::Integer(12), OwnedValue::Float(0.0)), + (OwnedValue::Integer(i64::MIN), OwnedValue::Integer(-1)), (OwnedValue::Integer(12), OwnedValue::Integer(3)), (OwnedValue::Float(12.0), OwnedValue::Float(3.0)), (OwnedValue::Float(12.0), OwnedValue::Integer(3)), (OwnedValue::Integer(12), OwnedValue::Float(3.0)), + (OwnedValue::Integer(12), OwnedValue::Integer(-3)), + (OwnedValue::Float(12.0), OwnedValue::Float(-3.0)), + (OwnedValue::Float(12.0), OwnedValue::Integer(-3)), + (OwnedValue::Integer(12), OwnedValue::Float(-3.0)), ( OwnedValue::Text(Text::from_str("12.0")), OwnedValue::Text(Text::from_str("3.0")), @@ -1716,6 +1721,11 @@ mod tests { OwnedValue::Null, OwnedValue::Null, OwnedValue::Null, + OwnedValue::Float(0.0), + OwnedValue::Integer(0), + OwnedValue::Float(0.0), + OwnedValue::Float(0.0), + OwnedValue::Float(0.0), OwnedValue::Integer(0), OwnedValue::Float(0.0), OwnedValue::Float(0.0), diff --git a/testing/math.test b/testing/math.test index dcfaa97df..51f1df56a 100755 --- a/testing/math.test +++ b/testing/math.test @@ -1370,6 +1370,14 @@ foreach {testnum lhs rhs ans} { do_execsql_test mod-text-$testnum "SELECT $lhs % $rhs" $::ans } +foreach {testnum lhs rhs ans} { + 1 '-9223372036854775808' '-1' 0 + 2 -9223372036854775808 -1 0 + 3 -9223372036854775809 -1 0.0 +} { + do_execsql_test mod-overflow-$testnum "SELECT $lhs % $rhs" $::ans +} + do_execsql_test comp-float-float { SELECT 0.0 = 0.0 } { 1 } From ebf467d04e98c2331ac0e06d50bf4d115cc1f985 Mon Sep 17 00:00:00 2001 From: jachewz Date: Mon, 7 Apr 2025 21:58:03 +1000 Subject: [PATCH 3/3] rename math.test % operator tests from mod- to remainder- --- testing/math.test | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/testing/math.test b/testing/math.test index 51f1df56a..afa0e29d1 100755 --- a/testing/math.test +++ b/testing/math.test @@ -1309,51 +1309,51 @@ do_execsql_test log-int-null { SELECT log(5, null) } {} -do_execsql_test mod-int-null { +do_execsql_test remainder-int-null { SELECT 183 % null } {} -do_execsql_test mod-int-0 { +do_execsql_test remainder-int-0 { SELECT 183 % 0 } {} -do_execsql_test mod-int-int { +do_execsql_test remainder-int-int { SELECT 183 % 10 } { 3 } -do_execsql_test mod-int-float { +do_execsql_test remainder-int-float { SELECT 38 % 10.35 } { 8.0 } -do_execsql_test mod-float-int { +do_execsql_test remainder-float-int { SELECT 38.43 % 13 } { 12.0 } -do_execsql_test mod-0-float { +do_execsql_test remainder-0-float { SELECT 0 % 12.0 } { 0.0 } -do_execsql_test mod-float-0 { +do_execsql_test remainder-float-0 { SELECT 23.14 % 0 } {} -do_execsql_test mod-float-float { +do_execsql_test remainder-float-float { SELECT 23.14 % 12.0 } { 11.0 } -do_execsql_test mod-float-agg { +do_execsql_test remainder-float-agg { SELECT 23.14 % sum(id) from products } { 23.0 } -do_execsql_test mod-int-agg { +do_execsql_test remainder-int-agg { SELECT 17 % sum(id) from users } { 17 } -do_execsql_test mod-agg-int { +do_execsql_test remainder-agg-int { SELECT count(*) % 17 from users } { 4 } -do_execsql_test mod-agg-float { +do_execsql_test remainder-agg-float { SELECT count(*) % 2.43 from users } { 0.0 } @@ -1367,7 +1367,7 @@ foreach {testnum lhs rhs ans} { 8 '10.0' '3' 1.0 9 '10.0' -3 1.0 } { - do_execsql_test mod-text-$testnum "SELECT $lhs % $rhs" $::ans + do_execsql_test remainder-text-$testnum "SELECT $lhs % $rhs" $::ans } foreach {testnum lhs rhs ans} { @@ -1375,7 +1375,7 @@ foreach {testnum lhs rhs ans} { 2 -9223372036854775808 -1 0 3 -9223372036854775809 -1 0.0 } { - do_execsql_test mod-overflow-$testnum "SELECT $lhs % $rhs" $::ans + do_execsql_test remainder-overflow-$testnum "SELECT $lhs % $rhs" $::ans } do_execsql_test comp-float-float {