You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by zy...@apache.org on 2024/04/28 04:17:29 UTC

(iotdb) 04/07: refactor expression to filter via visitor

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

zyk pushed a commit to branch table-model-debug
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 2adf50bbffae2de02fde0693c1bf2c6e7cba1777
Author: MarcosZyk <15...@qq.com>
AuthorDate: Sun Apr 28 11:20:32 2024 +0800

    refactor expression to filter via visitor
---
 .../ConvertSchemaPredicateToFilterVisitor.java     | 167 +++++++++++++++++++++
 .../analyzer/schema/TableModelSchemaFetcher.java   |  96 +-----------
 2 files changed, 175 insertions(+), 88 deletions(-)

diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertSchemaPredicateToFilterVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertSchemaPredicateToFilterVisitor.java
new file mode 100644
index 00000000000..1e9f116d3e2
--- /dev/null
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertSchemaPredicateToFilterVisitor.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.relational.analyzer.predicate;
+
+import org.apache.iotdb.commons.schema.filter.SchemaFilter;
+import org.apache.iotdb.commons.schema.filter.impl.DeviceAttributeFilter;
+import org.apache.iotdb.commons.schema.filter.impl.DeviceIdFilter;
+import org.apache.iotdb.commons.schema.filter.impl.OrFilter;
+import org.apache.iotdb.commons.schema.table.TsTable;
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
+import org.apache.iotdb.db.relational.sql.tree.BetweenPredicate;
+import org.apache.iotdb.db.relational.sql.tree.ComparisonExpression;
+import org.apache.iotdb.db.relational.sql.tree.Identifier;
+import org.apache.iotdb.db.relational.sql.tree.IfExpression;
+import org.apache.iotdb.db.relational.sql.tree.InPredicate;
+import org.apache.iotdb.db.relational.sql.tree.IsNotNullPredicate;
+import org.apache.iotdb.db.relational.sql.tree.IsNullPredicate;
+import org.apache.iotdb.db.relational.sql.tree.LikePredicate;
+import org.apache.iotdb.db.relational.sql.tree.Literal;
+import org.apache.iotdb.db.relational.sql.tree.LogicalExpression;
+import org.apache.iotdb.db.relational.sql.tree.NotExpression;
+import org.apache.iotdb.db.relational.sql.tree.NullIfExpression;
+import org.apache.iotdb.db.relational.sql.tree.SearchedCaseExpression;
+import org.apache.iotdb.db.relational.sql.tree.SimpleCaseExpression;
+import org.apache.iotdb.db.relational.sql.tree.StringLiteral;
+import org.apache.iotdb.db.relational.sql.tree.SymbolReference;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ConvertSchemaPredicateToFilterVisitor
+    extends PredicateVisitor<SchemaFilter, ConvertSchemaPredicateToFilterVisitor.Context> {
+
+  @Override
+  protected SchemaFilter visitInPredicate(InPredicate node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitIsNullPredicate(IsNullPredicate node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitIsNotNullPredicate(IsNotNullPredicate node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitLikePredicate(LikePredicate node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitLogicalExpression(LogicalExpression node, Context context) {
+    // the operator of the logical expression shall be OR
+    return new OrFilter(
+        node.getTerms().get(0).accept(this, context), node.getTerms().get(1).accept(this, context));
+  }
+
+  @Override
+  protected SchemaFilter visitNotExpression(NotExpression node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitComparisonExpression(ComparisonExpression node, Context context) {
+    String columnName;
+    String value;
+    if (node.getLeft() instanceof Literal) {
+      value = ((StringLiteral) (node.getLeft())).getValue();
+      if (node.getRight() instanceof Identifier) {
+        columnName = ((Identifier) (node.getRight())).getValue();
+      } else {
+        columnName = ((SymbolReference) (node.getRight())).getName();
+      }
+    } else {
+      value = ((StringLiteral) (node.getRight())).getValue();
+      if (node.getLeft() instanceof Identifier) {
+        columnName = ((Identifier) (node.getLeft())).getValue();
+      } else {
+        columnName = ((SymbolReference) (node.getLeft())).getName();
+      }
+    }
+    if (context
+        .table
+        .getColumnSchema(columnName)
+        .getColumnCategory()
+        .equals(TsTableColumnCategory.ID)) {
+      return new DeviceIdFilter(context.idColumeIndexMap.get(columnName), value);
+    } else {
+      return new DeviceAttributeFilter(columnName, value);
+    }
+  }
+
+  @Override
+  protected SchemaFilter visitSimpleCaseExpression(SimpleCaseExpression node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitSearchedCaseExpression(SearchedCaseExpression node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitIfExpression(IfExpression node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitNullIfExpression(NullIfExpression node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  @Override
+  protected SchemaFilter visitBetweenPredicate(BetweenPredicate node, Context context) {
+    return visitExpression(node, context);
+  }
+
+  public static class Context {
+
+    private final TsTable table;
+    private final Map<String, Integer> idColumeIndexMap;
+
+    private final List<SchemaFilter> idDeterminedFilters = new ArrayList<>();
+    private final List<SchemaFilter> idFuzzyFilters = new ArrayList<>();
+
+    public Context(TsTable table) {
+      this.table = table;
+      this.idColumeIndexMap = getIdColumnIndex(table);
+    }
+
+    private Map<String, Integer> getIdColumnIndex(TsTable table) {
+      Map<String, Integer> map = new HashMap<>();
+      List<TsTableColumnSchema> columnSchemaList = table.getColumnList();
+      int idIndex = 0;
+      for (TsTableColumnSchema columnSchema : columnSchemaList) {
+        if (columnSchema.getColumnCategory().equals(TsTableColumnCategory.ID)) {
+          map.put(columnSchema.getColumnName(), idIndex);
+          idIndex++;
+        }
+      }
+      return map;
+    }
+  }
+}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/schema/TableModelSchemaFetcher.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/schema/TableModelSchemaFetcher.java
index 231708e71b8..62557581979 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/schema/TableModelSchemaFetcher.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/schema/TableModelSchemaFetcher.java
@@ -22,8 +22,6 @@ package org.apache.iotdb.db.queryengine.plan.relational.analyzer.schema;
 import org.apache.iotdb.commons.exception.IoTDBException;
 import org.apache.iotdb.commons.schema.filter.SchemaFilter;
 import org.apache.iotdb.commons.schema.filter.SchemaFilterType;
-import org.apache.iotdb.commons.schema.filter.impl.DeviceAttributeFilter;
-import org.apache.iotdb.commons.schema.filter.impl.DeviceIdFilter;
 import org.apache.iotdb.commons.schema.filter.impl.OrFilter;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
@@ -38,16 +36,11 @@ import org.apache.iotdb.db.queryengine.plan.analyze.ClusterPartitionFetcher;
 import org.apache.iotdb.db.queryengine.plan.analyze.QueryType;
 import org.apache.iotdb.db.queryengine.plan.analyze.schema.ClusterSchemaFetcher;
 import org.apache.iotdb.db.queryengine.plan.execution.ExecutionResult;
+import org.apache.iotdb.db.queryengine.plan.relational.analyzer.predicate.ConvertSchemaPredicateToFilterVisitor;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.DeviceEntry;
 import org.apache.iotdb.db.queryengine.plan.statement.internal.CreateTableDeviceStatement;
 import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowTableDevicesStatement;
-import org.apache.iotdb.db.relational.sql.tree.ComparisonExpression;
 import org.apache.iotdb.db.relational.sql.tree.Expression;
-import org.apache.iotdb.db.relational.sql.tree.Identifier;
-import org.apache.iotdb.db.relational.sql.tree.Literal;
-import org.apache.iotdb.db.relational.sql.tree.LogicalExpression;
-import org.apache.iotdb.db.relational.sql.tree.StringLiteral;
-import org.apache.iotdb.db.relational.sql.tree.SymbolReference;
 import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
 import org.apache.iotdb.rpc.TSStatusCode;
 
@@ -199,27 +192,18 @@ public class TableModelSchemaFetcher {
       List<Expression> expressionList, TsTable table) {
     List<SchemaFilter> idDeterminedFilters = new ArrayList<>();
     List<SchemaFilter> idFuzzyFilters = new ArrayList<>();
-    Map<String, Integer> indexMap = getIdColumnIndex(table);
+    ConvertSchemaPredicateToFilterVisitor visitor = new ConvertSchemaPredicateToFilterVisitor();
+    ConvertSchemaPredicateToFilterVisitor.Context context =
+        new ConvertSchemaPredicateToFilterVisitor.Context(table);
     for (Expression expression : expressionList) {
       if (expression == null) {
         continue;
       }
-      if (expression instanceof LogicalExpression) {
-        LogicalExpression logicalExpression = (LogicalExpression) expression;
-        SchemaFilter schemaFilter = transformToSchemaFilter(logicalExpression, table, indexMap);
-        if (hasAttribute(schemaFilter)) {
-          idFuzzyFilters.add(schemaFilter);
-        } else {
-          idDeterminedFilters.add(schemaFilter);
-        }
+      SchemaFilter schemaFilter = expression.accept(visitor, context);
+      if (hasAttribute(schemaFilter)) {
+        idFuzzyFilters.add(schemaFilter);
       } else {
-        SchemaFilter schemaFilter =
-            transformToSchemaFilter((ComparisonExpression) expression, table, indexMap);
-        if (schemaFilter.getSchemaFilterType().equals(SchemaFilterType.DEVICE_ATTRIBUTE)) {
-          idFuzzyFilters.add(schemaFilter);
-        } else {
-          idDeterminedFilters.add(schemaFilter);
-        }
+        idDeterminedFilters.add(schemaFilter);
       }
     }
     return new Pair<>(idDeterminedFilters, idFuzzyFilters);
@@ -233,68 +217,4 @@ public class TableModelSchemaFetcher {
 
     return schemaFilter.getSchemaFilterType().equals(SchemaFilterType.DEVICE_ATTRIBUTE);
   }
-
-  private SchemaFilter transformToSchemaFilter(
-      LogicalExpression logicalExpression, TsTable table, Map<String, Integer> indexMap) {
-    SchemaFilter left;
-    SchemaFilter right;
-    if (logicalExpression.getTerms().get(0) instanceof LogicalExpression) {
-      left =
-          transformToSchemaFilter(
-              (LogicalExpression) (logicalExpression.getChildren().get(0)), table, indexMap);
-    } else {
-      left =
-          transformToSchemaFilter(
-              (ComparisonExpression) (logicalExpression.getChildren().get(0)), table, indexMap);
-    }
-    if (logicalExpression.getTerms().get(1) instanceof LogicalExpression) {
-      right =
-          transformToSchemaFilter(
-              (LogicalExpression) (logicalExpression.getChildren().get(1)), table, indexMap);
-    } else {
-      right =
-          transformToSchemaFilter(
-              (ComparisonExpression) (logicalExpression.getChildren().get(1)), table, indexMap);
-    }
-    return new OrFilter(left, right);
-  }
-
-  private SchemaFilter transformToSchemaFilter(
-      ComparisonExpression comparisonExpression, TsTable table, Map<String, Integer> indexMap) {
-    String columnName;
-    String value;
-    if (comparisonExpression.getLeft() instanceof Literal) {
-      value = ((StringLiteral) (comparisonExpression.getLeft())).getValue();
-      if (comparisonExpression.getRight() instanceof Identifier) {
-        columnName = ((Identifier) (comparisonExpression.getRight())).getValue();
-      } else {
-        columnName = ((SymbolReference) (comparisonExpression.getRight())).getName();
-      }
-    } else {
-      value = ((StringLiteral) (comparisonExpression.getRight())).getValue();
-      if (comparisonExpression.getLeft() instanceof Identifier) {
-        columnName = ((Identifier) (comparisonExpression.getLeft())).getValue();
-      } else {
-        columnName = ((SymbolReference) (comparisonExpression.getLeft())).getName();
-      }
-    }
-    if (table.getColumnSchema(columnName).getColumnCategory().equals(TsTableColumnCategory.ID)) {
-      return new DeviceIdFilter(indexMap.get(columnName), value);
-    } else {
-      return new DeviceAttributeFilter(columnName, value);
-    }
-  }
-
-  private Map<String, Integer> getIdColumnIndex(TsTable table) {
-    Map<String, Integer> map = new HashMap<>();
-    List<TsTableColumnSchema> columnSchemaList = table.getColumnList();
-    int idIndex = 0;
-    for (TsTableColumnSchema columnSchema : columnSchemaList) {
-      if (columnSchema.getColumnCategory().equals(TsTableColumnCategory.ID)) {
-        map.put(columnSchema.getColumnName(), idIndex);
-        idIndex++;
-      }
-    }
-    return map;
-  }
 }