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 e4ead169cee Support Show View (#9951)
e4ead169cee is described below
commit e4ead169cee45c55a20f280ededc0b7cb6f13f1e
Author: Marcos_Zyk <[email protected]>
AuthorDate: Fri May 26 14:42:41 2023 +0800
Support Show View (#9951)
---
.../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 6 +-
.../reader/SchemaReaderLimitOffsetWrapper.java | 86 ++++++++++
.../db/mpp/common/header/ColumnHeaderConstant.java | 11 ++
.../db/mpp/common/header/DatasetHeaderFactory.java | 4 +
.../schema/source/LogicalViewSchemaSource.java | 175 +++++++++++++++++++++
.../schema/source/SchemaSourceFactory.java | 5 +
.../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java | 17 ++
.../iotdb/db/mpp/plan/parser/ASTVisitor.java | 27 ++++
.../db/mpp/plan/planner/LogicalPlanBuilder.java | 9 ++
.../db/mpp/plan/planner/LogicalPlanVisitor.java | 37 +++++
.../db/mpp/plan/planner/OperatorTreeGenerator.java | 20 +++
.../mpp/plan/planner/plan/node/PlanNodeType.java | 6 +-
.../metedata/read/LogicalViewSchemaScanNode.java | 126 +++++++++++++++
.../db/mpp/plan/statement/StatementVisitor.java | 5 +
.../metadata/view/ShowLogicalViewStatement.java | 62 ++++++++
15 files changed, 594 insertions(+), 2 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 98a866e5fdb..93ffd7a1c5a 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
@@ -64,7 +64,7 @@ ddlStatement
// Quota
| setSpaceQuota | showSpaceQuota | setThrottleQuota | showThrottleQuota
// View
- | createLogicalView | dropLogicalView
+ | createLogicalView | dropLogicalView | showLogicalView
;
dmlStatement
@@ -563,6 +563,10 @@ createLogicalView
: CREATE VIEW viewTargetPaths AS viewSourcePaths
;
+showLogicalView
+ : SHOW VIEW prefixPath? timeseriesWhereClause? rowPaginationClause?
+ ;
+
dropLogicalView
: (DELETE | DROP) VIEW prefixPath (COMMA prefixPath)*
;
diff --git
a/server/src/main/java/org/apache/iotdb/db/metadata/query/reader/SchemaReaderLimitOffsetWrapper.java
b/server/src/main/java/org/apache/iotdb/db/metadata/query/reader/SchemaReaderLimitOffsetWrapper.java
new file mode 100644
index 00000000000..4c3ed2cb89b
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/metadata/query/reader/SchemaReaderLimitOffsetWrapper.java
@@ -0,0 +1,86 @@
+/*
+ * 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.query.reader;
+
+import org.apache.iotdb.db.metadata.query.info.ISchemaInfo;
+
+import java.util.NoSuchElementException;
+
+public class SchemaReaderLimitOffsetWrapper<T extends ISchemaInfo> implements
ISchemaReader<T> {
+
+ private final ISchemaReader<T> schemaReader;
+
+ private final long limit;
+ private final long offset;
+ private final boolean hasLimit;
+
+ private int count = 0;
+ int curOffset = 0;
+
+ public SchemaReaderLimitOffsetWrapper(ISchemaReader<T> schemaReader, long
limit, long offset) {
+ this.schemaReader = schemaReader;
+ this.limit = limit;
+ this.offset = offset;
+ this.hasLimit = limit > 0 || offset > 0;
+
+ if (hasLimit) {
+ while (curOffset < offset && schemaReader.hasNext()) {
+ schemaReader.next();
+ curOffset++;
+ }
+ }
+ }
+
+ @Override
+ public boolean isSuccess() {
+ return schemaReader.isSuccess();
+ }
+
+ @Override
+ public Throwable getFailure() {
+ return schemaReader.getFailure();
+ }
+
+ @Override
+ public void close() throws Exception {
+ schemaReader.close();
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (hasLimit) {
+ return count < limit && schemaReader.hasNext();
+ } else {
+ return schemaReader.hasNext();
+ }
+ }
+
+ @Override
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ T result = schemaReader.next();
+ if (hasLimit) {
+ count++;
+ }
+ return result;
+ }
+}
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 b5d6e60bb27..a5ab5165c8c 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
@@ -186,6 +186,7 @@ public class ColumnHeaderConstant {
// column names for views (eg. logical view)
public static final String VIEW_TYPE = "ViewType";
+ public static final String SOURCE = "Source";
public static final List<ColumnHeader> lastQueryColumnHeaders =
ImmutableList.of(
@@ -458,4 +459,14 @@ public class ColumnHeaderConstant {
new ColumnHeader(TRAIL_ID, TSDataType.TEXT),
new ColumnHeader(MODEL_PATH, TSDataType.TEXT),
new ColumnHeader(HYPERPARAMETER, TSDataType.TEXT));
+
+ public static final List<ColumnHeader> showLogicalViewColumnHeaders =
+ ImmutableList.of(
+ new ColumnHeader(TIMESERIES, TSDataType.TEXT),
+ new ColumnHeader(DATABASE, TSDataType.TEXT),
+ new ColumnHeader(DATATYPE, TSDataType.TEXT),
+ new ColumnHeader(TAGS, TSDataType.TEXT),
+ new ColumnHeader(ATTRIBUTES, TSDataType.TEXT),
+ new ColumnHeader(VIEW_TYPE, TSDataType.TEXT),
+ new ColumnHeader(SOURCE, TSDataType.TEXT));
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/common/header/DatasetHeaderFactory.java
b/server/src/main/java/org/apache/iotdb/db/mpp/common/header/DatasetHeaderFactory.java
index 6652bcfa2f1..430839e0d6d 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/common/header/DatasetHeaderFactory.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/common/header/DatasetHeaderFactory.java
@@ -188,4 +188,8 @@ public class DatasetHeaderFactory {
public static DatasetHeader getShowTrailsHeader() {
return new DatasetHeader(ColumnHeaderConstant.showTrailsColumnHeaders,
true);
}
+
+ public static DatasetHeader getShowLogicalViewHeader() {
+ return new
DatasetHeader(ColumnHeaderConstant.showLogicalViewColumnHeaders, true);
+ }
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/LogicalViewSchemaSource.java
b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/LogicalViewSchemaSource.java
new file mode 100644
index 00000000000..1841d64a8da
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/LogicalViewSchemaSource.java
@@ -0,0 +1,175 @@
+/*
+ * 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.execution.operator.schema.source;
+
+import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.filter.SchemaFilter;
+import org.apache.iotdb.commons.schema.view.LogicalViewSchema;
+import
org.apache.iotdb.db.metadata.plan.schemaregion.impl.read.SchemaRegionReadPlanFactory;
+import org.apache.iotdb.db.metadata.query.info.ITimeSeriesSchemaInfo;
+import org.apache.iotdb.db.metadata.query.reader.ISchemaReader;
+import
org.apache.iotdb.db.metadata.query.reader.SchemaReaderLimitOffsetWrapper;
+import org.apache.iotdb.db.metadata.schemaregion.ISchemaRegion;
+import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
+import org.apache.iotdb.db.mpp.common.header.ColumnHeaderConstant;
+import org.apache.iotdb.tsfile.read.common.block.TsBlockBuilder;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.stream.Collectors;
+
+import static org.apache.iotdb.db.metadata.MetadataConstant.ALL_MATCH_PATTERN;
+
+public class LogicalViewSchemaSource implements
ISchemaSource<ITimeSeriesSchemaInfo> {
+
+ private final PartialPath pathPattern;
+
+ private final long limit;
+ private final long offset;
+
+ private final SchemaFilter schemaFilter;
+
+ LogicalViewSchemaSource(
+ PartialPath pathPattern, long limit, long offset, SchemaFilter
schemaFilter) {
+ this.pathPattern = pathPattern;
+
+ this.limit = limit;
+ this.offset = offset;
+
+ this.schemaFilter = schemaFilter;
+ }
+
+ @Override
+ public ISchemaReader<ITimeSeriesSchemaInfo> getSchemaReader(ISchemaRegion
schemaRegion) {
+ try {
+ return new SchemaReaderLimitOffsetWrapper<ITimeSeriesSchemaInfo>(
+ new LogicalViewSchemaReader(
+ schemaRegion.getTimeSeriesReader(
+ SchemaRegionReadPlanFactory.getShowTimeSeriesPlan(
+ pathPattern, Collections.emptyMap(), 0, 0, false,
schemaFilter))),
+ limit,
+ offset);
+ } catch (MetadataException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public List<ColumnHeader> getInfoQueryColumnHeaders() {
+ return ColumnHeaderConstant.showLogicalViewColumnHeaders;
+ }
+
+ @Override
+ public void transformToTsBlockColumns(
+ ITimeSeriesSchemaInfo series, TsBlockBuilder builder, String database) {
+ builder.getTimeColumnBuilder().writeLong(0);
+ builder.writeNullableText(0, series.getFullPath());
+ builder.writeNullableText(1, database);
+
+ builder.writeNullableText(2, "");
+
+ builder.writeNullableText(3, mapToString(series.getTags()));
+ builder.writeNullableText(4, mapToString(series.getAttributes()));
+
+ builder.writeNullableText(5, "logical");
+ builder.writeNullableText(
+ 6, ((LogicalViewSchema)
series.getSchema()).getExpression().toString());
+ builder.declarePosition();
+ }
+
+ @Override
+ public boolean hasSchemaStatistic(ISchemaRegion schemaRegion) {
+ return pathPattern.equals(ALL_MATCH_PATTERN) && (schemaFilter == null);
+ }
+
+ @Override
+ public long getSchemaStatistic(ISchemaRegion schemaRegion) {
+ return schemaRegion.getSchemaRegionStatistics().getSeriesNumber();
+ }
+
+ private String mapToString(Map<String, String> map) {
+ if (map == null || map.isEmpty()) {
+ return null;
+ }
+ String content =
+ map.entrySet().stream()
+ .map(e -> "\"" + e.getKey() + "\"" + ":" + "\"" + e.getValue() +
"\"")
+ .collect(Collectors.joining(","));
+ return "{" + content + "}";
+ }
+
+ private static class LogicalViewSchemaReader implements
ISchemaReader<ITimeSeriesSchemaInfo> {
+
+ private final ISchemaReader<ITimeSeriesSchemaInfo> timeSeriesReader;
+
+ private ITimeSeriesSchemaInfo nextResult;
+
+ LogicalViewSchemaReader(ISchemaReader<ITimeSeriesSchemaInfo>
timeSeriesReader) {
+ this.timeSeriesReader = timeSeriesReader;
+ }
+
+ @Override
+ public boolean isSuccess() {
+ return timeSeriesReader.isSuccess();
+ }
+
+ @Override
+ public Throwable getFailure() {
+ return timeSeriesReader.getFailure();
+ }
+
+ @Override
+ public void close() throws Exception {
+ timeSeriesReader.close();
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (nextResult == null) {
+ getNext();
+ }
+ return nextResult != null;
+ }
+
+ @Override
+ public ITimeSeriesSchemaInfo next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ ITimeSeriesSchemaInfo result = nextResult;
+ nextResult = null;
+ return result;
+ }
+
+ private void getNext() {
+ ITimeSeriesSchemaInfo timeSeriesSchemaInfo;
+ while (timeSeriesReader.hasNext()) {
+ timeSeriesSchemaInfo = timeSeriesReader.next();
+ if (timeSeriesSchemaInfo.isLogicalView()) {
+ nextResult = timeSeriesSchemaInfo;
+ return;
+ }
+ }
+ }
+ }
+}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/SchemaSourceFactory.java
b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/SchemaSourceFactory.java
index 6c7cc9e6efa..ccfb31ccef8 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/SchemaSourceFactory.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/schema/source/SchemaSourceFactory.java
@@ -81,4 +81,9 @@ public class SchemaSourceFactory {
List<PartialPath> pathPatternList, int templateId) {
return new PathsUsingTemplateSource(pathPatternList, templateId);
}
+
+ public static ISchemaSource<ITimeSeriesSchemaInfo>
getLogicalViewSchemaSource(
+ PartialPath pathPattern, long limit, long offset, SchemaFilter
schemaFilter) {
+ return new LogicalViewSchemaSource(pathPattern, limit, offset,
schemaFilter);
+ }
}
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 a4983f060d3..6e32b1d658d 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
@@ -136,6 +136,7 @@ import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowPathSetTempl
import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowPathsUsingTemplateStatement;
import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowSchemaTemplateStatement;
import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.CreateLogicalViewStatement;
+import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.ShowLogicalViewStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.ExplainStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.ShowQueriesStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.ShowVersionStatement;
@@ -3326,4 +3327,20 @@ public class AnalyzeVisitor extends
StatementVisitor<Analysis, MPPQueryContext>
return analysis;
}
+
+ @Override
+ public Analysis visitShowLogicalView(
+ ShowLogicalViewStatement showLogicalViewStatement, MPPQueryContext
context) {
+ context.setQueryType(QueryType.READ);
+ Analysis analysis = new Analysis();
+ analysis.setStatement(showLogicalViewStatement);
+
+ PathPatternTree patternTree = new PathPatternTree();
+ patternTree.appendPathPattern(showLogicalViewStatement.getPathPattern());
+ SchemaPartition schemaPartitionInfo =
partitionFetcher.getSchemaPartition(patternTree);
+ analysis.setSchemaPartitionInfo(schemaPartitionInfo);
+
+
analysis.setRespDatasetHeader(DatasetHeaderFactory.getShowLogicalViewHeader());
+ return analysis;
+ }
}
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 8f965050939..2bd2080cff0 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
@@ -165,6 +165,7 @@ import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowSchemaTempla
import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.UnsetSchemaTemplateStatement;
import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.CreateLogicalViewStatement;
import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.DeleteLogicalViewStatement;
+import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.ShowLogicalViewStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.AuthorStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.ClearCacheStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.ExplainStatement;
@@ -1016,6 +1017,32 @@ public class ASTVisitor extends
IoTDBSqlParserBaseVisitor<Statement> {
return deleteLogicalViewStatement;
}
+ @Override
+ public Statement visitShowLogicalView(IoTDBSqlParser.ShowLogicalViewContext
ctx) {
+ ShowLogicalViewStatement showLogicalViewStatement;
+ if (ctx.prefixPath() != null) {
+ showLogicalViewStatement = new
ShowLogicalViewStatement(parsePrefixPath(ctx.prefixPath()));
+ } else {
+ showLogicalViewStatement =
+ new ShowLogicalViewStatement(new
PartialPath(SqlConstant.getSingleRootArray()));
+ }
+ if (ctx.timeseriesWhereClause() != null) {
+ SchemaFilter schemaFilter =
parseTimeseriesWhereClause(ctx.timeseriesWhereClause());
+ showLogicalViewStatement.setSchemaFilter(schemaFilter);
+ }
+ if (ctx.rowPaginationClause() != null) {
+ if (ctx.rowPaginationClause().limitClause() != null) {
+ showLogicalViewStatement.setLimit(
+ parseLimitClause(ctx.rowPaginationClause().limitClause()));
+ }
+ if (ctx.rowPaginationClause().offsetClause() != null) {
+ showLogicalViewStatement.setOffset(
+ parseOffsetClause(ctx.rowPaginationClause().offsetClause()));
+ }
+ }
+ return showLogicalViewStatement;
+ }
+
// parse suffix paths in logical view
private PartialPath
parseViewSuffixPath(IoTDBSqlParser.ViewSuffixPathsContext ctx) {
List<IoTDBSqlParser.NodeNameWithoutWildcardContext> nodeNamesWithoutStar =
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
index b191f3f2a1c..3bc06b12940 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
@@ -43,6 +43,7 @@ import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.CountSchemaM
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.DevicesCountNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.DevicesSchemaScanNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.LevelTimeSeriesCountNode;
+import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.LogicalViewSchemaScanNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodeManagementMemoryMergeNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodePathsConvertNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodePathsCountNode;
@@ -1148,6 +1149,14 @@ public class LogicalPlanBuilder {
return this;
}
+ public LogicalPlanBuilder planLogicalViewSchemaSource(
+ PartialPath pathPattern, SchemaFilter schemaFilter, long limit, long
offset) {
+ this.root =
+ new LogicalViewSchemaScanNode(
+ context.getQueryId().genPlanNodeId(), pathPattern, schemaFilter,
limit, offset);
+ return this;
+ }
+
private LogicalPlanBuilder planSort(OrderByParameter orderByParameter) {
if (orderByParameter.isEmpty()) {
return this;
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 01eaf88aecc..b3397e563b6 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
@@ -80,6 +80,7 @@ import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ActivateTemplate
import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.BatchActivateTemplateStatement;
import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowPathsUsingTemplateStatement;
import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.CreateLogicalViewStatement;
+import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.ShowLogicalViewStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.ShowQueriesStatement;
import org.apache.iotdb.tsfile.utils.Pair;
@@ -844,4 +845,40 @@ public class LogicalPlanVisitor extends
StatementVisitor<PlanNode, MPPQueryConte
createLogicalViewStatement.getTargetPathList(),
viewExpressionList);
}
+
+ @Override
+ public PlanNode visitShowLogicalView(
+ ShowLogicalViewStatement showTimeSeriesStatement, MPPQueryContext
context) {
+ LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
+
+ // If there is only one region, we can push down the offset and limit
operation to
+ // source operator.
+ boolean canPushDownOffsetLimit =
+ analysis.getSchemaPartitionInfo() != null
+ && analysis.getSchemaPartitionInfo().getDistributionInfo().size()
== 1;
+
+ long limit = showTimeSeriesStatement.getLimit();
+ long offset = showTimeSeriesStatement.getOffset();
+ if (!canPushDownOffsetLimit) {
+ limit = showTimeSeriesStatement.getLimit() +
showTimeSeriesStatement.getOffset();
+ offset = 0;
+ }
+ planBuilder =
+ planBuilder
+ .planLogicalViewSchemaSource(
+ showTimeSeriesStatement.getPathPattern(),
+ showTimeSeriesStatement.getSchemaFilter(),
+ limit,
+ offset)
+ .planSchemaQueryMerge(false);
+
+ if (canPushDownOffsetLimit) {
+ return planBuilder.getRoot();
+ }
+
+ return planBuilder
+ .planOffset(showTimeSeriesStatement.getOffset())
+ .planLimit(showTimeSeriesStatement.getLimit())
+ .getRoot();
+ }
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
index 13c033c8a29..e98855927e4 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
@@ -142,6 +142,7 @@ import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.CountSchemaM
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.DevicesCountNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.DevicesSchemaScanNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.LevelTimeSeriesCountNode;
+import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.LogicalViewSchemaScanNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodeManagementMemoryMergeNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodePathsConvertNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodePathsCountNode;
@@ -531,6 +532,8 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
return visitNodePathsSchemaScan((NodePathsSchemaScanNode) node, context);
} else if (node instanceof PathsUsingTemplateScanNode) {
return visitPathsUsingTemplateScan((PathsUsingTemplateScanNode) node,
context);
+ } else if (node instanceof LogicalViewSchemaScanNode) {
+ return visitLogicalViewSchemaScan((LogicalViewSchemaScanNode) node,
context);
}
return visitPlan(node, context);
}
@@ -2380,6 +2383,23 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
node.getPathPatternList(), node.getTemplateId()));
}
+ public Operator visitLogicalViewSchemaScan(
+ LogicalViewSchemaScanNode node, LocalExecutionPlanContext context) {
+ OperatorContext operatorContext =
+ context
+ .getDriverContext()
+ .addOperatorContext(
+ context.getNextOperatorId(),
+ node.getPlanNodeId(),
+ SchemaQueryScanOperator.class.getSimpleName());
+ context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1);
+ return new SchemaQueryScanOperator<>(
+ node.getPlanNodeId(),
+ operatorContext,
+ SchemaSourceFactory.getLogicalViewSchemaSource(
+ node.getPath(), node.getLimit(), node.getOffset(),
node.getSchemaFilter()));
+ }
+
public List<Operator> dealWithConsumeAllChildrenPipelineBreaker(
PlanNode node, LocalExecutionPlanContext context) {
// children after pipelining
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 9d0bc8a148d..f0ff085eded 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
@@ -23,6 +23,7 @@ import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.CountSchemaM
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.DevicesCountNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.DevicesSchemaScanNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.LevelTimeSeriesCountNode;
+import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.LogicalViewSchemaScanNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodeManagementMemoryMergeNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodePathsConvertNode;
import
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.NodePathsCountNode;
@@ -175,7 +176,8 @@ public enum PlanNodeType {
CREATE_LOGICAL_VIEW((short) 73),
CONSTRUCT_LOGICAL_VIEW_BLACK_LIST((short) 74),
ROLLBACK_LOGICAL_VIEW_BLACK_LIST((short) 75),
- DELETE_LOGICAL_VIEW((short) 76);
+ DELETE_LOGICAL_VIEW((short) 76),
+ LOGICAL_VIEW_SCHEMA_SCAN((short) 77);
public static final int BYTES = Short.BYTES;
@@ -376,6 +378,8 @@ public enum PlanNodeType {
return RollbackLogicalViewBlackListNode.deserialize(buffer);
case 76:
return DeleteLogicalViewNode.deserialize(buffer);
+ case 77:
+ return LogicalViewSchemaScanNode.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/metedata/read/LogicalViewSchemaScanNode.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/read/LogicalViewSchemaScanNode.java
new file mode 100644
index 00000000000..060d0ef23dd
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/read/LogicalViewSchemaScanNode.java
@@ -0,0 +1,126 @@
+/*
+ * 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.read;
+
+import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.filter.SchemaFilter;
+import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
+import org.apache.iotdb.db.mpp.common.header.ColumnHeaderConstant;
+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.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+public class LogicalViewSchemaScanNode extends SchemaQueryScanNode {
+
+ private final SchemaFilter schemaFilter;
+
+ public LogicalViewSchemaScanNode(
+ PlanNodeId id, PartialPath partialPath, SchemaFilter schemaFilter, long
limit, long offset) {
+ super(id, partialPath, limit, offset, false);
+ this.schemaFilter = schemaFilter;
+ }
+
+ public SchemaFilter getSchemaFilter() {
+ return schemaFilter;
+ }
+
+ @Override
+ protected void serializeAttributes(ByteBuffer byteBuffer) {
+ PlanNodeType.LOGICAL_VIEW_SCHEMA_SCAN.serialize(byteBuffer);
+ ReadWriteIOUtils.write(path.getFullPath(), byteBuffer);
+ SchemaFilter.serialize(schemaFilter, byteBuffer);
+ ReadWriteIOUtils.write(limit, byteBuffer);
+ ReadWriteIOUtils.write(offset, byteBuffer);
+ }
+
+ @Override
+ protected void serializeAttributes(DataOutputStream stream) throws
IOException {
+ PlanNodeType.LOGICAL_VIEW_SCHEMA_SCAN.serialize(stream);
+ ReadWriteIOUtils.write(path.getFullPath(), stream);
+ SchemaFilter.serialize(schemaFilter, stream);
+ ReadWriteIOUtils.write(limit, stream);
+ ReadWriteIOUtils.write(offset, stream);
+ }
+
+ public static LogicalViewSchemaScanNode deserialize(ByteBuffer byteBuffer) {
+ String fullPath = ReadWriteIOUtils.readString(byteBuffer);
+ PartialPath path;
+ try {
+ path = new PartialPath(fullPath);
+ } catch (IllegalPathException e) {
+ throw new IllegalArgumentException("Cannot deserialize
TimeSeriesSchemaScanNode", e);
+ }
+ SchemaFilter schemaFilter = SchemaFilter.deserialize(byteBuffer);
+ long limit = ReadWriteIOUtils.readLong(byteBuffer);
+ long offset = ReadWriteIOUtils.readLong(byteBuffer);
+
+ PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
+
+ return new LogicalViewSchemaScanNode(planNodeId, path, schemaFilter,
limit, offset);
+ }
+
+ @Override
+ public PlanNode clone() {
+ return new LogicalViewSchemaScanNode(getPlanNodeId(), path, schemaFilter,
limit, offset);
+ }
+
+ @Override
+ public List<String> getOutputColumnNames() {
+ return ColumnHeaderConstant.showLogicalViewColumnHeaders.stream()
+ .map(ColumnHeader::getColumnName)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ LogicalViewSchemaScanNode that = (LogicalViewSchemaScanNode) o;
+ return Objects.equals(schemaFilter, that.schemaFilter);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), schemaFilter);
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "LogicalViewSchemaScanNode-%s:[DataRegion: %s]",
+ this.getPlanNodeId(), this.getRegionReplicaSet());
+ }
+}
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 03c18855434..8a70c0cf927 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
@@ -92,6 +92,7 @@ import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowSchemaTempla
import
org.apache.iotdb.db.mpp.plan.statement.metadata.template.UnsetSchemaTemplateStatement;
import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.CreateLogicalViewStatement;
import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.DeleteLogicalViewStatement;
+import
org.apache.iotdb.db.mpp.plan.statement.metadata.view.ShowLogicalViewStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.AuthorStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.ClearCacheStatement;
import org.apache.iotdb.db.mpp.plan.statement.sys.ExplainStatement;
@@ -253,6 +254,10 @@ public abstract class StatementVisitor<R, C> {
return visitStatement(deleteLogicalViewStatement, context);
}
+ public R visitShowLogicalView(ShowLogicalViewStatement
showLogicalViewStatement, C context) {
+ return visitStatement(showLogicalViewStatement, 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/view/ShowLogicalViewStatement.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/view/ShowLogicalViewStatement.java
new file mode 100644
index 00000000000..e98d02ab6f6
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/view/ShowLogicalViewStatement.java
@@ -0,0 +1,62 @@
+/*
+ * 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.view;
+
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.filter.SchemaFilter;
+import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowStatement;
+
+import java.util.Collections;
+import java.util.List;
+
+public class ShowLogicalViewStatement extends ShowStatement {
+
+ private final PartialPath pathPattern;
+
+ private SchemaFilter schemaFilter;
+
+ public ShowLogicalViewStatement(PartialPath pathPattern) {
+ super();
+ this.pathPattern = pathPattern;
+ }
+
+ public PartialPath getPathPattern() {
+ return pathPattern;
+ }
+
+ public SchemaFilter getSchemaFilter() {
+ return schemaFilter;
+ }
+
+ public void setSchemaFilter(SchemaFilter schemaFilter) {
+ this.schemaFilter = schemaFilter;
+ }
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return Collections.singletonList(pathPattern);
+ }
+
+ @Override
+ public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
+ return visitor.visitShowLogicalView(this, context);
+ }
+}