This is an automated email from the ASF dual-hosted git repository. caogaofei pushed a commit to branch beyyes/debug-table in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 07f1b47caddd8ef9aa9e89d6cefefbacae98be2a Author: Beyyes <[email protected]> AuthorDate: Tue Apr 23 18:49:46 2024 +0800 make TypeProvider of tree model and table model clear; add TableModelTypeProviderExtractor, ExpressionTranslateVisitor; make select projection expression available --- .../execution/operator/AggregationUtil.java | 2 +- .../relational/ColumnTransformerBuilder.java | 74 ++++++------ .../db/queryengine/plan/analyze/TypeProvider.java | 80 +++++++------ .../visitor/ColumnTransformerVisitor.java | 2 +- .../predicate/ConvertPredicateToFilterVisitor.java | 2 +- .../plan/planner/LogicalPlanBuilder.java | 24 ++-- .../plan/planner/LogicalPlanVisitor.java | 6 +- .../plan/planner/OperatorTreeGenerator.java | 20 ++-- .../plan/planner/SubPlanTypeExtractor.java | 11 +- .../plan/planner/TableOperatorGenerator.java | 12 +- .../plan/planner/TemplatedLogicalPlan.java | 4 +- .../plan/planner/distribution/SourceRewriter.java | 2 +- .../plan/relational/planner/LogicalPlanner.java | 12 +- .../plan/relational/planner/PlanBuilder.java | 74 ++++-------- .../plan/relational/planner/QueryPlanner.java | 83 +++++++------- .../plan/relational/planner/RelationPlanner.java | 13 ++- .../TableModelTypeProviderExtractor.java | 46 +++++--- .../planner/ir/ExpressionTranslateVisitor.java | 127 +++++++++++++++++++++ .../planner/optimizations/IndexScan.java | 10 +- .../execution/operator/OperatorMemoryTest.java | 18 +-- .../plan/planner/PipelineBuilderTest.java | 22 ++-- 21 files changed, 392 insertions(+), 252 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/AggregationUtil.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/AggregationUtil.java index d8b835f96c6..3cce822ac41 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/AggregationUtil.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/AggregationUtil.java @@ -217,7 +217,7 @@ public class AggregationUtil { for (AggregationDescriptor descriptor : aggregationDescriptors) { List<TSDataType> outPutDataTypes = descriptor.getOutputColumnNames().stream() - .map(typeProvider::getType) + .map(typeProvider::getTreeModelType) .collect(Collectors.toList()); for (TSDataType tsDataType : outPutDataTypes) { timeValueColumnsSizePerLine += getOutputColumnSizePerLine(tsDataType); 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 577ef24121c..fec63e63cdf 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 @@ -118,44 +118,50 @@ public class ColumnTransformerBuilder @Override protected ColumnTransformer visitArithmeticBinary( ArithmeticBinaryExpression node, Context context) { - ColumnTransformer res = - context.cache.computeIfAbsent( - node, - n -> { - if (context.hasSeen.containsKey(node)) { - IdentityColumnTransformer identity = - new IdentityColumnTransformer( - DOUBLE, 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.DOUBLE); - return identity; - } else { - ColumnTransformer left = process(node.getLeft(), context); - ColumnTransformer right = process(node.getRight(), context); - switch (node.getOperator()) { - case ADD: - return new ArithmeticAdditionColumnTransformer(DOUBLE, left, right); - case SUBTRACT: - return new ArithmeticSubtractionColumnTransformer(DOUBLE, left, right); - case MULTIPLY: - return new ArithmeticMultiplicationColumnTransformer(DOUBLE, left, right); - case DIVIDE: - return new ArithmeticDivisionColumnTransformer(DOUBLE, left, right); - case MODULUS: - return new ArithmeticModuloColumnTransformer(DOUBLE, left, right); - default: - throw new UnsupportedOperationException( - String.format(UNSUPPORTED_EXPRESSION, node.getOperator())); - } - } - }); + ColumnTransformer res; + if (context.cache.containsKey(node)) { + res = context.cache.get(node); + } else { + res = getArithmeticBinaryTransformer(node, context); + context.cache.put(node, res); + } res.addReferenceCount(); return res; } + private ColumnTransformer getArithmeticBinaryTransformer( + ArithmeticBinaryExpression node, Context context) { + if (context.hasSeen.containsKey(node)) { + IdentityColumnTransformer identity = + new IdentityColumnTransformer( + DOUBLE, 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.DOUBLE); + return identity; + } else { + ColumnTransformer left = process(node.getLeft(), context); + ColumnTransformer right = process(node.getRight(), context); + switch (node.getOperator()) { + case ADD: + return new ArithmeticAdditionColumnTransformer(DOUBLE, left, right); + case SUBTRACT: + return new ArithmeticSubtractionColumnTransformer(DOUBLE, left, right); + case MULTIPLY: + return new ArithmeticMultiplicationColumnTransformer(DOUBLE, left, right); + case DIVIDE: + return new ArithmeticDivisionColumnTransformer(DOUBLE, left, right); + case MODULUS: + return new ArithmeticModuloColumnTransformer(DOUBLE, left, right); + default: + throw new UnsupportedOperationException( + String.format(UNSUPPORTED_EXPRESSION, node.getOperator())); + } + } + } + @Override protected ColumnTransformer visitArithmeticUnary( ArithmeticUnaryExpression node, Context context) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TypeProvider.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TypeProvider.java index 2ac23332cbe..39945fc27ca 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TypeProvider.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TypeProvider.java @@ -42,36 +42,35 @@ import static org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOper public class TypeProvider { - private final Map<String, TSDataType> typeMap; + private final Map<String, TSDataType> treeModelTypeMap; private TemplatedInfo templatedInfo; public TypeProvider() { - this.typeMap = new HashMap<>(); - types = null; + this.treeModelTypeMap = new HashMap<>(); } - public TypeProvider(Map<String, TSDataType> typeMap, TemplatedInfo templatedInfo) { - this.typeMap = typeMap; + public TypeProvider(Map<String, TSDataType> treeModelTypeMap, TemplatedInfo templatedInfo) { + this.treeModelTypeMap = treeModelTypeMap; this.templatedInfo = templatedInfo; // The type of TimeStampOperand is INT64 - this.typeMap.putIfAbsent(TIMESTAMP_EXPRESSION_STRING, TSDataType.INT64); - types = null; + this.treeModelTypeMap.putIfAbsent(TIMESTAMP_EXPRESSION_STRING, TSDataType.INT64); + this.tableModelTypes = null; } - public TSDataType getType(String symbol) { - return typeMap.get(symbol); + public TSDataType getTreeModelType(String symbol) { + return treeModelTypeMap.get(symbol); } - public void setType(String symbol, TSDataType dataType) { + public void setTreeModelType(String symbol, TSDataType dataType) { // DataType of NullOperand is null, we needn't put it into TypeProvider if (dataType != null) { - this.typeMap.put(symbol, dataType); + this.treeModelTypeMap.put(symbol, dataType); } } - public Map<String, TSDataType> getTypeMap() { - return this.typeMap; + public Map<String, TSDataType> getTreeModelTypeMap() { + return this.treeModelTypeMap; } public void setTemplatedInfo(TemplatedInfo templatedInfo) { @@ -84,7 +83,7 @@ public class TypeProvider { // ----------------------used for relational model---------------------------- - private final Map<Symbol, Type> types; + private Map<Symbol, Type> tableModelTypes = new HashMap<>(); public static TypeProvider viewOf(Map<Symbol, Type> types) { return new TypeProvider(types); @@ -98,43 +97,50 @@ public class TypeProvider { return new TypeProvider(ImmutableMap.of()); } - public TypeProvider(Map<Symbol, Type> types) { - this.types = types; + public TypeProvider(Map<Symbol, Type> tableModelTypes) { + this.tableModelTypes = tableModelTypes; - this.typeMap = null; + this.treeModelTypeMap = null; } public TypeProvider( - Map<String, TSDataType> typeMap, TemplatedInfo templatedInfo, Map<Symbol, Type> types) { - this.typeMap = typeMap; + Map<String, TSDataType> treeModelTypeMap, + TemplatedInfo templatedInfo, + Map<Symbol, Type> tableModelTypes) { + this.treeModelTypeMap = treeModelTypeMap; this.templatedInfo = templatedInfo; - this.types = types; + + this.tableModelTypes = tableModelTypes; } public Type getTableModelType(Symbol symbol) { requireNonNull(symbol, "symbol is null"); - Type type = types.get(symbol); - checkArgument(type != null, "no type found for symbol '%s'", symbol); + Type type = tableModelTypes.get(symbol); + checkArgument(type != null, "no type found for symbol '%s' in TypeProvider", symbol); return type; } + public boolean isSymbolExist(Symbol symbol) { + return tableModelTypes.containsKey(symbol); + } + public void putTableModelType(Symbol symbol, Type type) { requireNonNull(symbol, "symbol is null"); - types.put(symbol, type); + tableModelTypes.put(symbol, type); } - public Map<Symbol, Type> allTypes() { + public Map<Symbol, Type> allTableModelTypes() { // types may be a HashMap, so creating an ImmutableMap here would add extra cost when allTypes // gets called frequently - return Collections.unmodifiableMap(types); + return Collections.unmodifiableMap(tableModelTypes); } public void serialize(ByteBuffer byteBuffer) { - ReadWriteIOUtils.write(typeMap.size(), byteBuffer); - for (Map.Entry<String, TSDataType> entry : typeMap.entrySet()) { + ReadWriteIOUtils.write(treeModelTypeMap.size(), byteBuffer); + for (Map.Entry<String, TSDataType> entry : treeModelTypeMap.entrySet()) { ReadWriteIOUtils.write(entry.getKey(), byteBuffer); ReadWriteIOUtils.write(entry.getValue().ordinal(), byteBuffer); } @@ -146,11 +152,11 @@ public class TypeProvider { templatedInfo.serialize(byteBuffer); } - if (types == null) { + if (tableModelTypes == null) { ReadWriteIOUtils.write((byte) 0, byteBuffer); } else { - ReadWriteIOUtils.write(types.size(), byteBuffer); - for (Map.Entry<Symbol, Type> entry : types.entrySet()) { + ReadWriteIOUtils.write(tableModelTypes.size(), byteBuffer); + for (Map.Entry<Symbol, Type> entry : tableModelTypes.entrySet()) { ReadWriteIOUtils.write(entry.getKey().getName(), byteBuffer); ReadWriteIOUtils.write(entry.getValue().getTypeEnum().ordinal(), byteBuffer); } @@ -158,8 +164,8 @@ public class TypeProvider { } public void serialize(DataOutputStream stream) throws IOException { - ReadWriteIOUtils.write(typeMap.size(), stream); - for (Map.Entry<String, TSDataType> entry : typeMap.entrySet()) { + ReadWriteIOUtils.write(treeModelTypeMap.size(), stream); + for (Map.Entry<String, TSDataType> entry : treeModelTypeMap.entrySet()) { ReadWriteIOUtils.write(entry.getKey(), stream); ReadWriteIOUtils.write(entry.getValue().ordinal(), stream); } @@ -171,11 +177,11 @@ public class TypeProvider { templatedInfo.serialize(stream); } - if (types == null) { + if (tableModelTypes == null) { ReadWriteIOUtils.write((byte) 0, stream); } else { - ReadWriteIOUtils.write(types.size(), stream); - for (Map.Entry<Symbol, Type> entry : types.entrySet()) { + ReadWriteIOUtils.write(tableModelTypes.size(), stream); + for (Map.Entry<Symbol, Type> entry : tableModelTypes.entrySet()) { ReadWriteIOUtils.write(entry.getKey().getName(), stream); ReadWriteIOUtils.write(entry.getValue().getTypeEnum().ordinal(), stream); } @@ -223,11 +229,11 @@ public class TypeProvider { return false; } TypeProvider that = (TypeProvider) o; - return Objects.equals(typeMap, that.typeMap); + return Objects.equals(treeModelTypeMap, that.treeModelTypeMap); } @Override public int hashCode() { - return Objects.hash(typeMap); + return Objects.hash(treeModelTypeMap); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java index 09da66f3d9c..e537d7fc763 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java @@ -579,7 +579,7 @@ public class ColumnTransformerVisitor public TSDataType getType(Expression expression) { if (typeProvider != null) { - return typeProvider.getType(expression.getOutputSymbol()); + return typeProvider.getTreeModelType(expression.getOutputSymbol()); } return expressionTypes.get(NodeRef.of(expression)); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ConvertPredicateToFilterVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ConvertPredicateToFilterVisitor.java index eb4a5ceebfe..69afeaa7a71 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ConvertPredicateToFilterVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ConvertPredicateToFilterVisitor.java @@ -400,7 +400,7 @@ public class ConvertPredicateToFilterVisitor if (isBuildPlanUseTemplate) { return schemaMap.get(path.getFullPath()).getType(); } else { - return typeProvider.getType(path.getFullPath()); + return typeProvider.getTreeModelType(path.getFullPath()); } } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java index 1d31828c51b..10b92fe5985 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java @@ -171,7 +171,7 @@ public class LogicalPlanBuilder { && !expression.getExpressionString().equals(ENDTIME)) { context .getTypeProvider() - .setType(expression.getExpressionString(), getPreAnalyzedType(expression)); + .setTreeModelType(expression.getExpressionString(), getPreAnalyzedType(expression)); } }); } @@ -180,11 +180,11 @@ public class LogicalPlanBuilder { if (keys == null) { return; } - keys.forEach(k -> context.getTypeProvider().setType(k, dataType)); + keys.forEach(k -> context.getTypeProvider().setTreeModelType(k, dataType)); } private void updateTypeProviderWithConstantType(String columnName, TSDataType dataType) { - context.getTypeProvider().setType(columnName, dataType); + context.getTypeProvider().setTreeModelType(columnName, dataType); } public LogicalPlanBuilder planRawDataSource( @@ -349,7 +349,7 @@ public class LogicalPlanBuilder { columnHeader -> context .getTypeProvider() - .setType(columnHeader.getColumnName(), columnHeader.getColumnType())); + .setTreeModelType(columnHeader.getColumnName(), columnHeader.getColumnType())); return this; } @@ -707,7 +707,7 @@ public class LogicalPlanBuilder { // Currently UDAF only supports one input series String inputExpressionStr = aggregationDescriptor.getInputExpressions().get(0).getExpressionString(); - typeProvider.setType( + typeProvider.setTreeModelType( String.format("%s(%s)", partialAggregationNames, inputExpressionStr), aggregationType); } else { List<String> partialAggregationsNames = @@ -731,9 +731,11 @@ public class LogicalPlanBuilder { TypeProvider typeProvider, String partialAggregationName, String inputExpressionStr) { TSDataType aggregationType = SchemaUtils.getBuiltinAggregationTypeByFuncName(partialAggregationName); - typeProvider.setType( + typeProvider.setTreeModelType( String.format("%s(%s)", partialAggregationName, inputExpressionStr), - aggregationType == null ? typeProvider.getType(inputExpressionStr) : aggregationType); + aggregationType == null + ? typeProvider.getTreeModelType(inputExpressionStr) + : aggregationType); } public static void updateTypeProviderByPartialAggregation( @@ -749,13 +751,13 @@ public class LogicalPlanBuilder { // Currently UDAF only supports one input series String inputExpressionStr = aggregationDescriptor.getInputExpressions().get(0).getExpressionString(); - typeProvider.setType( + typeProvider.setTreeModelType( String.format("%s(%s)", partialAggregationNames, inputExpressionStr), aggregationType); } else { PartialPath path = ((TimeSeriesOperand) aggregationDescriptor.getOutputExpressions().get(0)).getPath(); for (String partialAggregationName : partialAggregationsNames) { - typeProvider.setType( + typeProvider.setTreeModelType( String.format("%s(%s)", partialAggregationName, path.getFullPath()), SchemaUtils.getSeriesTypeByPath(path, partialAggregationName)); } @@ -863,7 +865,7 @@ public class LogicalPlanBuilder { -1); } - context.getTypeProvider().setType(DEVICE, TSDataType.TEXT); + context.getTypeProvider().setTreeModelType(DEVICE, TSDataType.TEXT); updateTypeProvider(deviceViewOutputExpressions); if (queryStatement.needPushDownSort() @@ -1568,7 +1570,7 @@ public class LogicalPlanBuilder { columnHeader -> context .getTypeProvider() - .setType(columnHeader.getColumnName(), columnHeader.getColumnType())); + .setTreeModelType(columnHeader.getColumnName(), columnHeader.getColumnType())); return this; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java index d61ba35b164..04e119ccc8a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java @@ -144,7 +144,9 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte explainAnalyzeStatement.isVerbose(), context.getLocalQueryId(), context.getTimeOut()); - context.getTypeProvider().setType(ColumnHeaderConstant.EXPLAIN_ANALYZE, TSDataType.TEXT); + context + .getTypeProvider() + .setTreeModelType(ColumnHeaderConstant.EXPLAIN_ANALYZE, TSDataType.TEXT); return root; } @@ -289,7 +291,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte || needTransform(sourceTransformExpressions) || cannotUseStatistics(aggregationExpressions, sourceTransformExpressions); if (queryStatement.isOutputEndTime()) { - context.getTypeProvider().setType(ENDTIME, TSDataType.INT64); + context.getTypeProvider().setTreeModelType(ENDTIME, TSDataType.INT64); } AggregationStep curStep; if (isRawDataSource) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java index cc3326e2cf6..d6d1874ceed 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java @@ -1022,7 +1022,9 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP aggregationName, getAggregationTypeByFuncName(aggregationName), Collections.singletonList( - context.getTypeProvider().getType(functionExpression.getOutputSymbol())), + context + .getTypeProvider() + .getTreeModelType(functionExpression.getOutputSymbol())), functionExpression.getExpressions(), functionExpression.getFunctionAttributes(), timeAscending, @@ -1571,7 +1573,8 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP x -> context .getTypeProvider() - .getType(descriptor.getInputExpressions().get(x).getExpressionString())) + .getTreeModelType( + descriptor.getInputExpressions().get(x).getExpressionString())) .collect(Collectors.toList()); aggregators.add( new Aggregator( @@ -1631,7 +1634,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP List<InputLocation[]> inputLocations = calcInputLocationList(aggregationDescriptor, layout); List<TSDataType> inputDataTypes = aggregationDescriptor.getInputExpressions().stream() - .map(x -> context.getTypeProvider().getType(x.getExpressionString())) + .map(x -> context.getTypeProvider().getTreeModelType(x.getExpressionString())) .collect(Collectors.toList()); aggregators.add( new Aggregator( @@ -1698,7 +1701,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP descriptor.getAggregationFuncName(), descriptor.getAggregationType(), descriptor.getInputExpressions().stream() - .map(x -> context.getTypeProvider().getType(x.getExpressionString())) + .map(x -> context.getTypeProvider().getTreeModelType(x.getExpressionString())) .collect(Collectors.toList()), descriptor.getInputExpressions(), descriptor.getInputAttributes(), @@ -1771,7 +1774,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP descriptor.getAggregationFuncName(), descriptor.getAggregationType(), descriptor.getInputExpressions().stream() - .map(x -> context.getTypeProvider().getType(x.getExpressionString())) + .map(x -> context.getTypeProvider().getTreeModelType(x.getExpressionString())) .collect(Collectors.toList()), descriptor.getInputExpressions(), descriptor.getInputAttributes(), @@ -1812,7 +1815,8 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP throw new IllegalArgumentException("groupByVariationExpression can't be null"); } String controlColumn = groupByVariationExpression.getExpressionString(); - TSDataType controlColumnType = context.getTypeProvider().getType(controlColumn); + TSDataType controlColumnType = + context.getTypeProvider().getTreeModelType(controlColumn); windowParameter = new VariationWindowParameter( controlColumnType, @@ -2839,7 +2843,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP return node.getChildren().stream() .map(PlanNode::getOutputColumnNames) .flatMap(List::stream) - .map(typeProvider::getType) + .map(typeProvider::getTreeModelType) .collect(Collectors.toList()); } else { return getInputColumnTypesUseTemplate(node); @@ -2868,7 +2872,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP private List<TSDataType> getOutputColumnTypes(PlanNode node, TypeProvider typeProvider) { return node.getOutputColumnNames().stream() - .map(typeProvider::getType) + .map(typeProvider::getTreeModelType) .collect(Collectors.toList()); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/SubPlanTypeExtractor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/SubPlanTypeExtractor.java index b8efa1e3b3d..0a8cf6dc827 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/SubPlanTypeExtractor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/SubPlanTypeExtractor.java @@ -50,7 +50,7 @@ public class SubPlanTypeExtractor { public static TypeProvider extractor(PlanNode root, TypeProvider allTypes) { TypeProvider typeProvider = - new TypeProvider(allTypes.getTypeMap(), allTypes.getTemplatedInfo()); + new TypeProvider(allTypes.getTreeModelTypeMap(), allTypes.getTemplatedInfo()); root.accept(new Visitor(typeProvider, allTypes), null); return typeProvider; } @@ -68,7 +68,7 @@ public class SubPlanTypeExtractor { @Override public Void visitPlan(PlanNode node, Void context) { node.getOutputColumnNames() - .forEach(name -> typeProvider.setType(name, allTypes.getType(name))); + .forEach(name -> typeProvider.setTreeModelType(name, allTypes.getTreeModelType(name))); for (PlanNode source : node.getChildren()) { source.accept(this, context); } @@ -78,7 +78,7 @@ public class SubPlanTypeExtractor { @Override public Void visitSeriesAggregationScan(SeriesAggregationScanNode node, Void context) { String sourcePath = node.getSeriesPath().getFullPath(); - typeProvider.setType(sourcePath, allTypes.getType(sourcePath)); + typeProvider.setTreeModelType(sourcePath, allTypes.getTreeModelType(sourcePath)); return visitPlan(node, context); } @@ -88,7 +88,7 @@ public class SubPlanTypeExtractor { AlignedPath alignedPath = node.getAlignedPath(); for (int i = 0; i < alignedPath.getColumnNum(); i++) { String sourcePath = alignedPath.getPathWithMeasurement(i).getFullPath(); - typeProvider.setType(sourcePath, allTypes.getType(sourcePath)); + typeProvider.setTreeModelType(sourcePath, allTypes.getTreeModelType(sourcePath)); } return visitPlan(node, context); } @@ -200,7 +200,8 @@ public class SubPlanTypeExtractor { .forEach( expression -> { String expressionStr = expression.getExpressionString(); - typeProvider.setType(expressionStr, allTypes.getType(expressionStr)); + typeProvider.setTreeModelType( + expressionStr, allTypes.getTreeModelType(expressionStr)); }); } } 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 bd17059f141..57fbd344bd8 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 @@ -236,6 +236,7 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution Optional.of(pushDownPredicate), tableScanOperator, node.getOutputSymbols().stream() + .filter(symbol -> !TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(symbol.getName())) .map(Symbol::toSymbolReference) .toArray(Expression[]::new), tableScanOperator.getResultDataTypes(), @@ -296,7 +297,10 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution return constructFilterAndProjectOperator( predicate, inputOperator, - node.getOutputSymbols().stream().map(Symbol::toSymbolReference).toArray(Expression[]::new), + node.getOutputSymbols().stream() + .filter(symbol -> !TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(symbol.getName())) + .map(Symbol::toSymbolReference) + .toArray(Expression[]::new), inputDataTypes, inputLocations, node.getPlanNodeId(), @@ -414,7 +418,11 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution return constructFilterAndProjectOperator( predicate, inputOperator, - node.getAssignments().getExpressions().toArray(new Expression[0]), + node.getAssignments().getMap().entrySet().stream() + .filter( + entry -> !TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(entry.getKey().getName())) + .map(Map.Entry::getValue) + .toArray(Expression[]::new), inputDataTypes, inputLocations, node.getPlanNodeId(), diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TemplatedLogicalPlan.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TemplatedLogicalPlan.java index 75222efb6fc..7c8111e1f29 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TemplatedLogicalPlan.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TemplatedLogicalPlan.java @@ -117,7 +117,9 @@ public class TemplatedLogicalPlan { .getExpressionTypes() .forEach( (key, value) -> - context.getTypeProvider().setType(key.getNode().getOutputSymbol(), value)); + context + .getTypeProvider() + .setTreeModelType(key.getNode().getOutputSymbol(), value)); } context diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SourceRewriter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SourceRewriter.java index 97dfaf23fc0..0aa0014d81f 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SourceRewriter.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SourceRewriter.java @@ -259,7 +259,7 @@ public class SourceRewriter extends BaseSourceRewriter<DistributionPlanContext> context .queryContext .getTypeProvider() - .setType(partialFunctionExpression.getOutputSymbol(), dataType); + .setTreeModelType(partialFunctionExpression.getOutputSymbol(), dataType); } newPartialOutputColumns.add(partialFunctionExpression.getOutputSymbol()); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java index 531dc4fdff5..9190bcf5928 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java @@ -49,6 +49,7 @@ import java.util.Arrays; import java.util.List; import static java.util.Objects.requireNonNull; +import static org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOperand.TIMESTAMP_EXPRESSION_STRING; import static org.apache.tsfile.read.common.type.IntType.INT32; public class LogicalPlanner { @@ -110,15 +111,17 @@ public class LogicalPlanner { RelationType outputDescriptor = analysis.getOutputDescriptor(); for (Field field : outputDescriptor.getVisibleFields()) { String name = field.getName().orElse("_col" + columnNumber); - if (!"time".equalsIgnoreCase(name)) { - columnHeaders.add(new ColumnHeader(name, transferTypeToTsDataType(field.getType()))); - } names.add(name); int fieldIndex = outputDescriptor.indexOf(field); Symbol symbol = plan.getSymbol(fieldIndex); outputs.add(symbol); + if (!TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(name)) { + columnHeaders.add( + new ColumnHeader(symbol.getName(), transferTypeToTsDataType(field.getType()))); + } + columnNumber++; } @@ -141,8 +144,7 @@ public class LogicalPlanner { } private RelationPlanner getRelationPlanner(Analysis analysis) { - return new RelationPlanner( - analysis, symbolAllocator, context.getQueryId(), sessionInfo, ImmutableMap.of()); + return new RelationPlanner(analysis, symbolAllocator, context, sessionInfo, ImmutableMap.of()); } public TSDataType transferTypeToTsDataType(Type type) { 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 d48cc74ef71..38af83ec7f8 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 @@ -13,32 +13,25 @@ */ package org.apache.iotdb.db.queryengine.plan.relational.planner; -import org.apache.iotdb.db.queryengine.common.QueryId; -import org.apache.iotdb.db.queryengine.common.SessionInfo; +import org.apache.iotdb.db.queryengine.common.MPPQueryContext; 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.ir.ExpressionTranslateVisitor; 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.LogicalExpression; -import org.apache.iotdb.db.relational.sql.tree.SymbolReference; - -import com.google.common.collect.ImmutableMap; 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 java.util.stream.Collectors; import static com.google.common.base.Verify.verify; -import static com.google.common.collect.ImmutableList.toImmutableList; import static java.util.Objects.requireNonNull; public class PlanBuilder { @@ -58,16 +51,7 @@ public class PlanBuilder { this.fieldSymbols = fieldSymbols; } - public static PlanBuilder newPlanBuilder( - RelationPlan plan, Analysis analysis, SessionInfo session) { - return newPlanBuilder(plan, analysis, ImmutableMap.of(), session); - } - - public static PlanBuilder newPlanBuilder( - RelationPlan plan, - Analysis analysis, - Map<ScopeAware<Expression>, Symbol> mappings, - SessionInfo session) { + public static PlanBuilder newPlanBuilder(RelationPlan plan, Analysis analysis) { return new PlanBuilder( plan.getRoot(), analysis, plan.getFieldMappings().toArray(new Symbol[0])); } @@ -88,39 +72,20 @@ public class PlanBuilder { return this.fieldSymbols; } - public Expression rewrite(Expression root, boolean isRoot) { + public Expression rewrite(Expression root) { verify( analysis.isAnalyzed(root), "Expression is not analyzed (%s): %s", root.getClass().getName(), root); - return translate(root, isRoot); + return translate(root); } - private Expression translate(Expression expression, boolean isRoot) { - // 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(); - } else if (expression instanceof LogicalExpression) { - LogicalExpression logicalExpression = (LogicalExpression) expression; - return new LogicalExpression( - logicalExpression.getOperator(), - logicalExpression.getTerms().stream() - .map(e -> translate(e, false)) - .collect(toImmutableList())); - } - - return expression; + private Expression translate(Expression expression) { + return new ExpressionTranslateVisitor().process(expression, this); } - private Optional<Symbol> getSymbolForColumn(Expression expression) { + public Optional<Symbol> getSymbolForColumn(Expression expression) { if (!analysis.isColumnReference(expression)) { // Expression can be a reference to lambda argument (or DereferenceExpression based on lambda // argument reference). @@ -142,33 +107,34 @@ public class PlanBuilder { Iterable<T> expressions, Analysis analysis, SymbolAllocator symbolAllocator, - QueryId idAllocator) { + MPPQueryContext queryContext) { Assignments.Builder projections = Assignments.builder(); // add an identity projection for underlying plan projections.putIdentities(root.getOutputSymbols()); - Set<String> set = new HashSet<>(); - for (Symbol symbol : root.getOutputSymbols()) { - set.add(symbol.toString()); - } + Set<String> symbolSet = + root.getOutputSymbols().stream().map(Symbol::getName).collect(Collectors.toSet()); Map<Expression, Symbol> mappings = new HashMap<>(); for (T expression : expressions) { // Skip any expressions that have already been translated and recorded in the // translation map, or that are duplicated in the list of exp if (!mappings.containsKey(expression) - && !set.contains(expression.toString().toLowerCase()) + && !symbolSet.contains(expression.toString().toLowerCase()) && !(expression instanceof FieldReference)) { - set.add(expression.toString()); - Symbol symbol = symbolAllocator.newSymbol("expr", analysis.getType(expression)); - projections.put(symbol, expression); + symbolSet.add(expression.toString()); + // Symbol symbol = symbolAllocator.newSymbol("expr", analysis.getType(expression)); + Symbol symbol = + symbolAllocator.newSymbol(expression.toString(), analysis.getType(expression)); + queryContext.getTypeProvider().putTableModelType(symbol, analysis.getType(expression)); + projections.put(symbol, translate(expression)); mappings.put(expression, symbol); } } return new PlanBuilder( - new ProjectNode(idAllocator.genPlanNodeId(), this.root, projections.build()), + new ProjectNode(queryContext.getQueryId().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 f542fb07c7d..5f1f193e2e6 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 @@ -13,6 +13,7 @@ */ package org.apache.iotdb.db.queryengine.plan.relational.planner; +import org.apache.iotdb.db.queryengine.common.MPPQueryContext; 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; @@ -54,7 +55,8 @@ import static org.apache.iotdb.db.queryengine.plan.relational.planner.PredicateU public class QueryPlanner { private final Analysis analysis; private final SymbolAllocator symbolAllocator; - private final QueryId idAllocator; + private final MPPQueryContext queryContext; + private final QueryId queryIdAllocator; private final SessionInfo session; private final Map<NodeRef<Node>, RelationPlan> recursiveSubqueries; @@ -64,18 +66,19 @@ public class QueryPlanner { public QueryPlanner( Analysis analysis, SymbolAllocator symbolAllocator, - QueryId idAllocator, + MPPQueryContext queryContext, SessionInfo session, Map<NodeRef<Node>, RelationPlan> recursiveSubqueries) { requireNonNull(analysis, "analysis is null"); requireNonNull(symbolAllocator, "symbolAllocator is null"); - requireNonNull(idAllocator, "idAllocator is null"); + requireNonNull(queryContext, "idAllocator is null"); requireNonNull(session, "session is null"); requireNonNull(recursiveSubqueries, "recursiveSubqueries is null"); this.analysis = analysis; this.symbolAllocator = symbolAllocator; - this.idAllocator = idAllocator; + this.queryContext = queryContext; + this.queryIdAllocator = queryContext.getQueryId(); this.session = session; this.recursiveSubqueries = recursiveSubqueries; } @@ -83,9 +86,6 @@ public class QueryPlanner { public RelationPlan plan(Query query) { PlanBuilder builder = planQueryBody(query.getQueryBody()); - List<Expression> orderBy = analysis.getOrderByExpressions(query); - // builder = subqueryPlanner.handleSubqueries(builder, orderBy, analysis.getSubqueries(query)); - // TODO result is :input[0], :input[1], :input[2] List<Analysis.SelectExpression> selectExpressions = analysis.getSelectExpressions(query); List<Expression> outputs = @@ -93,10 +93,11 @@ public class QueryPlanner { .map(Analysis.SelectExpression::getExpression) .collect(toImmutableList()); + List<Expression> orderBy = analysis.getOrderByExpressions(query); if (orderBy.size() > 0) { builder = builder.appendProjections( - Iterables.concat(orderBy, outputs), analysis, symbolAllocator, idAllocator); + Iterables.concat(orderBy, outputs), analysis, symbolAllocator, queryContext); } Optional<OrderingScheme> orderingScheme = @@ -104,27 +105,28 @@ public class QueryPlanner { builder = sort(builder, orderingScheme); builder = offset(builder, query.getOffset()); builder = limit(builder, query.getLimit(), orderingScheme); - builder = builder.appendProjections(outputs, analysis, symbolAllocator, idAllocator); + builder = builder.appendProjections(outputs, analysis, symbolAllocator, queryContext); return new RelationPlan( - builder.getRoot(), analysis.getScope(query), computeOutputs(builder, analysis, outputs)); + builder.getRoot(), analysis.getScope(query), computeOutputs(builder, outputs)); } public RelationPlan plan(QuerySpecification node) { PlanBuilder builder = planFrom(node); - builder = filter(builder, analysis.getWhere(node), node); + builder = filter(builder, analysis.getWhere(node)); List<Analysis.SelectExpression> selectExpressions = analysis.getSelectExpressions(node); - List<Expression> expressions = - selectExpressions.stream() - .map(Analysis.SelectExpression::getExpression) - .collect(toImmutableList()); if (hasExpressionsToUnfold(selectExpressions)) { + List<Expression> expressions = + selectExpressions.stream() + .map(Analysis.SelectExpression::getExpression) + .collect(toImmutableList()); + // pre-project the folded expressions to preserve any non-deterministic semantics of functions // that might be referenced - builder = builder.appendProjections(expressions, analysis, symbolAllocator, idAllocator); + builder = builder.appendProjections(expressions, analysis, symbolAllocator, queryContext); } List<Expression> outputs = outputExpressions(selectExpressions); @@ -137,13 +139,13 @@ public class QueryPlanner { // aggregations are visible. List<Expression> orderByAggregates = analysis.getOrderByAggregates(node.getOrderBy().get()); builder = - builder.appendProjections(orderByAggregates, analysis, symbolAllocator, idAllocator); + builder.appendProjections(orderByAggregates, analysis, symbolAllocator, queryContext); } // Add projections for the outputs of SELECT, but stack them on top of the ones from the FROM // clause so both are visible // when resolving the ORDER BY clause. - builder = builder.appendProjections(outputs, analysis, symbolAllocator, idAllocator); + builder = builder.appendProjections(outputs, analysis, symbolAllocator, queryContext); // The new scope is the composite of the fields from the FROM and SELECT clause (local nested // scopes). Fields from the bottom of @@ -163,7 +165,7 @@ public class QueryPlanner { if (orderBy.size() > 0) { builder = builder.appendProjections( - Iterables.concat(orderBy, outputs), analysis, symbolAllocator, idAllocator); + Iterables.concat(orderBy, outputs), analysis, symbolAllocator, queryContext); } Optional<OrderingScheme> orderingScheme = @@ -171,10 +173,11 @@ public class QueryPlanner { builder = sort(builder, orderingScheme); builder = offset(builder, node.getOffset()); builder = limit(builder, node.getLimit(), orderingScheme); - builder = builder.appendProjections(outputs, analysis, symbolAllocator, idAllocator); + + builder = builder.appendProjections(outputs, analysis, symbolAllocator, queryContext); return new RelationPlan( - builder.getRoot(), analysis.getScope(node), computeOutputs(builder, analysis, outputs)); + builder.getRoot(), analysis.getScope(node), computeOutputs(builder, outputs)); // TODO handle aggregate, having, distinct, subQuery later } @@ -204,11 +207,9 @@ public class QueryPlanner { } private static List<Symbol> computeOutputs( - PlanBuilder builder, Analysis analysis, List<Expression> outputExpressions) { + PlanBuilder builder, List<Expression> outputExpressions) { ImmutableList.Builder<Symbol> outputSymbols = ImmutableList.builder(); for (Expression expression : outputExpressions) { - // Symbol symbol = builder.translate(analysis, expression); - // outputSymbols.add(symbol); Symbol symbol = null; if (expression instanceof FieldReference) { FieldReference reference = (FieldReference) expression; @@ -221,26 +222,26 @@ public class QueryPlanner { private PlanBuilder planQueryBody(QueryBody queryBody) { RelationPlan relationPlan = - new RelationPlanner(analysis, symbolAllocator, idAllocator, session, recursiveSubqueries) + new RelationPlanner(analysis, symbolAllocator, queryContext, session, recursiveSubqueries) .process(queryBody, null); - return newPlanBuilder(relationPlan, analysis, session); + return newPlanBuilder(relationPlan, analysis); } private PlanBuilder planFrom(QuerySpecification node) { if (node.getFrom().isPresent()) { RelationPlan relationPlan = - new RelationPlanner(analysis, symbolAllocator, idAllocator, session, recursiveSubqueries) + new RelationPlanner(analysis, symbolAllocator, queryContext, session, recursiveSubqueries) .process(node.getFrom().get(), null); - return newPlanBuilder(relationPlan, analysis, session); + return newPlanBuilder(relationPlan, analysis); } else { throw new IllegalStateException("From clause must not by empty"); } } - private PlanBuilder filter(PlanBuilder subPlan, Expression predicate, Node node) { + private PlanBuilder filter(PlanBuilder planBuilder, Expression predicate) { if (predicate == null) { - return subPlan; + return planBuilder; } Pair<Expression, Boolean> resultPair = extractGlobalTimePredicate(predicate, true, true); @@ -248,13 +249,15 @@ public class QueryPlanner { analysis.setGlobalTableModelTimePredicate(globalTimePredicate); boolean hasValueFilter = resultPair.right; if (!hasValueFilter) { - return subPlan; + return planBuilder; } - // TODO if predicate equals true, no need filter + // TODO if predicate equals TrueConstant, no need filter - return subPlan.withNewRoot( + return planBuilder.withNewRoot( new FilterNode( - idAllocator.genPlanNodeId(), subPlan.getRoot(), subPlan.rewrite(predicate, true))); + queryIdAllocator.genPlanNodeId(), + planBuilder.getRoot(), + planBuilder.rewrite(predicate))); // subPlan = subqueryPlanner.handleSubqueries(subPlan, predicate, analysis.getSubqueries(node)); } @@ -298,7 +301,8 @@ public class QueryPlanner { } return subPlan.withNewRoot( - new SortNode(idAllocator.genPlanNodeId(), subPlan.getRoot(), orderingScheme.get(), false)); + new SortNode( + queryIdAllocator.genPlanNodeId(), subPlan.getRoot(), orderingScheme.get(), false)); } private PlanBuilder offset(PlanBuilder subPlan, Optional<Offset> offset) { @@ -308,20 +312,17 @@ public class QueryPlanner { return subPlan.withNewRoot( new OffsetNode( - idAllocator.genPlanNodeId(), subPlan.getRoot(), analysis.getOffset(offset.get()))); + queryIdAllocator.genPlanNodeId(), subPlan.getRoot(), analysis.getOffset(offset.get()))); } private PlanBuilder limit( PlanBuilder subPlan, Optional<Node> limit, Optional<OrderingScheme> orderingScheme) { if (limit.isPresent() && analysis.getLimit(limit.get()).isPresent()) { Optional<OrderingScheme> tiesResolvingScheme = Optional.empty(); - // if (limit.get() instanceof FetchFirst && ((FetchFirst) - // limit.get()).isWithTies()) { - // tiesResolvingScheme = orderingScheme; - // } + return subPlan.withNewRoot( new LimitNode( - idAllocator.genPlanNodeId(), + queryIdAllocator.genPlanNodeId(), subPlan.getRoot(), analysis.getLimit(limit.get()).getAsLong(), tiesResolvingScheme)); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java index 50c33ee6c58..d991db2ca71 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java @@ -14,6 +14,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.planner; import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory; +import org.apache.iotdb.db.queryengine.common.MPPQueryContext; import org.apache.iotdb.db.queryengine.common.QueryId; import org.apache.iotdb.db.queryengine.common.SessionInfo; import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Analysis; @@ -49,6 +50,7 @@ import static java.util.Objects.requireNonNull; public class RelationPlanner extends AstVisitor<RelationPlan, Void> { private final Analysis analysis; private final SymbolAllocator symbolAllocator; + private final MPPQueryContext queryContext; private final QueryId idAllocator; private final SessionInfo sessionInfo; private final Map<NodeRef<Node>, RelationPlan> recursiveSubqueries; @@ -56,18 +58,19 @@ public class RelationPlanner extends AstVisitor<RelationPlan, Void> { public RelationPlanner( Analysis analysis, SymbolAllocator symbolAllocator, - QueryId idAllocator, + MPPQueryContext queryContext, SessionInfo sessionInfo, Map<NodeRef<Node>, RelationPlan> recursiveSubqueries) { requireNonNull(analysis, "analysis is null"); requireNonNull(symbolAllocator, "symbolAllocator is null"); - requireNonNull(idAllocator, "idAllocator is null"); + requireNonNull(queryContext, "queryContext is null"); requireNonNull(sessionInfo, "session is null"); requireNonNull(recursiveSubqueries, "recursiveSubqueries is null"); this.analysis = analysis; this.symbolAllocator = symbolAllocator; - this.idAllocator = idAllocator; + this.queryContext = queryContext; + this.idAllocator = queryContext.getQueryId(); this.sessionInfo = sessionInfo; this.recursiveSubqueries = recursiveSubqueries; } @@ -75,7 +78,7 @@ public class RelationPlanner extends AstVisitor<RelationPlan, Void> { @Override protected RelationPlan visitQuery(Query node, Void context) { return new QueryPlanner( - analysis, symbolAllocator, idAllocator, sessionInfo, recursiveSubqueries) + analysis, symbolAllocator, queryContext, sessionInfo, recursiveSubqueries) .plan(node); } @@ -133,7 +136,7 @@ public class RelationPlanner extends AstVisitor<RelationPlan, Void> { @Override protected RelationPlan visitQuerySpecification(QuerySpecification node, Void context) { return new QueryPlanner( - analysis, symbolAllocator, idAllocator, sessionInfo, recursiveSubqueries) + analysis, symbolAllocator, queryContext, sessionInfo, recursiveSubqueries) .plan(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 2ac38f8b0da..60b1b564898 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 @@ -22,32 +22,43 @@ 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.iotdb.db.relational.sql.tree.Expression; import org.apache.tsfile.read.common.type.BooleanType; import java.util.HashMap; +import java.util.Map; public class TableModelTypeProviderExtractor { - public static TypeProvider extractor(PlanNode root, TypeProvider allTypes) { - TypeProvider typeProvider = new TypeProvider(new HashMap<>()); - root.accept(new Visitor(typeProvider, allTypes), null); - return typeProvider; + + private TableModelTypeProviderExtractor() {} + + public static TypeProvider extractor(PlanNode root, TypeProvider analyzedTypeProvider) { + TypeProvider operatorTypeProvider = new TypeProvider(new HashMap<>()); + root.accept(new Visitor(operatorTypeProvider, analyzedTypeProvider), null); + return operatorTypeProvider; } private static class Visitor extends SimplePlanVisitor<Void> { - private final TypeProvider typeProvider; - private final TypeProvider allTypes; - public Visitor(TypeProvider typeProvider, TypeProvider allTypes) { - this.typeProvider = typeProvider; - this.allTypes = allTypes; + // typeProvider used for be operator execution + private final TypeProvider beTypeProvider; + + // typeProvider analyzed in fe stage + private final TypeProvider feTypeProvider; + + public Visitor(TypeProvider beTypeProvider, TypeProvider feTypeProvider) { + this.beTypeProvider = beTypeProvider; + this.feTypeProvider = feTypeProvider; } @Override public Void visitPlan(PlanNode node, Void context) { node.getOutputSymbols() .forEach( - symbol -> typeProvider.putTableModelType(symbol, allTypes.getTableModelType(symbol))); + symbol -> + beTypeProvider.putTableModelType( + symbol, feTypeProvider.getTableModelType(symbol))); for (PlanNode source : node.getChildren()) { source.accept(this, context); } @@ -56,24 +67,27 @@ public class TableModelTypeProviderExtractor { @Override public Void visitTableScan(TableScanNode node, Void context) { - node.getAssignments().forEach((k, v) -> typeProvider.putTableModelType(k, v.getType())); + node.getAssignments().forEach((k, v) -> beTypeProvider.putTableModelType(k, v.getType())); return null; } @Override public Void visitProject(ProjectNode node, Void context) { node.getChild().accept(this, context); - // TODO add expression process logic - // node.getAssignments().forEach((k,v) -> typeProvider.putTableModelType(k, - // v.getType())); + for (Map.Entry<Symbol, Expression> entry : node.getAssignments().getMap().entrySet()) { + Symbol symbol = entry.getKey(); + if (!beTypeProvider.isSymbolExist(symbol)) { + beTypeProvider.putTableModelType(symbol, feTypeProvider.getTableModelType(symbol)); + } + } return null; } @Override public Void visitFilter(FilterNode node, Void context) { node.getChild().accept(this, context); - // fixme toString method of expression is not expected - typeProvider.putTableModelType( + // TODO consider complex filter expression + beTypeProvider.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/ir/ExpressionTranslateVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionTranslateVisitor.java new file mode 100644 index 00000000000..400184f91b0 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionTranslateVisitor.java @@ -0,0 +1,127 @@ +/* + * Licensed 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.planner.ir; + +import org.apache.iotdb.db.queryengine.plan.relational.planner.PlanBuilder; +import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol; +import org.apache.iotdb.db.relational.sql.tree.ArithmeticBinaryExpression; +import org.apache.iotdb.db.relational.sql.tree.AstVisitor; +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.Expression; +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.SymbolReference; + +import static com.google.common.collect.ImmutableList.toImmutableList; + +/** Change Identifier to SymbolReference */ +public class ExpressionTranslateVisitor extends AstVisitor<Expression, PlanBuilder> { + + @Override + protected Expression visitSymbolReference(SymbolReference node, PlanBuilder context) { + return new SymbolReference(context.getSymbolForColumn(node).get().getName()); + } + + @Override + protected Expression visitIdentifier(Identifier node, PlanBuilder context) { + return context.getSymbolForColumn(node).map(Symbol::toSymbolReference).get(); + } + + @Override + protected Expression visitInPredicate(InPredicate node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitIsNullPredicate(IsNullPredicate node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitIsNotNullPredicate(IsNotNullPredicate node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitLikePredicate(LikePredicate node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitLogicalExpression(LogicalExpression node, PlanBuilder context) { + return new LogicalExpression( + node.getOperator(), + node.getTerms().stream().map(e -> process(e, context)).collect(toImmutableList())); + } + + @Override + protected Expression visitNotExpression(NotExpression node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitComparisonExpression(ComparisonExpression node, PlanBuilder context) { + Expression left = process(node.getLeft(), context); + Expression right = process(node.getRight(), context); + return new ComparisonExpression(node.getOperator(), left, right); + } + + @Override + protected Expression visitSimpleCaseExpression(SimpleCaseExpression node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitSearchedCaseExpression( + SearchedCaseExpression node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitIfExpression(IfExpression node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitNullIfExpression(NullIfExpression node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitBetweenPredicate(BetweenPredicate node, PlanBuilder context) { + return null; + } + + @Override + protected Expression visitArithmeticBinary(ArithmeticBinaryExpression node, PlanBuilder context) { + return new ArithmeticBinaryExpression( + node.getOperator(), process(node.getLeft(), context), process(node.getRight(), context)); + } + + @Override + protected Expression visitLiteral(Literal node, PlanBuilder context) { + return node; + } +} 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 102393d666d..a70281dcfe4 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 @@ -20,7 +20,6 @@ import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet; import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot; import org.apache.iotdb.commons.partition.DataPartition; import org.apache.iotdb.commons.partition.DataPartitionQueryParam; -import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.queryengine.common.MPPQueryContext; @@ -34,6 +33,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.analyzer.predicate.Predic import org.apache.iotdb.db.queryengine.plan.relational.metadata.DeviceEntry; import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata; import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName; +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.TableScanNode; import org.apache.iotdb.db.relational.sql.tree.Expression; @@ -101,12 +101,8 @@ public class IndexScan implements RelationalPlanOptimizer { Expression indexExpression = context.getPredicate(); if (indexExpression != null) { Set<String> idOrAttributeColumnNames = - node.getAssignments().entrySet().stream() - .filter( - e -> - TsTableColumnCategory.ID.equals(e.getValue().getColumnCategory()) - || ATTRIBUTE.equals(e.getValue().getColumnCategory())) - .map(e -> e.getKey().getName()) + node.getIdAndAttributeIndexMap().keySet().stream() + .map(Symbol::getName) .collect(Collectors.toSet()); if (indexExpression instanceof LogicalExpression) { for (Expression subExpression : ((LogicalExpression) indexExpression).getTerms()) { diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/OperatorMemoryTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/OperatorMemoryTest.java index 94a98b19f90..c16c89a10d1 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/OperatorMemoryTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/OperatorMemoryTest.java @@ -976,9 +976,9 @@ public class OperatorMemoryTest { try { MeasurementPath measurementPath = new MeasurementPath("root.sg.d1.s1", TSDataType.TEXT); TypeProvider typeProvider = new TypeProvider(); - typeProvider.setType("count(root.sg.d1.s1)", TSDataType.INT64); - typeProvider.setType("min_time(root.sg.d1.s1)", TSDataType.INT64); - typeProvider.setType("first_value(root.sg.d1.s1)", TSDataType.TEXT); + typeProvider.setTreeModelType("count(root.sg.d1.s1)", TSDataType.INT64); + typeProvider.setTreeModelType("min_time(root.sg.d1.s1)", TSDataType.INT64); + typeProvider.setTreeModelType("first_value(root.sg.d1.s1)", TSDataType.TEXT); // case1: without group by, step is SINGLE List<AggregationDescriptor> aggregationDescriptors1 = @@ -1235,8 +1235,8 @@ public class OperatorMemoryTest { MeasurementPath measurementPath = new MeasurementPath("root.sg.d1.s1", TSDataType.TEXT); TypeProvider typeProvider = new TypeProvider(); - typeProvider.setType("count(root.sg.d1.s1)", TSDataType.INT64); - typeProvider.setType("first_value(root.sg.d1.s1)", TSDataType.TEXT); + typeProvider.setTreeModelType("count(root.sg.d1.s1)", TSDataType.INT64); + typeProvider.setTreeModelType("first_value(root.sg.d1.s1)", TSDataType.TEXT); List<AggregationDescriptor> aggregationDescriptors = Arrays.asList( @@ -1308,8 +1308,8 @@ public class OperatorMemoryTest { MeasurementPath measurementPath = new MeasurementPath("root.sg.d1.s1", TSDataType.TEXT); TypeProvider typeProvider = new TypeProvider(); - typeProvider.setType("count(root.sg.d1.s1)", TSDataType.INT64); - typeProvider.setType("first_value(root.sg.d1.s1)", TSDataType.TEXT); + typeProvider.setTreeModelType("count(root.sg.d1.s1)", TSDataType.INT64); + typeProvider.setTreeModelType("first_value(root.sg.d1.s1)", TSDataType.TEXT); List<AggregationDescriptor> aggregationDescriptors = Arrays.asList( @@ -1388,8 +1388,8 @@ public class OperatorMemoryTest { MeasurementPath measurementPath = new MeasurementPath("root.sg.d1.s1", TSDataType.TEXT); TypeProvider typeProvider = new TypeProvider(); - typeProvider.setType("count(root.sg.d1.s1)", TSDataType.INT64); - typeProvider.setType("first_value(root.sg.d1.s1)", TSDataType.TEXT); + typeProvider.setTreeModelType("count(root.sg.d1.s1)", TSDataType.INT64); + typeProvider.setTreeModelType("first_value(root.sg.d1.s1)", TSDataType.TEXT); List<AggregationDescriptor> aggregationDescriptors = Arrays.asList( diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/PipelineBuilderTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/PipelineBuilderTest.java index 2161445954c..46065c623c9 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/PipelineBuilderTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/PipelineBuilderTest.java @@ -783,10 +783,10 @@ public class PipelineBuilderTest { @Test public void testConsumeOneByOneChildrenPipelineBuilderDependency() throws IllegalPathException { TypeProvider typeProvider = new TypeProvider(); - typeProvider.setType("root.sg.d0.s1", TSDataType.INT64); - typeProvider.setType("root.sg.d1.s1", TSDataType.INT64); - typeProvider.setType("count(root.sg.d0.s1)", TSDataType.INT64); - typeProvider.setType("count(root.sg.d1.s1)", TSDataType.INT64); + typeProvider.setTreeModelType("root.sg.d0.s1", TSDataType.INT64); + typeProvider.setTreeModelType("root.sg.d1.s1", TSDataType.INT64); + typeProvider.setTreeModelType("count(root.sg.d0.s1)", TSDataType.INT64); + typeProvider.setTreeModelType("count(root.sg.d1.s1)", TSDataType.INT64); DeviceViewNode deviceViewNode = new DeviceViewNode(new PlanNodeId("DeviceViewNode"), null, null, null); for (int i = 0; i < 2; i++) { @@ -1071,7 +1071,7 @@ public class PipelineBuilderTest { new SeriesScanNode( new PlanNodeId(String.format("SeriesScanNode%d", i)), new MeasurementPath(String.format("root.sg.d%d.s1", i), TSDataType.INT32)); - typeProvider.setType(seriesScanNode.getSeriesPath().toString(), TSDataType.INT32); + typeProvider.setTreeModelType(seriesScanNode.getSeriesPath().toString(), TSDataType.INT32); fullOuterTimeJoinNode.addChild(seriesScanNode); } return fullOuterTimeJoinNode; @@ -1095,7 +1095,7 @@ public class PipelineBuilderTest { new SeriesScanNode( new PlanNodeId(String.format("SeriesScanNode%d", i)), new MeasurementPath(String.format("root.sg.d%d.s1", i), TSDataType.INT32)); - typeProvider.setType(seriesScanNode.getSeriesPath().toString(), TSDataType.INT32); + typeProvider.setTreeModelType(seriesScanNode.getSeriesPath().toString(), TSDataType.INT32); fullOuterTimeJoinNode.addChild(seriesScanNode); } return fullOuterTimeJoinNode; @@ -1110,7 +1110,7 @@ public class PipelineBuilderTest { new SeriesScanNode( new PlanNodeId(String.format("SeriesScanNode%d", i)), new MeasurementPath(String.format("root.sg.d%d.s1", i), TSDataType.INT32)); - typeProvider.setType(seriesScanNode.getSeriesPath().toString(), TSDataType.INT32); + typeProvider.setTreeModelType(seriesScanNode.getSeriesPath().toString(), TSDataType.INT32); leftOuterTimeJoinNode.addChild(seriesScanNode); } return leftOuterTimeJoinNode; @@ -1159,11 +1159,11 @@ public class PipelineBuilderTest { new SeriesScanNode( new PlanNodeId(String.format("SeriesScanNode%d", i)), new MeasurementPath(String.format("root.sg.d%d.s1", i), TSDataType.INT32)); - typeProvider.setType(seriesScanNode.getSeriesPath().toString(), TSDataType.INT32); + typeProvider.setTreeModelType(seriesScanNode.getSeriesPath().toString(), TSDataType.INT32); singleDeviceViewNode.addChild(seriesScanNode); - typeProvider.setType("Time", TSDataType.INT64); - typeProvider.setType("Device", TSDataType.TEXT); - typeProvider.setType("s1", TSDataType.INT32); + typeProvider.setTreeModelType("Time", TSDataType.INT64); + typeProvider.setTreeModelType("Device", TSDataType.TEXT); + typeProvider.setTreeModelType("s1", TSDataType.INT32); topKNode.addChild(singleDeviceViewNode); } return topKNode;
