You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ca...@apache.org on 2023/07/07 08:15:14 UTC
[iotdb] branch beyyes/view_query_it created (now dbfb46eb3df)
This is an automated email from the ASF dual-hosted git repository.
caogaofei pushed a change to branch beyyes/view_query_it
in repository https://gitbox.apache.org/repos/asf/iotdb.git
at dbfb46eb3df add view query it, fix view select into problem
This branch includes the following new commits:
new dbfb46eb3df add view query it, fix view select into problem
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[iotdb] 01/01: add view query it, fix view select into problem
Posted by ca...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
caogaofei pushed a commit to branch beyyes/view_query_it
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit dbfb46eb3dfbef693d86f3feeef8add63667181e
Author: Beyyes <cg...@foxmail.com>
AuthorDate: Fri Jul 7 16:14:55 2023 +0800
add view query it, fix view select into problem
---
.../java/org/apache/iotdb/db/conf/IoTDBConfig.java | 2 +-
.../queryengine/plan/analyze/AnalyzeVisitor.java | 30 ++++++--
.../db/queryengine/plan/analyze/Constants.java | 22 ++++++
.../plan/analyze/ExpressionAnalyzer.java | 6 +-
.../db/queryengine/plan/expression/Constants.java | 29 +++++++
...catDeviceAndBindSchemaForExpressionVisitor.java | 26 +++----
...ncatDeviceAndBindSchemaForPredicateVisitor.java | 15 ++--
.../plan/statement/crud/QueryStatement.java | 4 +-
.../view/visitor/TransformToExpressionVisitor.java | 85 +++++++++++----------
.../db/queryengine/plan/analyze/AnalyzeTest.java | 57 ++++++++++++++
.../queryengine/plan/analyze/AnalyzeViewTest.java | 88 ++++++++++++++++++++++
.../plan/analyze/FakeSchemaFetcherImpl.java | 58 +++++++++++++-
.../plan/statement/QueryStatementTest.java | 5 +-
13 files changed, 356 insertions(+), 71 deletions(-)
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index 959db5ab547..b7ebed30af7 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -576,7 +576,7 @@ public class IoTDBConfig {
private long cacheFileReaderClearPeriod = 100000;
/** the max executing time of query in ms. Unit: millisecond */
- private long queryTimeoutThreshold = 60000;
+ private long queryTimeoutThreshold = 60000000;
/** the max time to live of a session in ms. Unit: millisecond */
private int sessionTimeoutThreshold = 0;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
index b88c01219a2..ee7995a1afe 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
@@ -1218,6 +1218,10 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
ExpressionAnalyzer.normalizeExpression(
analyzeWhereSplitByDevice(queryStatement, devicePath, schemaTree));
} catch (MeasurementNotExistException e) {
+ logger.warn(
+ "Meets MeasurementNotExistException in analyzeDeviceToWhere when executing align by device, "
+ + "error msg: {}",
+ e.getMessage());
deviceIterator.remove();
continue;
}
@@ -1933,25 +1937,39 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
IntoPathDescriptor intoPathDescriptor = new IntoPathDescriptor();
PathPatternTree targetPathTree = new PathPatternTree();
IntoComponent.IntoPathIterator intoPathIterator = intoComponent.getIntoPathIterator();
- for (Expression sourceColumn : sourceColumns) {
+ for (Pair<Expression, String> pair : outputExpressions) {
+ Expression sourceExpression = pair.left;
+ String viewPath = pair.right;
PartialPath deviceTemplate = intoPathIterator.getDeviceTemplate();
String measurementTemplate = intoPathIterator.getMeasurementTemplate();
boolean isAlignedDevice = intoPathIterator.isAlignedDevice();
+ PartialPath sourcePath;
+ String sourceColumn;
PartialPath targetPath;
- if (sourceColumn instanceof TimeSeriesOperand) {
- PartialPath sourcePath = ((TimeSeriesOperand) sourceColumn).getPath();
+ if (sourceExpression instanceof TimeSeriesOperand) {
+ if (viewPath != null) {
+ try {
+ sourcePath = new PartialPath(viewPath);
+ sourceColumn = viewPath;
+ } catch (IllegalPathException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ sourcePath = ((TimeSeriesOperand) sourceExpression).getPath();
+ sourceColumn = sourceExpression.getExpressionString();
+ }
targetPath = constructTargetPath(sourcePath, deviceTemplate, measurementTemplate);
} else {
+ sourceColumn = sourceExpression.getExpressionString();
targetPath = deviceTemplate.concatNode(measurementTemplate);
}
- intoPathDescriptor.specifyTargetPath(sourceColumn.getExpressionString(), targetPath);
+ intoPathDescriptor.specifyTargetPath(sourceColumn, targetPath);
intoPathDescriptor.specifyDeviceAlignment(
targetPath.getDevicePath().toString(), isAlignedDevice);
targetPathTree.appendFullPath(targetPath);
- intoPathDescriptor.recordSourceColumnDataType(
- sourceColumn.getExpressionString(), analysis.getType(sourceColumn));
+ intoPathDescriptor.recordSourceColumnDataType(sourceColumn, analysis.getType(sourceExpression));
intoPathIterator.next();
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Constants.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Constants.java
new file mode 100644
index 00000000000..142b3721f08
--- /dev/null
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Constants.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.analyze;
+
+public class Constants {}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzer.java
index 886d284edd2..6be54e1aaf3 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzer.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzer.java
@@ -443,9 +443,9 @@ public class ExpressionAnalyzer {
}
/**
- * Concat expression with the device path in the FROM clause.And then, bind schema ({@link
- * PartialPath} -> {@link MeasurementPath}) and removes wildcards in Expression. This method used
- * in ALIGN BY DEVICE query.
+ * Concat expression with the device path in the FROM clause. And then, bind schema ({@link
+ * PartialPath} -> {@link MeasurementPath}) and removes wildcards in Expression. This method is
+ * used in ALIGN BY DEVICE query.
*
* @param devicePath device path in the FROM clause
* @return expression list with full path and after binding schema
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/Constants.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/Constants.java
new file mode 100644
index 00000000000..08755090cc5
--- /dev/null
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/Constants.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.expression;
+
+public class Constants {
+
+ public static final String ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW =
+ "Only writable view timeseries are supported in ALIGN BY DEVICE queries.";
+
+ public static final String WHERE_CLAUSE_NOT_SUPPORT_AGGREGATION_FUNCTION =
+ "aggregate functions are not supported in WHERE clause";
+}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForExpressionVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForExpressionVisitor.java
index 9292204dc82..312d5f2ff5a 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForExpressionVisitor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForExpressionVisitor.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.commons.path.MeasurementPath;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.exception.sql.SemanticException;
import org.apache.iotdb.db.queryengine.common.schematree.ISchemaTree;
-import org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils;
import org.apache.iotdb.db.queryengine.plan.expression.Expression;
import org.apache.iotdb.db.queryengine.plan.expression.leaf.ConstantOperand;
import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand;
@@ -36,6 +35,8 @@ import java.util.List;
import static org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils.cartesianProduct;
import static org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils.reconstructFunctionExpressions;
+import static org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands;
+import static org.apache.iotdb.db.queryengine.plan.expression.Constants.ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW;
import static org.apache.iotdb.db.queryengine.plan.expression.visitor.cartesian.BindSchemaForExpressionVisitor.transformViewPath;
import static org.apache.iotdb.db.utils.TypeInferenceUtils.bindTypeForAggregationNonSeriesInputExpressions;
@@ -47,9 +48,9 @@ public class ConcatDeviceAndBindSchemaForExpressionVisitor
FunctionExpression functionExpression, Context context) {
List<List<Expression>> extendedExpressions = new ArrayList<>();
for (Expression suffixExpression : functionExpression.getExpressions()) {
- List<Expression> concatedExpression = process(suffixExpression, context);
- if (concatedExpression != null && !concatedExpression.isEmpty()) {
- extendedExpressions.add(concatedExpression);
+ List<Expression> concatExpression = process(suffixExpression, context);
+ if (concatExpression != null && !concatExpression.isEmpty()) {
+ extendedExpressions.add(concatExpression);
}
// We just process first input Expression of AggregationFunction,
@@ -82,23 +83,22 @@ public class ConcatDeviceAndBindSchemaForExpressionVisitor
}
// process logical view
- List<MeasurementPath> nonViewActualPaths = new ArrayList<>();
- List<MeasurementPath> viewPaths = new ArrayList<>();
+ List<MeasurementPath> nonViewPathList = new ArrayList<>();
+ List<MeasurementPath> viewPathList = new ArrayList<>();
for (MeasurementPath measurementPath : actualPaths) {
if (measurementPath.getMeasurementSchema().isLogicalView()) {
- viewPaths.add(measurementPath);
+ viewPathList.add(measurementPath);
} else {
- nonViewActualPaths.add(measurementPath);
+ nonViewPathList.add(measurementPath);
}
}
+
List<Expression> reconstructTimeSeriesOperands =
- ExpressionUtils.reconstructTimeSeriesOperands(timeSeriesOperand, nonViewActualPaths);
- // handle logical views
- for (MeasurementPath measurementPath : viewPaths) {
+ reconstructTimeSeriesOperands(timeSeriesOperand, nonViewPathList);
+ for (MeasurementPath measurementPath : viewPathList) {
Expression replacedExpression = transformViewPath(measurementPath, context.getSchemaTree());
if (!(replacedExpression instanceof TimeSeriesOperand)) {
- throw new SemanticException(
- "Only writable view timeseries are supported in ALIGN BY DEVICE queries.");
+ throw new SemanticException(ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW);
}
replacedExpression.setViewPath(measurementPath);
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForPredicateVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForPredicateVisitor.java
index 722938fef6f..c8f2e914692 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForPredicateVisitor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForPredicateVisitor.java
@@ -37,15 +37,19 @@ import java.util.List;
import static org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils.cartesianProduct;
import static org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils.reconstructFunctionExpressions;
import static org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands;
+import static org.apache.iotdb.db.queryengine.plan.expression.Constants.ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW;
+import static org.apache.iotdb.db.queryengine.plan.expression.Constants.WHERE_CLAUSE_NOT_SUPPORT_AGGREGATION_FUNCTION;
import static org.apache.iotdb.db.queryengine.plan.expression.visitor.cartesian.BindSchemaForExpressionVisitor.transformViewPath;
public class ConcatDeviceAndBindSchemaForPredicateVisitor
extends CartesianProductVisitor<ConcatDeviceAndBindSchemaForPredicateVisitor.Context> {
+
@Override
public List<Expression> visitFunctionExpression(FunctionExpression predicate, Context context) {
if (predicate.isBuiltInAggregationFunctionExpression() && context.isWhere()) {
- throw new SemanticException("aggregate functions are not supported in WHERE clause");
+ throw new SemanticException(WHERE_CLAUSE_NOT_SUPPORT_AGGREGATION_FUNCTION);
}
+
List<List<Expression>> extendedExpressions = new ArrayList<>();
for (Expression suffixExpression : predicate.getExpressions()) {
extendedExpressions.add(process(suffixExpression, context));
@@ -60,13 +64,15 @@ public class ConcatDeviceAndBindSchemaForPredicateVisitor
PartialPath measurement = predicate.getPath();
PartialPath concatPath = context.getDevicePath().concatPath(measurement);
- List<MeasurementPath> nonViewPathList = new ArrayList<>();
- List<MeasurementPath> viewPathList = new ArrayList<>();
List<MeasurementPath> actualPaths =
context.getSchemaTree().searchMeasurementPaths(concatPath).left;
if (actualPaths.isEmpty()) {
return Collections.singletonList(new NullOperand());
}
+
+ // process logical view
+ List<MeasurementPath> nonViewPathList = new ArrayList<>();
+ List<MeasurementPath> viewPathList = new ArrayList<>();
for (MeasurementPath measurementPath : actualPaths) {
if (measurementPath.getMeasurementSchema().isLogicalView()) {
viewPathList.add(measurementPath);
@@ -80,8 +86,7 @@ public class ConcatDeviceAndBindSchemaForPredicateVisitor
for (MeasurementPath measurementPath : viewPathList) {
Expression replacedExpression = transformViewPath(measurementPath, context.getSchemaTree());
if (!(replacedExpression instanceof TimeSeriesOperand)) {
- throw new SemanticException(
- "Only writable view timeseries are supported in ALIGN BY DEVICE queries.");
+ throw new SemanticException(ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW);
}
replacedExpression.setViewPath(measurementPath);
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/QueryStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/QueryStatement.java
index 973414be8e1..0681cd2403a 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/QueryStatement.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/QueryStatement.java
@@ -51,6 +51,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import static org.apache.iotdb.db.queryengine.plan.expression.Constants.WHERE_CLAUSE_NOT_SUPPORT_AGGREGATION_FUNCTION;
+
/**
* Base class of SELECT statement.
*
@@ -542,7 +544,7 @@ public class QueryStatement extends Statement {
Expression whereExpression = getWhereCondition().getPredicate();
if (ExpressionAnalyzer.identifyOutputColumnType(whereExpression, true)
== ResultColumn.ColumnType.AGGREGATION) {
- throw new SemanticException("aggregate functions are not supported in WHERE clause");
+ throw new SemanticException(WHERE_CLAUSE_NOT_SUPPORT_AGGREGATION_FUNCTION);
}
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/view/visitor/TransformToExpressionVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/view/visitor/TransformToExpressionVisitor.java
index 6636cc466cc..d956d49fab9 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/view/visitor/TransformToExpressionVisitor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/view/visitor/TransformToExpressionVisitor.java
@@ -56,6 +56,29 @@ import org.apache.iotdb.commons.schema.view.viewExpression.unary.RegularViewExpr
import org.apache.iotdb.commons.schema.view.viewExpression.unary.UnaryViewExpression;
import org.apache.iotdb.commons.schema.view.viewExpression.visitor.ViewExpressionVisitor;
import org.apache.iotdb.db.queryengine.plan.expression.Expression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.AdditionExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.DivisionExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.EqualToExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.GreaterEqualExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.GreaterThanExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.LessEqualExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.LessThanExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.LogicAndExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.LogicOrExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.ModuloExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.MultiplicationExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.NonEqualExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.binary.SubtractionExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.queryengine.plan.expression.leaf.NullOperand;
+import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOperand;
+import org.apache.iotdb.db.queryengine.plan.expression.unary.InExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.unary.IsNullExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.unary.LikeExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.unary.LogicNotExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.unary.NegationExpression;
+import org.apache.iotdb.db.queryengine.plan.expression.unary.RegularExpression;
import org.apache.iotdb.tsfile.utils.Pair;
import javax.ws.rs.NotSupportedException;
@@ -85,20 +108,19 @@ public class TransformToExpressionVisitor extends ViewExpressionVisitor<Expressi
@Override
public Expression visitConstantOperand(ConstantViewOperand constantOperand, Void context) {
- return new org.apache.iotdb.db.queryengine.plan.expression.leaf.ConstantOperand(
- constantOperand.getDataType(), constantOperand.getValueString());
+ return new ConstantOperand(constantOperand.getDataType(), constantOperand.getValueString());
}
@Override
public Expression visitNullOperand(NullViewOperand nullOperand, Void context) {
- return new org.apache.iotdb.db.queryengine.plan.expression.leaf.NullOperand();
+ return new NullOperand();
}
@Override
public Expression visitTimeSeriesOperand(TimeSeriesViewOperand timeSeriesOperand, Void context) {
try {
PartialPath path = new PartialPath(timeSeriesOperand.getPathString());
- return new org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand(path);
+ return new TimeSeriesOperand(path);
} catch (IllegalPathException e) {
throw new RuntimeException(e);
}
@@ -106,7 +128,7 @@ public class TransformToExpressionVisitor extends ViewExpressionVisitor<Expressi
@Override
public Expression visitTimeStampOperand(TimestampViewOperand timestampOperand, Void context) {
- return new org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOperand();
+ return new TimestampOperand();
}
// endregion
@@ -119,21 +141,19 @@ public class TransformToExpressionVisitor extends ViewExpressionVisitor<Expressi
@Override
public Expression visitInExpression(InViewExpression inExpression, Void context) {
Expression child = this.process(inExpression.getExpression(), context);
- return new org.apache.iotdb.db.queryengine.plan.expression.unary.InExpression(
- child, inExpression.isNotIn(), inExpression.getValuesInLinkedHashSet());
+ return new InExpression(child, inExpression.isNotIn(), inExpression.getValuesInLinkedHashSet());
}
@Override
public Expression visitIsNullExpression(IsNullViewExpression isNullExpression, Void context) {
Expression child = this.process(isNullExpression.getExpression(), context);
- return new org.apache.iotdb.db.queryengine.plan.expression.unary.IsNullExpression(
- child, isNullExpression.isNot());
+ return new IsNullExpression(child, isNullExpression.isNot());
}
@Override
public Expression visitLikeExpression(LikeViewExpression likeExpression, Void context) {
Expression child = this.process(likeExpression.getExpression(), context);
- return new org.apache.iotdb.db.queryengine.plan.expression.unary.LikeExpression(
+ return new LikeExpression(
child, likeExpression.getPatternString(), likeExpression.getPattern());
}
@@ -141,20 +161,20 @@ public class TransformToExpressionVisitor extends ViewExpressionVisitor<Expressi
public Expression visitLogicNotExpression(
LogicNotViewExpression logicNotExpression, Void context) {
Expression child = this.process(logicNotExpression.getExpression(), context);
- return new org.apache.iotdb.db.queryengine.plan.expression.unary.LogicNotExpression(child);
+ return new LogicNotExpression(child);
}
@Override
public Expression visitNegationExpression(
NegationViewExpression negationExpression, Void context) {
Expression child = this.process(negationExpression.getExpression(), context);
- return new org.apache.iotdb.db.queryengine.plan.expression.unary.NegationExpression(child);
+ return new NegationExpression(child);
}
@Override
public Expression visitRegularExpression(RegularViewExpression regularExpression, Void context) {
Expression child = this.process(regularExpression.getExpression(), context);
- return new org.apache.iotdb.db.queryengine.plan.expression.unary.RegularExpression(
+ return new RegularExpression(
child, regularExpression.getPatternString(), regularExpression.getPattern());
}
// endregion
@@ -181,37 +201,32 @@ public class TransformToExpressionVisitor extends ViewExpressionVisitor<Expressi
public Expression visitAdditionExpression(
AdditionViewExpression additionExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(additionExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.AdditionExpression(
- pair.left, pair.right);
+ return new AdditionExpression(pair.left, pair.right);
}
public Expression visitDivisionExpression(
DivisionViewExpression divisionExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(divisionExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.DivisionExpression(
- pair.left, pair.right);
+ return new DivisionExpression(pair.left, pair.right);
}
public Expression visitModuloExpression(ModuloViewExpression moduloExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(moduloExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.ModuloExpression(
- pair.left, pair.right);
+ return new ModuloExpression(pair.left, pair.right);
}
public Expression visitMultiplicationExpression(
MultiplicationViewExpression multiplicationExpression, Void context) {
Pair<Expression, Expression> pair =
this.getExpressionsForBinaryExpression(multiplicationExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.MultiplicationExpression(
- pair.left, pair.right);
+ return new MultiplicationExpression(pair.left, pair.right);
}
public Expression visitSubtractionExpression(
SubtractionViewExpression subtractionExpression, Void context) {
Pair<Expression, Expression> pair =
this.getExpressionsForBinaryExpression(subtractionExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.SubtractionExpression(
- pair.left, pair.right);
+ return new SubtractionExpression(pair.left, pair.right);
}
// endregion
@@ -223,45 +238,39 @@ public class TransformToExpressionVisitor extends ViewExpressionVisitor<Expressi
public Expression visitEqualToExpression(EqualToViewExpression equalToExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(equalToExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.EqualToExpression(
- pair.left, pair.right);
+ return new EqualToExpression(pair.left, pair.right);
}
public Expression visitGreaterEqualExpression(
GreaterEqualViewExpression greaterEqualExpression, Void context) {
Pair<Expression, Expression> pair =
this.getExpressionsForBinaryExpression(greaterEqualExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.GreaterEqualExpression(
- pair.left, pair.right);
+ return new GreaterEqualExpression(pair.left, pair.right);
}
public Expression visitGreaterThanExpression(
GreaterThanViewExpression greaterThanExpression, Void context) {
Pair<Expression, Expression> pair =
this.getExpressionsForBinaryExpression(greaterThanExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.GreaterThanExpression(
- pair.left, pair.right);
+ return new GreaterThanExpression(pair.left, pair.right);
}
public Expression visitLessEqualExpression(
LessEqualViewExpression lessEqualExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(lessEqualExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.LessEqualExpression(
- pair.left, pair.right);
+ return new LessEqualExpression(pair.left, pair.right);
}
public Expression visitLessThanExpression(
LessThanViewExpression lessThanExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(lessThanExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.LessThanExpression(
- pair.left, pair.right);
+ return new LessThanExpression(pair.left, pair.right);
}
public Expression visitNonEqualExpression(
NonEqualViewExpression nonEqualExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(nonEqualExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.NonEqualExpression(
- pair.left, pair.right);
+ return new NonEqualExpression(pair.left, pair.right);
}
// endregion
@@ -274,14 +283,12 @@ public class TransformToExpressionVisitor extends ViewExpressionVisitor<Expressi
public Expression visitLogicAndExpression(
LogicAndViewExpression logicAndExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(logicAndExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.LogicAndExpression(
- pair.left, pair.right);
+ return new LogicAndExpression(pair.left, pair.right);
}
public Expression visitLogicOrExpression(LogicOrViewExpression logicOrExpression, Void context) {
Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(logicOrExpression);
- return new org.apache.iotdb.db.queryengine.plan.expression.binary.LogicOrExpression(
- pair.left, pair.right);
+ return new LogicOrExpression(pair.left, pair.right);
}
// endregion
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java
index 0a12f59c498..9a5e14c4fbf 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java
@@ -1023,6 +1023,63 @@ public class AnalyzeTest {
"alias 'a' can only be matched with one time series");
}
+ @Test
+ public void testLastQuery() {
+ String sql = "select count(s1 + s2), last_value(s2) from root.sg.d1 group by ([0, 100), 10ms);";
+ Analysis actualAnalysis = analyzeSQL(sql);
+ }
+
+ @Test
+ public void testGroupBy() {
+ // test group by level
+ String sql =
+ "select count(s1), count(s2) from root.sg.d1 group by ([0, 100), 10ms), level=2 "
+ + "having count(s2) > 1 offset 1 limit 1";
+ Analysis actualAnalysis = analyzeSQL(sql);
+
+ // test group by tag
+
+ // test group by + align by device
+
+ //
+ }
+
+ @Test
+ public void testShowTimeseries() {
+ String sql = "show timeseries";
+ Analysis actualAnalysis = analyzeSQL(sql);
+ assert actualAnalysis != null;
+ assertEquals(11, actualAnalysis.getRespDatasetHeader().getColumnHeaders().size());
+ assertEquals(
+ new ColumnHeader("Timeseries", TSDataType.TEXT, null),
+ actualAnalysis.getRespDatasetHeader().getColumnHeaders().get(0));
+ }
+
+ @Test
+ public void testShowStorageGroup() {
+ String sql = "show storage group";
+ Analysis actualAnalysis = analyzeSQL(sql);
+ assert actualAnalysis != null;
+ assertEquals(5, actualAnalysis.getRespDatasetHeader().getColumnHeaders().size());
+ assertEquals(
+ new ColumnHeader("Database", TSDataType.TEXT, null),
+ actualAnalysis.getRespDatasetHeader().getColumnHeaders().get(0));
+ }
+
+ @Test
+ public void testExplain() {
+ Analysis analysis =
+ analyzeSQL("explain select s1 as a, s2 as b from root.sg.d2.a, root.sg.d2.b");
+ assert analysis != null;
+ Assert.assertEquals(
+ analysis.getRespDatasetHeader(),
+ new DatasetHeader(
+ Arrays.asList(
+ new ColumnHeader("root.sg.d2.a.s1", TSDataType.INT32, "a"),
+ new ColumnHeader("root.sg.d2.a.s2", TSDataType.DOUBLE, "b")),
+ false));
+ }
+
private void assertTestFail(String sql, String errMsg) {
try {
Statement statement =
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeViewTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeViewTest.java
new file mode 100644
index 00000000000..5ff788f5482
--- /dev/null
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeViewTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.analyze;
+
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
+import org.apache.iotdb.db.queryengine.common.QueryId;
+import org.apache.iotdb.db.queryengine.plan.parser.StatementGenerator;
+import org.apache.iotdb.db.queryengine.plan.statement.Statement;
+import org.apache.iotdb.tsfile.utils.Pair;
+
+import org.junit.Test;
+
+import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.apache.iotdb.db.queryengine.plan.expression.Constants.ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class AnalyzeViewTest {
+
+ @Test
+ public void rawQueryTest() {
+ String sql =
+ "select s1, ms1, ms1 as another_ms1 from root.cpu.d1, root.cpu.d2 where ms1 > 1 or s2 < 6 align by device";
+ Analysis actualAnalysis = analyzeSQL(sql);
+ assert actualAnalysis != null;
+ }
+
+ @Test
+ public void errorSqlTest() {
+ List<Pair<String, String>> errorSqlWithMsg =
+ Arrays.asList(
+ new Pair<>(
+ "select ms3 from root.cpu.d3 align by device",
+ ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW),
+ new Pair<>(
+ "select s1 from root.cpu.d3 where ms3 > 1 align by device",
+ ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW),
+ new Pair<>(
+ "select count(ms3) from root.cpu.d3 having(count(ms3) > 1) align by device",
+ ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW),
+ new Pair<>(
+ "select count(ms3) from root.cpu.d3 group by variation(ms3) align by device",
+ ALIGN_BY_DEVICE_ONLY_SUPPORT_WRITABLE_VIEW));
+
+ for (Pair<String, String> pair : errorSqlWithMsg) {
+ String errorSql = pair.left;
+ String errorMsg = pair.right;
+ try {
+ analyzeSQL(errorSql);
+ } catch (SemanticException e) {
+ assertEquals("Test sql is: " + errorSql, errorMsg, e.getMessage());
+ continue;
+ } catch (Exception ex) {
+ fail(String.format("Meets exception %s in test sql: `%s`", errorMsg, errorSql));
+ }
+ fail(String.format("Sql: `%s` must throw exception: %s", errorSql, errorMsg));
+ }
+ }
+
+ private Analysis analyzeSQL(String sql) {
+ Statement statement = StatementGenerator.createStatement(sql, ZonedDateTime.now().getOffset());
+ MPPQueryContext context = new MPPQueryContext(new QueryId("test_query"));
+ Analyzer analyzer =
+ new Analyzer(context, new FakePartitionFetcherImpl(), new FakeSchemaFetcherImpl());
+ return analyzer.analyze(statement);
+ }
+}
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/FakeSchemaFetcherImpl.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/FakeSchemaFetcherImpl.java
index fd1220f79c9..d19f587347d 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/FakeSchemaFetcherImpl.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/FakeSchemaFetcherImpl.java
@@ -21,6 +21,10 @@ package org.apache.iotdb.db.queryengine.plan.analyze;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathPatternTree;
+import org.apache.iotdb.commons.schema.view.LogicalViewSchema;
+import org.apache.iotdb.commons.schema.view.viewExpression.binary.arithmetic.AdditionViewExpression;
+import org.apache.iotdb.commons.schema.view.viewExpression.leaf.ConstantViewOperand;
+import org.apache.iotdb.commons.schema.view.viewExpression.leaf.TimeSeriesViewOperand;
import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
import org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree;
import org.apache.iotdb.db.queryengine.common.schematree.ISchemaTree;
@@ -37,7 +41,9 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.utils.Pair;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -49,7 +55,7 @@ public class FakeSchemaFetcherImpl implements ISchemaFetcher {
@Override
public ClusterSchemaTree fetchSchema(PathPatternTree patternTree, MPPQueryContext context) {
this.context = context;
- schemaTree.setDatabases(Collections.singleton("root.sg"));
+ schemaTree.setDatabases(new HashSet<>(Arrays.asList("root.sg", "root.cpu")));
return schemaTree;
}
@@ -118,6 +124,56 @@ public class FakeSchemaFetcherImpl implements ISchemaFetcher {
a.addChild("s2", s2);
a.addAliasChild("status", s2);
+ // add view node
+ SchemaNode cpu = new SchemaInternalNode("cpu");
+ root.addChild("cpu", cpu);
+
+ // device1 only has base series (s1, s2, ms1)
+ SchemaEntityNode cpuDevice1 = new SchemaEntityNode("d1");
+ cpuDevice1.addChild(
+ "s1", new SchemaMeasurementNode("s1", new MeasurementSchema("s1", TSDataType.INT32)));
+ cpuDevice1.addChild(
+ "s2", new SchemaMeasurementNode("s2", new MeasurementSchema("s2", TSDataType.FLOAT)));
+ cpuDevice1.addChild(
+ "ms1", new SchemaMeasurementNode("ms1", new MeasurementSchema("ms1", TSDataType.INT32)));
+
+ // device1 only has base series (s1, s2)
+ SchemaEntityNode cpuDevice2 = new SchemaEntityNode("d2");
+ cpuDevice2.addChild(
+ "s1", new SchemaMeasurementNode("s1", new MeasurementSchema("s1", TSDataType.INT32)));
+ cpuDevice2.addChild(
+ "s2", new SchemaMeasurementNode("s2", new MeasurementSchema("s2", TSDataType.FLOAT)));
+
+ // device3 only has view series (ms1, ms2, ms3)
+ SchemaEntityNode cpuDevice3 = new SchemaEntityNode("d3");
+ cpuDevice3.addChild(
+ "ms1",
+ new SchemaMeasurementNode(
+ "ms1", new LogicalViewSchema("ms1", new TimeSeriesViewOperand("root.cpu.d1.s1"))));
+ cpuDevice3.addChild(
+ "ms2",
+ new SchemaMeasurementNode(
+ "ms2", new LogicalViewSchema("ms2", new TimeSeriesViewOperand("root.cpu.d1.s1"))));
+ TimeSeriesViewOperand timeSeriesViewOperand = new TimeSeriesViewOperand("root.cpu.d1.s1");
+ ConstantViewOperand constantViewOperand = new ConstantViewOperand(TSDataType.INT32, "2");
+ AdditionViewExpression add =
+ new AdditionViewExpression(timeSeriesViewOperand, constantViewOperand);
+ cpuDevice3.addChild("ms3", new SchemaMeasurementNode("ms3", new LogicalViewSchema("ms3", add)));
+
+ // device4 has both base series(s1) and view series(ms1)
+ SchemaEntityNode cpuDevice4 = new SchemaEntityNode("d4");
+ cpuDevice4.addChild(
+ "s1", new SchemaMeasurementNode("s1", new MeasurementSchema("s1", TSDataType.INT32)));
+ cpuDevice4.addChild(
+ "ms1",
+ new SchemaMeasurementNode(
+ "ms1", new LogicalViewSchema("ms1", new TimeSeriesViewOperand("root.cpu.d2.s1"))));
+
+ cpu.addChild("d1", cpuDevice1);
+ cpu.addChild("d2", cpuDevice2);
+ cpu.addChild("d3", cpuDevice3);
+ cpu.addChild("d4", cpuDevice4);
+
return root;
}
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/QueryStatementTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/QueryStatementTest.java
index e6bd0c2796c..8e63bd5a6d2 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/QueryStatementTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/QueryStatementTest.java
@@ -33,6 +33,7 @@ import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.List;
+import static org.apache.iotdb.db.queryengine.plan.expression.Constants.WHERE_CLAUSE_NOT_SUPPORT_AGGREGATION_FUNCTION;
import static org.apache.iotdb.db.queryengine.plan.statement.crud.QueryStatement.RAW_AGGREGATION_HYBRID_QUERY_ERROR_MSG;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -58,7 +59,7 @@ public class QueryStatementTest {
// test for where clause
new Pair<>(
"SELECT s1 FROM root.sg.d1 WHERE count(s1) > 0",
- "aggregate functions are not supported in WHERE clause"),
+ WHERE_CLAUSE_NOT_SUPPORT_AGGREGATION_FUNCTION),
// test for having clause
new Pair<>(
@@ -135,7 +136,7 @@ public class QueryStatementTest {
try {
checkErrorQuerySql(errorSql);
} catch (SemanticException e) {
- assertEquals(errorMsg, e.getMessage());
+ assertEquals("Test sql is: " + errorSql, errorMsg, e.getMessage());
continue;
} catch (Exception ex) {
fail(String.format("Meets exception %s in test sql: `%s`", errorMsg, errorSql));