You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by zy...@apache.org on 2023/05/09 01:01:42 UTC
[iotdb] branch master updated: Support Create and Query Schema of Logical View (#9742)
This is an automated email from the ASF dual-hosted git repository.
zyk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new f579e3ca0d Support Create and Query Schema of Logical View (#9742)
f579e3ca0d is described below
commit f579e3ca0d66d837f794cf2b9bbd850ddad5019e
Author: 橘子 <70...@users.noreply.github.com>
AuthorDate: Tue May 9 09:01:37 2023 +0800
Support Create and Query Schema of Logical View (#9742)
---
.../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 22 ++
.../antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 | 4 +
client-py/tests/test_dataframe.py | 2 +
.../apache/iotdb/db/it/query/IoTDBResultSetIT.java | 2 +
.../iotdb/db/it/schema/IoTDBExtendTemplateIT.java | 32 +-
.../iotdb/db/it/schema/IoTDBMetadataFetchIT.java | 44 +--
.../iotdb/zeppelin/it/IoTDBInterpreterIT.java | 14 +-
.../node/common/AbstractMeasurementMNode.java | 4 +
.../schema/node/role/IMeasurementMNode.java | 2 +
.../commons/schema/node/utils/IMNodeFactory.java | 4 +
.../schemaregion/rocksdb/RSchemaRegion.java | 7 +
.../rocksdb/mnode/RMeasurementMNode.java | 5 +
.../metadata/tagSchemaRegion/TagSchemaRegion.java | 7 +
.../apache/iotdb/db/metadata/MetadataConstant.java | 6 +
.../mnode/config/factory/ConfigMNodeFactory.java | 7 +
.../mnode/mem/factory/MemMNodeFactory.java | 14 +
...MeasurementMNode.java => LogicalViewMNode.java} | 30 +-
.../metadata/mnode/mem/impl/LogicalViewSchema.java | 215 +++++++++++
.../metadata/mnode/mem/impl/MeasurementMNode.java | 5 +
.../metadata/mnode/mem/info/LogicalViewInfo.java | 161 +++++++++
.../schemafile/factory/CacheMNodeFactory.java | 7 +
.../schemafile/impl/CachedMeasurementMNode.java | 5 +
.../db/metadata/mtree/MTreeBelowSGCachedImpl.java | 10 +-
.../db/metadata/mtree/MTreeBelowSGMemoryImpl.java | 75 +++-
.../mtree/snapshot/MemMTreeSnapshotUtil.java | 41 ++-
.../plan/schemaregion/SchemaRegionPlanType.java | 2 +
.../plan/schemaregion/SchemaRegionPlanVisitor.java | 5 +
.../impl/SchemaRegionPlanDeserializer.java | 24 ++
.../impl/SchemaRegionPlanSerializer.java | 27 ++
.../impl/SchemaRegionPlanTxtSerializer.java | 21 ++
.../impl/write/CreateLogicalViewPlanImpl.java | 75 ++++
.../schemaregion/result/ShowTimeSeriesResult.java | 14 +-
.../schemaregion/write/ICreateLogicalViewPlan.java | 66 ++++
.../metadata/query/info/ITimeSeriesSchemaInfo.java | 6 +-
.../db/metadata/schemaregion/ISchemaRegion.java | 5 +
.../schemaregion/SchemaRegionMemoryImpl.java | 40 +++
.../schemaregion/SchemaRegionSchemaFileImpl.java | 7 +
.../view/viewExpression/ViewExpression.java | 318 +++++++++++++++++
.../view/viewExpression/ViewExpressionType.java | 76 ++++
.../binary/BinaryViewExpression.java | 119 +++++++
.../binary/arithmetic/AdditionViewExpression.java | 61 ++++
.../arithmetic/ArithmeticBinaryViewExpression.java | 52 +++
.../binary/arithmetic/DivisionViewExpression.java | 61 ++++
.../binary/arithmetic/ModuloViewExpression.java | 61 ++++
.../arithmetic/MultiplicationViewExpression.java | 63 ++++
.../arithmetic/SubtractionViewExpression.java | 61 ++++
.../compare/CompareBinaryViewExpression.java | 52 +++
.../binary/compare/EqualToViewExpression.java | 57 +++
.../binary/compare/GreaterEqualViewExpression.java | 57 +++
.../binary/compare/GreaterThanViewExpression.java | 57 +++
.../binary/compare/LessEqualViewExpression.java | 57 +++
.../binary/compare/LessThanViewExpression.java | 57 +++
.../binary/compare/NonEqualViewExpression.java | 57 +++
.../binary/logic/LogicAndViewExpression.java | 57 +++
.../binary/logic/LogicBinaryViewExpression.java | 52 +++
.../binary/logic/LogicOrViewExpression.java | 57 +++
.../viewExpression/leaf/ConstantViewOperand.java | 98 ++++++
.../viewExpression/leaf/LeafViewOperand.java} | 28 +-
.../view/viewExpression/leaf/NullViewOperand.java | 61 ++++
.../viewExpression/leaf/TimeSeriesViewOperand.java | 87 +++++
.../viewExpression/leaf/TimestampViewOperand.java | 72 ++++
.../multi/FunctionViewExpression.java | 198 +++++++++++
.../ternary/BetweenViewExpression.java | 111 ++++++
.../ternary/TernaryViewExpression.java | 105 ++++++
.../viewExpression/unary/InViewExpression.java | 106 ++++++
.../viewExpression/unary/IsNullViewExpression.java | 89 +++++
.../viewExpression/unary/LikeViewExpression.java | 163 +++++++++
.../unary/LogicNotViewExpression.java | 61 ++++
.../unary/NegationViewExpression.java | 61 ++++
.../unary/RegularViewExpression.java | 105 ++++++
.../viewExpression/unary/UnaryViewExpression.java | 73 ++++
.../visitor/GetSourcePathsVisitor.java | 95 +++++
.../visitor/TransformToExpressionVisitor.java | 320 +++++++++++++++++
.../visitor/ViewExpressionVisitor.java | 219 ++++++++++++
.../metadata/visitor/SchemaExecutionVisitor.java | 22 ++
.../db/mpp/common/header/ColumnHeaderConstant.java | 6 +-
.../execution/executor/RegionWriteExecutor.java | 49 +++
.../schema/source/TimeSeriesSchemaSource.java | 14 +-
.../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java | 45 +++
.../visitor/TransformToViewExpressionVisitor.java | 391 +++++++++++++++++++++
.../iotdb/db/mpp/plan/parser/ASTVisitor.java | 86 +++++
.../db/mpp/plan/planner/LogicalPlanVisitor.java | 21 ++
.../mpp/plan/planner/plan/node/PlanNodeType.java | 6 +-
.../db/mpp/plan/planner/plan/node/PlanVisitor.java | 5 +
.../node/metedata/write/CreateLogicalViewNode.java | 250 +++++++++++++
.../iotdb/db/mpp/plan/statement/StatementType.java | 2 +
.../db/mpp/plan/statement/StatementVisitor.java | 7 +
.../metadata/CreateLogicalViewStatement.java | 246 +++++++++++++
.../metadata/view/ViewExpressionToStringTest.java | 183 ++++++++++
89 files changed, 5745 insertions(+), 89 deletions(-)
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index d88e4533c6..4a95f1a812 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -63,6 +63,8 @@ ddlStatement
| createModel | dropModel | showModels | showTrails
// Quota
| setSpaceQuota | showSpaceQuota | setThrottleQuota | showThrottleQuota
+ // View
+ | createLogicalView
;
dmlStatement
@@ -530,6 +532,26 @@ showTrails
: SHOW TRAILS modelId=identifier
;
+// Create Logical View
+createLogicalView
+ : CREATE VIEW viewTargetPaths AS viewSourcePaths
+ ;
+
+viewSuffixPaths
+ : nodeNameWithoutWildcard (DOT nodeNameWithoutWildcard)*
+ ;
+
+viewTargetPaths
+ : fullPath (COMMA fullPath)*
+ | prefixPath LR_BRACKET viewSuffixPaths (COMMA viewSuffixPaths)* RR_BRACKET
+ ;
+
+viewSourcePaths
+ : fullPath (COMMA fullPath)*
+ | prefixPath LR_BRACKET viewSuffixPaths (COMMA viewSuffixPaths)* RR_BRACKET
+ | selectClause fromClause
+ ;
+
/**
* 3. Data Manipulation Language (DML)
*/
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
index fb7c5af931..b702f0ec25 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
@@ -810,6 +810,10 @@ VERSION
: V E R S I O N
;
+VIEW
+ : V I E W
+ ;
+
WATERMARK_EMBEDDING
: W A T E R M A R K '_' E M B E D D I N G
;
diff --git a/client-py/tests/test_dataframe.py b/client-py/tests/test_dataframe.py
index 801b7c1bcd..7cdabac6e0 100644
--- a/client-py/tests/test_dataframe.py
+++ b/client-py/tests/test_dataframe.py
@@ -71,6 +71,7 @@ def test_non_time_query():
"Attributes",
"Deadband",
"DeadbandParameters",
+ "ViewType",
]
assert_array_equal(
df.values,
@@ -86,6 +87,7 @@ def test_non_time_query():
None,
None,
None,
+ "",
]
],
)
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBResultSetIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBResultSetIT.java
index 57e246c09f..d9d006f2fa 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBResultSetIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBResultSetIT.java
@@ -177,6 +177,8 @@ public class IoTDBResultSetIT {
+ ColumnHeaderConstant.DEADBAND
+ ","
+ ColumnHeaderConstant.DEADBAND_PARAMETERS
+ + ","
+ + ColumnHeaderConstant.VIEW_TYPE
+ ",";
resultSetEqualTest("show timeseries root.sg1.**", expectedHeader, emptyResultSet);
}
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBExtendTemplateIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBExtendTemplateIT.java
index 1816c17adc..a1fddcca81 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBExtendTemplateIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBExtendTemplateIT.java
@@ -87,10 +87,10 @@ public class IoTDBExtendTemplateIT extends AbstractSchemaIT {
new Set[] {
new HashSet<>(
Arrays.asList(
- "root.db.d1.s1,null,root.db,INT64,PLAIN,SNAPPY,null,null,null,null,",
- "root.db.d1.s2,null,root.db,DOUBLE,RLE,SNAPPY,null,null,null,null,",
- "root.db.d1.s3,null,root.db,INT64,RLE,SNAPPY,null,null,null,null,",
- "root.db.d1.s4,null,root.db,DOUBLE,GORILLA,SNAPPY,null,null,null,null,"))
+ "root.db.d1.s1,null,root.db,INT64,PLAIN,SNAPPY,null,null,null,null,,",
+ "root.db.d1.s2,null,root.db,DOUBLE,RLE,SNAPPY,null,null,null,null,,",
+ "root.db.d1.s3,null,root.db,INT64,RLE,SNAPPY,null,null,null,null,,",
+ "root.db.d1.s4,null,root.db,DOUBLE,GORILLA,SNAPPY,null,null,null,null,,"))
};
for (int n = 0; n < sqls.length; n++) {
String sql = sqls[n];
@@ -140,18 +140,18 @@ public class IoTDBExtendTemplateIT extends AbstractSchemaIT {
new Set[] {
new HashSet<>(
Arrays.asList(
- "root.db.d1.s1,null,root.db,INT64,PLAIN,SNAPPY,null,null,null,null,",
- "root.db.d1.s2,null,root.db,DOUBLE,RLE,SNAPPY,null,null,null,null,",
- "root.db.d1.s3,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,",
- "root.db.d1.s4,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,",
- "root.db.d1.s5,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,",
- "root.db.d2.s1,null,root.db,INT64,PLAIN,SNAPPY,null,null,null,null,",
- "root.db.d2.s2,null,root.db,DOUBLE,RLE,SNAPPY,null,null,null,null,",
- "root.db.d2.s3,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,",
- "root.db.d2.s4,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,",
- "root.db.d2.s5,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,",
- "root.db1.d1.s2,null,root.db1,FLOAT,GORILLA,SNAPPY,null,null,null,null,",
- "root.db1.d1.s3,null,root.db1,FLOAT,GORILLA,SNAPPY,null,null,null,null,"))
+ "root.db.d1.s1,null,root.db,INT64,PLAIN,SNAPPY,null,null,null,null,,",
+ "root.db.d1.s2,null,root.db,DOUBLE,RLE,SNAPPY,null,null,null,null,,",
+ "root.db.d1.s3,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,,",
+ "root.db.d1.s4,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,,",
+ "root.db.d1.s5,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,,",
+ "root.db.d2.s1,null,root.db,INT64,PLAIN,SNAPPY,null,null,null,null,,",
+ "root.db.d2.s2,null,root.db,DOUBLE,RLE,SNAPPY,null,null,null,null,,",
+ "root.db.d2.s3,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,,",
+ "root.db.d2.s4,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,,",
+ "root.db.d2.s5,null,root.db,FLOAT,GORILLA,SNAPPY,null,null,null,null,,",
+ "root.db1.d1.s2,null,root.db1,FLOAT,GORILLA,SNAPPY,null,null,null,null,,",
+ "root.db1.d1.s3,null,root.db1,FLOAT,GORILLA,SNAPPY,null,null,null,null,,"))
};
for (int n = 0; n < sqls.length; n++) {
String sql = sqls[n];
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBMetadataFetchIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBMetadataFetchIT.java
index 9c877983a2..7c1774d82d 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBMetadataFetchIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBMetadataFetchIT.java
@@ -114,27 +114,27 @@ public class IoTDBMetadataFetchIT extends AbstractSchemaIT {
new Set[] {
new HashSet<>(
Collections.singletonList(
- "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,")),
+ "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,,")),
new HashSet<>(
Arrays.asList(
- "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,",
- "root.ln.wf01.wt01.temperature,null,root.ln.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,",
- "root.ln.wf01.wt02.s1,null,root.ln.wf01.wt02,INT32,RLE,SNAPPY,null,null,null,null,",
- "root.ln.wf01.wt02.s2,null,root.ln.wf01.wt02,DOUBLE,GORILLA,SNAPPY,null,null,null,null,")),
+ "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,,",
+ "root.ln.wf01.wt01.temperature,null,root.ln.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,,",
+ "root.ln.wf01.wt02.s1,null,root.ln.wf01.wt02,INT32,RLE,SNAPPY,null,null,null,null,,",
+ "root.ln.wf01.wt02.s2,null,root.ln.wf01.wt02,DOUBLE,GORILLA,SNAPPY,null,null,null,null,,")),
new HashSet<>(
Arrays.asList(
- "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,",
- "root.ln.wf01.wt01.temperature,null,root.ln.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,")),
+ "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,,",
+ "root.ln.wf01.wt01.temperature,null,root.ln.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,,")),
new HashSet<>(
Arrays.asList(
- "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,",
- "root.ln.wf01.wt01.temperature,null,root.ln.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,",
- "root.ln.wf01.wt02.s1,null,root.ln.wf01.wt02,INT32,RLE,SNAPPY,null,null,null,null,",
- "root.ln.wf01.wt02.s2,null,root.ln.wf01.wt02,DOUBLE,GORILLA,SNAPPY,null,null,null,null,",
- "root.ln1.wf01.wt01.status,null,root.ln1.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,",
- "root.ln1.wf01.wt01.temperature,null,root.ln1.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,",
- "root.ln2.wf01.wt01.status,null,root.ln2.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,",
- "root.ln2.wf01.wt01.temperature,null,root.ln2.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,")),
+ "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,,",
+ "root.ln.wf01.wt01.temperature,null,root.ln.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,,",
+ "root.ln.wf01.wt02.s1,null,root.ln.wf01.wt02,INT32,RLE,SNAPPY,null,null,null,null,,",
+ "root.ln.wf01.wt02.s2,null,root.ln.wf01.wt02,DOUBLE,GORILLA,SNAPPY,null,null,null,null,,",
+ "root.ln1.wf01.wt01.status,null,root.ln1.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,,",
+ "root.ln1.wf01.wt01.temperature,null,root.ln1.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,,",
+ "root.ln2.wf01.wt01.status,null,root.ln2.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,,",
+ "root.ln2.wf01.wt01.temperature,null,root.ln2.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,,")),
new HashSet<>()
};
for (int n = 0; n < sqls.length; n++) {
@@ -623,8 +623,8 @@ public class IoTDBMetadataFetchIT extends AbstractSchemaIT {
"create aligned timeseries root.sg.d(s1(alias1) int32 tags('tag1'='v1', 'tag2'='v2'), s2 double attributes('attr3'='v3'))");
String[] expected =
new String[] {
- "root.sg.d.s1,alias1,root.sg,INT32,RLE,SNAPPY,{\"tag1\":\"v1\",\"tag2\":\"v2\"},null,null,null,",
- "root.sg.d.s2,null,root.sg,DOUBLE,GORILLA,SNAPPY,null,{\"attr3\":\"v3\"},null,null,"
+ "root.sg.d.s1,alias1,root.sg,INT32,RLE,SNAPPY,{\"tag1\":\"v1\",\"tag2\":\"v2\"},null,null,null,,",
+ "root.sg.d.s2,null,root.sg,DOUBLE,GORILLA,SNAPPY,null,{\"attr3\":\"v3\"},null,null,,"
};
int num = 0;
@@ -653,8 +653,8 @@ public class IoTDBMetadataFetchIT extends AbstractSchemaIT {
Set<String> standard =
new HashSet<>(
Arrays.asList(
- "root.ln.wf01.wt01.temperature,null,root.ln.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,",
- "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,"));
+ "root.ln.wf01.wt01.temperature,null,root.ln.wf01.wt01,FLOAT,RLE,SNAPPY,null,null,null,null,,",
+ "root.ln.wf01.wt01.status,null,root.ln.wf01.wt01,BOOLEAN,PLAIN,SNAPPY,null,null,null,null,,"));
try (ResultSet resultSet = statement.executeQuery(sql)) {
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
while (resultSet.next()) {
@@ -691,9 +691,9 @@ public class IoTDBMetadataFetchIT extends AbstractSchemaIT {
Set<String> standard =
new HashSet<>(
Arrays.asList(
- "root.sg1.d0.s0,null,root.sg1,INT32,RLE,SNAPPY,null,null,null,null,\n",
- "root.sg1.d0.s1,null,root.sg1,INT32,PLAIN,SNAPPY,null,null,SDT,{compdev=2},\n",
- "root.sg1.d0.s2,null,root.sg1,INT32,PLAIN,SNAPPY,null,null,SDT,{compdev=0.01, compmintime=2, compmaxtime=15},\n"));
+ "root.sg1.d0.s0,null,root.sg1,INT32,RLE,SNAPPY,null,null,null,null,,\n",
+ "root.sg1.d0.s1,null,root.sg1,INT32,PLAIN,SNAPPY,null,null,SDT,{compdev=2},,\n",
+ "root.sg1.d0.s2,null,root.sg1,INT32,PLAIN,SNAPPY,null,null,SDT,{compdev=0.01, compmintime=2, compmaxtime=15},,\n"));
try (ResultSet resultSet = statement.executeQuery("SHOW TIMESERIES root.sg1.d0.*")) {
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
while (resultSet.next()) {
diff --git a/integration-test/src/test/java/org/apache/iotdb/zeppelin/it/IoTDBInterpreterIT.java b/integration-test/src/test/java/org/apache/iotdb/zeppelin/it/IoTDBInterpreterIT.java
index ba6170c0cb..514b66c13e 100644
--- a/integration-test/src/test/java/org/apache/iotdb/zeppelin/it/IoTDBInterpreterIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/zeppelin/it/IoTDBInterpreterIT.java
@@ -307,13 +307,13 @@ public class IoTDBInterpreterIT {
public void testShowTimeseries() {
InterpreterResult actual = interpreter.internalInterpret("show timeseries", null);
String gt =
- "Timeseries\tAlias\tDatabase\tDataType\tEncoding\tCompression\tTags\tAttributes\tDeadband\tDeadbandParameters\n"
- + "root.test.wf01.wt01.temperature\tnull\troot.test.wf01\tFLOAT\tGORILLA\tSNAPPY\tnull\tnull\tnull\tnull\n"
- + "root.test.wf01.wt01.status\tnull\troot.test.wf01\tBOOLEAN\tRLE\tSNAPPY\tnull\tnull\tnull\tnull\n"
- + "root.test.wf01.wt01.hardware\tnull\troot.test.wf01\tFLOAT\tGORILLA\tSNAPPY\tnull\tnull\tnull\tnull\n"
- + "root.test.wf02.wt02.temperature\tnull\troot.test.wf02\tFLOAT\tGORILLA\tSNAPPY\tnull\tnull\tnull\tnull\n"
- + "root.test.wf02.wt02.status\tnull\troot.test.wf02\tBOOLEAN\tRLE\tSNAPPY\tnull\tnull\tnull\tnull\n"
- + "root.test.wf02.wt02.hardware\tnull\troot.test.wf02\tFLOAT\tGORILLA\tSNAPPY\tnull\tnull\tnull\tnull";
+ "Timeseries\tAlias\tDatabase\tDataType\tEncoding\tCompression\tTags\tAttributes\tDeadband\tDeadbandParameters\tViewType\n"
+ + "root.test.wf01.wt01.temperature\tnull\troot.test.wf01\tFLOAT\tGORILLA\tSNAPPY\tnull\tnull\tnull\tnull\t\n"
+ + "root.test.wf01.wt01.status\tnull\troot.test.wf01\tBOOLEAN\tRLE\tSNAPPY\tnull\tnull\tnull\tnull\t\n"
+ + "root.test.wf01.wt01.hardware\tnull\troot.test.wf01\tFLOAT\tGORILLA\tSNAPPY\tnull\tnull\tnull\tnull\t\n"
+ + "root.test.wf02.wt02.temperature\tnull\troot.test.wf02\tFLOAT\tGORILLA\tSNAPPY\tnull\tnull\tnull\tnull\t\n"
+ + "root.test.wf02.wt02.status\tnull\troot.test.wf02\tBOOLEAN\tRLE\tSNAPPY\tnull\tnull\tnull\tnull\t\n"
+ + "root.test.wf02.wt02.hardware\tnull\troot.test.wf02\tFLOAT\tGORILLA\tSNAPPY\tnull\tnull\tnull\tnull\t";
Assert.assertNotNull(actual);
Assert.assertEquals(Code.SUCCESS, actual.code());
Assert.assertEquals(gt, actual.message().get(0).getData());
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractMeasurementMNode.java b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractMeasurementMNode.java
index 602c5d8d3c..c8338deead 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractMeasurementMNode.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractMeasurementMNode.java
@@ -253,4 +253,8 @@ public abstract class AbstractMeasurementMNode<N extends IMNode<N>, BasicNode ex
public int estimateSize() {
return 8 + 8 + measurementInfo.estimateSize() + basicMNode.estimateSize();
}
+
+ protected IMeasurementInfo getMeasurementInfo() {
+ return this.measurementInfo;
+ }
}
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/role/IMeasurementMNode.java b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/role/IMeasurementMNode.java
index 57ad4dd948..cbee170460 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/role/IMeasurementMNode.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/role/IMeasurementMNode.java
@@ -45,4 +45,6 @@ public interface IMeasurementMNode<N extends IMNode<N>> extends IMNode<N> {
void setPreDeleted(boolean preDeleted);
MeasurementPath getMeasurementPath();
+
+ public abstract boolean isLogicalView();
}
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/utils/IMNodeFactory.java b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/utils/IMNodeFactory.java
index f8aaa669bc..da7a3c1dc5 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/utils/IMNodeFactory.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/utils/IMNodeFactory.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.commons.schema.node.utils;
import org.apache.iotdb.commons.schema.node.IMNode;
+import org.apache.iotdb.commons.schema.node.info.IMeasurementInfo;
import org.apache.iotdb.commons.schema.node.role.IDatabaseMNode;
import org.apache.iotdb.commons.schema.node.role.IDeviceMNode;
import org.apache.iotdb.commons.schema.node.role.IMeasurementMNode;
@@ -39,4 +40,7 @@ public interface IMNodeFactory<N extends IMNode<N>> {
N createAboveDatabaseMNode(N parent, String name);
N createInternalMNode(N parent, String name);
+
+ IMeasurementMNode<N> createLogicalViewMNode(
+ IDeviceMNode<N> parent, String name, IMeasurementInfo measurementInfo);
}
diff --git a/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/RSchemaRegion.java b/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/RSchemaRegion.java
index 4d5d9a9372..23deb238dd 100644
--- a/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/RSchemaRegion.java
+++ b/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/RSchemaRegion.java
@@ -50,6 +50,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.result.ShowTimeSeriesResult;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IActivateTemplateInClusterPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeactivateTemplatePlan;
@@ -702,6 +703,12 @@ public class RSchemaRegion implements ISchemaRegion {
throw new UnsupportedOperationException();
}
+ @Override
+ public void createLogicalView(ICreateLogicalViewPlan createLogicalViewPlan)
+ throws MetadataException {
+ throw new UnsupportedOperationException("createLogicalView is unsupported.");
+ }
+
private void traverseOutcomeBasins(
String[] nodes,
int maxLevel,
diff --git a/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/mnode/RMeasurementMNode.java b/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/mnode/RMeasurementMNode.java
index 58a9708d44..faa398a8dd 100644
--- a/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/mnode/RMeasurementMNode.java
+++ b/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/mnode/RMeasurementMNode.java
@@ -100,6 +100,11 @@ public class RMeasurementMNode extends RMNode implements IMeasurementMNode<IMemM
return result;
}
+ @Override
+ public boolean isLogicalView() {
+ return false;
+ }
+
@Override
public IMeasurementSchema getSchema() {
return schema;
diff --git a/schema-engine-tag/src/main/java/org/apache/iotdb/db/metadata/tagSchemaRegion/TagSchemaRegion.java b/schema-engine-tag/src/main/java/org/apache/iotdb/db/metadata/tagSchemaRegion/TagSchemaRegion.java
index d1f92538bf..cc611a2c67 100644
--- a/schema-engine-tag/src/main/java/org/apache/iotdb/db/metadata/tagSchemaRegion/TagSchemaRegion.java
+++ b/schema-engine-tag/src/main/java/org/apache/iotdb/db/metadata/tagSchemaRegion/TagSchemaRegion.java
@@ -45,6 +45,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.result.ShowTimeSeriesResult;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IActivateTemplateInClusterPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeactivateTemplatePlan;
@@ -342,6 +343,12 @@ public class TagSchemaRegion implements ISchemaRegion {
throw new UnsupportedOperationException("deleteTimeseriesInBlackList");
}
+ @Override
+ public void createLogicalView(ICreateLogicalViewPlan createLogicalViewPlan)
+ throws MetadataException {
+ throw new UnsupportedOperationException("createLogicalView is unsupported.");
+ }
+
private List<String> getDevicePaths(List<IDeviceID> deviceIDS) {
List<String> devicePaths = new ArrayList<>();
if (config.getDeviceIDTransformationMethod().equals("SHA256")) {
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MetadataConstant.java b/server/src/main/java/org/apache/iotdb/db/metadata/MetadataConstant.java
index b498e4d145..f175271c40 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MetadataConstant.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MetadataConstant.java
@@ -64,12 +64,16 @@ public class MetadataConstant {
public static final byte ENTITY_MNODE_TYPE = 3;
public static final byte STORAGE_GROUP_ENTITY_MNODE_TYPE = 4;
+ public static final byte LOGICAL_VIEW_MNODE_TYPE = 5;
+
public static final String INTERNAL_MNODE_TYPE_NAME = "InternalMNode";
public static final String STORAGE_GROUP_MNODE_TYPE_NAME = "StorageGroupMNode";
public static final String MEASUREMENT_MNODE_TYPE_NAME = "MeasurementMNode";
public static final String ENTITY_MNODE_TYPE_NAME = "EntityMNode";
public static final String STORAGE_GROUP_ENTITY_MNODE_TYPE_NAME = "StorageGroupEntityMNode";
+ public static final String LOGICAL_VIEW_MNODE_TYPE_NAME = "LogicalViewMNode";
+
public static final String SCHEMA_REGION_METRIC_NAME = "schema_region";
public static final String SCHEMA_ENGINE_METRIC_NAME = "schema_file";
@@ -87,6 +91,8 @@ public class MetadataConstant {
return ENTITY_MNODE_TYPE_NAME;
case STORAGE_GROUP_ENTITY_MNODE_TYPE:
return STORAGE_GROUP_ENTITY_MNODE_TYPE_NAME;
+ case LOGICAL_VIEW_MNODE_TYPE:
+ return LOGICAL_VIEW_MNODE_TYPE_NAME;
default:
throw new RuntimeException("Undefined MNode type " + type);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/config/factory/ConfigMNodeFactory.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/config/factory/ConfigMNodeFactory.java
index dc1a03e36b..a1a7611d08 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/config/factory/ConfigMNodeFactory.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/config/factory/ConfigMNodeFactory.java
@@ -18,6 +18,7 @@
*/
package org.apache.iotdb.db.metadata.mnode.config.factory;
+import org.apache.iotdb.commons.schema.node.info.IMeasurementInfo;
import org.apache.iotdb.commons.schema.node.role.IDatabaseMNode;
import org.apache.iotdb.commons.schema.node.role.IDeviceMNode;
import org.apache.iotdb.commons.schema.node.role.IMeasurementMNode;
@@ -78,4 +79,10 @@ public class ConfigMNodeFactory implements IMNodeFactory<IConfigMNode> {
public IConfigMNode createInternalMNode(IConfigMNode parent, String name) {
return new ConfigBasicInternalMNode(parent, name);
}
+
+ @Override
+ public IMeasurementMNode<IConfigMNode> createLogicalViewMNode(
+ IDeviceMNode<IConfigMNode> parent, String name, IMeasurementInfo measurementInfo) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/factory/MemMNodeFactory.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/factory/MemMNodeFactory.java
index 24215c1e15..1f4e21f7e1 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/factory/MemMNodeFactory.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/factory/MemMNodeFactory.java
@@ -18,6 +18,7 @@
*/
package org.apache.iotdb.db.metadata.mnode.mem.factory;
+import org.apache.iotdb.commons.schema.node.info.IMeasurementInfo;
import org.apache.iotdb.commons.schema.node.role.IDatabaseMNode;
import org.apache.iotdb.commons.schema.node.role.IDeviceMNode;
import org.apache.iotdb.commons.schema.node.role.IMeasurementMNode;
@@ -28,7 +29,9 @@ import org.apache.iotdb.db.metadata.mnode.mem.impl.BasicInternalMNode;
import org.apache.iotdb.db.metadata.mnode.mem.impl.DatabaseDeviceMNode;
import org.apache.iotdb.db.metadata.mnode.mem.impl.DatabaseMNode;
import org.apache.iotdb.db.metadata.mnode.mem.impl.DeviceMNode;
+import org.apache.iotdb.db.metadata.mnode.mem.impl.LogicalViewMNode;
import org.apache.iotdb.db.metadata.mnode.mem.impl.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.mem.info.LogicalViewInfo;
import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
public class MemMNodeFactory implements IMNodeFactory<IMemMNode> {
@@ -81,4 +84,15 @@ public class MemMNodeFactory implements IMNodeFactory<IMemMNode> {
public IMemMNode createInternalMNode(IMemMNode parent, String name) {
return new BasicInternalMNode(parent, name);
}
+
+ @Override
+ public IMeasurementMNode<IMemMNode> createLogicalViewMNode(
+ IDeviceMNode<IMemMNode> parent, String name, IMeasurementInfo measurementInfo) {
+ if (measurementInfo instanceof LogicalViewInfo) {
+ return new LogicalViewMNode(
+ parent, name, ((LogicalViewInfo) measurementInfo).getExpression());
+ }
+ throw new UnsupportedOperationException(
+ "createLogicalViewMNode should accept LogicalViewInfo, but got an instance that is not of this type.");
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/MeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/LogicalViewMNode.java
similarity index 67%
copy from server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/MeasurementMNode.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/LogicalViewMNode.java
index 79e66a366b..b99b829cde 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/MeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/LogicalViewMNode.java
@@ -16,25 +16,32 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.apache.iotdb.db.metadata.mnode.mem.impl;
import org.apache.iotdb.commons.schema.node.common.AbstractMeasurementMNode;
+import org.apache.iotdb.commons.schema.node.info.IMeasurementInfo;
import org.apache.iotdb.commons.schema.node.role.IDeviceMNode;
import org.apache.iotdb.commons.schema.node.utils.IMNodeContainer;
import org.apache.iotdb.db.metadata.mnode.mem.IMemMNode;
import org.apache.iotdb.db.metadata.mnode.mem.basic.BasicMNode;
import org.apache.iotdb.db.metadata.mnode.mem.container.MemMNodeContainer;
-import org.apache.iotdb.db.metadata.mnode.mem.info.MeasurementInfo;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.db.metadata.mnode.mem.info.LogicalViewInfo;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
-public class MeasurementMNode extends AbstractMeasurementMNode<IMemMNode, BasicMNode>
+public class LogicalViewMNode extends AbstractMeasurementMNode<IMemMNode, BasicMNode>
implements IMemMNode {
- public MeasurementMNode(
- IDeviceMNode<IMemMNode> parent, String name, IMeasurementSchema schema, String alias) {
+ public LogicalViewMNode(
+ IDeviceMNode<IMemMNode> parent, String name, ViewExpression viewExpression) {
super(
new BasicMNode(parent == null ? null : parent.getAsMNode(), name),
- new MeasurementInfo(schema, alias));
+ new LogicalViewInfo(new LogicalViewSchema(name, viewExpression)));
+ }
+
+ @Override
+ public IMNodeContainer<IMemMNode> getChildren() {
+ return MemMNodeContainer.emptyMNodeContainer();
}
@Override
@@ -42,8 +49,15 @@ public class MeasurementMNode extends AbstractMeasurementMNode<IMemMNode, BasicM
return this;
}
+ public void setExpression(ViewExpression expression) {
+ IMeasurementInfo measurementInfo = this.getMeasurementInfo();
+ if (measurementInfo instanceof LogicalViewInfo) {
+ ((LogicalViewInfo) measurementInfo).setExpression(expression);
+ }
+ }
+
@Override
- public IMNodeContainer<IMemMNode> getChildren() {
- return MemMNodeContainer.emptyMNodeContainer();
+ public final boolean isLogicalView() {
+ return true;
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/LogicalViewSchema.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/LogicalViewSchema.java
new file mode 100644
index 0000000000..97dd088b1f
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/LogicalViewSchema.java
@@ -0,0 +1,215 @@
+/*
+ * 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.metadata.mnode.mem.impl;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.tsfile.encoding.encoder.Encoder;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class LogicalViewSchema
+ implements IMeasurementSchema, Comparable<LogicalViewSchema>, Serializable {
+
+ private String measurementId;
+
+ private ViewExpression expression;
+
+ public LogicalViewSchema(String measurementId, ViewExpression expression) {
+ this.measurementId = measurementId;
+ this.expression = expression;
+ }
+
+ @Override
+ public int compareTo(LogicalViewSchema o) {
+ if (equals(o)) {
+ return 0;
+ } else {
+ return this.measurementId.compareTo(o.measurementId);
+ }
+ }
+
+ @Override
+ public String getMeasurementId() {
+ return this.measurementId;
+ }
+
+ @Override
+ public CompressionType getCompressor() {
+ // TODO: CRTODO:add new CompressionType
+ return CompressionType.UNCOMPRESSED;
+ }
+
+ @Override
+ public TSEncoding getEncodingType() {
+ // TODO: CRTODO: add new TSEncoding
+ return TSEncoding.PLAIN;
+ }
+
+ @Override
+ public TSDataType getType() {
+ // TODO: CRTODO: use a dynamic method to compute data type
+ return TSDataType.BOOLEAN;
+ }
+
+ @Override
+ public byte getTypeInByte() {
+ return TSDataType.BOOLEAN.getType();
+ }
+
+ @Override
+ public void setType(TSDataType dataType) {
+ // do nothing
+ }
+
+ @Override
+ public TSEncoding getTimeTSEncoding() {
+ // TODO: CRTODO: add new TSEncoding
+ return TSEncoding.PLAIN;
+ }
+
+ @Override
+ public Encoder getTimeEncoder() {
+ // TODO: CRTODO: is this ok to return a null value?
+ return null;
+ }
+
+ @Override
+ public Encoder getValueEncoder() {
+ // TODO: CRTODO: is this ok to return a null value?
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getProps() {
+ return new HashMap<>();
+ }
+
+ @Override
+ public List<String> getSubMeasurementsList() {
+ throw new UnsupportedOperationException("unsupported method for LogicalViewSchema");
+ }
+
+ @Override
+ public List<TSDataType> getSubMeasurementsTSDataTypeList() {
+ throw new UnsupportedOperationException("unsupported method for LogicalViewSchema");
+ }
+
+ @Override
+ public List<TSEncoding> getSubMeasurementsTSEncodingList() {
+ throw new UnsupportedOperationException("unsupported method for LogicalViewSchema");
+ }
+
+ @Override
+ public List<Encoder> getSubMeasurementsEncoderList() {
+ throw new UnsupportedOperationException("unsupported method for LogicalViewSchema");
+ }
+
+ @Override
+ public int getSubMeasurementIndex(String measurementId) {
+ return this.measurementId.equals(measurementId) ? 0 : -1;
+ }
+
+ @Override
+ public int getSubMeasurementsCount() {
+ return 1;
+ }
+
+ @Override
+ public boolean containsSubMeasurement(String measurementId) {
+ return this.measurementId.equals(measurementId);
+ }
+
+ // region serialize and deserialize
+
+ @Override
+ public int serializedSize() {
+ throw new RuntimeException(
+ new UnsupportedOperationException(
+ "Can not calculate the size of logical view schema before serializing."));
+ }
+
+ @Override
+ public int serializeTo(ByteBuffer buffer) {
+ // TODO: CRTODO: the size of buffer is not calculated!
+ ReadWriteIOUtils.write(measurementId, buffer);
+
+ ViewExpression.serialize(this.expression, buffer);
+ return 0;
+ }
+
+ @Override
+ public int serializeTo(OutputStream outputStream) throws IOException {
+ // TODO: CRTODO: the size of buffer is not calculated!
+ ReadWriteIOUtils.write(measurementId, outputStream);
+
+ ViewExpression.serialize(this.expression, outputStream);
+ return 0;
+ }
+
+ @Override
+ public int partialSerializeTo(ByteBuffer buffer) {
+ return this.serializeTo(buffer);
+ }
+
+ @Override
+ public int partialSerializeTo(OutputStream outputStream) throws IOException {
+ return this.serializeTo(outputStream);
+ }
+
+ public static LogicalViewSchema deserializeFrom(InputStream inputStream) throws IOException {
+ String measurementId = ReadWriteIOUtils.readString(inputStream);
+
+ ViewExpression expression = ViewExpression.deserialize(inputStream);
+
+ LogicalViewSchema logicalViewSchema = new LogicalViewSchema(measurementId, expression);
+ return logicalViewSchema;
+ }
+
+ public static LogicalViewSchema deserializeFrom(ByteBuffer buffer) throws IOException {
+ String measurementId = ReadWriteIOUtils.readString(buffer);
+
+ ViewExpression expression = ViewExpression.deserialize(buffer);
+
+ LogicalViewSchema logicalViewSchema = new LogicalViewSchema(measurementId, expression);
+ return logicalViewSchema;
+ }
+
+ // endregion
+
+ public ViewExpression getExpression() {
+ return this.expression;
+ }
+
+ public void setExpression(ViewExpression expression) {
+ this.expression = expression;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/MeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/MeasurementMNode.java
index 79e66a366b..9c3d16adac 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/MeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/impl/MeasurementMNode.java
@@ -46,4 +46,9 @@ public class MeasurementMNode extends AbstractMeasurementMNode<IMemMNode, BasicM
public IMNodeContainer<IMemMNode> getChildren() {
return MemMNodeContainer.emptyMNodeContainer();
}
+
+ @Override
+ public final boolean isLogicalView() {
+ return false;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/info/LogicalViewInfo.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/info/LogicalViewInfo.java
new file mode 100644
index 0000000000..e264988aff
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/info/LogicalViewInfo.java
@@ -0,0 +1,161 @@
+/*
+ * 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.metadata.mnode.mem.info;
+
+import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.node.info.IMeasurementInfo;
+import org.apache.iotdb.commons.schema.node.role.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.mem.impl.LogicalViewMNode;
+import org.apache.iotdb.db.metadata.mnode.mem.impl.LogicalViewSchema;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimeSeriesViewOperand;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+
+/**
+ * This structure is used in ViewMNode. It stores all information except the name of this view. The
+ * name of the view is stored by ViewMNode.
+ */
+public class LogicalViewInfo implements IMeasurementInfo {
+
+ /** whether this measurement is pre deleted and considered in black list */
+ private boolean preDeleted = false;
+
+ private LogicalViewSchema schema;
+
+ public LogicalViewInfo(LogicalViewSchema schema) {
+ this.schema = schema;
+ }
+
+ // region logical view interfaces
+ public boolean isAliasSeries() {
+ if (this.getExpression() != null) {
+ if (this.getExpression().isSourceForAliasSeries()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** @return return the path of alias series if this view is alias series; else return null. */
+ public PartialPath getAliasSeriesPath() {
+ if (this.isAliasSeries()) {
+ if (this.getExpression().getExpressionType() == ViewExpressionType.TIMESERIES) {
+ String pathString = ((TimeSeriesViewOperand) this.getExpression()).getPathString();
+ try {
+ return new PartialPath(pathString);
+ } catch (IllegalPathException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return null;
+ }
+
+ public ViewExpression getExpression() {
+ return this.schema.getExpression();
+ }
+
+ public void setExpression(ViewExpression expression) {
+ this.schema.setExpression(expression);
+ }
+ // endregion
+
+ // region IMeasurementInfo interfaces
+
+ @Override
+ public IMeasurementSchema getSchema() {
+ return this.schema;
+ }
+
+ @Override
+ public void setSchema(IMeasurementSchema schema) {
+ this.schema = (LogicalViewSchema) schema;
+ }
+
+ @Override
+ public TSDataType getDataType() {
+ return null;
+ }
+
+ @Override
+ public String getAlias() {
+ return null;
+ }
+
+ @Override
+ public void setAlias(String alias) {
+ // can not set alias for a logical view
+ }
+
+ @Override
+ public long getOffset() {
+ // tag/attribute's start offset in tag file
+ return -1;
+ }
+
+ @Override
+ public void setOffset(long offset) {
+ // can not set offset for a logical view
+ }
+
+ @Override
+ public boolean isPreDeleted() {
+ return this.preDeleted;
+ }
+
+ @Override
+ public void setPreDeleted(boolean preDeleted) {
+ this.preDeleted = preDeleted;
+ }
+
+ /**
+ * The memory occupied by an MeasurementInfo based occupation
+ *
+ * <ol>
+ * <li>object header, 8B
+ * <li>boolean preDeleted, 1B
+ * <li>estimated schema size, 32B
+ * <li>viewExpression
+ * </ol>
+ */
+ @Override
+ public int estimateSize() {
+ return 8 + 1 + 32 + 64;
+ }
+
+ @Override
+ public void moveDataToNewMNode(IMeasurementMNode<?> newMNode) {
+ // TODO: CRTODO: is this ok for a logical view?
+ if (newMNode instanceof LogicalViewMNode) {
+ LogicalViewMNode logicalViewMNode = (LogicalViewMNode) newMNode;
+ logicalViewMNode.setSchema(this.schema);
+ logicalViewMNode.setPreDeleted(preDeleted);
+ logicalViewMNode.setExpression(this.getExpression());
+ }
+ throw new RuntimeException(
+ new IllegalArgumentException(
+ "Type of newMNode is not LogicalViewMNode! It's "
+ + newMNode.getMNodeType(false).toString()));
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/schemafile/factory/CacheMNodeFactory.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/schemafile/factory/CacheMNodeFactory.java
index 5e79e03258..75b99bdf22 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/schemafile/factory/CacheMNodeFactory.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/schemafile/factory/CacheMNodeFactory.java
@@ -18,6 +18,7 @@
*/
package org.apache.iotdb.db.metadata.mnode.schemafile.factory;
+import org.apache.iotdb.commons.schema.node.info.IMeasurementInfo;
import org.apache.iotdb.commons.schema.node.role.IDatabaseMNode;
import org.apache.iotdb.commons.schema.node.role.IDeviceMNode;
import org.apache.iotdb.commons.schema.node.role.IMeasurementMNode;
@@ -81,4 +82,10 @@ public class CacheMNodeFactory implements IMNodeFactory<ICachedMNode> {
public ICachedMNode createInternalMNode(ICachedMNode parent, String name) {
return new CachedBasicInternalMNode(parent, name);
}
+
+ @Override
+ public IMeasurementMNode<ICachedMNode> createLogicalViewMNode(
+ IDeviceMNode<ICachedMNode> parent, String name, IMeasurementInfo measurementInfo) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/schemafile/impl/CachedMeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/schemafile/impl/CachedMeasurementMNode.java
index df10e21f74..f82c6b1108 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/schemafile/impl/CachedMeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/schemafile/impl/CachedMeasurementMNode.java
@@ -57,4 +57,9 @@ public class CachedMeasurementMNode extends AbstractMeasurementMNode<ICachedMNod
public IMNodeContainer<ICachedMNode> getChildren() {
return CachedMNodeContainer.emptyMNodeContainer();
}
+
+ @Override
+ public final boolean isLogicalView() {
+ return false;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
index 92b106e0db..e2c0c65150 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
@@ -66,6 +66,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.utils.Pair;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
import org.slf4j.Logger;
@@ -1058,8 +1059,8 @@ public class MTreeBelowSGCachedImpl {
return node.getAlias();
}
- public MeasurementSchema getSchema() {
- return (MeasurementSchema) node.getSchema();
+ public IMeasurementSchema getSchema() {
+ return node.getSchema();
}
public Map<String, String> getTags() {
@@ -1080,6 +1081,11 @@ public class MTreeBelowSGCachedImpl {
return getParentOfNextMatchedNode().getAsDeviceMNode().isAligned();
}
+ @Override
+ public boolean isLogicalView() {
+ return node.isLogicalView();
+ }
+
public String getFullPath() {
return getPartialPathFromRootToNode(node.getAsMNode()).getFullPath();
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
index 8d06137c99..8fb818ca53 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
@@ -42,6 +42,8 @@ import org.apache.iotdb.db.exception.quota.ExceedQuotaException;
import org.apache.iotdb.db.metadata.MetadataConstant;
import org.apache.iotdb.db.metadata.mnode.mem.IMemMNode;
import org.apache.iotdb.db.metadata.mnode.mem.factory.MemMNodeFactory;
+import org.apache.iotdb.db.metadata.mnode.mem.impl.LogicalViewSchema;
+import org.apache.iotdb.db.metadata.mnode.mem.info.LogicalViewInfo;
import org.apache.iotdb.db.metadata.mtree.store.MemMTreeStore;
import org.apache.iotdb.db.metadata.mtree.traverser.Traverser;
import org.apache.iotdb.db.metadata.mtree.traverser.TraverserWithLimitOffsetWrapper;
@@ -64,12 +66,14 @@ import org.apache.iotdb.db.metadata.query.reader.ISchemaReader;
import org.apache.iotdb.db.metadata.rescon.MemSchemaRegionStatistics;
import org.apache.iotdb.db.metadata.template.Template;
import org.apache.iotdb.db.metadata.utils.MetaFormatUtils;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
import org.apache.iotdb.db.quotas.DataNodeSpaceQuotaManager;
import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.utils.Pair;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
import java.io.File;
@@ -898,8 +902,8 @@ public class MTreeBelowSGMemoryImpl {
return node.getAlias();
}
- public MeasurementSchema getSchema() {
- return (MeasurementSchema) node.getSchema();
+ public IMeasurementSchema getSchema() {
+ return node.getSchema();
}
public Map<String, String> getTags() {
@@ -920,6 +924,11 @@ public class MTreeBelowSGMemoryImpl {
return getParentOfNextMatchedNode().getAsDeviceMNode().isAligned();
}
+ @Override
+ public boolean isLogicalView() {
+ return node.isLogicalView();
+ }
+
public String getFullPath() {
return getPartialPathFromRootToNode(node.getAsMNode()).getFullPath();
}
@@ -1000,4 +1009,66 @@ public class MTreeBelowSGMemoryImpl {
};
}
// endregion
+
+ // region interfaces for logical view
+ public IMeasurementMNode<IMemMNode> createLogicalView(
+ PartialPath path, ViewExpression viewExpression) throws MetadataException {
+ // check path
+ String[] nodeNames = path.getNodes();
+ if (nodeNames.length <= 2) {
+ throw new IllegalPathException(path.getFullPath());
+ }
+ MetaFormatUtils.checkTimeseries(path);
+ PartialPath devicePath = path.getDevicePath();
+ IMemMNode deviceParent = checkAndAutoCreateInternalPath(devicePath);
+
+ synchronized (this) {
+ IMemMNode device = checkAndAutoCreateDeviceNode(devicePath.getTailNode(), deviceParent);
+
+ String leafName = path.getMeasurement();
+
+ // no need to check alias, because logical view has no alias
+
+ if (device.hasChild(leafName)) {
+ IMemMNode node = device.getChild(leafName);
+ if (node.isMeasurement()) {
+ if (node.getAsMeasurementMNode().isPreDeleted()) {
+ throw new MeasurementInBlackListException(path);
+ } else {
+ throw new MeasurementAlreadyExistException(
+ path.getFullPath(), node.getAsMeasurementMNode().getMeasurementPath());
+ }
+ } else {
+ throw new PathAlreadyExistException(path.getFullPath());
+ }
+ }
+
+ if (device.isDevice() && device.getAsDeviceMNode().isAligned()) {
+ throw new AlignedTimeseriesException(
+ "timeseries under this entity is aligned, can not create view under this entity.",
+ device.getFullPath());
+ }
+
+ IDeviceMNode<IMemMNode> entityMNode;
+ if (device.isDevice()) {
+ entityMNode = device.getAsDeviceMNode();
+ } else {
+ entityMNode = store.setToEntity(device);
+ if (entityMNode.isDatabase()) {
+ replaceStorageGroupMNode(entityMNode.getAsDatabaseMNode());
+ }
+ }
+
+ IMeasurementMNode<IMemMNode> measurementMNode =
+ nodeFactory.createLogicalViewMNode(
+ entityMNode,
+ leafName,
+ new LogicalViewInfo(new LogicalViewSchema(leafName, viewExpression)));
+
+ store.addChild(entityMNode.getAsMNode(), leafName, measurementMNode.getAsMNode());
+
+ return measurementMNode;
+ }
+ }
+ // endregion
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/snapshot/MemMTreeSnapshotUtil.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/snapshot/MemMTreeSnapshotUtil.java
index 7da7632185..6f45ae7baf 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/snapshot/MemMTreeSnapshotUtil.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/snapshot/MemMTreeSnapshotUtil.java
@@ -33,6 +33,8 @@ import org.apache.iotdb.commons.schema.node.visitor.MNodeVisitor;
import org.apache.iotdb.db.metadata.MetadataConstant;
import org.apache.iotdb.db.metadata.mnode.mem.IMemMNode;
import org.apache.iotdb.db.metadata.mnode.mem.factory.MemMNodeFactory;
+import org.apache.iotdb.db.metadata.mnode.mem.impl.LogicalViewSchema;
+import org.apache.iotdb.db.metadata.mnode.mem.info.LogicalViewInfo;
import org.apache.iotdb.db.metadata.mtree.store.MemMTreeStore;
import org.apache.iotdb.db.metadata.rescon.MemSchemaRegionStatistics;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
@@ -55,6 +57,7 @@ import java.util.function.Consumer;
import static org.apache.iotdb.db.metadata.MetadataConstant.ENTITY_MNODE_TYPE;
import static org.apache.iotdb.db.metadata.MetadataConstant.INTERNAL_MNODE_TYPE;
+import static org.apache.iotdb.db.metadata.MetadataConstant.LOGICAL_VIEW_MNODE_TYPE;
import static org.apache.iotdb.db.metadata.MetadataConstant.MEASUREMENT_MNODE_TYPE;
import static org.apache.iotdb.db.metadata.MetadataConstant.STORAGE_GROUP_ENTITY_MNODE_TYPE;
import static org.apache.iotdb.db.metadata.MetadataConstant.STORAGE_GROUP_MNODE_TYPE;
@@ -240,6 +243,10 @@ public class MemMTreeSnapshotUtil {
node = deserializer.deserializeMeasurementMNode(inputStream);
measurementProcess.accept(node.getAsMeasurementMNode());
break;
+ case LOGICAL_VIEW_MNODE_TYPE:
+ childrenNum = 0;
+ node = deserializer.deserializeLogicalViewMNode(inputStream);
+ measurementProcess.accept(node.getAsMeasurementMNode());
default:
throw new IOException("Unrecognized MNode type " + type);
}
@@ -327,14 +334,24 @@ public class MemMTreeSnapshotUtil {
public Boolean visitMeasurementMNode(
AbstractMeasurementMNode<?, ? extends IMNode<?>> node, OutputStream outputStream) {
try {
- ReadWriteIOUtils.write(MEASUREMENT_MNODE_TYPE, outputStream);
- ReadWriteIOUtils.write(node.getName(), outputStream);
- node.getSchema().serializeTo(outputStream);
- ReadWriteIOUtils.write(node.getAlias(), outputStream);
- ReadWriteIOUtils.write(node.getOffset(), outputStream);
- ReadWriteIOUtils.write(node.isPreDeleted(), outputStream);
- return true;
- } catch (IOException e) {
+ if (node.isMeasurement()) {
+ if (node.isLogicalView()) {
+ ReadWriteIOUtils.write(LOGICAL_VIEW_MNODE_TYPE, outputStream);
+ ReadWriteIOUtils.write(node.getName(), outputStream);
+ node.getSchema().serializeTo(outputStream);
+ } else {
+ ReadWriteIOUtils.write(MEASUREMENT_MNODE_TYPE, outputStream);
+ ReadWriteIOUtils.write(node.getName(), outputStream);
+ node.getSchema().serializeTo(outputStream);
+ ReadWriteIOUtils.write(node.getAlias(), outputStream);
+ ReadWriteIOUtils.write(node.getOffset(), outputStream);
+ ReadWriteIOUtils.write(node.isPreDeleted(), outputStream);
+ }
+ return true;
+ }
+ throw new IllegalArgumentException(
+ "visitMeasurementMNode got unknown node type" + node.getMNodeType(false).toString());
+ } catch (Exception e) {
logger.error(SERIALIZE_ERROR_INFO, e);
return false;
}
@@ -394,5 +411,13 @@ public class MemMTreeSnapshotUtil {
node.setPreDeleted(ReadWriteIOUtils.readBool(inputStream));
return node.getAsMNode();
}
+
+ public IMemMNode deserializeLogicalViewMNode(InputStream inputStream) throws IOException {
+ String name = ReadWriteIOUtils.readString(inputStream);
+ LogicalViewSchema logicalViewSchema = LogicalViewSchema.deserializeFrom(inputStream);
+ IMeasurementMNode<IMemMNode> node =
+ nodeFactory.createLogicalViewMNode(null, name, new LogicalViewInfo(logicalViewSchema));
+ return node.getAsMNode();
+ }
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/SchemaRegionPlanType.java b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/SchemaRegionPlanType.java
index e6f0601304..0d36c80161 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/SchemaRegionPlanType.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/SchemaRegionPlanType.java
@@ -44,6 +44,8 @@ public enum SchemaRegionPlanType {
PRE_DEACTIVATE_TEMPLATE((byte) 0),
ROLLBACK_PRE_DEACTIVATE_TEMPLATE((byte) 1),
DEACTIVATE_TEMPLATE((byte) 2),
+ // logical view
+ CREATE_LOGICAL_VIEW((byte) 66),
// query plan doesn't need any ser/deSer, thus use one type to represent all
READ_SCHEMA(Byte.MAX_VALUE);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/SchemaRegionPlanVisitor.java b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/SchemaRegionPlanVisitor.java
index 355480f96c..e6d145139a 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/SchemaRegionPlanVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/SchemaRegionPlanVisitor.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IAutoCreateDeviceMNo
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeAliasPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeTagOffsetPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeleteTimeSeriesPlan;
@@ -89,4 +90,8 @@ public abstract class SchemaRegionPlanVisitor<R, C> {
public R visitDeactivateTemplate(IDeactivateTemplatePlan deactivateTemplatePlan, C context) {
return visitSchemaRegionPlan(deactivateTemplatePlan, context);
}
+
+ public R visitCreateLogicalView(ICreateLogicalViewPlan createLogicalViewPlan, C context) {
+ return visitSchemaRegionPlan(createLogicalViewPlan, context);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanDeserializer.java b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanDeserializer.java
index 4fdcd33187..872567109a 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanDeserializer.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanDeserializer.java
@@ -32,6 +32,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IAutoCreateDeviceMNo
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeAliasPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeTagOffsetPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeleteTimeSeriesPlan;
@@ -39,6 +40,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeactivateTempla
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeleteTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IRollbackPreDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IRollbackPreDeleteTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
@@ -337,5 +339,27 @@ public class SchemaRegionPlanDeserializer implements IDeserializer<ISchemaRegion
}
return result;
}
+
+ @Override
+ public ISchemaRegionPlan visitCreateLogicalView(
+ ICreateLogicalViewPlan createLogicalViewPlan, ByteBuffer buffer) {
+
+ int viewSize = buffer.getInt();
+ Map<PartialPath, ViewExpression> viewPathToSourceMap = new HashMap<>();
+ for (int i = 0; i < viewSize; i++) {
+ int byteSizeOfPath = buffer.getInt();
+ byte[] bytesOfPath = new byte[byteSizeOfPath];
+ buffer.get(bytesOfPath);
+ try {
+ PartialPath thisPath = new PartialPath(new String(bytesOfPath));
+ ViewExpression thisExp = ViewExpression.deserialize(buffer);
+ viewPathToSourceMap.put(thisPath, thisExp);
+ } catch (IllegalPathException e) {
+ LOGGER.error("Cannot deserialize SchemaRegionPlan from buffer", e);
+ }
+ }
+ createLogicalViewPlan.setViewPathToSourceExpressionMap(viewPathToSourceMap);
+ return createLogicalViewPlan;
+ }
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanSerializer.java b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanSerializer.java
index d421211663..afaebf7a32 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanSerializer.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanSerializer.java
@@ -28,6 +28,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IAutoCreateDeviceMNo
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeAliasPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeTagOffsetPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeleteTimeSeriesPlan;
@@ -35,6 +36,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeactivateTempla
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeleteTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IRollbackPreDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IRollbackPreDeleteTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
@@ -397,5 +399,30 @@ public class SchemaRegionPlanSerializer implements ISerializer<ISchemaRegionPlan
}
}
}
+
+ @Override
+ public SchemaRegionPlanSerializationResult visitCreateLogicalView(
+ ICreateLogicalViewPlan createLogicalViewPlan, DataOutputStream dataOutputStream) {
+ try {
+ int viewSize = createLogicalViewPlan.getViewSize();
+ // serialize size of views
+ dataOutputStream.writeInt(viewSize);
+ List<PartialPath> viewPAthList = createLogicalViewPlan.getViewPathList();
+ Map<PartialPath, ViewExpression> viewPathToSourceMap =
+ createLogicalViewPlan.getViewPathToSourceExpressionMap();
+ for (int i = 0; i < viewSize; i++) {
+ PartialPath thisPath = viewPAthList.get(i);
+ ViewExpression thisExp = viewPathToSourceMap.get(thisPath);
+ // for each view, serialize info of it
+ byte[] bytes = thisPath.getFullPath().getBytes();
+ dataOutputStream.writeInt(bytes.length);
+ dataOutputStream.write(bytes);
+ ViewExpression.serialize(thisExp, dataOutputStream);
+ }
+ return SchemaRegionPlanSerializationResult.SUCCESS;
+ } catch (IOException e) {
+ return new SchemaRegionPlanSerializationResult(e);
+ }
+ }
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanTxtSerializer.java b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanTxtSerializer.java
index c820f0db95..5cbf7b6eb6 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanTxtSerializer.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/SchemaRegionPlanTxtSerializer.java
@@ -28,6 +28,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IAutoCreateDeviceMNo
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeAliasPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeTagOffsetPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeleteTimeSeriesPlan;
@@ -35,6 +36,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeactivateTempla
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeleteTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IRollbackPreDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IRollbackPreDeleteTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
@@ -240,5 +242,24 @@ public class SchemaRegionPlanTxtSerializer implements ISerializer<ISchemaRegionP
templateSetInfo.forEach((k, v) -> stringBuilder.append(k).append(": ").append(v).append(";"));
stringBuilder.append("}");
}
+
+ @Override
+ public Void visitCreateLogicalView(
+ ICreateLogicalViewPlan createLogicalViewPlan, StringBuilder stringBuilder) {
+ int viewSize = createLogicalViewPlan.getViewSize();
+ List<PartialPath> viewPathList = createLogicalViewPlan.getViewPathList();
+ Map<PartialPath, ViewExpression> viewPathToSourceMap =
+ createLogicalViewPlan.getViewPathToSourceExpressionMap();
+ for (int i = 0; i < viewSize; i++) {
+ PartialPath thisPath = viewPathList.get(i);
+ ViewExpression thisExp = viewPathToSourceMap.get(thisPath);
+ stringBuilder.append(thisPath).append(FIELD_SEPARATOR).append(thisExp.toString());
+ if (i + 1 >= viewSize) {
+ break;
+ }
+ stringBuilder.append(FIELD_SEPARATOR);
+ }
+ return null;
+ }
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/write/CreateLogicalViewPlanImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/write/CreateLogicalViewPlanImpl.java
new file mode 100644
index 0000000000..f871cb54b5
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/impl/write/CreateLogicalViewPlanImpl.java
@@ -0,0 +1,75 @@
+/*
+ * 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.metadata.plan.schemaregion.impl.write;
+
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CreateLogicalViewPlanImpl implements ICreateLogicalViewPlan {
+
+ private PartialPath targetPath;
+ private ViewExpression sourceExpression;
+
+ public CreateLogicalViewPlanImpl(PartialPath targetPath, ViewExpression sourceExpression) {
+ this.targetPath = targetPath;
+ this.sourceExpression = sourceExpression;
+ }
+
+ @Override
+ public int getViewSize() {
+ return 1;
+ }
+
+ @Override
+ public Map<PartialPath, ViewExpression> getViewPathToSourceExpressionMap() {
+ Map<PartialPath, ViewExpression> result = new HashMap<>();
+ result.put(this.targetPath, this.sourceExpression);
+ return result;
+ }
+
+ @Override
+ public List<PartialPath> getViewPathList() {
+ return Collections.singletonList(this.targetPath);
+ }
+
+ @Override
+ public void setViewPathToSourceExpressionMap(
+ Map<PartialPath, ViewExpression> viewPathToSourceExpressionMap) {
+ for (Map.Entry<PartialPath, ViewExpression> entry : viewPathToSourceExpressionMap.entrySet()) {
+ this.targetPath = entry.getKey();
+ this.sourceExpression = entry.getValue();
+ break;
+ }
+ }
+
+ public PartialPath getTargetPath() {
+ return this.targetPath;
+ }
+
+ public ViewExpression getSourceExpression() {
+ return this.sourceExpression;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/result/ShowTimeSeriesResult.java b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/result/ShowTimeSeriesResult.java
index bbd5065166..37512da58c 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/result/ShowTimeSeriesResult.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/result/ShowTimeSeriesResult.java
@@ -18,11 +18,12 @@
*/
package org.apache.iotdb.db.metadata.plan.schemaregion.result;
+import org.apache.iotdb.db.metadata.mnode.mem.impl.LogicalViewSchema;
import org.apache.iotdb.db.metadata.query.info.ITimeSeriesSchemaInfo;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
-import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
import java.util.Map;
import java.util.Objects;
@@ -31,7 +32,7 @@ public class ShowTimeSeriesResult extends ShowSchemaResult implements ITimeSerie
private String alias;
- private MeasurementSchema measurementSchema;
+ private IMeasurementSchema measurementSchema;
private Map<String, String> tags;
private Map<String, String> attributes;
@@ -41,7 +42,7 @@ public class ShowTimeSeriesResult extends ShowSchemaResult implements ITimeSerie
public ShowTimeSeriesResult(
String name,
String alias,
- MeasurementSchema measurementSchema,
+ IMeasurementSchema measurementSchema,
Map<String, String> tags,
Map<String, String> attributes,
boolean isUnderAlignedDevice) {
@@ -62,7 +63,7 @@ public class ShowTimeSeriesResult extends ShowSchemaResult implements ITimeSerie
}
@Override
- public MeasurementSchema getSchema() {
+ public IMeasurementSchema getSchema() {
return measurementSchema;
}
@@ -81,6 +82,11 @@ public class ShowTimeSeriesResult extends ShowSchemaResult implements ITimeSerie
return isUnderAlignedDevice;
}
+ @Override
+ public boolean isLogicalView() {
+ return this.measurementSchema instanceof LogicalViewSchema;
+ }
+
public TSDataType getDataType() {
return measurementSchema.getType();
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/write/ICreateLogicalViewPlan.java b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/write/ICreateLogicalViewPlan.java
new file mode 100644
index 0000000000..33c6a399fb
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/write/ICreateLogicalViewPlan.java
@@ -0,0 +1,66 @@
+/*
+ * 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.metadata.plan.schemaregion.write;
+
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.plan.schemaregion.ISchemaRegionPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.SchemaRegionPlanType;
+import org.apache.iotdb.db.metadata.plan.schemaregion.SchemaRegionPlanVisitor;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ICreateLogicalViewPlan extends ISchemaRegionPlan {
+ @Override
+ default SchemaRegionPlanType getPlanType() {
+ return SchemaRegionPlanType.CREATE_LOGICAL_VIEW;
+ }
+
+ @Override
+ default <R, C> R accept(SchemaRegionPlanVisitor<R, C> visitor, C context) {
+ return visitor.visitCreateLogicalView(this, context);
+ }
+
+ /**
+ * Get how many views will be created.
+ *
+ * @return the number of views that will be created
+ */
+ int getViewSize();
+
+ /** @return return a map, from view path (the targets) to source expression. */
+ Map<PartialPath, ViewExpression> getViewPathToSourceExpressionMap();
+
+ /** @return return a list of target paths (paths of views). */
+ List<PartialPath> getViewPathList();
+
+ /**
+ * @param viewPathToSourceExpressionMap a map from view path (the targets) to source expression.
+ */
+ void setViewPathToSourceExpressionMap(
+ Map<PartialPath, ViewExpression> viewPathToSourceExpressionMap);
+
+ // /**
+ // * @param partialPaths a list of partialPaths. Will be transformed into expressions then set
+ // as source. (source timeseries or expressions in query statement)
+ // */
+ // void setSourceByPartialPath(List<PartialPath> partialPaths);
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/query/info/ITimeSeriesSchemaInfo.java b/server/src/main/java/org/apache/iotdb/db/metadata/query/info/ITimeSeriesSchemaInfo.java
index 94f487a917..577d5f49b3 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/query/info/ITimeSeriesSchemaInfo.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/query/info/ITimeSeriesSchemaInfo.java
@@ -19,7 +19,7 @@
package org.apache.iotdb.db.metadata.query.info;
-import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
import java.util.Map;
@@ -27,11 +27,13 @@ public interface ITimeSeriesSchemaInfo extends ISchemaInfo {
String getAlias();
- MeasurementSchema getSchema();
+ IMeasurementSchema getSchema();
Map<String, String> getTags();
Map<String, String> getAttributes();
boolean isUnderAlignedDevice();
+
+ boolean isLogicalView();
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/ISchemaRegion.java b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/ISchemaRegion.java
index 97febd7ce5..1dcac009dc 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/ISchemaRegion.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/ISchemaRegion.java
@@ -31,6 +31,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowNodesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IActivateTemplateInClusterPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IPreDeactivateTemplatePlan;
@@ -162,6 +163,10 @@ public interface ISchemaRegion {
void deleteTimeseriesInBlackList(PathPatternTree patternTree) throws MetadataException;
// endregion
+ // region Interfaces for Logical View
+ void createLogicalView(ICreateLogicalViewPlan createLogicalViewPlan) throws MetadataException;
+ // endregion
+
// region Interfaces for metadata info Query
// region Interfaces for timeseries, measurement and schema info Query
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionMemoryImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionMemoryImpl.java
index bdd8300746..d511c34ee9 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionMemoryImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionMemoryImpl.java
@@ -60,6 +60,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IAutoCreateDeviceMNo
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeAliasPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeTagOffsetPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeleteTimeSeriesPlan;
@@ -74,6 +75,7 @@ import org.apache.iotdb.db.metadata.query.reader.ISchemaReader;
import org.apache.iotdb.db.metadata.rescon.MemSchemaRegionStatistics;
import org.apache.iotdb.db.metadata.tag.TagManager;
import org.apache.iotdb.db.metadata.template.Template;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
import org.apache.iotdb.db.utils.SchemaUtils;
import org.apache.iotdb.external.api.ISeriesNumerMonitor;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -781,6 +783,44 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
}
}
+ @Override
+ public void createLogicalView(ICreateLogicalViewPlan plan) throws MetadataException {
+ if (!regionStatistics.isAllowToCreateNewSeries()) {
+ throw new SeriesOverflowException();
+ }
+
+ try {
+ List<PartialPath> pathList = plan.getViewPathList();
+ Map<PartialPath, ViewExpression> viewPathToSourceMap =
+ plan.getViewPathToSourceExpressionMap();
+ for (PartialPath path : pathList) {
+ try {
+ if (seriesNumberMonitor != null && !seriesNumberMonitor.addTimeSeries(1)) {
+ throw new SeriesNumberOverflowException();
+ }
+
+ // create one logical view
+ IMeasurementMNode<IMemMNode> leafMNode;
+ leafMNode = mtree.createLogicalView(path, viewPathToSourceMap.get(path));
+ } catch (Throwable t) {
+ if (seriesNumberMonitor != null) {
+ seriesNumberMonitor.deleteTimeSeries(1);
+ }
+ throw t;
+ }
+ }
+ // write log
+ if (!isRecovering) {
+ writeToMLog(plan);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ // update statistics
+ regionStatistics.addTimeseries(1L);
+ // TODO: CRTODO: shall we update id table?
+ }
+
private void deleteSingleTimeseriesInBlackList(PartialPath path)
throws MetadataException, IOException {
IMeasurementMNode<IMemMNode> measurementMNode = mtree.deleteTimeseries(path);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionSchemaFileImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionSchemaFileImpl.java
index 522c4e87e0..f54068f4de 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionSchemaFileImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionSchemaFileImpl.java
@@ -63,6 +63,7 @@ import org.apache.iotdb.db.metadata.plan.schemaregion.write.IAutoCreateDeviceMNo
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeAliasPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IChangeTagOffsetPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeactivateTemplatePlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.IDeleteTimeSeriesPlan;
@@ -891,6 +892,12 @@ public class SchemaRegionSchemaFileImpl implements ISchemaRegion {
}
}
+ @Override
+ public void createLogicalView(ICreateLogicalViewPlan createLogicalViewPlan)
+ throws MetadataException {
+ throw new UnsupportedOperationException("createLogicalView is unsupported.");
+ }
+
private void deleteSingleTimeseriesInBlackList(PartialPath path)
throws MetadataException, IOException {
IMeasurementMNode<ICachedMNode> measurementMNode = mtree.deleteTimeseries(path);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ViewExpression.java
new file mode 100644
index 0000000000..9a37eff104
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ViewExpression.java
@@ -0,0 +1,318 @@
+/*
+ * 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.metadata.view.viewExpression;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.AdditionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.DivisionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.ModuloViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.MultiplicationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.SubtractionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.EqualToViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.GreaterEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.GreaterThanViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.LessEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.LessThanViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.NonEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicAndViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicOrViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.ConstantViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.NullViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimeSeriesViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimestampViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.multi.FunctionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ternary.BetweenViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.InViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.IsNullViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.LikeViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.LogicNotViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.NegationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.RegularViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * This is a class designed for views, such as logical views. The view expression is a simple sketch
+ * of an expression. A view expression stores less information, that make it easier to store and
+ * serialize.
+ *
+ * <p>A view expression has to be transformed into expression in same type before analyzing. Also,
+ * an expression should be transformed into view expression before storage in views.
+ */
+public abstract class ViewExpression {
+
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitExpression(this, context);
+ }
+
+ public abstract ViewExpressionType getExpressionType();
+
+ /** @return if this view expression is a leaf node, return true; else return false. */
+ public final boolean isLeafOperand() {
+ return isLeafOperandInternal();
+ }
+
+ protected abstract boolean isLeafOperandInternal();
+
+ /**
+ * @return return the DIRECT children view expressions if it has any, otherwise an EMPTY list will
+ * be returned
+ */
+ public abstract List<ViewExpression> getChildViewExpressions();
+
+ /**
+ * @return if this view expression could be a source for an ALIAS series (one kind of view),
+ * return true; else return false. Foe example, a SINGLE TimeSeriesOperand could be a source
+ * for an alias view.
+ */
+ public final boolean isSourceForAliasSeries() {
+ if (this.getExpressionType().getExpressionTypeInShortEnum()
+ == ViewExpressionType.TIMESERIES.getExpressionTypeInShortEnum()) {
+ return true;
+ }
+ return false;
+ }
+
+ public String toString() {
+ return this.toString(true);
+ }
+
+ public abstract String toString(boolean isRoot);
+
+ // region methods for serializing and deserializing
+ protected abstract void serialize(ByteBuffer byteBuffer);
+
+ protected abstract void serialize(OutputStream stream) throws IOException;
+
+ public static void serialize(ViewExpression expression, ByteBuffer byteBuffer) {
+ ReadWriteIOUtils.write(
+ expression.getExpressionType().getExpressionTypeInShortEnum(), byteBuffer);
+
+ expression.serialize(byteBuffer);
+ }
+
+ public static void serialize(ViewExpression expression, OutputStream stream) throws IOException {
+ ReadWriteIOUtils.write(expression.getExpressionType().getExpressionTypeInShortEnum(), stream);
+
+ expression.serialize(stream);
+ }
+
+ public static ViewExpression deserialize(ByteBuffer byteBuffer) {
+ short type = ReadWriteIOUtils.readShort(byteBuffer);
+
+ ViewExpression expression;
+ switch (type) {
+ case -4:
+ expression = new ConstantViewOperand(byteBuffer);
+ case -3:
+ expression = new TimestampViewOperand(byteBuffer);
+ break;
+ case -2:
+ expression = new TimeSeriesViewOperand(byteBuffer);
+ break;
+ case -1:
+ expression = new FunctionViewExpression(byteBuffer);
+ break;
+
+ case 0:
+ expression = new NegationViewExpression(byteBuffer);
+ break;
+ case 1:
+ expression = new LogicNotViewExpression(byteBuffer);
+ break;
+
+ case 2:
+ expression = new MultiplicationViewExpression(byteBuffer);
+ break;
+ case 3:
+ expression = new DivisionViewExpression(byteBuffer);
+ break;
+ case 4:
+ expression = new ModuloViewExpression(byteBuffer);
+ break;
+
+ case 5:
+ expression = new AdditionViewExpression(byteBuffer);
+ break;
+ case 6:
+ expression = new SubtractionViewExpression(byteBuffer);
+ break;
+
+ case 7:
+ expression = new EqualToViewExpression(byteBuffer);
+ break;
+ case 8:
+ expression = new NonEqualViewExpression(byteBuffer);
+ break;
+ case 9:
+ expression = new GreaterEqualViewExpression(byteBuffer);
+ break;
+ case 10:
+ expression = new GreaterThanViewExpression(byteBuffer);
+ break;
+ case 11:
+ expression = new LessEqualViewExpression(byteBuffer);
+ break;
+ case 12:
+ expression = new LessThanViewExpression(byteBuffer);
+ break;
+
+ case 13:
+ expression = new LikeViewExpression(byteBuffer);
+ break;
+ case 14:
+ expression = new RegularViewExpression(byteBuffer);
+ break;
+
+ case 15:
+ expression = new IsNullViewExpression(byteBuffer);
+ break;
+
+ case 16:
+ expression = new BetweenViewExpression(byteBuffer);
+ break;
+
+ case 17:
+ expression = new InViewExpression(byteBuffer);
+ break;
+
+ case 18:
+ expression = new LogicAndViewExpression(byteBuffer);
+ break;
+
+ case 19:
+ expression = new LogicOrViewExpression(byteBuffer);
+ break;
+
+ case 20:
+ expression = new NullViewOperand();
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid viewExpression type: " + type);
+ }
+ return expression;
+ }
+
+ public static ViewExpression deserialize(InputStream inputStream) {
+ try {
+ short type = ReadWriteIOUtils.readShort(inputStream);
+
+ ViewExpression expression;
+ switch (type) {
+ case -4:
+ expression = new ConstantViewOperand(inputStream);
+ case -3:
+ expression = new TimestampViewOperand(inputStream);
+ break;
+ case -2:
+ expression = new TimeSeriesViewOperand(inputStream);
+ break;
+ case -1:
+ expression = new FunctionViewExpression(inputStream);
+ break;
+
+ case 0:
+ expression = new NegationViewExpression(inputStream);
+ break;
+ case 1:
+ expression = new LogicNotViewExpression(inputStream);
+ break;
+
+ case 2:
+ expression = new MultiplicationViewExpression(inputStream);
+ break;
+ case 3:
+ expression = new DivisionViewExpression(inputStream);
+ break;
+ case 4:
+ expression = new ModuloViewExpression(inputStream);
+ break;
+
+ case 5:
+ expression = new AdditionViewExpression(inputStream);
+ break;
+ case 6:
+ expression = new SubtractionViewExpression(inputStream);
+ break;
+
+ case 7:
+ expression = new EqualToViewExpression(inputStream);
+ break;
+ case 8:
+ expression = new NonEqualViewExpression(inputStream);
+ break;
+ case 9:
+ expression = new GreaterEqualViewExpression(inputStream);
+ break;
+ case 10:
+ expression = new GreaterThanViewExpression(inputStream);
+ break;
+ case 11:
+ expression = new LessEqualViewExpression(inputStream);
+ break;
+ case 12:
+ expression = new LessThanViewExpression(inputStream);
+ break;
+
+ case 13:
+ expression = new LikeViewExpression(inputStream);
+ break;
+ case 14:
+ expression = new RegularViewExpression(inputStream);
+ break;
+
+ case 15:
+ expression = new IsNullViewExpression(inputStream);
+ break;
+
+ case 16:
+ expression = new BetweenViewExpression(inputStream);
+ break;
+
+ case 17:
+ expression = new InViewExpression(inputStream);
+ break;
+
+ case 18:
+ expression = new LogicAndViewExpression(inputStream);
+ break;
+
+ case 19:
+ expression = new LogicOrViewExpression(inputStream);
+ break;
+
+ case 20:
+ expression = new NullViewOperand();
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid viewExpression type: " + type);
+ }
+ return expression;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // end region
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ViewExpressionType.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ViewExpressionType.java
new file mode 100644
index 0000000000..a0134f27eb
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ViewExpressionType.java
@@ -0,0 +1,76 @@
+/*
+ * 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.metadata.view.viewExpression;
+
+public enum ViewExpressionType {
+ CONSTANT((short) -4, (short) 1400),
+ TIMESTAMP((short) -3, (short) 1300),
+ TIMESERIES((short) -2, (short) 1200),
+ FUNCTION((short) -1, (short) 1100),
+
+ NEGATION((short) 0, (short) 1000),
+ LOGIC_NOT((short) 1, (short) 1000),
+
+ MULTIPLICATION((short) 2, (short) 900),
+ DIVISION((short) 3, (short) 900),
+ MODULO((short) 4, (short) 900),
+
+ ADDITION((short) 5, (short) 800),
+ SUBTRACTION((short) 6, (short) 800),
+
+ EQUAL_TO((short) 7, (short) 600),
+ NON_EQUAL((short) 8, (short) 600),
+ GREATER_EQUAL((short) 9, (short) 600),
+ GREATER_THAN((short) 10, (short) 600),
+ LESS_EQUAL((short) 11, (short) 600),
+ LESS_THAN((short) 12, (short) 600),
+
+ LIKE((short) 13, (short) 500),
+ REGEXP((short) 14, (short) 500),
+
+ IS_NULL((short) 15, (short) 475),
+
+ BETWEEN((short) 16, (short) 450),
+
+ IN((short) 17, (short) 400),
+
+ LOGIC_AND((short) 18, (short) 300),
+
+ LOGIC_OR((short) 19, (short) 200),
+
+ NULL((short) 20, (short) 1400),
+ ;
+
+ private final short expressionType;
+ private final short priority;
+
+ ViewExpressionType(short expressionType, short priority) {
+ this.expressionType = expressionType;
+ this.priority = priority;
+ }
+
+ public short getExpressionTypeInShortEnum() {
+ return expressionType;
+ }
+
+ public short getPriority() {
+ return priority;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/BinaryViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/BinaryViewExpression.java
new file mode 100644
index 0000000000..a4c660804f
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/BinaryViewExpression.java
@@ -0,0 +1,119 @@
+/*
+ * 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.metadata.view.viewExpression.binary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+public abstract class BinaryViewExpression extends ViewExpression {
+
+ // region member variables and init functions
+ protected ViewExpression leftExpression;
+ protected ViewExpression rightExpression;
+
+ protected BinaryViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ this.leftExpression = leftExpression;
+ this.rightExpression = rightExpression;
+ }
+
+ protected BinaryViewExpression(ByteBuffer byteBuffer) {
+ this.leftExpression = ViewExpression.deserialize(byteBuffer);
+ this.rightExpression = ViewExpression.deserialize(byteBuffer);
+ }
+
+ protected BinaryViewExpression(InputStream inputStream) {
+ this.leftExpression = ViewExpression.deserialize(inputStream);
+ this.rightExpression = ViewExpression.deserialize(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitBinaryExpression(this, context);
+ }
+
+ @Override
+ protected final boolean isLeafOperandInternal() {
+ return false;
+ }
+
+ @Override
+ public final List<ViewExpression> getChildViewExpressions() {
+ return Arrays.asList(leftExpression, rightExpression);
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ ViewExpression.serialize(leftExpression, byteBuffer);
+ ViewExpression.serialize(rightExpression, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ ViewExpression.serialize(leftExpression, stream);
+ ViewExpression.serialize(rightExpression, stream);
+ }
+ // endregion
+ public void setLeftExpression(ViewExpression leftExpression) {
+ this.leftExpression = leftExpression;
+ }
+
+ public void setRightExpression(ViewExpression rightExpression) {
+ this.rightExpression = rightExpression;
+ }
+
+ public ViewExpression getLeftExpression() {
+ return leftExpression;
+ }
+
+ public ViewExpression getRightExpression() {
+ return rightExpression;
+ }
+
+ public abstract String getStringSymbol();
+
+ @Override
+ public String toString() {
+ return this.toString(true);
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ String basicString =
+ leftExpression.toString(false)
+ + " "
+ + this.getStringSymbol()
+ + " "
+ + rightExpression.toString(false);
+ if (isRoot) {
+ return basicString;
+ } else {
+ return "(" + basicString + ")";
+ }
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/AdditionViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/AdditionViewExpression.java
new file mode 100644
index 0000000000..40aeffe364
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/AdditionViewExpression.java
@@ -0,0 +1,61 @@
+/*
+ * 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.metadata.view.viewExpression.binary.arithmetic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class AdditionViewExpression extends ArithmeticBinaryViewExpression {
+
+ // region member variables and init functions
+ public AdditionViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public AdditionViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public AdditionViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitAdditionExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "+";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.ADDITION;
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/ArithmeticBinaryViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/ArithmeticBinaryViewExpression.java
new file mode 100644
index 0000000000..24b7a44178
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/ArithmeticBinaryViewExpression.java
@@ -0,0 +1,52 @@
+/*
+ * 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.metadata.view.viewExpression.binary.arithmetic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.BinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public abstract class ArithmeticBinaryViewExpression extends BinaryViewExpression {
+
+ // region member variables and init functions
+ protected ArithmeticBinaryViewExpression(
+ ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ protected ArithmeticBinaryViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ protected ArithmeticBinaryViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitArithmeticBinaryExpression(this, context);
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/DivisionViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/DivisionViewExpression.java
new file mode 100644
index 0000000000..cf43cd44e1
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/DivisionViewExpression.java
@@ -0,0 +1,61 @@
+/*
+ * 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.metadata.view.viewExpression.binary.arithmetic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class DivisionViewExpression extends ArithmeticBinaryViewExpression {
+
+ // region member variables and init functions
+ public DivisionViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public DivisionViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public DivisionViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitDivisionExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "/";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.DIVISION;
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/ModuloViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/ModuloViewExpression.java
new file mode 100644
index 0000000000..fe569255cc
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/ModuloViewExpression.java
@@ -0,0 +1,61 @@
+/*
+ * 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.metadata.view.viewExpression.binary.arithmetic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class ModuloViewExpression extends ArithmeticBinaryViewExpression {
+
+ // region member variables and init functions
+ public ModuloViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public ModuloViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public ModuloViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitModuloExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "%";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.MODULO;
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/MultiplicationViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/MultiplicationViewExpression.java
new file mode 100644
index 0000000000..ea6e6b50de
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/MultiplicationViewExpression.java
@@ -0,0 +1,63 @@
+/*
+ * 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.metadata.view.viewExpression.binary.arithmetic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class MultiplicationViewExpression extends ArithmeticBinaryViewExpression {
+
+ // region member variables and init functions
+ public MultiplicationViewExpression(
+ ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public MultiplicationViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public MultiplicationViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitMultiplicationExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "*";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.MULTIPLICATION;
+ }
+ // endregion
+
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/SubtractionViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/SubtractionViewExpression.java
new file mode 100644
index 0000000000..08097e60d9
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/arithmetic/SubtractionViewExpression.java
@@ -0,0 +1,61 @@
+/*
+ * 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.metadata.view.viewExpression.binary.arithmetic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class SubtractionViewExpression extends ArithmeticBinaryViewExpression {
+
+ // region member variables and init functions
+ public SubtractionViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public SubtractionViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public SubtractionViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitSubtractionExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "-";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.SUBTRACTION;
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/CompareBinaryViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/CompareBinaryViewExpression.java
new file mode 100644
index 0000000000..64da03ad30
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/CompareBinaryViewExpression.java
@@ -0,0 +1,52 @@
+/*
+ * 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.metadata.view.viewExpression.binary.compare;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.BinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public abstract class CompareBinaryViewExpression extends BinaryViewExpression {
+
+ // region member variables and init functions
+ protected CompareBinaryViewExpression(
+ ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ protected CompareBinaryViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ protected CompareBinaryViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitCompareBinaryExpression(this, context);
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/EqualToViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/EqualToViewExpression.java
new file mode 100644
index 0000000000..9a76d16e23
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/EqualToViewExpression.java
@@ -0,0 +1,57 @@
+/*
+ * 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.metadata.view.viewExpression.binary.compare;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class EqualToViewExpression extends CompareBinaryViewExpression {
+
+ public EqualToViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public EqualToViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public EqualToViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitEqualToExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "==";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.EQUAL_TO;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/GreaterEqualViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/GreaterEqualViewExpression.java
new file mode 100644
index 0000000000..90c79baff9
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/GreaterEqualViewExpression.java
@@ -0,0 +1,57 @@
+/*
+ * 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.metadata.view.viewExpression.binary.compare;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class GreaterEqualViewExpression extends CompareBinaryViewExpression {
+
+ public GreaterEqualViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public GreaterEqualViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public GreaterEqualViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitGreaterEqualExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return ">=";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.GREATER_EQUAL;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/GreaterThanViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/GreaterThanViewExpression.java
new file mode 100644
index 0000000000..1e371516c6
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/GreaterThanViewExpression.java
@@ -0,0 +1,57 @@
+/*
+ * 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.metadata.view.viewExpression.binary.compare;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class GreaterThanViewExpression extends CompareBinaryViewExpression {
+
+ public GreaterThanViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public GreaterThanViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public GreaterThanViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitGreaterThanExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return ">";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.GREATER_THAN;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/LessEqualViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/LessEqualViewExpression.java
new file mode 100644
index 0000000000..e3ea2efe28
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/LessEqualViewExpression.java
@@ -0,0 +1,57 @@
+/*
+ * 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.metadata.view.viewExpression.binary.compare;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class LessEqualViewExpression extends CompareBinaryViewExpression {
+
+ public LessEqualViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public LessEqualViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public LessEqualViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitLessEqualExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "<=";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.LESS_EQUAL;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/LessThanViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/LessThanViewExpression.java
new file mode 100644
index 0000000000..7b3b1f8436
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/LessThanViewExpression.java
@@ -0,0 +1,57 @@
+/*
+ * 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.metadata.view.viewExpression.binary.compare;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class LessThanViewExpression extends CompareBinaryViewExpression {
+
+ public LessThanViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public LessThanViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public LessThanViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitLessThanExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "<";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.LESS_THAN;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/NonEqualViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/NonEqualViewExpression.java
new file mode 100644
index 0000000000..5627912cc7
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/compare/NonEqualViewExpression.java
@@ -0,0 +1,57 @@
+/*
+ * 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.metadata.view.viewExpression.binary.compare;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class NonEqualViewExpression extends CompareBinaryViewExpression {
+
+ public NonEqualViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public NonEqualViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public NonEqualViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitNonEqualExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "!=";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.NON_EQUAL;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicAndViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicAndViewExpression.java
new file mode 100644
index 0000000000..077ef3acc5
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicAndViewExpression.java
@@ -0,0 +1,57 @@
+/*
+ * 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.metadata.view.viewExpression.binary.logic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class LogicAndViewExpression extends LogicBinaryViewExpression {
+
+ public LogicAndViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public LogicAndViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public LogicAndViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitLogicAndExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "AND";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.LOGIC_AND;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicBinaryViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicBinaryViewExpression.java
new file mode 100644
index 0000000000..3b48ea7140
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicBinaryViewExpression.java
@@ -0,0 +1,52 @@
+/*
+ * 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.metadata.view.viewExpression.binary.logic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.BinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public abstract class LogicBinaryViewExpression extends BinaryViewExpression {
+
+ // region member variables and init functions
+ protected LogicBinaryViewExpression(
+ ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ protected LogicBinaryViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ protected LogicBinaryViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitLogicBinaryExpression(this, context);
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicOrViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicOrViewExpression.java
new file mode 100644
index 0000000000..4791d29d1f
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/binary/logic/LogicOrViewExpression.java
@@ -0,0 +1,57 @@
+/*
+ * 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.metadata.view.viewExpression.binary.logic;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class LogicOrViewExpression extends LogicBinaryViewExpression {
+
+ public LogicOrViewExpression(ViewExpression leftExpression, ViewExpression rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ public LogicOrViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ public LogicOrViewExpression(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitLogicOrExpression(this, context);
+ }
+
+ @Override
+ public String getStringSymbol() {
+ return "OR";
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.LOGIC_OR;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/ConstantViewOperand.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/ConstantViewOperand.java
new file mode 100644
index 0000000000..7e727c25fa
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/ConstantViewOperand.java
@@ -0,0 +1,98 @@
+/*
+ * 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.metadata.view.viewExpression.leaf;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import org.apache.commons.lang3.Validate;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class ConstantViewOperand extends LeafViewOperand {
+
+ // region member variables and init functions
+ private final String valueString;
+ private final TSDataType dataType;
+
+ public ConstantViewOperand(TSDataType dataType, String valueString) {
+ this.dataType = Validate.notNull(dataType);
+ this.valueString = Validate.notNull(valueString);
+ }
+
+ public ConstantViewOperand(ByteBuffer byteBuffer) {
+ dataType = TSDataType.deserializeFrom(byteBuffer);
+ valueString = ReadWriteIOUtils.readString(byteBuffer);
+ }
+
+ public ConstantViewOperand(InputStream inputStream) {
+ try {
+ dataType = TSDataType.deserialize(ReadWriteIOUtils.readByte(inputStream));
+ valueString = ReadWriteIOUtils.readString(inputStream);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitConstantOperand(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.CONSTANT;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return this.valueString;
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ dataType.serializeTo(byteBuffer);
+ ReadWriteIOUtils.write(valueString, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ stream.write(dataType.serialize());
+ ReadWriteIOUtils.write(valueString, stream);
+ }
+
+ // endregion
+
+ public TSDataType getDataType() {
+ return dataType;
+ }
+
+ public String getValueString() {
+ return valueString;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/query/info/ITimeSeriesSchemaInfo.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/LeafViewOperand.java
similarity index 59%
copy from server/src/main/java/org/apache/iotdb/db/metadata/query/info/ITimeSeriesSchemaInfo.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/LeafViewOperand.java
index 94f487a917..127306f284 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/query/info/ITimeSeriesSchemaInfo.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/LeafViewOperand.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -17,21 +17,23 @@
* under the License.
*/
-package org.apache.iotdb.db.metadata.query.info;
+package org.apache.iotdb.db.metadata.view.viewExpression.leaf;
-import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
-public interface ITimeSeriesSchemaInfo extends ISchemaInfo {
+public abstract class LeafViewOperand extends ViewExpression {
- String getAlias();
+ @Override
+ protected final boolean isLeafOperandInternal() {
+ return true;
+ }
- MeasurementSchema getSchema();
-
- Map<String, String> getTags();
-
- Map<String, String> getAttributes();
-
- boolean isUnderAlignedDevice();
+ @Override
+ public final List<ViewExpression> getChildViewExpressions() {
+ // leaf node has no child nodes.
+ return new ArrayList<>();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/NullViewOperand.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/NullViewOperand.java
new file mode 100644
index 0000000000..a62e94e4b0
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/NullViewOperand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.metadata.view.viewExpression.leaf;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class NullViewOperand extends LeafViewOperand {
+
+ // region member variables and init functions
+ public NullViewOperand() {};
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitNullOperand(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.NULL;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return "null";
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ // do nothing
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ // do nothing
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/TimeSeriesViewOperand.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/TimeSeriesViewOperand.java
new file mode 100644
index 0000000000..c34aefdac3
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/TimeSeriesViewOperand.java
@@ -0,0 +1,87 @@
+/*
+ * 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.metadata.view.viewExpression.leaf;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class TimeSeriesViewOperand extends LeafViewOperand {
+
+ // region member variables and init functions
+ private String pathString;
+
+ public TimeSeriesViewOperand(String path) {
+ this.pathString = path;
+ }
+
+ public TimeSeriesViewOperand(ByteBuffer byteBuffer) {
+ this.pathString = ReadWriteIOUtils.readString(byteBuffer);
+ }
+
+ public TimeSeriesViewOperand(InputStream inputStream) {
+ try {
+ this.pathString = ReadWriteIOUtils.readString(inputStream);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitTimeSeriesOperand(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.TIMESERIES;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return this.pathString;
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ ReadWriteIOUtils.write(pathString, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ ReadWriteIOUtils.write(pathString, stream);
+ }
+ // endregion
+
+ public String getPathString() {
+ return pathString;
+ }
+
+ public void setPathString(String path) {
+ this.pathString = path;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/TimestampViewOperand.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/TimestampViewOperand.java
new file mode 100644
index 0000000000..b492bad644
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/leaf/TimestampViewOperand.java
@@ -0,0 +1,72 @@
+/*
+ * 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.metadata.view.viewExpression.leaf;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class TimestampViewOperand extends LeafViewOperand {
+ // region member variables and init functions
+ public TimestampViewOperand() {
+ // do nothing
+ };
+
+ public TimestampViewOperand(ByteBuffer byteBuffer) {
+ // do nothing
+ }
+
+ public TimestampViewOperand(InputStream inputStream) {
+ // do nothing
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitTimeStampOperand(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.TIMESTAMP;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return "TIMESTAMP";
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ // do nothing
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ // do nothing
+ }
+
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/multi/FunctionViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/multi/FunctionViewExpression.java
new file mode 100644
index 0000000000..46c0ea9811
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/multi/FunctionViewExpression.java
@@ -0,0 +1,198 @@
+/*
+ * 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.metadata.view.viewExpression.multi;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+public class FunctionViewExpression extends ViewExpression {
+
+ // region member variables and init functions
+ private final String functionName;
+
+ /**
+ * for a map {key1: value1, key2: value2}, this struct saves String[]{"key1", "value1", "key2",
+ * "value2"}
+ */
+ private final List<String> functionAttributesKeyValueList;
+
+ /**
+ * example: select udf(a, b, udf(c)) from root.sg.d;
+ *
+ * <p>3 expressions [root.sg.d.a, root.sg.d.b, udf(root.sg.d.c)] will be in this field.
+ */
+ private List<ViewExpression> expressions;
+
+ public FunctionViewExpression(String functionName) {
+ this.functionName = functionName;
+ functionAttributesKeyValueList = new ArrayList<>();
+ expressions = new ArrayList<>();
+ }
+
+ public FunctionViewExpression(
+ String functionName,
+ List<String> functionAttributeKeys,
+ List<String> functionAttributeValues,
+ List<ViewExpression> expressions) {
+ this.functionName = functionName;
+ this.functionAttributesKeyValueList = new ArrayList<>();
+ if (functionAttributeKeys.size() == functionAttributeValues.size()) {
+ for (int i = 0; i < functionAttributeKeys.size(); i++) {
+ this.functionAttributesKeyValueList.add(functionAttributeKeys.get(i));
+ this.functionAttributesKeyValueList.add(functionAttributeValues.get(i));
+ }
+ } else {
+ String errorMsg =
+ String.format(
+ "Illegal parameters during FunctionExpression construction. Array length mismatch.");
+ throw new RuntimeException(errorMsg);
+ }
+ this.expressions = expressions;
+ }
+
+ public FunctionViewExpression(ByteBuffer byteBuffer) {
+ functionName = ReadWriteIOUtils.readString(byteBuffer);
+ functionAttributesKeyValueList = ReadWriteIOUtils.readStringList(byteBuffer);
+ int expressionSize = ReadWriteIOUtils.readInt(byteBuffer);
+ expressions = new ArrayList<>();
+ for (int i = 0; i < expressionSize; i++) {
+ expressions.add(ViewExpression.deserialize(byteBuffer));
+ }
+ }
+
+ public FunctionViewExpression(InputStream inputStream) {
+ try {
+ functionName = ReadWriteIOUtils.readString(inputStream);
+ functionAttributesKeyValueList = ReadWriteIOUtils.readStringList(inputStream);
+ int expressionSize = ReadWriteIOUtils.readInt(inputStream);
+ expressions = new ArrayList<>();
+ for (int i = 0; i < expressionSize; i++) {
+ expressions.add(ViewExpression.deserialize(inputStream));
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitFunctionExpression(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.FUNCTION;
+ }
+
+ @Override
+ protected boolean isLeafOperandInternal() {
+ // if this expression has no children, return true; else return false.
+ if (this.expressions.size() == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public List<ViewExpression> getChildViewExpressions() {
+ return this.expressions;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ StringBuilder result = new StringBuilder(this.functionName);
+ int keyValueSize = this.functionAttributesKeyValueList.size();
+ if (this.functionAttributesKeyValueList.size() > 1) {
+ result.append("(");
+ for (int i = 0; i + 1 < keyValueSize; i += 2) {
+ result
+ .append(this.functionAttributesKeyValueList.get(i))
+ .append("=")
+ .append(this.functionAttributesKeyValueList.get(i + 1));
+ if (i + 2 >= keyValueSize) {
+ break;
+ }
+ result.append(", ");
+ }
+ result.append(")");
+ }
+ result.append("(");
+ for (int i = 0; i < this.expressions.size(); i++) {
+ result.append(this.expressions.get(i).toString());
+ if (i + 1 >= this.expressions.size()) {
+ break;
+ }
+ result.append(", ");
+ }
+ result.append(")");
+ return result.toString();
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ ReadWriteIOUtils.write(functionName, byteBuffer);
+ ReadWriteIOUtils.writeStringList(functionAttributesKeyValueList, byteBuffer);
+ ReadWriteIOUtils.write(expressions.size(), byteBuffer);
+ for (ViewExpression expression : expressions) {
+ ViewExpression.serialize(expression, byteBuffer);
+ }
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ ReadWriteIOUtils.write(functionName, stream);
+ ReadWriteIOUtils.writeStringList(functionAttributesKeyValueList, stream);
+ ReadWriteIOUtils.write(expressions.size(), stream);
+ for (ViewExpression expression : expressions) {
+ ViewExpression.serialize(expression, stream);
+ }
+ }
+ // endregion
+
+ public String getFunctionName() {
+ return this.functionName;
+ }
+
+ public LinkedHashMap<String, String> getFunctionAttributes() {
+ LinkedHashMap<String, String> result = new LinkedHashMap<>();
+ for (int i = 0; i + 1 < this.functionAttributesKeyValueList.size(); i += 2) {
+ result.put(
+ this.functionAttributesKeyValueList.get(i),
+ this.functionAttributesKeyValueList.get(i + 1));
+ }
+ return result;
+ }
+
+ public List<ViewExpression> getExpressions() {
+ return this.expressions;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ternary/BetweenViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ternary/BetweenViewExpression.java
new file mode 100644
index 0000000000..98bff83c9d
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ternary/BetweenViewExpression.java
@@ -0,0 +1,111 @@
+/*
+ * 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.metadata.view.viewExpression.ternary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class BetweenViewExpression extends TernaryViewExpression {
+
+ // region member variables and init functions
+ /** default value is false. */
+ private final boolean isNotBetween;
+
+ public BetweenViewExpression(
+ ViewExpression firstExpression,
+ ViewExpression secondExpression,
+ ViewExpression thirdExpression,
+ boolean isNotBetween) {
+ super(firstExpression, secondExpression, thirdExpression);
+ this.isNotBetween = isNotBetween;
+ }
+
+ public BetweenViewExpression(
+ ViewExpression firstExpression,
+ ViewExpression secondExpression,
+ ViewExpression thirdExpression) {
+ super(firstExpression, secondExpression, thirdExpression);
+ this.isNotBetween = false;
+ }
+
+ public BetweenViewExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ this.isNotBetween = ReadWriteIOUtils.readBool(byteBuffer);
+ }
+
+ public BetweenViewExpression(InputStream inputStream) {
+ super(inputStream);
+ try {
+ this.isNotBetween = ReadWriteIOUtils.readBool(inputStream);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitBetweenExpression(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.BETWEEN;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ String basicString =
+ this.firstExpression.toString(true)
+ + " BETWEEN "
+ + this.secondExpression.toString(false)
+ + " AND "
+ + this.secondExpression.toString(false);
+ if (isRoot) {
+ return basicString;
+ }
+ return "(" + basicString + ")";
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ super.serialize(byteBuffer);
+ ReadWriteIOUtils.write(isNotBetween, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ super.serialize(stream);
+ ReadWriteIOUtils.write(isNotBetween, stream);
+ }
+ // endregion
+
+ public boolean isNotBetween() {
+ return isNotBetween;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ternary/TernaryViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ternary/TernaryViewExpression.java
new file mode 100644
index 0000000000..89fd6328e4
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/ternary/TernaryViewExpression.java
@@ -0,0 +1,105 @@
+/*
+ * 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.metadata.view.viewExpression.ternary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+public abstract class TernaryViewExpression extends ViewExpression {
+
+ // region member variables and init functions
+ protected final ViewExpression firstExpression;
+
+ protected final ViewExpression secondExpression;
+
+ protected final ViewExpression thirdExpression;
+
+ protected TernaryViewExpression(
+ ViewExpression firstExpression,
+ ViewExpression secondExpression,
+ ViewExpression thirdExpression) {
+ this.firstExpression = firstExpression;
+ this.secondExpression = secondExpression;
+ this.thirdExpression = thirdExpression;
+ }
+
+ protected TernaryViewExpression(ByteBuffer byteBuffer) {
+ this.firstExpression = ViewExpression.deserialize(byteBuffer);
+ this.secondExpression = ViewExpression.deserialize(byteBuffer);
+ this.thirdExpression = ViewExpression.deserialize(byteBuffer);
+ }
+
+ protected TernaryViewExpression(InputStream inputStream) {
+ this.firstExpression = ViewExpression.deserialize(inputStream);
+ this.secondExpression = ViewExpression.deserialize(inputStream);
+ this.thirdExpression = ViewExpression.deserialize(inputStream);
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitTernaryExpression(this, context);
+ }
+
+ @Override
+ protected final boolean isLeafOperandInternal() {
+ return false;
+ }
+
+ @Override
+ public final List<ViewExpression> getChildViewExpressions() {
+ return Arrays.asList(firstExpression, secondExpression, thirdExpression);
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ ViewExpression.serialize(firstExpression, byteBuffer);
+ ViewExpression.serialize(secondExpression, byteBuffer);
+ ViewExpression.serialize(thirdExpression, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ ViewExpression.serialize(firstExpression, stream);
+ ViewExpression.serialize(secondExpression, stream);
+ ViewExpression.serialize(thirdExpression, stream);
+ }
+ // endregion
+
+ public ViewExpression getFirstExpression() {
+ return this.firstExpression;
+ }
+
+ public ViewExpression getSecondExpression() {
+ return this.secondExpression;
+ }
+
+ public ViewExpression getThirdExpression() {
+ return this.thirdExpression;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/InViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/InViewExpression.java
new file mode 100644
index 0000000000..b35fed6d16
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/InViewExpression.java
@@ -0,0 +1,106 @@
+/*
+ * 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.metadata.view.viewExpression.unary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+public class InViewExpression extends UnaryViewExpression {
+
+ // region member variables and init functions
+ private final boolean isNotIn;
+
+ private final List<String> valueList;
+
+ public InViewExpression(ViewExpression expression, boolean isNotIn, List<String> values) {
+ super(expression);
+ this.isNotIn = isNotIn;
+ this.valueList = values;
+ }
+
+ public InViewExpression(ByteBuffer byteBuffer) {
+ super(ViewExpression.deserialize(byteBuffer));
+ isNotIn = ReadWriteIOUtils.readBool(byteBuffer);
+ valueList = ReadWriteIOUtils.readStringList(byteBuffer);
+ }
+
+ public InViewExpression(InputStream inputStream) {
+ super(ViewExpression.deserialize(inputStream));
+ try {
+ isNotIn = ReadWriteIOUtils.readBool(inputStream);
+ valueList = ReadWriteIOUtils.readStringList(inputStream);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitInExpression(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.IN;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return "IN " + this.expression.toString();
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ super.serialize(byteBuffer);
+ ReadWriteIOUtils.write(isNotIn, byteBuffer);
+ ReadWriteIOUtils.writeStringList(this.valueList, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ super.serialize(stream);
+ ReadWriteIOUtils.write(isNotIn, stream);
+ ReadWriteIOUtils.writeStringList(this.valueList, stream);
+ }
+ // endregion
+
+ public boolean isNotIn() {
+ return isNotIn;
+ }
+
+ public LinkedHashSet<String> getValuesInLinkedHashSet() {
+ return new LinkedHashSet<>(this.valueList);
+ }
+
+ public List<String> getValueList() {
+ return this.valueList;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/IsNullViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/IsNullViewExpression.java
new file mode 100644
index 0000000000..d2f17c9633
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/IsNullViewExpression.java
@@ -0,0 +1,89 @@
+/*
+ * 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.metadata.view.viewExpression.unary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class IsNullViewExpression extends UnaryViewExpression {
+
+ // region member variables and init functions
+ private final boolean isNot;
+
+ public IsNullViewExpression(ViewExpression expression, boolean isNot) {
+ super(expression);
+ this.isNot = isNot;
+ }
+
+ public IsNullViewExpression(ByteBuffer byteBuffer) {
+ super(ViewExpression.deserialize(byteBuffer));
+ isNot = ReadWriteIOUtils.readBool(byteBuffer);
+ }
+
+ public IsNullViewExpression(InputStream inputStream) {
+ super(ViewExpression.deserialize(inputStream));
+ try {
+ isNot = ReadWriteIOUtils.readBool(inputStream);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitIsNullExpression(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.IS_NULL;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return this.expression.toString(false) + " IS_NULL";
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ super.serialize(byteBuffer);
+ ReadWriteIOUtils.write(isNot, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ super.serialize(stream);
+ ReadWriteIOUtils.write(isNot, stream);
+ }
+ // endregion
+
+ public boolean isNot() {
+ return isNot;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/LikeViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/LikeViewExpression.java
new file mode 100644
index 0000000000..27e1baef19
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/LikeViewExpression.java
@@ -0,0 +1,163 @@
+/*
+ * 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.metadata.view.viewExpression.unary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.regex.Pattern;
+
+public class LikeViewExpression extends UnaryViewExpression {
+
+ // region member variables and init functions
+ private final String patternString;
+ private final Pattern pattern;
+
+ public LikeViewExpression(ViewExpression expression, String patternString) {
+ super(expression);
+ this.patternString = patternString;
+ pattern = this.compile();
+ }
+
+ public LikeViewExpression(ViewExpression expression, String patternString, Pattern pattern) {
+ super(expression);
+ this.patternString = patternString;
+ this.pattern = pattern;
+ }
+
+ public LikeViewExpression(ByteBuffer byteBuffer) {
+ super(ViewExpression.deserialize(byteBuffer));
+ patternString = ReadWriteIOUtils.readString(byteBuffer);
+ pattern = compile();
+ }
+
+ public LikeViewExpression(InputStream inputStream) {
+ super(ViewExpression.deserialize(inputStream));
+ try {
+ patternString = ReadWriteIOUtils.readString(inputStream);
+ pattern = compile();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitLikeExpression(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.LIKE;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ String basicString = this.expression.toString(false) + "LIKE " + this.patternString;
+ if (isRoot) {
+ return basicString;
+ }
+ return "( " + basicString + " )";
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ super.serialize(byteBuffer);
+ ReadWriteIOUtils.write(patternString, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ super.serialize(stream);
+ ReadWriteIOUtils.write(patternString, stream);
+ }
+ // endregion
+
+ public String getPatternString() {
+ return patternString;
+ }
+
+ public Pattern getPattern() {
+ return pattern;
+ }
+
+ /**
+ * This Method is for un-escaping strings except '\' before special string '%', '_', '\', because
+ * we need to use '\' to judge whether to replace this to regexp string
+ */
+ private String unescapeString(String value) {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < value.length(); i++) {
+ String ch = String.valueOf(value.charAt(i));
+ if ("\\".equals(ch)) {
+ if (i < value.length() - 1) {
+ String nextChar = String.valueOf(value.charAt(i + 1));
+ if ("%".equals(nextChar) || "_".equals(nextChar) || "\\".equals(nextChar)) {
+ stringBuilder.append(ch);
+ }
+ if ("\\".equals(nextChar)) {
+ i++;
+ }
+ }
+ } else {
+ stringBuilder.append(ch);
+ }
+ }
+ return stringBuilder.toString();
+ }
+
+ /**
+ * The main idea of this part comes from
+ * https://codereview.stackexchange.com/questions/36861/convert-sql-like-to-regex/36864
+ */
+ private Pattern compile() {
+ String unescapeValue = unescapeString(patternString);
+ String specialRegexString = ".^$*+?{}[]|()";
+ StringBuilder patternBuilder = new StringBuilder();
+ patternBuilder.append("^");
+ for (int i = 0; i < unescapeValue.length(); i++) {
+ String ch = String.valueOf(unescapeValue.charAt(i));
+ if (specialRegexString.contains(ch)) {
+ ch = "\\" + unescapeValue.charAt(i);
+ }
+ if (i == 0
+ || !"\\".equals(String.valueOf(unescapeValue.charAt(i - 1)))
+ || i >= 2
+ && "\\\\"
+ .equals(
+ patternBuilder.substring(
+ patternBuilder.length() - 2, patternBuilder.length()))) {
+ patternBuilder.append(ch.replace("%", ".*?").replace("_", "."));
+ } else {
+ patternBuilder.append(ch);
+ }
+ }
+ patternBuilder.append("$");
+ return Pattern.compile(patternBuilder.toString());
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/LogicNotViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/LogicNotViewExpression.java
new file mode 100644
index 0000000000..35ecc779e2
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/LogicNotViewExpression.java
@@ -0,0 +1,61 @@
+/*
+ * 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.metadata.view.viewExpression.unary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class LogicNotViewExpression extends UnaryViewExpression {
+
+ // region member variables and init functions
+ public LogicNotViewExpression(ViewExpression expression) {
+ super(expression);
+ }
+
+ public LogicNotViewExpression(ByteBuffer byteBuffer) {
+ super(ViewExpression.deserialize(byteBuffer));
+ }
+
+ public LogicNotViewExpression(InputStream inputStream) {
+ super(ViewExpression.deserialize(inputStream));
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitLogicNotExpression(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.LOGIC_NOT;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return "NOT " + this.expression.toString(false);
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/NegationViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/NegationViewExpression.java
new file mode 100644
index 0000000000..2e0462c1c5
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/NegationViewExpression.java
@@ -0,0 +1,61 @@
+/*
+ * 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.metadata.view.viewExpression.unary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class NegationViewExpression extends UnaryViewExpression {
+
+ // region member variables and init functions
+ public NegationViewExpression(ViewExpression expression) {
+ super(expression);
+ }
+
+ public NegationViewExpression(ByteBuffer byteBuffer) {
+ super(ViewExpression.deserialize(byteBuffer));
+ }
+
+ public NegationViewExpression(InputStream inputStream) {
+ super(ViewExpression.deserialize(inputStream));
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitNegationExpression(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.NEGATION;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return "NEGATION_OF " + this.expression.toString(false);
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/RegularViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/RegularViewExpression.java
new file mode 100644
index 0000000000..d2aefe48b3
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/RegularViewExpression.java
@@ -0,0 +1,105 @@
+/*
+ * 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.metadata.view.viewExpression.unary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpressionType;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import org.apache.commons.lang3.Validate;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.regex.Pattern;
+
+public class RegularViewExpression extends UnaryViewExpression {
+
+ // region member variables and init functions
+ private final String patternString;
+ private final Pattern pattern;
+
+ public RegularViewExpression(ViewExpression expression, String patternString) {
+ super(expression);
+ this.patternString = patternString;
+ pattern = Pattern.compile(patternString);
+ }
+
+ public RegularViewExpression(ViewExpression expression, String patternString, Pattern pattern) {
+ super(expression);
+ this.patternString = patternString;
+ this.pattern = pattern;
+ }
+
+ public RegularViewExpression(ByteBuffer byteBuffer) {
+ super(ViewExpression.deserialize(byteBuffer));
+ patternString = ReadWriteIOUtils.readString(byteBuffer);
+ pattern = Pattern.compile(Validate.notNull(patternString));
+ }
+
+ public RegularViewExpression(InputStream inputStream) {
+ super(ViewExpression.deserialize(inputStream));
+ try {
+ patternString = ReadWriteIOUtils.readString(inputStream);
+ pattern = Pattern.compile(Validate.notNull(patternString));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitRegularExpression(this, context);
+ }
+
+ @Override
+ public ViewExpressionType getExpressionType() {
+ return ViewExpressionType.REGEXP;
+ }
+
+ @Override
+ public String toString(boolean isRoot) {
+ return "REGULAR(" + this.expression.toString() + ", " + this.patternString + ")";
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ super.serialize(byteBuffer);
+ ReadWriteIOUtils.write(patternString, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ super.serialize(stream);
+ ReadWriteIOUtils.write(patternString, stream);
+ }
+ // endregion
+ public String getPatternString() {
+ return patternString;
+ }
+
+ public Pattern getPattern() {
+ return pattern;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/UnaryViewExpression.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/UnaryViewExpression.java
new file mode 100644
index 0000000000..3bd78a549e
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/unary/UnaryViewExpression.java
@@ -0,0 +1,73 @@
+/*
+ * 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.metadata.view.viewExpression.unary;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.ViewExpressionVisitor;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+public abstract class UnaryViewExpression extends ViewExpression {
+
+ // region member variables and init functions
+ protected final ViewExpression expression;
+
+ protected UnaryViewExpression(ViewExpression expression) {
+ this.expression = expression;
+ }
+
+ // endregion
+
+ // region common interfaces that have to be implemented
+ @Override
+ public <R, C> R accept(ViewExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitUnaryExpression(this, context);
+ }
+
+ @Override
+ protected final boolean isLeafOperandInternal() {
+ return false;
+ }
+
+ @Override
+ public final List<ViewExpression> getChildViewExpressions() {
+ // leaf node has no child nodes.
+ return Arrays.asList(expression);
+ }
+
+ @Override
+ protected void serialize(ByteBuffer byteBuffer) {
+ ViewExpression.serialize(expression, byteBuffer);
+ }
+
+ @Override
+ protected void serialize(OutputStream stream) throws IOException {
+ ViewExpression.serialize(expression, stream);
+ }
+ // endregion
+
+ public final ViewExpression getExpression() {
+ return expression;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java
new file mode 100644
index 0000000000..74ac94fb73
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java
@@ -0,0 +1,95 @@
+/*
+ * 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.metadata.view.viewExpression.visitor;
+
+import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.BinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimeSeriesViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.multi.FunctionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ternary.TernaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.UnaryViewExpression;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** Use this visitor to find all the paths of time series used in one expression. */
+public class GetSourcePathsVisitor extends ViewExpressionVisitor<List<PartialPath>, Void> {
+
+ @Override
+ public List<PartialPath> visitExpression(ViewExpression expression, Void context) {
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List<PartialPath> visitTimeSeriesOperand(
+ TimeSeriesViewOperand timeSeriesOperand, Void context) {
+ String pathString = timeSeriesOperand.getPathString();
+ try {
+ PartialPath path = new PartialPath(pathString);
+ return Collections.singletonList(path);
+ } catch (IllegalPathException e) {
+ // the path is illegal!
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public List<PartialPath> visitUnaryExpression(
+ UnaryViewExpression unaryViewExpression, Void context) {
+ ViewExpression expression = unaryViewExpression.getExpression();
+ return this.process(expression, null);
+ }
+
+ @Override
+ public List<PartialPath> visitBinaryExpression(
+ BinaryViewExpression binaryViewExpression, Void context) {
+ List<PartialPath> result = new ArrayList<>();
+ List<ViewExpression> expressionList = binaryViewExpression.getChildViewExpressions();
+ for (ViewExpression expression : expressionList) {
+ result.addAll(this.process(expression, null));
+ }
+ return result;
+ }
+
+ @Override
+ public List<PartialPath> visitTernaryExpression(
+ TernaryViewExpression ternaryViewExpression, Void context) {
+ List<PartialPath> result = new ArrayList<>();
+ List<ViewExpression> expressionList = ternaryViewExpression.getChildViewExpressions();
+ for (ViewExpression expression : expressionList) {
+ result.addAll(this.process(expression, null));
+ }
+ return result;
+ }
+
+ @Override
+ public List<PartialPath> visitFunctionExpression(
+ FunctionViewExpression functionViewExpression, Void context) {
+ List<PartialPath> result = new ArrayList<>();
+ List<ViewExpression> expressionList = functionViewExpression.getChildViewExpressions();
+ for (ViewExpression expression : expressionList) {
+ result.addAll(this.process(expression, null));
+ }
+ return result;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/TransformToExpressionVisitor.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/TransformToExpressionVisitor.java
new file mode 100644
index 0000000000..8a4af23a01
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/TransformToExpressionVisitor.java
@@ -0,0 +1,320 @@
+/*
+ * 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.metadata.view.viewExpression.visitor;
+
+import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.BinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.AdditionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.ArithmeticBinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.DivisionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.ModuloViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.MultiplicationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.SubtractionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.CompareBinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.EqualToViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.GreaterEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.GreaterThanViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.LessEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.LessThanViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.NonEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicAndViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicBinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicOrViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.ConstantViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.LeafViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.NullViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimeSeriesViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimestampViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.multi.FunctionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ternary.BetweenViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ternary.TernaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.InViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.IsNullViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.LikeViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.LogicNotViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.NegationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.RegularViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.UnaryViewExpression;
+import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.tsfile.utils.Pair;
+
+import javax.ws.rs.NotSupportedException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TransformToExpressionVisitor extends ViewExpressionVisitor<Expression, Void> {
+
+ @Override
+ public Expression process(ViewExpression viewExpression, Void context) {
+ return viewExpression.accept(this, context);
+ }
+
+ @Override
+ public Expression visitExpression(ViewExpression expression, Void context) {
+ throw new RuntimeException(
+ new NotSupportedException(
+ "visitExpression in TransformToExpressionVisitor is not supported."));
+ }
+
+ // region leaf operand
+ @Override
+ public Expression visitLeafOperand(LeafViewOperand leafViewOperand, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ @Override
+ public Expression visitConstantOperand(ConstantViewOperand constantOperand, Void context) {
+ return new org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand(
+ constantOperand.getDataType(), constantOperand.getValueString());
+ }
+
+ @Override
+ public Expression visitNullOperand(NullViewOperand nullOperand, Void context) {
+ return new org.apache.iotdb.db.mpp.plan.expression.leaf.NullOperand();
+ }
+
+ @Override
+ public Expression visitTimeSeriesOperand(TimeSeriesViewOperand timeSeriesOperand, Void context) {
+ try {
+ PartialPath path = new PartialPath(timeSeriesOperand.getPathString());
+ return new org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand(path);
+ } catch (IllegalPathException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public Expression visitTimeStampOperand(TimestampViewOperand timestampOperand, Void context) {
+ return new org.apache.iotdb.db.mpp.plan.expression.leaf.TimestampOperand();
+ }
+ // endregion
+
+ // region Unary Expressions
+ @Override
+ public Expression visitUnaryExpression(UnaryViewExpression unaryViewExpression, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ @Override
+ public Expression visitInExpression(InViewExpression inExpression, Void context) {
+ Expression child = this.process(inExpression.getExpression(), context);
+ return new org.apache.iotdb.db.mpp.plan.expression.unary.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.mpp.plan.expression.unary.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.mpp.plan.expression.unary.LikeExpression(
+ child, likeExpression.getPatternString(), likeExpression.getPattern());
+ }
+
+ @Override
+ public Expression visitLogicNotExpression(
+ LogicNotViewExpression logicNotExpression, Void context) {
+ Expression child = this.process(logicNotExpression.getExpression(), context);
+ return new org.apache.iotdb.db.mpp.plan.expression.unary.LogicNotExpression(child);
+ }
+
+ @Override
+ public Expression visitNegationExpression(
+ NegationViewExpression negationExpression, Void context) {
+ Expression child = this.process(negationExpression.getExpression(), context);
+ return new org.apache.iotdb.db.mpp.plan.expression.unary.NegationExpression(child);
+ }
+
+ @Override
+ public Expression visitRegularExpression(RegularViewExpression regularExpression, Void context) {
+ Expression child = this.process(regularExpression.getExpression(), context);
+ return new org.apache.iotdb.db.mpp.plan.expression.unary.RegularExpression(
+ child, regularExpression.getPatternString(), regularExpression.getPattern());
+ }
+ // endregion
+
+ @Override
+ // region Binary Expressions
+ public Expression visitBinaryExpression(BinaryViewExpression binaryViewExpression, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ private Pair<Expression, Expression> getExpressionsForBinaryExpression(
+ BinaryViewExpression binaryViewExpression) {
+ Expression left = this.process(binaryViewExpression.getLeftExpression(), null);
+ Expression right = this.process(binaryViewExpression.getRightExpression(), null);
+ return new Pair<>(left, right);
+ }
+
+ // region Binary : Arithmetic Binary Expression
+ public Expression visitArithmeticBinaryExpression(
+ ArithmeticBinaryViewExpression arithmeticBinaryExpression, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ public Expression visitAdditionExpression(
+ AdditionViewExpression additionExpression, Void context) {
+ Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(additionExpression);
+ return new org.apache.iotdb.db.mpp.plan.expression.binary.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.mpp.plan.expression.binary.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.mpp.plan.expression.binary.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.mpp.plan.expression.binary.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.mpp.plan.expression.binary.SubtractionExpression(
+ pair.left, pair.right);
+ }
+ // endregion
+
+ // region Binary: Compare Binary Expression
+ public Expression visitCompareBinaryExpression(
+ CompareBinaryViewExpression compareBinaryExpression, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ public Expression visitEqualToExpression(EqualToViewExpression equalToExpression, Void context) {
+ Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(equalToExpression);
+ return new org.apache.iotdb.db.mpp.plan.expression.binary.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.mpp.plan.expression.binary.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.mpp.plan.expression.binary.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.mpp.plan.expression.binary.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.mpp.plan.expression.binary.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.mpp.plan.expression.binary.NonEqualExpression(
+ pair.left, pair.right);
+ }
+ // endregion
+
+ // region Binary : Logic Binary Expression
+ public Expression visitLogicBinaryExpression(
+ LogicBinaryViewExpression logicBinaryExpression, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ public Expression visitLogicAndExpression(
+ LogicAndViewExpression logicAndExpression, Void context) {
+ Pair<Expression, Expression> pair = this.getExpressionsForBinaryExpression(logicAndExpression);
+ return new org.apache.iotdb.db.mpp.plan.expression.binary.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.mpp.plan.expression.binary.LogicOrExpression(
+ pair.left, pair.right);
+ }
+ // endregion
+
+ // endregion
+
+ // region Ternary Expressions
+ public Expression visitTernaryExpression(
+ TernaryViewExpression ternaryViewExpression, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ public Expression visitBetweenExpression(
+ BetweenViewExpression betweenViewExpression, Void context) {
+ Expression first = this.process(betweenViewExpression.getFirstExpression(), null);
+ Expression second = this.process(betweenViewExpression.getSecondExpression(), null);
+ Expression third = this.process(betweenViewExpression.getThirdExpression(), null);
+ return new org.apache.iotdb.db.mpp.plan.expression.ternary.BetweenExpression(
+ first, second, third, betweenViewExpression.isNotBetween());
+ }
+ // endregion
+
+ // region FunctionExpression
+ public Expression visitFunctionExpression(
+ FunctionViewExpression functionViewExpression, Void context) {
+ List<ViewExpression> viewExpressionList = functionViewExpression.getExpressions();
+ List<Expression> expressionList = new ArrayList<>();
+ for (ViewExpression viewExpression : viewExpressionList) {
+ expressionList.add(this.process(viewExpression, null));
+ }
+ return new org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression(
+ functionViewExpression.getFunctionName(),
+ functionViewExpression.getFunctionAttributes(),
+ expressionList);
+ }
+ // endregion
+
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/ViewExpressionVisitor.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/ViewExpressionVisitor.java
new file mode 100644
index 0000000000..a2023bc898
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/ViewExpressionVisitor.java
@@ -0,0 +1,219 @@
+/*
+ * 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.metadata.view.viewExpression.visitor;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.BinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.AdditionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.ArithmeticBinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.DivisionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.ModuloViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.MultiplicationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.SubtractionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.CompareBinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.EqualToViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.GreaterEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.GreaterThanViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.LessEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.LessThanViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.NonEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicAndViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicBinaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicOrViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.ConstantViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.LeafViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.NullViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimeSeriesViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimestampViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.multi.FunctionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ternary.BetweenViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ternary.TernaryViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.InViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.IsNullViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.LikeViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.LogicNotViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.NegationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.RegularViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.UnaryViewExpression;
+
+/**
+ * This class provides a visitor of {@link ViewExpression}, which can be extended to create a
+ * visitor which only needs to handle a subset of the available methods.
+ *
+ * @param <R> The return type of the visit operation.
+ * @param <C> The context information during visiting.
+ */
+public abstract class ViewExpressionVisitor<R, C> {
+
+ public R process(ViewExpression expression, C context) {
+ return expression.accept(this, context);
+ }
+
+ public abstract R visitExpression(ViewExpression expression, C context);
+
+ // region leaf operand
+ public R visitLeafOperand(LeafViewOperand leafViewOperand, C context) {
+ return visitExpression(leafViewOperand, context);
+ }
+
+ public R visitConstantOperand(ConstantViewOperand constantOperand, C context) {
+ return visitLeafOperand(constantOperand, context);
+ }
+
+ public R visitNullOperand(NullViewOperand nullOperand, C context) {
+ return visitLeafOperand(nullOperand, context);
+ }
+
+ public R visitTimeSeriesOperand(TimeSeriesViewOperand timeSeriesOperand, C context) {
+ return visitLeafOperand(timeSeriesOperand, context);
+ }
+
+ public R visitTimeStampOperand(TimestampViewOperand timestampOperand, C context) {
+ return visitLeafOperand(timestampOperand, context);
+ }
+ // endregion
+
+ // region Unary Expressions
+ public R visitUnaryExpression(UnaryViewExpression unaryViewExpression, C context) {
+ return visitExpression(unaryViewExpression, context);
+ }
+
+ public R visitInExpression(InViewExpression inExpression, C context) {
+ return visitUnaryExpression(inExpression, context);
+ }
+
+ public R visitIsNullExpression(IsNullViewExpression isNullExpression, C context) {
+ return visitUnaryExpression(isNullExpression, context);
+ }
+
+ public R visitLikeExpression(LikeViewExpression likeExpression, C context) {
+ return visitUnaryExpression(likeExpression, context);
+ }
+
+ public R visitLogicNotExpression(LogicNotViewExpression logicNotExpression, C context) {
+ return visitUnaryExpression(logicNotExpression, context);
+ }
+
+ public R visitNegationExpression(NegationViewExpression negationExpression, C context) {
+ return visitUnaryExpression(negationExpression, context);
+ }
+
+ public R visitRegularExpression(RegularViewExpression regularExpression, C context) {
+ return visitUnaryExpression(regularExpression, context);
+ }
+ // endregion
+
+ // region Binary Expressions
+ public R visitBinaryExpression(BinaryViewExpression binaryViewExpression, C context) {
+ return visitExpression(binaryViewExpression, context);
+ }
+
+ // region Binary : Arithmetic Binary Expression
+ public R visitArithmeticBinaryExpression(
+ ArithmeticBinaryViewExpression arithmeticBinaryExpression, C context) {
+ return visitBinaryExpression(arithmeticBinaryExpression, context);
+ }
+
+ public R visitAdditionExpression(AdditionViewExpression additionExpression, C context) {
+ return visitArithmeticBinaryExpression(additionExpression, context);
+ }
+
+ public R visitDivisionExpression(DivisionViewExpression divisionExpression, C context) {
+ return visitArithmeticBinaryExpression(divisionExpression, context);
+ }
+
+ public R visitModuloExpression(ModuloViewExpression moduloExpression, C context) {
+ return visitArithmeticBinaryExpression(moduloExpression, context);
+ }
+
+ public R visitMultiplicationExpression(
+ MultiplicationViewExpression multiplicationExpression, C context) {
+ return visitArithmeticBinaryExpression(multiplicationExpression, context);
+ }
+
+ public R visitSubtractionExpression(SubtractionViewExpression subtractionExpression, C context) {
+ return visitArithmeticBinaryExpression(subtractionExpression, context);
+ }
+ // endregion
+
+ // region Binary: Compare Binary Expression
+ public R visitCompareBinaryExpression(
+ CompareBinaryViewExpression compareBinaryExpression, C context) {
+ return visitBinaryExpression(compareBinaryExpression, context);
+ }
+
+ public R visitEqualToExpression(EqualToViewExpression equalToExpression, C context) {
+ return visitCompareBinaryExpression(equalToExpression, context);
+ }
+
+ public R visitGreaterEqualExpression(
+ GreaterEqualViewExpression greaterEqualExpression, C context) {
+ return visitCompareBinaryExpression(greaterEqualExpression, context);
+ }
+
+ public R visitGreaterThanExpression(GreaterThanViewExpression greaterThanExpression, C context) {
+ return visitCompareBinaryExpression(greaterThanExpression, context);
+ }
+
+ public R visitLessEqualExpression(LessEqualViewExpression lessEqualExpression, C context) {
+ return visitCompareBinaryExpression(lessEqualExpression, context);
+ }
+
+ public R visitLessThanExpression(LessThanViewExpression lessThanExpression, C context) {
+ return visitCompareBinaryExpression(lessThanExpression, context);
+ }
+
+ public R visitNonEqualExpression(NonEqualViewExpression nonEqualExpression, C context) {
+ return visitCompareBinaryExpression(nonEqualExpression, context);
+ }
+ // endregion
+
+ // region Binary : Logic Binary Expression
+ public R visitLogicBinaryExpression(LogicBinaryViewExpression logicBinaryExpression, C context) {
+ return visitBinaryExpression(logicBinaryExpression, context);
+ }
+
+ public R visitLogicAndExpression(LogicAndViewExpression logicAndExpression, C context) {
+ return visitLogicBinaryExpression(logicAndExpression, context);
+ }
+
+ public R visitLogicOrExpression(LogicOrViewExpression logicOrExpression, C context) {
+ return visitLogicBinaryExpression(logicOrExpression, context);
+ }
+ // endregion
+
+ // endregion
+
+ // region Ternary Expressions
+ public R visitTernaryExpression(TernaryViewExpression ternaryViewExpression, C context) {
+ return visitExpression(ternaryViewExpression, context);
+ }
+
+ public R visitBetweenExpression(BetweenViewExpression betweenViewExpression, C context) {
+ return visitTernaryExpression(betweenViewExpression, context);
+ }
+ // endregion
+
+ // region FunctionExpression
+ public R visitFunctionExpression(FunctionViewExpression functionViewExpression, C context) {
+ return visitExpression(functionViewExpression, context);
+ }
+ // endregion
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/visitor/SchemaExecutionVisitor.java b/server/src/main/java/org/apache/iotdb/db/metadata/visitor/SchemaExecutionVisitor.java
index d2ca0038b2..853b3fe5c4 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/visitor/SchemaExecutionVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/visitor/SchemaExecutionVisitor.java
@@ -26,12 +26,14 @@ import org.apache.iotdb.commons.path.MeasurementPath;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.exception.metadata.MeasurementAlreadyExistException;
import org.apache.iotdb.db.exception.metadata.template.TemplateIsInUseException;
+import org.apache.iotdb.db.metadata.plan.schemaregion.impl.write.CreateLogicalViewPlanImpl;
import org.apache.iotdb.db.metadata.plan.schemaregion.impl.write.SchemaRegionWritePlanFactory;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateAlignedTimeSeriesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateTimeSeriesPlan;
import org.apache.iotdb.db.metadata.schemaregion.ISchemaRegion;
import org.apache.iotdb.db.metadata.template.ClusterTemplateManager;
import org.apache.iotdb.db.metadata.template.Template;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanVisitor;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ActivateTemplateNode;
@@ -39,6 +41,7 @@ import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSe
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ConstructSchemaBlackListNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateAlignedTimeSeriesNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateLogicalViewNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateMultiTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.DeactivateTemplateNode;
@@ -440,6 +443,25 @@ public class SchemaExecutionVisitor extends PlanVisitor<TSStatus, ISchemaRegion>
}
}
+ @Override
+ public TSStatus visitCreateLogicalView(CreateLogicalViewNode node, ISchemaRegion schemaRegion) {
+ Map<PartialPath, ViewExpression> viewPathToSourceMap = node.getViewPathToSourceExpressionMap();
+ List<TSStatus> failingStatus = new ArrayList<>();
+ for (Map.Entry<PartialPath, ViewExpression> entry : viewPathToSourceMap.entrySet()) {
+ try {
+ schemaRegion.createLogicalView(
+ new CreateLogicalViewPlanImpl(entry.getKey(), entry.getValue()));
+ } catch (MetadataException e) {
+ logger.error("{}: MetaData error: ", IoTDBConstant.GLOBAL_DB_NAME, e);
+ failingStatus.add(RpcUtils.getStatus(e.getErrorCode(), e.getMessage()));
+ }
+ }
+ if (!failingStatus.isEmpty()) {
+ return RpcUtils.getStatus(failingStatus);
+ }
+ return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS, "Execute successfully");
+ }
+
@Override
public TSStatus visitPlan(PlanNode node, ISchemaRegion context) {
return null;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/common/header/ColumnHeaderConstant.java b/server/src/main/java/org/apache/iotdb/db/mpp/common/header/ColumnHeaderConstant.java
index 824fa23ce0..1270955119 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/common/header/ColumnHeaderConstant.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/common/header/ColumnHeaderConstant.java
@@ -182,6 +182,9 @@ public class ColumnHeaderConstant {
public static final String HYPERPARAMETER = "Hyperparameter";
public static final String MODEL_PATH = "ModelPath";
+ // column names for views (eg. logical view)
+ public static final String VIEW_TYPE = "ViewType";
+
public static final List<ColumnHeader> lastQueryColumnHeaders =
ImmutableList.of(
new ColumnHeader(TIMESERIES, TSDataType.TEXT),
@@ -199,7 +202,8 @@ public class ColumnHeaderConstant {
new ColumnHeader(TAGS, TSDataType.TEXT),
new ColumnHeader(ATTRIBUTES, TSDataType.TEXT),
new ColumnHeader(DEADBAND, TSDataType.TEXT),
- new ColumnHeader(DEADBAND_PARAMETERS, TSDataType.TEXT));
+ new ColumnHeader(DEADBAND_PARAMETERS, TSDataType.TEXT),
+ new ColumnHeader(VIEW_TYPE, TSDataType.TEXT));
public static final List<ColumnHeader> showDevicesWithSgColumnHeaders =
ImmutableList.of(
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/executor/RegionWriteExecutor.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/executor/RegionWriteExecutor.java
index c035edabe5..a5bbf26195 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/executor/RegionWriteExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/executor/RegionWriteExecutor.java
@@ -47,6 +47,7 @@ import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanVisitor;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ActivateTemplateNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateAlignedTimeSeriesNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateLogicalViewNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateMultiTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.InternalBatchActivateTemplateNode;
@@ -685,6 +686,54 @@ public class RegionWriteExecutor {
context.getRegionWriteValidationRWLock().readLock().unlock();
}
}
+
+ @Override
+ public RegionExecutionResult visitCreateLogicalView(
+ CreateLogicalViewNode node, WritePlanNodeExecutionContext context) {
+ ISchemaRegion schemaRegion =
+ SchemaEngine.getInstance().getSchemaRegion((SchemaRegionId) context.getRegionId());
+ if (config.getSchemaRegionConsensusProtocolClass().equals(ConsensusFactory.RATIS_CONSENSUS)) {
+ context.getRegionWriteValidationRWLock().writeLock().lock();
+ try {
+ // step 1. make sure all target paths are NOT exist.
+ List<PartialPath> targetPaths = node.getViewPathList();
+ List<MetadataException> failingMetadataException = new ArrayList<>();
+ for (PartialPath thisPath : targetPaths) {
+ // no alias list for a view, so the third parameter is null
+ Map<Integer, MetadataException> failingMeasurementMap =
+ schemaRegion.checkMeasurementExistence(
+ thisPath.getDevicePath(),
+ Collections.singletonList(thisPath.getMeasurement()),
+ null);
+ // merge all exception into one map
+ for (Map.Entry<Integer, MetadataException> entry : failingMeasurementMap.entrySet()) {
+ failingMetadataException.add(entry.getValue());
+ }
+ }
+ // if there is some exception, handle each exception and return first of them.
+ if (!failingMetadataException.isEmpty()) {
+ MetadataException metadataException = failingMetadataException.get(0);
+ LOGGER.error("Metadata error: ", metadataException);
+ RegionExecutionResult result = new RegionExecutionResult();
+ result.setAccepted(false);
+ result.setMessage(metadataException.getMessage());
+ result.setStatus(
+ RpcUtils.getStatus(
+ metadataException.getErrorCode(), metadataException.getMessage()));
+ return result;
+ }
+ // step 2. make sure all source paths are existed.
+ // TODO: CRTODO use a more efficient method
+ // List<PartialPath> sourcePaths = node.getAllTimeSeriesPathInSource();
+ return super.visitCreateLogicalView(node, context);
+ } finally {
+ context.getRegionWriteValidationRWLock().writeLock().unlock();
+ }
+ } else {
+ return super.visitCreateLogicalView(node, context);
+ }
+ // end of visitCreateLogicalView
+ }
}
private static class WritePlanNodeExecutionContext {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/TimeSeriesSchemaSource.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/TimeSeriesSchemaSource.java
index 9e52ece3ec..575fb4c7bb 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/TimeSeriesSchemaSource.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/TimeSeriesSchemaSource.java
@@ -98,9 +98,17 @@ public class TimeSeriesSchemaSource implements ISchemaSource<ITimeSeriesSchemaIn
builder.writeNullableText(0, series.getFullPath());
builder.writeNullableText(1, series.getAlias());
builder.writeNullableText(2, database);
- builder.writeNullableText(3, series.getSchema().getType().toString());
- builder.writeNullableText(4, series.getSchema().getEncodingType().toString());
- builder.writeNullableText(5, series.getSchema().getCompressor().toString());
+ if (series.isLogicalView()) {
+ builder.writeNullableText(3, "");
+ builder.writeNullableText(4, "null");
+ builder.writeNullableText(5, "null");
+ builder.writeNullableText(10, "logical");
+ } else {
+ builder.writeNullableText(3, series.getSchema().getType().toString());
+ builder.writeNullableText(4, series.getSchema().getEncodingType().toString());
+ builder.writeNullableText(5, series.getSchema().getCompressor().toString());
+ builder.writeNullableText(10, "");
+ }
builder.writeNullableText(6, mapToString(series.getTags()));
builder.writeNullableText(7, mapToString(series.getAttributes()));
builder.writeNullableText(8, deadbandInfo.left);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
index 248a7209fa..c9980705f9 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
@@ -111,6 +111,7 @@ import org.apache.iotdb.db.mpp.plan.statement.metadata.CountLevelTimeSeriesState
import org.apache.iotdb.db.mpp.plan.statement.metadata.CountNodesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CountTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateAlignedTimeSeriesStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateLogicalViewStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateMultiTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.DatabaseSchemaStatement;
@@ -3019,4 +3020,48 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
analysis.setWhereExpression(whereExpression);
}
+
+ // create Logical View
+ @Override
+ public Analysis visitCreateLogicalView(
+ CreateLogicalViewStatement createLogicalViewStatement, MPPQueryContext context) {
+ Analysis analysis = new Analysis();
+ // TODO: CRTODO: add more analyzing
+ context.setQueryType(QueryType.WRITE);
+
+ // check target paths; check source expressions.
+ Pair<Boolean, Exception> checkResult = createLogicalViewStatement.checkAll();
+ if (checkResult.left == false) {
+ throw new RuntimeException(checkResult.right);
+ }
+
+ Analysis queryAnalysis = null;
+ if (createLogicalViewStatement.getQueryStatement() != null) {
+ // analysis query statement
+ // AnalyzeVisitor queryVisitor = new AnalyzeVisitor(this.partitionFetcher,
+ // this.schemaFetcher);
+ // queryAnalysis =
+ // queryVisitor.visitQuery(createLogicalViewStatement.getQueryStatement(), null);
+ this.visitQuery(createLogicalViewStatement.getQueryStatement(), null);
+ // get all expression from resultColumns
+ List<ResultColumn> resultColumns =
+ createLogicalViewStatement.getQueryStatement().getSelectComponent().getResultColumns();
+ List<Expression> expressionList = new ArrayList<>();
+ for (ResultColumn resultCol : resultColumns) {
+ expressionList.add(resultCol.getExpression());
+ }
+ createLogicalViewStatement.setSourceExpressions(expressionList);
+ }
+ analysis.setStatement(createLogicalViewStatement);
+
+ // set schema partition info, this info will be used to split logical plan node.
+ PathPatternTree patternTree = new PathPatternTree();
+ for (PartialPath thisFullPath : createLogicalViewStatement.getTargetPathList()) {
+ patternTree.appendFullPath(thisFullPath);
+ }
+ SchemaPartition schemaPartitionInfo = partitionFetcher.getOrCreateSchemaPartition(patternTree);
+ analysis.setSchemaPartitionInfo(schemaPartitionInfo);
+
+ return analysis;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/TransformToViewExpressionVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/TransformToViewExpressionVisitor.java
new file mode 100644
index 0000000000..b19e9a460d
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/TransformToViewExpressionVisitor.java
@@ -0,0 +1,391 @@
+/*
+ * 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.mpp.plan.expression.visitor;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.AdditionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.DivisionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.ModuloViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.MultiplicationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.SubtractionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.EqualToViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.GreaterEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.GreaterThanViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.LessEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.LessThanViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.compare.NonEqualViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicAndViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.logic.LogicOrViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.ConstantViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.NullViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimeSeriesViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimestampViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.multi.FunctionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ternary.BetweenViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.InViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.IsNullViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.LikeViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.LogicNotViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.NegationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.unary.RegularViewExpression;
+import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.AdditionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.ArithmeticBinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.BinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.CompareBinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.DivisionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.EqualToExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.GreaterEqualExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.GreaterThanExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.LessEqualExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.LessThanExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.LogicAndExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.LogicBinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.LogicOrExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.ModuloExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.MultiplicationExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.NonEqualExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.SubtractionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.LeafOperand;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.NullOperand;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.TimestampOperand;
+import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.ternary.BetweenExpression;
+import org.apache.iotdb.db.mpp.plan.expression.ternary.TernaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.InExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.IsNullExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.LikeExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.LogicNotExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.NegationExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.RegularExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.UnaryExpression;
+import org.apache.iotdb.tsfile.utils.Pair;
+
+import javax.ws.rs.NotSupportedException;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class TransformToViewExpressionVisitor extends ExpressionVisitor<ViewExpression, Void> {
+
+ @Override
+ public ViewExpression process(Expression expression, Void context) {
+ return expression.accept(this, context);
+ }
+
+ @Override
+ public ViewExpression visitExpression(Expression expression, Void context) {
+ throw new RuntimeException(
+ new NotSupportedException(
+ "visitExpression in TransformToViewExpressionVisitor is not supported."));
+ }
+
+ // region leaf operand
+ @Override
+ public ViewExpression visitLeafOperand(LeafOperand leafOperand, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ @Override
+ public ViewExpression visitConstantOperand(ConstantOperand constantOperand, Void context) {
+ return new ConstantViewOperand(constantOperand.getDataType(), constantOperand.getValueString());
+ }
+
+ @Override
+ public ViewExpression visitNullOperand(NullOperand nullOperand, Void context) {
+ return new NullViewOperand();
+ }
+
+ @Override
+ public ViewExpression visitTimeSeriesOperand(TimeSeriesOperand timeSeriesOperand, Void context) {
+ return new TimeSeriesViewOperand(timeSeriesOperand.getPath().toString());
+ }
+
+ @Override
+ public ViewExpression visitTimeStampOperand(TimestampOperand timestampOperand, Void context) {
+ return new TimestampViewOperand();
+ }
+ // endregion
+
+ // region Unary Expressions
+ @Override
+ public ViewExpression visitUnaryExpression(UnaryExpression unaryExpression, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ @Override
+ public ViewExpression visitInExpression(InExpression inExpression, Void context) {
+ ViewExpression child = this.process(inExpression.getExpression(), context);
+ List<String> valueList = new ArrayList<>(inExpression.getValues());
+ return new InViewExpression(child, inExpression.isNotIn(), valueList);
+ }
+
+ @Override
+ public ViewExpression visitIsNullExpression(IsNullExpression isNullExpression, Void context) {
+ ViewExpression child = this.process(isNullExpression.getExpression(), context);
+ return new IsNullViewExpression(child, isNullExpression.isNot());
+ }
+
+ @Override
+ public ViewExpression visitLikeExpression(LikeExpression likeExpression, Void context) {
+ ViewExpression child = this.process(likeExpression.getExpression(), context);
+ return new LikeViewExpression(
+ child, likeExpression.getPatternString(), likeExpression.getPattern());
+ }
+
+ @Override
+ public ViewExpression visitLogicNotExpression(
+ LogicNotExpression logicNotExpression, Void context) {
+ ViewExpression child = this.process(logicNotExpression.getExpression(), context);
+ return new LogicNotViewExpression(child);
+ }
+
+ @Override
+ public ViewExpression visitNegationExpression(
+ NegationExpression negationExpression, Void context) {
+ ViewExpression child = this.process(negationExpression.getExpression(), context);
+ return new NegationViewExpression(child);
+ }
+
+ @Override
+ public ViewExpression visitRegularExpression(RegularExpression regularExpression, Void context) {
+ ViewExpression child = this.process(regularExpression.getExpression(), context);
+ return new RegularViewExpression(
+ child, regularExpression.getPatternString(), regularExpression.getPattern());
+ }
+ // endregion
+
+ // region Binary Expressions
+ @Override
+ public ViewExpression visitBinaryExpression(BinaryExpression binaryExpression, Void context) {
+ if (binaryExpression instanceof ArithmeticBinaryExpression) {
+ return this.visitArithmeticBinaryExpression(
+ (ArithmeticBinaryExpression) binaryExpression, context);
+ } else if (binaryExpression instanceof CompareBinaryExpression) {
+ return this.visitCompareBinaryExpression((CompareBinaryExpression) binaryExpression, context);
+ } else if (binaryExpression instanceof LogicBinaryExpression) {
+ return this.visitLogicBinaryExpression((LogicBinaryExpression) binaryExpression, context);
+ }
+ throw new RuntimeException(
+ new NotSupportedException(
+ "unsupported expression type:" + binaryExpression.getExpressionType()));
+ }
+
+ private Pair<ViewExpression, ViewExpression> getExpressionsForBinaryExpression(
+ BinaryExpression binaryExpression) {
+ ViewExpression left = this.process(binaryExpression.getLeftExpression(), null);
+ ViewExpression right = this.process(binaryExpression.getRightExpression(), null);
+ return new Pair<>(left, right);
+ }
+
+ // region Binary : Arithmetic Binary Expression
+ @Override
+ public ViewExpression visitArithmeticBinaryExpression(
+ ArithmeticBinaryExpression arithmeticBinaryExpression, Void context) {
+ if (arithmeticBinaryExpression instanceof AdditionExpression) {
+ return this.visitAdditionExpression((AdditionExpression) arithmeticBinaryExpression, context);
+ } else if (arithmeticBinaryExpression instanceof DivisionExpression) {
+ return this.visitDivisionExpression((DivisionExpression) arithmeticBinaryExpression, context);
+ } else if (arithmeticBinaryExpression instanceof ModuloExpression) {
+ return this.visitModuloExpression((ModuloExpression) arithmeticBinaryExpression, context);
+ } else if (arithmeticBinaryExpression instanceof MultiplicationExpression) {
+ return this.visitMultiplicationExpression(
+ (MultiplicationExpression) arithmeticBinaryExpression, context);
+ } else if (arithmeticBinaryExpression instanceof SubtractionExpression) {
+ return this.visitSubtractionExpression(
+ (SubtractionExpression) arithmeticBinaryExpression, context);
+ }
+ throw new RuntimeException(
+ new NotSupportedException(
+ "unsupported expression type:" + arithmeticBinaryExpression.getExpressionType()));
+ }
+
+ public ViewExpression visitAdditionExpression(
+ AdditionExpression additionExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(additionExpression);
+ return new AdditionViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitDivisionExpression(
+ DivisionExpression divisionExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(divisionExpression);
+ return new DivisionViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitModuloExpression(ModuloExpression moduloExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(moduloExpression);
+ return new ModuloViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitMultiplicationExpression(
+ MultiplicationExpression multiplicationExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(multiplicationExpression);
+ return new MultiplicationViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitSubtractionExpression(
+ SubtractionExpression subtractionExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(subtractionExpression);
+ return new SubtractionViewExpression(pair.left, pair.right);
+ }
+ // endregion
+
+ // region Binary: Compare Binary Expression
+ @Override
+ public ViewExpression visitCompareBinaryExpression(
+ CompareBinaryExpression compareBinaryExpression, Void context) {
+ if (compareBinaryExpression instanceof EqualToExpression) {
+ return this.visitEqualToExpression((EqualToExpression) compareBinaryExpression, context);
+ } else if (compareBinaryExpression instanceof GreaterEqualExpression) {
+ return this.visitGreaterEqualExpression(
+ (GreaterEqualExpression) compareBinaryExpression, context);
+ } else if (compareBinaryExpression instanceof GreaterThanExpression) {
+ return this.visitGreaterThanExpression(
+ (GreaterThanExpression) compareBinaryExpression, context);
+ } else if (compareBinaryExpression instanceof LessEqualExpression) {
+ return this.visitLessEqualExpression((LessEqualExpression) compareBinaryExpression, context);
+ } else if (compareBinaryExpression instanceof LessThanExpression) {
+ return this.visitLessThanExpression((LessThanExpression) compareBinaryExpression, context);
+ } else if (compareBinaryExpression instanceof NonEqualExpression) {
+ return this.visitNonEqualExpression((NonEqualExpression) compareBinaryExpression, context);
+ }
+ throw new RuntimeException(
+ new NotSupportedException(
+ "unsupported expression type:" + compareBinaryExpression.getExpressionType()));
+ }
+
+ public ViewExpression visitEqualToExpression(EqualToExpression equalToExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(equalToExpression);
+ return new EqualToViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitGreaterEqualExpression(
+ GreaterEqualExpression greaterEqualExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(greaterEqualExpression);
+ return new GreaterEqualViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitGreaterThanExpression(
+ GreaterThanExpression greaterThanExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(greaterThanExpression);
+ return new GreaterThanViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitLessEqualExpression(
+ LessEqualExpression lessEqualExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(lessEqualExpression);
+ return new LessEqualViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitLessThanExpression(
+ LessThanExpression lessThanExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(lessThanExpression);
+ return new LessThanViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitNonEqualExpression(
+ NonEqualExpression nonEqualExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(nonEqualExpression);
+ return new NonEqualViewExpression(pair.left, pair.right);
+ }
+ // endregion
+
+ // region Binary : Logic Binary Expression
+ @Override
+ public ViewExpression visitLogicBinaryExpression(
+ LogicBinaryExpression logicBinaryExpression, Void context) {
+ if (logicBinaryExpression instanceof LogicAndExpression) {
+ return this.visitLogicAndExpression((LogicAndExpression) logicBinaryExpression, context);
+ } else if (logicBinaryExpression instanceof LogicOrExpression) {
+ return this.visitLogicOrExpression((LogicOrExpression) logicBinaryExpression, context);
+ }
+ throw new RuntimeException(
+ new NotSupportedException(
+ "unsupported expression type:" + logicBinaryExpression.getExpressionType()));
+ }
+
+ public ViewExpression visitLogicAndExpression(
+ LogicAndExpression logicAndExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(logicAndExpression);
+ return new LogicAndViewExpression(pair.left, pair.right);
+ }
+
+ public ViewExpression visitLogicOrExpression(LogicOrExpression logicOrExpression, Void context) {
+ Pair<ViewExpression, ViewExpression> pair =
+ this.getExpressionsForBinaryExpression(logicOrExpression);
+ return new LogicOrViewExpression(pair.left, pair.right);
+ }
+ // endregion
+
+ // endregion
+
+ // region Ternary Expressions
+ @Override
+ public ViewExpression visitTernaryExpression(TernaryExpression ternaryExpression, Void context) {
+ throw new RuntimeException(new NotSupportedException("Can not construct abstract class."));
+ }
+
+ @Override
+ public ViewExpression visitBetweenExpression(BetweenExpression betweenExpression, Void context) {
+ ViewExpression first = this.process(betweenExpression.getFirstExpression(), null);
+ ViewExpression second = this.process(betweenExpression.getSecondExpression(), null);
+ ViewExpression third = this.process(betweenExpression.getSecondExpression(), null);
+ return new BetweenViewExpression(first, second, third, betweenExpression.isNotBetween());
+ }
+ // endregion
+
+ // region FunctionExpression
+ @Override
+ public ViewExpression visitFunctionExpression(
+ FunctionExpression functionExpression, Void context) {
+ List<Expression> expressionList = functionExpression.getExpressions();
+ List<ViewExpression> viewExpressionList = new ArrayList<>();
+ for (Expression expression : expressionList) {
+ viewExpressionList.add(this.process(expression, null));
+ }
+ LinkedHashMap<String, String> map = functionExpression.getFunctionAttributes();
+ List<String> keyList = new ArrayList<>();
+ List<String> valueList = new ArrayList<>();
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ keyList.add(entry.getKey());
+ valueList.add(entry.getValue());
+ }
+ return new FunctionViewExpression(
+ functionExpression.getFunctionName(), keyList, valueList, viewExpressionList);
+ }
+ // endregion
+
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index 28203751ee..bea8913d26 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -113,6 +113,7 @@ import org.apache.iotdb.db.mpp.plan.statement.metadata.CountTimeSlotListStatemen
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateAlignedTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateContinuousQueryStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateFunctionStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateLogicalViewStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreatePipePluginStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTriggerStatement;
@@ -960,6 +961,91 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
return new ShowContinuousQueriesStatement();
}
+ // Create Logical View
+ @Override
+ public Statement visitCreateLogicalView(IoTDBSqlParser.CreateLogicalViewContext ctx) {
+ CreateLogicalViewStatement createLogicalViewStatement = new CreateLogicalViewStatement();
+ // parse target
+ parseViewTargetPaths(ctx.viewTargetPaths(), createLogicalViewStatement);
+ // parse source
+ parseViewSourcePaths(ctx.viewSourcePaths(), createLogicalViewStatement);
+
+ return createLogicalViewStatement;
+ }
+
+ // parse suffix paths in logical view
+ private PartialPath parseViewSuffixPath(IoTDBSqlParser.ViewSuffixPathsContext ctx) {
+ List<IoTDBSqlParser.NodeNameWithoutWildcardContext> nodeNamesWithoutStar =
+ ctx.nodeNameWithoutWildcard();
+ String[] nodeList = new String[nodeNamesWithoutStar.size()];
+ for (int i = 0; i < nodeNamesWithoutStar.size(); i++) {
+ nodeList[i] = parseNodeNameWithoutWildCard(nodeNamesWithoutStar.get(i));
+ }
+ return new PartialPath(nodeList);
+ }
+
+ // parse target paths in CreateLogicalView statement
+ private void parseViewTargetPaths(
+ IoTDBSqlParser.ViewTargetPathsContext ctx,
+ CreateLogicalViewStatement createLogicalViewStatement) {
+ // full paths
+ if (ctx.fullPath() != null && ctx.fullPath().size() > 0) {
+ List<IoTDBSqlParser.FullPathContext> fullPathContextList = ctx.fullPath();
+ List<PartialPath> pathList = new ArrayList<>();
+ for (IoTDBSqlParser.FullPathContext pathContext : fullPathContextList) {
+ pathList.add(parseFullPath(pathContext));
+ }
+ createLogicalViewStatement.setTargetFullPaths(pathList);
+ }
+ // prefix path and suffix paths
+ if (ctx.prefixPath() != null
+ && ctx.viewSuffixPaths() != null
+ && ctx.viewSuffixPaths().size() > 0) {
+ IoTDBSqlParser.PrefixPathContext prefixPathContext = ctx.prefixPath();
+ PartialPath prefixPath = parsePrefixPath(prefixPathContext);
+ List<IoTDBSqlParser.ViewSuffixPathsContext> suffixPathContextList = ctx.viewSuffixPaths();
+ List<PartialPath> suffixPathList = new ArrayList<>();
+ for (IoTDBSqlParser.ViewSuffixPathsContext suffixPathContext : suffixPathContextList) {
+ suffixPathList.add(parseViewSuffixPath(suffixPathContext));
+ }
+ createLogicalViewStatement.setTargetPathsGroup(prefixPath, suffixPathList);
+ }
+ }
+
+ // parse source paths in CreateLogicalView statement
+ private void parseViewSourcePaths(
+ IoTDBSqlParser.ViewSourcePathsContext ctx,
+ CreateLogicalViewStatement createLogicalViewStatement) {
+ // full paths
+ if (ctx.fullPath() != null && ctx.fullPath().size() > 0) {
+ List<IoTDBSqlParser.FullPathContext> fullPathContextList = ctx.fullPath();
+ List<PartialPath> pathList = new ArrayList<>();
+ for (IoTDBSqlParser.FullPathContext pathContext : fullPathContextList) {
+ pathList.add(parseFullPath(pathContext));
+ }
+ createLogicalViewStatement.setSourceFullPaths(pathList);
+ }
+ // prefix path and suffix paths
+ if (ctx.prefixPath() != null
+ && ctx.viewSuffixPaths() != null
+ && ctx.viewSuffixPaths().size() > 0) {
+ IoTDBSqlParser.PrefixPathContext prefixPathContext = ctx.prefixPath();
+ PartialPath prefixPath = parsePrefixPath(prefixPathContext);
+ List<IoTDBSqlParser.ViewSuffixPathsContext> suffixPathContextList = ctx.viewSuffixPaths();
+ List<PartialPath> suffixPathList = new ArrayList<>();
+ for (IoTDBSqlParser.ViewSuffixPathsContext suffixPathContext : suffixPathContextList) {
+ suffixPathList.add(parseViewSuffixPath(suffixPathContext));
+ }
+ createLogicalViewStatement.setSourcePathsGroup(prefixPath, suffixPathList);
+ }
+ if (ctx.selectClause() != null && ctx.fromClause() != null) {
+ QueryStatement queryStatement = new QueryStatement();
+ queryStatement.setSelectComponent(parseSelectClause(ctx.selectClause(), queryStatement));
+ queryStatement.setFromComponent(parseFromClause(ctx.fromClause()));
+ createLogicalViewStatement.setSourceQueryStatement(queryStatement);
+ }
+ }
+
// Create Model =====================================================================
@Override
public Statement visitCreateModel(IoTDBSqlParser.CreateModelContext ctx) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
index a8cb30fac9..6c12ab2f00 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
@@ -21,17 +21,20 @@ package org.apache.iotdb.db.mpp.plan.planner;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
import org.apache.iotdb.db.metadata.template.Template;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
import org.apache.iotdb.db.mpp.common.MPPQueryContext;
import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
import org.apache.iotdb.db.mpp.plan.analyze.ExpressionAnalyzer;
import org.apache.iotdb.db.mpp.plan.expression.Expression;
import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.TransformToViewExpressionVisitor;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.load.LoadTsFileNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ActivateTemplateNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateAlignedTimeSeriesNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateLogicalViewNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateMultiTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.InternalBatchActivateTemplateNode;
@@ -67,6 +70,7 @@ import org.apache.iotdb.db.mpp.plan.statement.metadata.CountLevelTimeSeriesState
import org.apache.iotdb.db.mpp.plan.statement.metadata.CountNodesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CountTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateAlignedTimeSeriesStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateLogicalViewStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateMultiTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildNodesStatement;
@@ -812,4 +816,21 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
.planLimit(showQueriesStatement.getRowLimit());
return planBuilder.getRoot();
}
+
+ @Override
+ public PlanNode visitCreateLogicalView(
+ CreateLogicalViewStatement createLogicalViewStatement, MPPQueryContext context) {
+ // Transform all Expressions into ViewExpressions.
+ TransformToViewExpressionVisitor transformToViewExpressionVisitor =
+ new TransformToViewExpressionVisitor();
+ List<ViewExpression> viewExpressionList = new ArrayList<>();
+ List<Expression> expressionList = createLogicalViewStatement.getSourceExpressionList();
+ for (Expression expression : expressionList) {
+ viewExpressionList.add(transformToViewExpressionVisitor.process(expression, null));
+ }
+ return new CreateLogicalViewNode(
+ context.getQueryId().genPlanNodeId(),
+ createLogicalViewStatement.getTargetPathList(),
+ viewExpressionList);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanNodeType.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanNodeType.java
index 11b7b71717..762238ac91 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanNodeType.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanNodeType.java
@@ -39,6 +39,7 @@ import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSe
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ConstructSchemaBlackListNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateAlignedTimeSeriesNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateLogicalViewNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateMultiTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.DeactivateTemplateNode;
@@ -167,7 +168,8 @@ public enum PlanNodeType {
INTERNAL_CREATE_MULTI_TIMESERIES((short) 69),
IDENTITY_SINK((short) 70),
SHUFFLE_SINK((short) 71),
- BATCH_ACTIVATE_TEMPLATE((short) 72);
+ BATCH_ACTIVATE_TEMPLATE((short) 72),
+ CREATE_LOGICAL_VIEW((short) 73);
public static final int BYTES = Short.BYTES;
@@ -360,6 +362,8 @@ public enum PlanNodeType {
return ShuffleSinkNode.deserialize(buffer);
case 72:
return BatchActivateTemplateNode.deserialize(buffer);
+ case 73:
+ return CreateLogicalViewNode.deserialize(buffer);
default:
throw new IllegalArgumentException("Invalid node type: " + nodeType);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanVisitor.java
index 86ef541965..771a805014 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanVisitor.java
@@ -38,6 +38,7 @@ import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSe
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ConstructSchemaBlackListNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateAlignedTimeSeriesNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateLogicalViewNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateMultiTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateTimeSeriesNode;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.DeactivateTemplateNode;
@@ -401,4 +402,8 @@ public abstract class PlanVisitor<R, C> {
public R visitDeleteData(DeleteDataNode node, C context) {
return visitPlan(node, context);
}
+
+ public R visitCreateLogicalView(CreateLogicalViewNode node, C context) {
+ return visitPlan(node, context);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/CreateLogicalViewNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/CreateLogicalViewNode.java
new file mode 100644
index 0000000000..52e2a03519
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/CreateLogicalViewNode.java
@@ -0,0 +1,250 @@
+/*
+ * 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.mpp.plan.planner.plan.node.metedata.write;
+
+import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.path.PathDeserializeUtil;
+import org.apache.iotdb.db.metadata.plan.schemaregion.write.ICreateLogicalViewPlan;
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.visitor.GetSourcePathsVisitor;
+import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeType;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanVisitor;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.WritePlanNode;
+import org.apache.iotdb.tsfile.exception.NotImplementedException;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class CreateLogicalViewNode extends WritePlanNode implements ICreateLogicalViewPlan {
+
+ /**
+ * A map from target path to source expression. Yht target path is the name of this logical view,
+ * and the source expression is the data source of this view.
+ */
+ private Map<PartialPath, ViewExpression> viewPathToSourceMap;
+
+ /**
+ * This variable will be set in function splitByPartition() according to analysis. And it will be
+ * set when creating new split nodes.
+ */
+ private TRegionReplicaSet regionReplicaSet = null;
+
+ public CreateLogicalViewNode(
+ PlanNodeId id, List<PartialPath> paths, List<ViewExpression> expressions) {
+ super(id);
+ this.viewPathToSourceMap = convertTargetAndSourceListsToMap(paths, expressions);
+ }
+
+ public CreateLogicalViewNode(
+ PlanNodeId id, Map<PartialPath, ViewExpression> viewPathToSourceMap) {
+ super(id);
+ this.viewPathToSourceMap = viewPathToSourceMap;
+ }
+
+ public CreateLogicalViewNode(
+ PlanNodeId id,
+ Map<PartialPath, ViewExpression> viewPathToSourceMap,
+ TRegionReplicaSet regionReplicaSet) {
+ super(id);
+ this.viewPathToSourceMap = viewPathToSourceMap;
+ this.regionReplicaSet = regionReplicaSet;
+ }
+
+ protected final Map<PartialPath, ViewExpression> convertTargetAndSourceListsToMap(
+ List<PartialPath> paths, List<ViewExpression> expressions) {
+ if (paths.size() != expressions.size()) {
+ return null;
+ }
+ Map<PartialPath, ViewExpression> result = new HashMap<>();
+ for (int i = 0; i < paths.size(); i++) {
+ result.put(paths.get(i), expressions.get(i));
+ }
+ return result;
+ }
+
+ // region Interfaces in ICreateLogicalViewPlan
+ @Override
+ public int getViewSize() {
+ return this.viewPathToSourceMap.size();
+ }
+
+ @Override
+ public Map<PartialPath, ViewExpression> getViewPathToSourceExpressionMap() {
+ return this.viewPathToSourceMap;
+ }
+
+ @Override
+ public List<PartialPath> getViewPathList() {
+ List<PartialPath> result = new ArrayList<>(this.viewPathToSourceMap.keySet());
+ return result;
+ }
+
+ @Override
+ public void setViewPathToSourceExpressionMap(
+ Map<PartialPath, ViewExpression> viewPathToSourceExpressionMap) {
+ this.viewPathToSourceMap = viewPathToSourceExpressionMap;
+ }
+
+ @Override
+ public <R, C> R accept(PlanVisitor<R, C> visitor, C schemaRegion) {
+ return visitor.visitCreateLogicalView(this, schemaRegion);
+ }
+ // endregion
+
+ // region Interfaces in WritePlanNode or PlanNode
+
+ @Override
+ public TRegionReplicaSet getRegionReplicaSet() {
+ return this.regionReplicaSet;
+ }
+
+ @Override
+ public List<PlanNode> getChildren() {
+ return new ArrayList<>();
+ }
+
+ @Override
+ public void addChild(PlanNode child) {
+ // do nothing. this node should never have any child
+ }
+
+ @Override
+ public PlanNode clone() {
+ // TODO: CRTODO, complete this method
+ throw new NotImplementedException("Clone of CreateMultiTimeSeriesNode is not implemented");
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ CreateLogicalViewNode that = (CreateLogicalViewNode) obj;
+ return (this.getPlanNodeId().equals(that.getPlanNodeId())
+ && Objects.equals(this.viewPathToSourceMap, that.viewPathToSourceMap));
+ }
+
+ @Override
+ public int allowedChildCount() {
+ // this node should never have any child
+ return NO_CHILD_ALLOWED;
+ }
+
+ @Override
+ public List<String> getOutputColumnNames() {
+ // TODO: CRTODO, complete this method
+ throw new NotImplementedException(
+ "getOutputColumnNames of CreateMultiTimeSeriesNode is not implemented");
+ }
+
+ @Override
+ protected void serializeAttributes(ByteBuffer byteBuffer) {
+ PlanNodeType.CREATE_LOGICAL_VIEW.serialize(byteBuffer);
+ // serialize other member variables for this node
+ ReadWriteIOUtils.write(this.viewPathToSourceMap.size(), byteBuffer);
+ for (Map.Entry<PartialPath, ViewExpression> entry : viewPathToSourceMap.entrySet()) {
+ entry.getKey().serialize(byteBuffer);
+ ViewExpression.serialize(entry.getValue(), byteBuffer);
+ }
+ }
+
+ @Override
+ protected void serializeAttributes(DataOutputStream stream) throws IOException {
+ PlanNodeType.CREATE_LOGICAL_VIEW.serialize(stream);
+ // serialize other member variables for this node
+ ReadWriteIOUtils.write(this.viewPathToSourceMap.size(), stream);
+ for (Map.Entry<PartialPath, ViewExpression> entry : viewPathToSourceMap.entrySet()) {
+ entry.getKey().serialize(stream);
+ ViewExpression.serialize(entry.getValue(), stream);
+ }
+ }
+
+ public static CreateLogicalViewNode deserialize(ByteBuffer byteBuffer) {
+ // deserialize member variables
+ Map<PartialPath, ViewExpression> viewPathToSourceMap = new HashMap<>();
+ int size = byteBuffer.getInt();
+ PartialPath path;
+ ViewExpression viewExpression;
+ for (int i = 0; i < size; i++) {
+ path = (PartialPath) PathDeserializeUtil.deserialize(byteBuffer);
+ viewExpression = ViewExpression.deserialize(byteBuffer);
+ viewPathToSourceMap.put(path, viewExpression);
+ }
+ // deserialize PlanNodeId next
+ PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
+ return new CreateLogicalViewNode(planNodeId, viewPathToSourceMap);
+ }
+
+ @Override
+ public List<WritePlanNode> splitByPartition(Analysis analysis) {
+ Map<TRegionReplicaSet, Map<PartialPath, ViewExpression>> splitMap = new HashMap<>();
+ for (Map.Entry<PartialPath, ViewExpression> entry : this.viewPathToSourceMap.entrySet()) {
+ // for each entry in the map for target path to source expression,
+ // build a map from TRegionReplicaSet to this entry.
+ // Please note that getSchemaRegionReplicaSet needs a device path as parameter.
+ TRegionReplicaSet regionReplicaSet =
+ analysis.getSchemaPartitionInfo().getSchemaRegionReplicaSet(entry.getKey().getDevice());
+
+ // create a map if the key(regionReplicaSet) is not exists,
+ // then put this entry into this map(from regionReplicaSet to this entry)
+ splitMap
+ .computeIfAbsent(regionReplicaSet, k -> new HashMap<>())
+ .put(entry.getKey(), entry.getValue());
+ }
+
+ // split this node into several nodes according to their regionReplicaSet
+ List<WritePlanNode> result = new ArrayList<>();
+ for (Map.Entry<TRegionReplicaSet, Map<PartialPath, ViewExpression>> entry :
+ splitMap.entrySet()) {
+ // for each entry in splitMap, create a plan node.
+ result.add(new CreateLogicalViewNode(getPlanNodeId(), entry.getValue(), entry.getKey()));
+ }
+ return result;
+ }
+ // endregion
+
+ public List<PartialPath> getAllTimeSeriesPathInSource() {
+ List<ViewExpression> sourceExpressions = new ArrayList<>();
+ for (Map.Entry<PartialPath, ViewExpression> entry : this.viewPathToSourceMap.entrySet()) {
+ sourceExpressions.add(entry.getValue());
+ }
+ // for each view expression, get the partial path for time series operand
+ List<PartialPath> result = new ArrayList<>();
+ GetSourcePathsVisitor getSourcePathsVisitor = new GetSourcePathsVisitor();
+ for (ViewExpression expression : sourceExpressions) {
+ result.addAll(getSourcePathsVisitor.process(expression, null));
+ }
+ return result;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementType.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementType.java
index 4bf8190495..e3ebe07d41 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementType.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementType.java
@@ -167,4 +167,6 @@ public enum StatementType {
SHOW_SPACE_QUOTA,
SET_THROTTLE_QUOTA,
SHOW_THROTTLE_QUOTA,
+
+ CREATE_LOGICAL_VIEW,
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
index 8a5bcf18ab..5f716f95b5 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
@@ -42,6 +42,7 @@ import org.apache.iotdb.db.mpp.plan.statement.metadata.CountTimeSlotListStatemen
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateAlignedTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateContinuousQueryStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateFunctionStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateLogicalViewStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateMultiTimeSeriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreatePipePluginStatement;
import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement;
@@ -240,6 +241,12 @@ public abstract class StatementVisitor<R, C> {
return visitStatement(showPipePluginsStatement, context);
}
+ // Create Logical View
+ public R visitCreateLogicalView(
+ CreateLogicalViewStatement createLogicalViewStatement, C context) {
+ return visitStatement(createLogicalViewStatement, context);
+ }
+
// ML Model
public R visitCreateModel(CreateModelStatement createModelStatement, C context) {
return visitStatement(createModelStatement, context);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateLogicalViewStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateLogicalViewStatement.java
new file mode 100644
index 0000000000..b96aa42dd7
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateLogicalViewStatement.java
@@ -0,0 +1,246 @@
+/*
+ * 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.mpp.plan.statement.metadata;
+
+import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.mpp.plan.statement.Statement;
+import org.apache.iotdb.db.mpp.plan.statement.StatementType;
+import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
+import org.apache.iotdb.db.mpp.plan.statement.crud.QueryStatement;
+import org.apache.iotdb.tsfile.utils.Pair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** CREATE LOGICAL VIEW statement. */
+public class CreateLogicalViewStatement extends Statement {
+
+ // the paths of this view
+ private viewPaths targetPaths;
+
+ // the paths of sources
+ private viewPaths sourcePaths;
+ private QueryStatement queryStatement;
+
+ public CreateLogicalViewStatement() {
+ super();
+ this.statementType = StatementType.CREATE_LOGICAL_VIEW;
+ this.sourcePaths = new viewPaths();
+ this.targetPaths = new viewPaths();
+ }
+
+ // region Interfaces about setting and getting
+
+ // get paths
+ @Override
+ public List<PartialPath> getPaths() {
+ return this.getTargetPathList();
+ }
+
+ public List<PartialPath> getTargetPathList() {
+ return this.targetPaths.fullPathList;
+ }
+
+ public List<Expression> getSourceExpressionList() {
+ this.sourcePaths.generateExpressionsIfNecessary();
+ return this.sourcePaths.expressionsList;
+ }
+
+ public QueryStatement getQueryStatement() {
+ return this.queryStatement;
+ }
+
+ // set source paths
+ public void setSourceFullPaths(List<PartialPath> paths) {
+ this.sourcePaths.setViewPathType(ViewPathType.FULL_PATH_LIST);
+ this.sourcePaths.setFullPathList(paths);
+ }
+
+ public void setSourcePathsGroup(PartialPath prefixPath, List<PartialPath> suffixPaths) {
+ this.sourcePaths.setViewPathType(ViewPathType.PATHS_GROUP);
+ this.sourcePaths.setPrefixOfPathsGroup(prefixPath);
+ this.sourcePaths.setSuffixOfPathsGroup(suffixPaths);
+ this.sourcePaths.generateFullPathsFromPathsGroup();
+ }
+
+ public void setSourceQueryStatement(QueryStatement queryStatement) {
+ this.sourcePaths.setViewPathType(ViewPathType.QUERY_STATEMENT);
+ this.queryStatement = queryStatement;
+ }
+
+ /**
+ * This function must be called after analyzing query statement. Expressions that analyzed should
+ * be set through here.
+ *
+ * @param expressionList
+ */
+ public void setSourceExpressions(List<Expression> expressionList) {
+ this.sourcePaths.setExpressionsList(expressionList);
+ }
+
+ // set target paths
+ public void setTargetFullPaths(List<PartialPath> paths) {
+ this.targetPaths.setViewPathType(ViewPathType.FULL_PATH_LIST);
+ this.targetPaths.setFullPathList(paths);
+ }
+
+ public void setTargetPathsGroup(PartialPath prefixPath, List<PartialPath> suffixPaths) {
+ this.targetPaths.setViewPathType(ViewPathType.PATHS_GROUP);
+ this.targetPaths.setPrefixOfPathsGroup(prefixPath);
+ this.targetPaths.setSuffixOfPathsGroup(suffixPaths);
+ this.targetPaths.generateFullPathsFromPathsGroup();
+ }
+
+ // endregion
+
+ // region Interfaces for checking
+ /**
+ * Check errors in targetPaths.
+ *
+ * @return Pair<Boolean, Exception>. True: checks passed, exception is null; False: checks failed,
+ * returns exception.
+ */
+ public Pair<Boolean, Exception> checkTargetPaths() {
+ for (PartialPath thisPath : this.getTargetPathList()) {
+ if (thisPath.getNodeLength() < 3) {
+ return new Pair<>(false, new IllegalPathException(thisPath.getFullPath()));
+ }
+ }
+ return new Pair<>(true, null);
+ }
+
+ /**
+ * Check errors in sourcePaths. Only usable when not using query statement. If this statement is
+ * generated with a query statement, check always pass; if not, check each full paths.
+ *
+ * @return Pair<Boolean, Exception>. True: checks passed, exception is null; False: checks failed,
+ * returns exception.
+ */
+ public Pair<Boolean, Exception> checkSourcePathsIfNotUsingQueryStatement() {
+ if (this.sourcePaths.viewPathType == ViewPathType.PATHS_GROUP
+ || this.sourcePaths.viewPathType == ViewPathType.FULL_PATH_LIST) {
+ for (PartialPath thisPath : this.sourcePaths.fullPathList) {
+ if (thisPath.getNodeLength() < 3) {
+ return new Pair<>(false, new IllegalPathException(thisPath.getFullPath()));
+ }
+ }
+ }
+ return new Pair<>(true, null);
+ }
+
+ public Pair<Boolean, Exception> checkAll() {
+ Pair<Boolean, Exception> result = null;
+ result = this.checkTargetPaths();
+ if (result.left == false) return result;
+ result = this.checkSourcePathsIfNotUsingQueryStatement();
+ if (result.left == false) return result;
+ return new Pair<>(true, null);
+ }
+
+ // endregion
+
+ @Override
+ public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
+ return visitor.visitCreateLogicalView(this, context);
+ }
+
+ // region private classes
+
+ private enum ViewPathType {
+ FULL_PATH_LIST,
+ PATHS_GROUP,
+ QUERY_STATEMENT
+ }
+
+ /**
+ * A private class to save all paths' info in targetPaths and sourcePaths except query statement.
+ *
+ * <p>fullPathList: CREATE VIEW root.db.device.temp AS root.ln.d.s01 PathGroup: CREATE VIEW
+ * root.db(device.temp, status) AS root.ln(d.s01, wf.abc.s02)
+ */
+ private class viewPaths {
+ public ViewPathType viewPathType = ViewPathType.FULL_PATH_LIST;
+ public List<PartialPath> fullPathList = null;
+ public PartialPath prefixOfPathsGroup = null;
+ public List<PartialPath> suffixOfPathsGroup = null;
+
+ public List<Expression> expressionsList = null;
+
+ public void addPath(PartialPath path) {
+ if (this.fullPathList == null) {
+ this.fullPathList = new ArrayList<>();
+ this.fullPathList.add(path);
+ } else {
+ this.fullPathList.add(path);
+ }
+ }
+
+ public void setFullPathList(List<PartialPath> pathList) {
+ this.fullPathList = pathList;
+ }
+
+ public void setPrefixOfPathsGroup(PartialPath path) {
+ this.prefixOfPathsGroup = path;
+ }
+
+ public void setSuffixOfPathsGroup(List<PartialPath> pathList) {
+ this.suffixOfPathsGroup = pathList;
+ }
+
+ public void setViewPathType(ViewPathType viewPathType) {
+ this.viewPathType = viewPathType;
+ }
+
+ public void generateFullPathsFromPathsGroup() {
+ if (prefixOfPathsGroup != null && suffixOfPathsGroup != null) {
+ this.fullPathList = new ArrayList<>();
+ for (PartialPath suffixPath : suffixOfPathsGroup) {
+ PartialPath pathToAdd = prefixOfPathsGroup.concatPath(suffixPath);
+ this.addPath(pathToAdd);
+ }
+ }
+ }
+
+ public void generateExpressionsIfNecessary() {
+ if (this.viewPathType == ViewPathType.FULL_PATH_LIST
+ || this.viewPathType == ViewPathType.PATHS_GROUP) {
+ if (this.fullPathList != null) {
+ this.expressionsList = new ArrayList<>();
+ for (PartialPath path : this.fullPathList) {
+ TimeSeriesOperand tsExpression = new TimeSeriesOperand(path);
+ this.expressionsList.add(tsExpression);
+ }
+ }
+ } else if (this.viewPathType == ViewPathType.QUERY_STATEMENT) {
+ // no nothing. expressions should be set by setExpressionsList
+ }
+ }
+
+ public void setExpressionsList(List<Expression> expressionsList) {
+ this.expressionsList = expressionsList;
+ }
+ // end of viewPaths
+ }
+
+ // endregion
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/view/ViewExpressionToStringTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/view/ViewExpressionToStringTest.java
new file mode 100644
index 0000000000..aad623eb10
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/view/ViewExpressionToStringTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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.metadata.view;
+
+import org.apache.iotdb.db.metadata.view.viewExpression.ViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.AdditionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.binary.arithmetic.MultiplicationViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.ConstantViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimeSeriesViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.leaf.TimestampViewOperand;
+import org.apache.iotdb.db.metadata.view.viewExpression.multi.FunctionViewExpression;
+import org.apache.iotdb.db.metadata.view.viewExpression.ternary.BetweenViewExpression;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class ViewExpressionToStringTest {
+
+ @Test
+ public void testTimseriesOperand() {
+ String fullPath = new String("root.db.device.s01");
+ TimeSeriesViewOperand timeSeriesViewOperand = new TimeSeriesViewOperand(fullPath);
+ Assert.assertEquals(fullPath, timeSeriesViewOperand.toString());
+ Assert.assertEquals(fullPath, timeSeriesViewOperand.toString(true));
+ Assert.assertEquals(fullPath, timeSeriesViewOperand.toString(false));
+ }
+
+ @Test
+ public void testAdditionViewExpression() {
+ TimeSeriesViewOperand timeSeriesViewOperand = new TimeSeriesViewOperand("root.db.device.s01");
+ ConstantViewOperand constantViewOperand = new ConstantViewOperand(TSDataType.INT32, "2");
+ AdditionViewExpression add =
+ new AdditionViewExpression(timeSeriesViewOperand, constantViewOperand);
+
+ String expectedRoot = new String("root.db.device.s01 + 2");
+ String expectedNotRoot = new String("(root.db.device.s01 + 2)");
+ Assert.assertEquals(expectedRoot, add.toString());
+ Assert.assertEquals(expectedRoot, add.toString(true));
+ Assert.assertEquals(expectedNotRoot, add.toString(false));
+ }
+
+ @Test
+ public void testTwoBinaryExpression() {
+ TimeSeriesViewOperand ts1 = new TimeSeriesViewOperand("root.db.device.s01");
+ ConstantViewOperand constant2 = new ConstantViewOperand(TSDataType.INT32, "2");
+ AdditionViewExpression add = new AdditionViewExpression(ts1, constant2);
+ TimeSeriesViewOperand ts2 = new TimeSeriesViewOperand("root.ln.d.s01");
+ MultiplicationViewExpression multiplication = new MultiplicationViewExpression(add, ts2);
+
+ String expectedRoot = new String("(root.db.device.s01 + 2) * root.ln.d.s01");
+ String expectedNotRoot = new String("((root.db.device.s01 + 2) * root.ln.d.s01)");
+ Assert.assertEquals(expectedRoot, multiplication.toString());
+ Assert.assertEquals(expectedRoot, multiplication.toString(true));
+ Assert.assertEquals(expectedNotRoot, multiplication.toString(false));
+ }
+
+ @Test
+ public void testFunctionViewExpression01() {
+ String functionName = "func";
+ FunctionViewExpression func = new FunctionViewExpression(functionName);
+
+ String expectedRoot = new String("func()");
+ String expectedNotRoot = new String("func()");
+ Assert.assertEquals(expectedRoot, func.toString());
+ Assert.assertEquals(expectedRoot, func.toString(true));
+ Assert.assertEquals(expectedNotRoot, func.toString(false));
+ }
+
+ @Test
+ public void testFunctionViewExpression02() {
+ String functionName = "MAX";
+ List<String> keys = new ArrayList<>();
+ List<String> values = new ArrayList<>();
+
+ TimeSeriesViewOperand ts1 = new TimeSeriesViewOperand("root.db.device.s01");
+ ConstantViewOperand constant2 = new ConstantViewOperand(TSDataType.INT32, "2");
+ AdditionViewExpression add = new AdditionViewExpression(ts1, constant2);
+ TimeSeriesViewOperand ts2 = new TimeSeriesViewOperand("root.ln.d.s01");
+ List<ViewExpression> exps = Arrays.asList(add, ts2);
+
+ FunctionViewExpression func = new FunctionViewExpression(functionName, keys, values, exps);
+
+ String expectedRoot = new String("MAX(root.db.device.s01 + 2, root.ln.d.s01)");
+ String expectedNotRoot = new String("MAX(root.db.device.s01 + 2, root.ln.d.s01)");
+ Assert.assertEquals(expectedRoot, func.toString());
+ Assert.assertEquals(expectedRoot, func.toString(true));
+ Assert.assertEquals(expectedNotRoot, func.toString(false));
+ }
+
+ @Test
+ public void testFunctionViewExpression03() {
+ String functionName = "CAST";
+ List<String> keys = Collections.singletonList("type");
+ List<String> values = Collections.singletonList("INT32");
+
+ TimeSeriesViewOperand ts2 = new TimeSeriesViewOperand("root.ln.d.s01");
+ List<ViewExpression> exps = Collections.singletonList(ts2);
+
+ FunctionViewExpression func = new FunctionViewExpression(functionName, keys, values, exps);
+
+ String expectedRoot = new String("CAST(type=INT32)(root.ln.d.s01)");
+ String expectedNotRoot = new String("CAST(type=INT32)(root.ln.d.s01)");
+ Assert.assertEquals(expectedRoot, func.toString());
+ Assert.assertEquals(expectedRoot, func.toString(true));
+ Assert.assertEquals(expectedNotRoot, func.toString(false));
+ }
+
+ @Test
+ public void testFunctionViewExpression04() {
+ String functionName = "CAST";
+ List<String> keys = Collections.singletonList("type");
+ List<String> values = Collections.singletonList("INT32");
+
+ TimeSeriesViewOperand ts2 = new TimeSeriesViewOperand("root.ln.d.s01");
+ List<ViewExpression> exps = Collections.singletonList(ts2);
+
+ FunctionViewExpression func = new FunctionViewExpression(functionName, keys, values, exps);
+
+ String expectedRoot = new String("CAST(type=INT32)(root.ln.d.s01)");
+ String expectedNotRoot = new String("CAST(type=INT32)(root.ln.d.s01)");
+ Assert.assertEquals(expectedRoot, func.toString());
+ Assert.assertEquals(expectedRoot, func.toString(true));
+ Assert.assertEquals(expectedNotRoot, func.toString(false));
+ }
+
+ @Test
+ public void testFunctionViewExpression05() {
+ String functionName = "FUNC";
+ List<String> keys = Arrays.asList("type", "key");
+ List<String> values = Arrays.asList("INT32", "value");
+
+ TimeSeriesViewOperand ts1 = new TimeSeriesViewOperand("root.db.device.s01");
+ TimeSeriesViewOperand ts2 = new TimeSeriesViewOperand("root.ln.d.s01");
+ List<ViewExpression> exps = Arrays.asList(ts1, ts2);
+
+ FunctionViewExpression func = new FunctionViewExpression(functionName, keys, values, exps);
+
+ String expectedRoot =
+ new String("FUNC(type=INT32, key=value)(root.db.device.s01, root.ln.d.s01)");
+ String expectedNotRoot =
+ new String("FUNC(type=INT32, key=value)(root.db.device.s01, root.ln.d.s01)");
+ Assert.assertEquals(expectedRoot, func.toString());
+ Assert.assertEquals(expectedRoot, func.toString(true));
+ Assert.assertEquals(expectedNotRoot, func.toString(false));
+ }
+
+ @Test
+ public void testBetweenViewExpression() {
+ TimestampViewOperand timestamp01 = new TimestampViewOperand();
+ TimestampViewOperand timestamp02 = new TimestampViewOperand();
+ TimeSeriesViewOperand ts1 = new TimeSeriesViewOperand("root.db.device.s01");
+ BetweenViewExpression exp = new BetweenViewExpression(ts1, timestamp01, timestamp02);
+
+ String expectedRoot = new String("root.db.device.s01 BETWEEN TIMESTAMP AND TIMESTAMP");
+ String expectedNotRoot = new String("(root.db.device.s01 BETWEEN TIMESTAMP AND TIMESTAMP)");
+ Assert.assertEquals(expectedRoot, exp.toString());
+ Assert.assertEquals(expectedRoot, exp.toString(true));
+ Assert.assertEquals(expectedNotRoot, exp.toString(false));
+ }
+}