From dcc28a6ec7ff6bf9838b742a7ca8d711f9dc244b Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Fri, 9 Dec 2022 16:02:36 +0000 Subject: [PATCH] Allow `SELECT` statements to `START AT 0` Closes #1516 --- lib/src/sql/number.rs | 24 ++++++++++++++++++++++++ lib/src/sql/start.rs | 2 +- lib/src/sql/value/value.rs | 12 ++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/src/sql/number.rs b/lib/src/sql/number.rs index b8d697a7..ff070800 100644 --- a/lib/src/sql/number.rs +++ b/lib/src/sql/number.rs @@ -235,6 +235,30 @@ impl Number { } } + pub fn is_negative(&self) -> bool { + match self { + Number::Int(v) => v < &0, + Number::Float(v) => v < &0.0, + Number::Decimal(v) => v < &BigDecimal::from(0), + } + } + + pub fn is_zero_or_positive(&self) -> bool { + match self { + Number::Int(v) => v >= &0, + Number::Float(v) => v >= &0.0, + Number::Decimal(v) => v >= &BigDecimal::from(0), + } + } + + pub fn is_zero_or_negative(&self) -> bool { + match self { + Number::Int(v) => v <= &0, + Number::Float(v) => v <= &0.0, + Number::Decimal(v) => v <= &BigDecimal::from(0), + } + } + // ----------------------------------- // Simple conversion of number // ----------------------------------- diff --git a/lib/src/sql/start.rs b/lib/src/sql/start.rs index 8c4157c6..6bd92ba9 100644 --- a/lib/src/sql/start.rs +++ b/lib/src/sql/start.rs @@ -23,7 +23,7 @@ impl Start { doc: Option<&Value>, ) -> Result { match self.0.compute(ctx, opt, txn, doc).await { - Ok(v) if v.is_integer() && v.is_positive() => Ok(v.as_usize()), + Ok(v) if v.is_integer() && v.is_zero_or_positive() => Ok(v.as_usize()), Ok(v) => Err(Error::InvalidStart { value: v.as_string(), }), diff --git a/lib/src/sql/value/value.rs b/lib/src/sql/value/value.rs index aae2559f..3535d5a4 100644 --- a/lib/src/sql/value/value.rs +++ b/lib/src/sql/value/value.rs @@ -698,6 +698,18 @@ impl Value { matches!(self, Value::Number(v) if v.is_positive()) } + pub fn is_negative(&self) -> bool { + matches!(self, Value::Number(v) if v.is_negative()) + } + + pub fn is_zero_or_positive(&self) -> bool { + matches!(self, Value::Number(v) if v.is_zero_or_positive()) + } + + pub fn is_zero_or_negative(&self) -> bool { + matches!(self, Value::Number(v) if v.is_zero_or_negative()) + } + pub fn is_datetime(&self) -> bool { matches!(self, Value::Datetime(_)) }