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

blue pushed a commit to branch 0.9.x
in repository https://gitbox.apache.org/repos/asf/iceberg.git

commit 37a5709f5206ef84bd1b35a3a052a0c3d58355a8
Author: Ryan Blue <[email protected]>
AuthorDate: Fri Jul 31 15:06:31 2020 -0700

    Implement negate in bound predicates (#1282)
---
 .../iceberg/expressions/BoundLiteralPredicate.java |  5 ++
 .../iceberg/expressions/BoundUnaryPredicate.java   |  5 ++
 .../iceberg/expressions/TestExpressionHelpers.java | 57 ++++++++++++++++++++++
 3 files changed, 67 insertions(+)

diff --git 
a/api/src/main/java/org/apache/iceberg/expressions/BoundLiteralPredicate.java 
b/api/src/main/java/org/apache/iceberg/expressions/BoundLiteralPredicate.java
index 698b839..e0770ce 100644
--- 
a/api/src/main/java/org/apache/iceberg/expressions/BoundLiteralPredicate.java
+++ 
b/api/src/main/java/org/apache/iceberg/expressions/BoundLiteralPredicate.java
@@ -32,6 +32,11 @@ public class BoundLiteralPredicate<T> extends 
BoundPredicate<T> {
     this.literal = lit;
   }
 
+  @Override
+  public Expression negate() {
+    return new BoundLiteralPredicate<>(op().negate(), term(), literal);
+  }
+
   public Literal<T> literal() {
     return literal;
   }
diff --git 
a/api/src/main/java/org/apache/iceberg/expressions/BoundUnaryPredicate.java 
b/api/src/main/java/org/apache/iceberg/expressions/BoundUnaryPredicate.java
index c5835ba..528dd1f 100644
--- a/api/src/main/java/org/apache/iceberg/expressions/BoundUnaryPredicate.java
+++ b/api/src/main/java/org/apache/iceberg/expressions/BoundUnaryPredicate.java
@@ -25,6 +25,11 @@ public class BoundUnaryPredicate<T> extends 
BoundPredicate<T> {
   }
 
   @Override
+  public Expression negate() {
+    return new BoundUnaryPredicate<>(op().negate(), term());
+  }
+
+  @Override
   public boolean isUnaryPredicate() {
     return true;
   }
diff --git 
a/api/src/test/java/org/apache/iceberg/expressions/TestExpressionHelpers.java 
b/api/src/test/java/org/apache/iceberg/expressions/TestExpressionHelpers.java
index 5bf336f..302e4a6 100644
--- 
a/api/src/test/java/org/apache/iceberg/expressions/TestExpressionHelpers.java
+++ 
b/api/src/test/java/org/apache/iceberg/expressions/TestExpressionHelpers.java
@@ -20,6 +20,9 @@
 package org.apache.iceberg.expressions;
 
 import org.apache.iceberg.AssertHelpers;
+import org.apache.iceberg.types.Types;
+import org.apache.iceberg.types.Types.NestedField;
+import org.apache.iceberg.types.Types.StructType;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -29,11 +32,20 @@ import static 
org.apache.iceberg.expressions.Expressions.and;
 import static org.apache.iceberg.expressions.Expressions.bucket;
 import static org.apache.iceberg.expressions.Expressions.day;
 import static org.apache.iceberg.expressions.Expressions.equal;
+import static org.apache.iceberg.expressions.Expressions.greaterThan;
+import static org.apache.iceberg.expressions.Expressions.greaterThanOrEqual;
 import static org.apache.iceberg.expressions.Expressions.hour;
+import static org.apache.iceberg.expressions.Expressions.in;
+import static org.apache.iceberg.expressions.Expressions.isNull;
 import static org.apache.iceberg.expressions.Expressions.lessThan;
+import static org.apache.iceberg.expressions.Expressions.lessThanOrEqual;
 import static org.apache.iceberg.expressions.Expressions.month;
 import static org.apache.iceberg.expressions.Expressions.not;
+import static org.apache.iceberg.expressions.Expressions.notEqual;
+import static org.apache.iceberg.expressions.Expressions.notIn;
+import static org.apache.iceberg.expressions.Expressions.notNull;
 import static org.apache.iceberg.expressions.Expressions.or;
+import static org.apache.iceberg.expressions.Expressions.rewriteNot;
 import static org.apache.iceberg.expressions.Expressions.truncate;
 import static org.apache.iceberg.expressions.Expressions.year;
 
@@ -78,6 +90,51 @@ public class TestExpressionHelpers {
   }
 
   @Test
+  public void testRewriteNot() {
+    StructType struct = StructType.of(NestedField.optional(1, "a", 
Types.IntegerType.get()));
+    Expression[][] expressions = new Expression[][] {
+        // (rewritten pred, original pred) pairs
+        { isNull("a"), isNull("a") },
+        { notNull("a"), not(isNull("a")) },
+        { notNull("a"), notNull("a") },
+        { isNull("a"), not(notNull("a")) },
+        { equal("a", 5), equal("a", 5) },
+        { notEqual("a", 5), not(equal("a", 5)) },
+        { notEqual("a", 5), notEqual("a", 5) },
+        { equal("a", 5), not(notEqual("a", 5)) },
+        { in("a", 5, 6), in("a", 5, 6) },
+        { notIn("a", 5, 6), not(in("a", 5, 6)) },
+        { notIn("a", 5, 6), notIn("a", 5, 6) },
+        { in("a", 5, 6), not(notIn("a", 5, 6)) },
+        { lessThan("a", 5), lessThan("a", 5) },
+        { greaterThanOrEqual("a", 5), not(lessThan("a", 5)) },
+        { greaterThanOrEqual("a", 5), greaterThanOrEqual("a", 5) },
+        { lessThan("a", 5), not(greaterThanOrEqual("a", 5)) },
+        { lessThanOrEqual("a", 5), lessThanOrEqual("a", 5) },
+        { greaterThan("a", 5), not(lessThanOrEqual("a", 5)) },
+        { greaterThan("a", 5), greaterThan("a", 5) },
+        { lessThanOrEqual("a", 5), not(greaterThan("a", 5)) },
+        { or(equal("a", 5), isNull("a")), or(equal("a", 5), isNull("a")) },
+        { and(notEqual("a", 5), notNull("a")), not(or(equal("a", 5), 
isNull("a"))) },
+        { and(notEqual("a", 5), notNull("a")), and(notEqual("a", 5), 
notNull("a")) },
+        { or(equal("a", 5), isNull("a")), not(and(notEqual("a", 5), 
notNull("a"))) },
+        { or(equal("a", 5), notNull("a")), or(equal("a", 5), not(isNull("a"))) 
},
+    };
+
+    for (Expression[] pair : expressions) {
+      // unbound rewrite
+      Assert.assertEquals(String.format("rewriteNot(%s) should be %s", 
pair[1], pair[0]),
+          pair[0].toString(), rewriteNot(pair[1]).toString());
+
+      // bound rewrite
+      Expression expectedBound = Binder.bind(struct, pair[0]);
+      Expression toRewriteBound = Binder.bind(struct, pair[1]);
+      Assert.assertEquals(String.format("rewriteNot(%s) should be %s", 
toRewriteBound, expectedBound),
+          expectedBound.toString(), rewriteNot(toRewriteBound).toString());
+    }
+  }
+
+  @Test
   public void testTransformExpressions() {
     Assert.assertEquals("Should produce the correct expression string",
         "year(ref(name=\"ts\")) == \"2019\"",

Reply via email to