This is an automated email from the ASF dual-hosted git repository.

liurenjie1024 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-rust.git


The following commit(s) were added to refs/heads/main by this push:
     new 94c9af0  feat: Complete predicate builders for all operators. (#276)
94c9af0 is described below

commit 94c9af08d4f8a56c820655b212f94d62da949e3a
Author: QuakeWang <[email protected]>
AuthorDate: Wed Mar 27 11:54:03 2024 +0800

    feat: Complete predicate builders for all operators. (#276)
    
    * feat: Complete predicate builders for all operators.
    
    * ci: fix fmt error
    
    * fix nan and notnan
---
 crates/iceberg/src/expr/predicate.rs | 134 ++++++++++++++++++++++++++++++++
 crates/iceberg/src/expr/term.rs      | 145 +++++++++++++++++++++++++++++++++++
 2 files changed, 279 insertions(+)

diff --git a/crates/iceberg/src/expr/predicate.rs 
b/crates/iceberg/src/expr/predicate.rs
index f8bcffe..da8a863 100644
--- a/crates/iceberg/src/expr/predicate.rs
+++ b/crates/iceberg/src/expr/predicate.rs
@@ -769,6 +769,7 @@ mod tests {
                     NestedField::optional(1, "foo", 
Type::Primitive(PrimitiveType::String)).into(),
                     NestedField::required(2, "bar", 
Type::Primitive(PrimitiveType::Int)).into(),
                     NestedField::optional(3, "baz", 
Type::Primitive(PrimitiveType::Boolean)).into(),
+                    NestedField::optional(4, "qux", 
Type::Primitive(PrimitiveType::Float)).into(),
                 ])
                 .build()
                 .unwrap(),
@@ -807,6 +808,43 @@ mod tests {
         assert_eq!(&format!("{bound_expr}"), "True");
     }
 
+    #[test]
+    fn test_bind_is_nan() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("qux").is_nan();
+        let bound_expr = expr.bind(schema, true).unwrap();
+        assert_eq!(&format!("{bound_expr}"), "qux IS NAN");
+
+        let schema_string = table_schema_simple();
+        let expr_string = Reference::new("foo").is_nan();
+        let bound_expr_string = expr_string.bind(schema_string, true);
+        assert!(bound_expr_string.is_err());
+    }
+
+    #[test]
+    fn test_bind_is_nan_wrong_type() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("foo").is_nan();
+        let bound_expr = expr.bind(schema, true);
+        assert!(bound_expr.is_err());
+    }
+
+    #[test]
+    fn test_bind_is_not_nan() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("qux").is_not_nan();
+        let bound_expr = expr.bind(schema, true).unwrap();
+        assert_eq!(&format!("{bound_expr}"), "qux IS NOT NAN");
+    }
+
+    #[test]
+    fn test_bind_is_not_nan_wrong_type() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("foo").is_not_nan();
+        let bound_expr = expr.bind(schema, true);
+        assert!(bound_expr.is_err());
+    }
+
     #[test]
     fn test_bind_less_than() {
         let schema = table_schema_simple();
@@ -823,6 +861,38 @@ mod tests {
         assert!(bound_expr.is_err());
     }
 
+    #[test]
+    fn test_bind_less_than_or_eq() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("bar").less_than_or_equal_to(Datum::int(10));
+        let bound_expr = expr.bind(schema, true).unwrap();
+        assert_eq!(&format!("{bound_expr}"), "bar <= 10");
+    }
+
+    #[test]
+    fn test_bind_less_than_or_eq_wrong_type() {
+        let schema = table_schema_simple();
+        let expr = 
Reference::new("bar").less_than_or_equal_to(Datum::string("abcd"));
+        let bound_expr = expr.bind(schema, true);
+        assert!(bound_expr.is_err());
+    }
+
+    #[test]
+    fn test_bind_greater_than() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("bar").greater_than(Datum::int(10));
+        let bound_expr = expr.bind(schema, true).unwrap();
+        assert_eq!(&format!("{bound_expr}"), "bar > 10");
+    }
+
+    #[test]
+    fn test_bind_greater_than_wrong_type() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("bar").greater_than(Datum::string("abcd"));
+        let bound_expr = expr.bind(schema, true);
+        assert!(bound_expr.is_err());
+    }
+
     #[test]
     fn test_bind_greater_than_or_eq() {
         let schema = table_schema_simple();
@@ -839,6 +909,70 @@ mod tests {
         assert!(bound_expr.is_err());
     }
 
+    #[test]
+    fn test_bind_equal_to() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("bar").equal_to(Datum::int(10));
+        let bound_expr = expr.bind(schema, true).unwrap();
+        assert_eq!(&format!("{bound_expr}"), "bar = 10");
+    }
+
+    #[test]
+    fn test_bind_equal_to_wrong_type() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("bar").equal_to(Datum::string("abcd"));
+        let bound_expr = expr.bind(schema, true);
+        assert!(bound_expr.is_err());
+    }
+
+    #[test]
+    fn test_bind_not_equal_to() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("bar").not_equal_to(Datum::int(10));
+        let bound_expr = expr.bind(schema, true).unwrap();
+        assert_eq!(&format!("{bound_expr}"), "bar != 10");
+    }
+
+    #[test]
+    fn test_bind_not_equal_to_wrong_type() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("bar").not_equal_to(Datum::string("abcd"));
+        let bound_expr = expr.bind(schema, true);
+        assert!(bound_expr.is_err());
+    }
+
+    #[test]
+    fn test_bind_starts_with() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("foo").starts_with(Datum::string("abcd"));
+        let bound_expr = expr.bind(schema, true).unwrap();
+        assert_eq!(&format!("{bound_expr}"), r#"foo STARTS WITH "abcd""#);
+    }
+
+    #[test]
+    fn test_bind_starts_with_wrong_type() {
+        let schema = table_schema_simple();
+        let expr = Reference::new("bar").starts_with(Datum::string("abcd"));
+        let bound_expr = expr.bind(schema, true);
+        assert!(bound_expr.is_err());
+    }
+
+    #[test]
+    fn test_bind_not_starts_with() {
+        let schema = table_schema_simple();
+        let expr = 
Reference::new("foo").not_starts_with(Datum::string("abcd"));
+        let bound_expr = expr.bind(schema, true).unwrap();
+        assert_eq!(&format!("{bound_expr}"), r#"foo NOT STARTS WITH "abcd""#);
+    }
+
+    #[test]
+    fn test_bind_not_starts_with_wrong_type() {
+        let schema = table_schema_simple();
+        let expr = 
Reference::new("bar").not_starts_with(Datum::string("abcd"));
+        let bound_expr = expr.bind(schema, true);
+        assert!(bound_expr.is_err());
+    }
+
     #[test]
     fn test_bind_in() {
         let schema = table_schema_simple();
diff --git a/crates/iceberg/src/expr/term.rs b/crates/iceberg/src/expr/term.rs
index 15cb298..94ae6bc 100644
--- a/crates/iceberg/src/expr/term.rs
+++ b/crates/iceberg/src/expr/term.rs
@@ -69,6 +69,46 @@ impl Reference {
         ))
     }
 
+    /// Creates an less than or equal to expression. For example, `a <= 10`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    ///
+    /// use iceberg::expr::Reference;
+    /// use iceberg::spec::Datum;
+    /// let expr = Reference::new("a").less_than_or_equal_to(Datum::long(10));
+    ///
+    /// assert_eq!(&format!("{expr}"), "a <= 10");
+    /// ```
+    pub fn less_than_or_equal_to(self, datum: Datum) -> Predicate {
+        Predicate::Binary(BinaryExpression::new(
+            PredicateOperator::LessThanOrEq,
+            self,
+            datum,
+        ))
+    }
+
+    /// Creates an greater than expression. For example, `a > 10`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    ///
+    /// use iceberg::expr::Reference;
+    /// use iceberg::spec::Datum;
+    /// let expr = Reference::new("a").greater_than(Datum::long(10));
+    ///
+    /// assert_eq!(&format!("{expr}"), "a > 10");
+    /// ```
+    pub fn greater_than(self, datum: Datum) -> Predicate {
+        Predicate::Binary(BinaryExpression::new(
+            PredicateOperator::GreaterThan,
+            self,
+            datum,
+        ))
+    }
+
     /// Creates a greater-than-or-equal-to than expression. For example, `a >= 
10`.
     ///
     /// # Example
@@ -89,6 +129,111 @@ impl Reference {
         ))
     }
 
+    /// Creates an equal-to expression. For example, `a = 10`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    ///
+    /// use iceberg::expr::Reference;
+    /// use iceberg::spec::Datum;
+    /// let expr = Reference::new("a").equal_to(Datum::long(10));
+    ///
+    /// assert_eq!(&format!("{expr}"), "a = 10");
+    /// ```
+    pub fn equal_to(self, datum: Datum) -> Predicate {
+        Predicate::Binary(BinaryExpression::new(PredicateOperator::Eq, self, 
datum))
+    }
+
+    /// Creates a not equal-to expression. For example, `a!= 10`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    ///
+    /// use iceberg::expr::Reference;
+    /// use iceberg::spec::Datum;
+    /// let expr = Reference::new("a").not_equal_to(Datum::long(10));
+    ///
+    /// assert_eq!(&format!("{expr}"), "a != 10");
+    /// ```
+    pub fn not_equal_to(self, datum: Datum) -> Predicate {
+        Predicate::Binary(BinaryExpression::new(PredicateOperator::NotEq, 
self, datum))
+    }
+
+    /// Creates a start-with expression. For example, `a STARTS WITH "foo"`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    ///
+    /// use iceberg::expr::Reference;
+    /// use iceberg::spec::Datum;
+    /// let expr = Reference::new("a").starts_with(Datum::string("foo"));
+    ///
+    /// assert_eq!(&format!("{expr}"), r#"a STARTS WITH "foo""#);
+    /// ```
+    pub fn starts_with(self, datum: Datum) -> Predicate {
+        Predicate::Binary(BinaryExpression::new(
+            PredicateOperator::StartsWith,
+            self,
+            datum,
+        ))
+    }
+
+    /// Creates a not start-with expression. For example, `a NOT STARTS WITH 
'foo'`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    ///
+    /// use iceberg::expr::Reference;
+    /// use iceberg::spec::Datum;
+    ///
+    /// let expr = Reference::new("a").not_starts_with(Datum::string("foo"));
+    ///
+    /// assert_eq!(&format!("{expr}"), r#"a NOT STARTS WITH "foo""#);
+    /// ```
+    pub fn not_starts_with(self, datum: Datum) -> Predicate {
+        Predicate::Binary(BinaryExpression::new(
+            PredicateOperator::NotStartsWith,
+            self,
+            datum,
+        ))
+    }
+
+    /// Creates an is-nan expression. For example, `a IS NAN`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    ///
+    /// use iceberg::expr::Reference;
+    /// use iceberg::spec::Datum;
+    /// let expr = Reference::new("a").is_nan();
+    ///
+    /// assert_eq!(&format!("{expr}"), "a IS NAN");
+    /// ```
+    pub fn is_nan(self) -> Predicate {
+        Predicate::Unary(UnaryExpression::new(PredicateOperator::IsNan, self))
+    }
+
+    /// Creates an is-not-nan expression. For example, `a IS NOT NAN`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    ///
+    /// use iceberg::expr::Reference;
+    /// use iceberg::spec::Datum;
+    /// let expr = Reference::new("a").is_not_nan();
+    ///
+    /// assert_eq!(&format!("{expr}"), "a IS NOT NAN");
+    /// ```
+    pub fn is_not_nan(self) -> Predicate {
+        Predicate::Unary(UnaryExpression::new(PredicateOperator::NotNan, self))
+    }
+
     /// Creates an is-null expression. For example, `a IS NULL`.
     ///
     /// # Example

Reply via email to