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

hui pushed a commit to branch lmh/likeDebug
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit c036ed84ac4e10fc3b89f72d97614c05b30e42bf
Author: Minghui Liu <[email protected]>
AuthorDate: Thu Oct 27 14:18:22 2022 +0800

    Implement `NOT LIKE` filter
---
 .../iotdb/db/qp/logical/crud/LikeOperator.java     | 40 ++++++++++++++++------
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    |  2 +-
 .../qp/strategy/optimizer/ConcatPathOptimizer.java |  3 +-
 .../iotdb/db/qp/physical/PhysicalPlanTest.java     |  3 +-
 .../iotdb/tsfile/read/filter/ValueFilter.java      | 19 +++++-----
 .../iotdb/tsfile/read/filter/operator/Like.java    | 13 ++++---
 6 files changed, 54 insertions(+), 26 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LikeOperator.java 
b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LikeOperator.java
index 9183205230..1dd1e47151 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LikeOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LikeOperator.java
@@ -38,12 +38,14 @@ import static 
org.apache.iotdb.tsfile.file.metadata.enums.TSDataType.TEXT;
 /** fuzzy query structure LikeOperator. */
 public class LikeOperator extends FunctionOperator {
 
+  private boolean not;
   protected String value;
 
-  public LikeOperator(FilterType filterType, PartialPath path, String value) {
+  public LikeOperator(FilterType filterType, PartialPath path, String value, 
boolean not) {
     super(filterType);
     this.singlePath = path;
     this.value = value;
+    this.not = not;
     isLeaf = true;
     isSingle = true;
   }
@@ -68,19 +70,20 @@ public class LikeOperator extends FunctionOperator {
               singlePath,
               (value.startsWith("'") && value.endsWith("'"))
                   ? value.substring(1, value.length() - 1)
-                  : value);
+                  : value,
+              not);
     }
     return new Pair<>(ret, singlePath.getFullPath());
   }
 
   private static class Like {
     public static <T extends Comparable<T>> IUnaryExpression 
getUnaryExpression(
-        PartialPath path, String value) {
-      return new SingleSeriesExpression(path, ValueFilter.like(value));
+        PartialPath path, String value, boolean not) {
+      return new SingleSeriesExpression(path, ValueFilter.like(value, not));
     }
 
-    public <T extends Comparable<T>> Filter getValueFilter(String value) {
-      return ValueFilter.like(value);
+    public <T extends Comparable<T>> Filter getValueFilter(String value, 
boolean not) {
+      return ValueFilter.like(value, not);
     }
   }
 
@@ -90,13 +93,13 @@ public class LikeOperator extends FunctionOperator {
     for (int i = 0; i < spaceNum; i++) {
       sc.addTail("  ");
     }
-    sc.addTail(singlePath.getFullPath(), getFilterSymbol(), value, ", 
single\n");
+    sc.addTail(singlePath.getFullPath(), getFilterSymbol(), not, value, ", 
single\n");
     return sc.toString();
   }
 
   @Override
   public LikeOperator copy() {
-    LikeOperator ret = new LikeOperator(this.filterType, singlePath.clone(), 
value);
+    LikeOperator ret = new LikeOperator(this.filterType, singlePath.clone(), 
value, not);
     ret.isLeaf = isLeaf;
     ret.isSingle = isSingle;
     ret.pathSet = pathSet;
@@ -115,20 +118,35 @@ public class LikeOperator extends FunctionOperator {
       return false;
     }
     LikeOperator that = (LikeOperator) o;
-    return Objects.equals(value, that.value);
+    return Objects.equals(value, that.value) && not == that.not;
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(super.hashCode(), singlePath, value);
+    return Objects.hash(super.hashCode(), singlePath, value, not);
   }
 
   @Override
   public String toString() {
-    return "[" + singlePath.getFullPath() + getFilterSymbol() + value + "]";
+    return "["
+        + singlePath.getFullPath()
+        + (not ? " NOT " : " ")
+        + getFilterSymbol()
+        + " "
+        + value
+        + "]";
+  }
+
+  @Override
+  public void reverseFunc() {
+    not = !not;
   }
 
   public String getValue() {
     return value;
   }
+
+  public boolean isNot() {
+    return not;
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java 
b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index 9b909b4aee..7f2f969d2e 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
@@ -2621,7 +2621,7 @@ public class IoTDBSqlVisitor extends 
IoTDBSqlParserBaseVisitor<Operator> {
       }
       return ctx.REGEXP() != null
           ? new RegexpOperator(FilterType.REGEXP, path, 
ctx.STRING_LITERAL().getText())
-          : new LikeOperator(FilterType.LIKE, path, 
ctx.STRING_LITERAL().getText());
+          : new LikeOperator(FilterType.LIKE, path, 
ctx.STRING_LITERAL().getText(), false);
     } else {
       if (ctx.TIME() != null || ctx.TIMESTAMP() != null) {
         path = new PartialPath(SQLConstant.getSingleTimeArray());
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
index 756c27ac6b..a3ffabe5d5 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
@@ -343,7 +343,8 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
               new LikeOperator(
                   operator.getFilterType(),
                   noStarPaths.get(i),
-                  ((LikeOperator) operator).getValue()));
+                  ((LikeOperator) operator).getValue(),
+                  ((LikeOperator) operator).isNot()));
         } else if (operator instanceof RegexpOperator) {
           currentNode.addChildOperator(
               new RegexpOperator(
diff --git 
a/server/src/test/java/org/apache/iotdb/db/qp/physical/PhysicalPlanTest.java 
b/server/src/test/java/org/apache/iotdb/db/qp/physical/PhysicalPlanTest.java
index 76fe66a39c..2018f0a27d 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/physical/PhysicalPlanTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/physical/PhysicalPlanTest.java
@@ -1443,7 +1443,8 @@ public class PhysicalPlanTest {
     PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);
     IExpression queryFilter = ((RawDataQueryPlan) plan).getExpression();
     IExpression expect =
-        new SingleSeriesExpression(new Path("root.vehicle.d5", "s1"), 
ValueFilter.like("string*"));
+        new SingleSeriesExpression(
+            new Path("root.vehicle.d5", "s1"), ValueFilter.like("string*", 
false));
     assertEquals(expect.toString(), queryFilter.toString());
   }
 
diff --git 
a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/ValueFilter.java 
b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/ValueFilter.java
index 3dcfbe94f8..fd06538cb7 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/ValueFilter.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/ValueFilter.java
@@ -74,8 +74,8 @@ public class ValueFilter {
     return new ValueRegexp(value);
   }
 
-  public static <T extends Comparable<T>> ValueLike<T> like(String value) {
-    return new ValueLike(value);
+  public static <T extends Comparable<T>> ValueLike<T> like(String value, 
boolean not) {
+    return new ValueLike(value, not);
   }
 
   public static class ValueIn<T extends Comparable<T>> extends In<T> {
@@ -268,8 +268,8 @@ public class ValueFilter {
 
   public static class ValueLike<T extends Comparable<T>> extends Like<T> {
 
-    private ValueLike(String value) {
-      super(value, FilterType.VALUE_FILTER);
+    private ValueLike(String value, boolean not) {
+      super(value, FilterType.VALUE_FILTER, not);
     }
   }
 
@@ -277,14 +277,17 @@ public class ValueFilter {
 
     private final int index;
 
-    private VectorValueLike(String value, int index) {
-      super(value);
+    private VectorValueLike(String value, int index, boolean not) {
+      super(value, not);
       this.index = index;
     }
 
     public boolean satisfy(long time, TsPrimitiveType[] values) {
-      Object v = filterType == FilterType.TIME_FILTER ? time : 
values[index].getValue();
-      return this.value.equals(v);
+      if (filterType != FilterType.VALUE_FILTER) {
+        return false;
+      }
+      Object value = values[index].getValue();
+      return pattern.matcher(value.toString()).find() != not;
     }
   }
 }
diff --git 
a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/operator/Like.java 
b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/operator/Like.java
index fac3dfcf5b..c3230e586b 100644
--- 
a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/operator/Like.java
+++ 
b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/operator/Like.java
@@ -45,15 +45,18 @@ public class Like<T extends Comparable<T>> implements 
Filter {
 
   protected Pattern pattern;
 
+  protected boolean not;
+
   private Like() {}
 
   /**
    * The main idea of this part comes from
    * 
https://codereview.stackexchange.com/questions/36861/convert-sql-like-to-regex/36864
    */
-  public Like(String value, FilterType filterType) {
+  public Like(String value, FilterType filterType, boolean not) {
     this.value = value;
     this.filterType = filterType;
+    this.not = not;
     try {
       String unescapeValue = unescapeString(value);
       String specialRegexStr = ".^$*+?{}[]|()";
@@ -94,7 +97,7 @@ public class Like<T extends Comparable<T>> implements Filter {
     if (filterType != FilterType.VALUE_FILTER) {
       return false;
     }
-    return pattern.matcher(value.toString()).find();
+    return pattern.matcher(value.toString()).find() != not;
   }
 
   @Override
@@ -109,7 +112,7 @@ public class Like<T extends Comparable<T>> implements 
Filter {
 
   @Override
   public Filter copy() {
-    return new Like(value, filterType);
+    return new Like(value, filterType, not);
   }
 
   @Override
@@ -118,6 +121,7 @@ public class Like<T extends Comparable<T>> implements 
Filter {
       outputStream.write(getSerializeId().ordinal());
       outputStream.write(filterType.ordinal());
       ReadWriteIOUtils.writeObject(value, outputStream);
+      ReadWriteIOUtils.write(not, outputStream);
     } catch (IOException ex) {
       throw new IllegalArgumentException("Failed to serialize outputStream of 
type:", ex);
     }
@@ -127,11 +131,12 @@ public class Like<T extends Comparable<T>> implements 
Filter {
   public void deserialize(ByteBuffer buffer) {
     filterType = FilterType.values()[buffer.get()];
     value = ReadWriteIOUtils.readString(buffer);
+    not = ReadWriteIOUtils.readBool(buffer);
   }
 
   @Override
   public String toString() {
-    return filterType + " is " + value;
+    return filterType + (not ? " not like " : " like ") + value;
   }
 
   @Override

Reply via email to