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;
}