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

caogaofei pushed a commit to branch ty/TableModelGrammar
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/ty/TableModelGrammar by this 
push:
     new 219286825a1 add where filter impl for table model
219286825a1 is described below

commit 219286825a15b7c33b9a57eeeeebe9de80e9b0eb
Author: Beyyes <[email protected]>
AuthorDate: Sun Apr 21 21:39:33 2024 +0800

    add where filter impl for table model
---
 .../relational/ColumnTransformerBuilder.java       | 82 ++++++++++++----------
 .../plan/planner/TableOperatorGenerator.java       |  1 +
 .../plan/relational/planner/PlanBuilder.java       | 63 +++++++++++++----
 .../plan/relational/planner/QueryPlanner.java      |  3 +-
 .../TableModelTypeProviderExtractor.java           |  6 ++
 .../planner/optimizations/IndexScan.java           |  1 +
 6 files changed, 105 insertions(+), 51 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
index f94c44c0205..5f1c4544e44 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
@@ -297,44 +297,50 @@ public class ColumnTransformerBuilder
   @Override
   protected ColumnTransformer visitComparisonExpression(
       ComparisonExpression node, Context context) {
-    ColumnTransformer res =
-        context.cache.computeIfAbsent(
-            node,
-            n -> {
-              if (context.hasSeen.containsKey(node)) {
-                IdentityColumnTransformer identity =
-                    new IdentityColumnTransformer(
-                        BOOLEAN, context.originSize + 
context.commonTransformerList.size());
-                ColumnTransformer columnTransformer = 
context.hasSeen.get(node);
-                columnTransformer.addReferenceCount();
-                context.commonTransformerList.add(columnTransformer);
-                context.leafList.add(identity);
-                context.inputDataTypes.add(TSDataType.BOOLEAN);
-                return identity;
-              } else {
-                ColumnTransformer left = process(node.getLeft(), context);
-                ColumnTransformer right = process(node.getRight(), context);
-                switch (node.getOperator()) {
-                  case EQUAL:
-                    return new CompareEqualToColumnTransformer(BOOLEAN, left, 
right);
-                  case NOT_EQUAL:
-                    return new CompareNonEqualColumnTransformer(BOOLEAN, left, 
right);
-                  case GREATER_THAN:
-                    return new CompareGreaterThanColumnTransformer(BOOLEAN, 
left, right);
-                  case GREATER_THAN_OR_EQUAL:
-                    return new CompareGreaterEqualColumnTransformer(BOOLEAN, 
left, right);
-                  case LESS_THAN:
-                    return new CompareLessThanColumnTransformer(BOOLEAN, left, 
right);
-                  case LESS_THAN_OR_EQUAL:
-                    return new CompareLessEqualColumnTransformer(BOOLEAN, 
left, right);
-                  default:
-                    throw new UnsupportedOperationException(
-                        String.format(UNSUPPORTED_EXPRESSION, 
node.getOperator()));
-                }
-              }
-            });
-    res.addReferenceCount();
-    return res;
+    // fixme why using computeIfAbsent throw npe
+    ColumnTransformer comparisonTransformer;
+    if (!context.cache.containsKey(node)) {
+      comparisonTransformer = getColumnTransformer(node, context);
+    } else {
+      comparisonTransformer = getColumnTransformer(node, context);
+      context.cache.put(node, comparisonTransformer);
+    }
+    comparisonTransformer.addReferenceCount();
+    return comparisonTransformer;
+  }
+
+  private ColumnTransformer getColumnTransformer(ComparisonExpression node, 
Context context) {
+    if (context.hasSeen.containsKey(node)) {
+      IdentityColumnTransformer identity =
+          new IdentityColumnTransformer(
+              BOOLEAN, context.originSize + 
context.commonTransformerList.size());
+      ColumnTransformer columnTransformer = context.hasSeen.get(node);
+      columnTransformer.addReferenceCount();
+      context.commonTransformerList.add(columnTransformer);
+      context.leafList.add(identity);
+      context.inputDataTypes.add(TSDataType.BOOLEAN);
+      return identity;
+    } else {
+      ColumnTransformer left = process(node.getLeft(), context);
+      ColumnTransformer right = process(node.getRight(), context);
+      switch (node.getOperator()) {
+        case EQUAL:
+          return new CompareEqualToColumnTransformer(BOOLEAN, left, right);
+        case NOT_EQUAL:
+          return new CompareNonEqualColumnTransformer(BOOLEAN, left, right);
+        case GREATER_THAN:
+          return new CompareGreaterThanColumnTransformer(BOOLEAN, left, right);
+        case GREATER_THAN_OR_EQUAL:
+          return new CompareGreaterEqualColumnTransformer(BOOLEAN, left, 
right);
+        case LESS_THAN:
+          return new CompareLessThanColumnTransformer(BOOLEAN, left, right);
+        case LESS_THAN_OR_EQUAL:
+          return new CompareLessEqualColumnTransformer(BOOLEAN, left, right);
+        default:
+          throw new UnsupportedOperationException(
+              String.format(UNSUPPORTED_EXPRESSION, node.getOperator()));
+      }
+    }
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
index ad548923e45..741a2582e34 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
@@ -425,6 +425,7 @@ public class TableOperatorGenerator extends 
PlanVisitor<Operator, LocalExecution
     return node.getChildren().stream()
         .map(PlanNode::getOutputSymbols)
         .flatMap(List::stream)
+        .filter(s -> 
!TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(s.getName()))
         .map(s -> getTSDataType(typeProvider.getTableModelType(s)))
         .collect(Collectors.toList());
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/PlanBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/PlanBuilder.java
index 34758694318..21254c1d9ea 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/PlanBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/PlanBuilder.java
@@ -17,10 +17,15 @@ import org.apache.iotdb.db.queryengine.common.QueryId;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Analysis;
+import org.apache.iotdb.db.queryengine.plan.relational.analyzer.NodeRef;
+import org.apache.iotdb.db.queryengine.plan.relational.analyzer.ResolvedField;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Scope;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.ProjectNode;
+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.FieldReference;
+import org.apache.iotdb.db.relational.sql.tree.Identifier;
+import org.apache.iotdb.db.relational.sql.tree.SymbolReference;
 
 import com.google.common.collect.ImmutableMap;
 
@@ -28,6 +33,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 import static com.google.common.base.Verify.verify;
@@ -37,13 +43,16 @@ public class PlanBuilder {
 
   private final PlanNode root;
 
+  private final Analysis analysis;
+
   // current mappings of underlying field -> symbol for translating direct 
field references
   private final Symbol[] fieldSymbols;
 
-  public PlanBuilder(PlanNode root, Symbol[] fieldSymbols) {
+  public PlanBuilder(PlanNode root, Analysis analysis, Symbol[] fieldSymbols) {
     requireNonNull(root, "root is null");
 
     this.root = root;
+    this.analysis = analysis;
     this.fieldSymbols = fieldSymbols;
   }
 
@@ -57,15 +66,16 @@ public class PlanBuilder {
       Analysis analysis,
       Map<ScopeAware<Expression>, Symbol> mappings,
       SessionInfo session) {
-    return new PlanBuilder(plan.getRoot(), plan.getFieldMappings().toArray(new 
Symbol[0]));
+    return new PlanBuilder(
+        plan.getRoot(), analysis, plan.getFieldMappings().toArray(new 
Symbol[0]));
   }
 
   public PlanBuilder withNewRoot(PlanNode root) {
-    return new PlanBuilder(root, fieldSymbols);
+    return new PlanBuilder(root, this.analysis, this.fieldSymbols);
   }
 
   public PlanBuilder withScope(Scope scope, List<Symbol> fields) {
-    return new PlanBuilder(root, fields.toArray(new Symbol[0]));
+    return new PlanBuilder(root, this.analysis, fields.toArray(new Symbol[0]));
   }
 
   public PlanNode getRoot() {
@@ -76,22 +86,49 @@ public class PlanBuilder {
     return this.fieldSymbols;
   }
 
-  public Symbol translate(Analysis analysis, Expression expression) {
+  public Expression rewrite(Expression root, boolean isRoot) {
     verify(
-        analysis.isAnalyzed(expression),
+        analysis.isAnalyzed(root),
         "Expression is not analyzed (%s): %s",
-        expression.getClass().getName(),
-        expression);
-    Expression ret = translate(expression, true);
-    return Symbol.from(ret);
+        root.getClass().getName(),
+        root);
+    return translate(root, isRoot);
   }
 
   private Expression translate(Expression expression, boolean isRoot) {
-    if (expression instanceof FieldReference) {}
+    // TODO add more translate expressions impl
+    if (expression instanceof FieldReference) {
+      return new 
SymbolReference(getSymbolForColumn(expression).get().getName());
+    } else if (expression instanceof ComparisonExpression) {
+      ComparisonExpression comparisonExpression = (ComparisonExpression) 
expression;
+      Expression left = translate(comparisonExpression.getLeft(), false);
+      Expression right = translate(comparisonExpression.getRight(), false);
+      return new ComparisonExpression(comparisonExpression.getOperator(), 
left, right);
+    } else if (expression instanceof Identifier) {
+      return 
getSymbolForColumn(expression).map(Symbol::toSymbolReference).get();
+    }
 
     return expression;
   }
 
+  private Optional<Symbol> getSymbolForColumn(Expression expression) {
+    if (!analysis.isColumnReference(expression)) {
+      // Expression can be a reference to lambda argument (or 
DereferenceExpression based on lambda
+      // argument reference).
+      // In such case, the expression might still be resolvable with 
plan.getScope() but we should
+      // not resolve it.
+      return Optional.empty();
+    }
+
+    ResolvedField field = 
analysis.getColumnReferenceFields().get(NodeRef.of(expression));
+
+    if (field != null) {
+      return Optional.of(fieldSymbols[field.getHierarchyFieldIndex()]);
+    }
+
+    return Optional.empty();
+  }
+
   public <T extends Expression> PlanBuilder appendProjections(
       Iterable<T> expressions,
       Analysis analysis,
@@ -122,6 +159,8 @@ public class PlanBuilder {
     }
 
     return new PlanBuilder(
-        new ProjectNode(idAllocator.genPlanNodeId(), root, 
projections.build()), fieldSymbols);
+        new ProjectNode(idAllocator.genPlanNodeId(), this.root, 
projections.build()),
+        this.analysis,
+        this.fieldSymbols);
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/QueryPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/QueryPlanner.java
index aefdf7e7e23..48182677f15 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/QueryPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/QueryPlanner.java
@@ -248,7 +248,8 @@ public class QueryPlanner {
     analysis.setGlobalTableModelTimePredicate(globalTimePredicate);
 
     return subPlan.withNewRoot(
-        new FilterNode(idAllocator.genPlanNodeId(), subPlan.getRoot(), 
predicate));
+        new FilterNode(
+            idAllocator.genPlanNodeId(), subPlan.getRoot(), 
subPlan.rewrite(predicate, true)));
 
     // subPlan = subqueryPlanner.handleSubqueries(subPlan, predicate, 
analysis.getSubqueries(node));
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableModelTypeProviderExtractor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableModelTypeProviderExtractor.java
index 4077642ab4e..2ac38f8b0da 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableModelTypeProviderExtractor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableModelTypeProviderExtractor.java
@@ -17,11 +17,14 @@ package 
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute;
 import org.apache.iotdb.db.queryengine.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.SimplePlanVisitor;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.FilterNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.OutputNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.ProjectNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode;
 
+import org.apache.tsfile.read.common.type.BooleanType;
+
 import java.util.HashMap;
 
 public class TableModelTypeProviderExtractor {
@@ -69,6 +72,9 @@ public class TableModelTypeProviderExtractor {
     @Override
     public Void visitFilter(FilterNode node, Void context) {
       node.getChild().accept(this, context);
+      // fixme toString method of expression is not expected
+      typeProvider.putTableModelType(
+          new Symbol(node.getPredicate().toString()), BooleanType.BOOLEAN);
       return null;
     }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/IndexScan.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/IndexScan.java
index 0307f9bb0fe..c704b5e8000 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/IndexScan.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/IndexScan.java
@@ -83,6 +83,7 @@ public class IndexScan implements RelationalPlanOptimizer {
     @Override
     public PlanNode visitFilter(FilterNode node, RewriterContext context) {
       context.setPredicate(node.getPredicate());
+      node.getChild().accept(this, context);
       return node;
     }
 

Reply via email to