This is an automated email from the ASF dual-hosted git repository.
caogaofei pushed a commit to branch beyyes/TableModelGrammar_DistributePlan
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to
refs/heads/beyyes/TableModelGrammar_DistributePlan by this push:
new 16d07feb15d add explain support
16d07feb15d is described below
commit 16d07feb15d1751ddf5e0292765bbd5dd45019f0
Author: Beyyes <[email protected]>
AuthorDate: Thu Jun 13 21:06:08 2024 +0800
add explain support
---
.../memory/StatementMemorySourceVisitor.java | 4 +
.../TableModelStatementMemorySourceContext.java | 41 ++++++++++
.../TableModelStatementMemorySourceVisitor.java | 90 ++++++++++++++++++++++
.../plan/planner/plan/node/PlanGraphPrinter.java | 54 +++++++++++++
.../plan/relational/analyzer/Analysis.java | 20 +++--
.../relational/analyzer/StatementAnalyzer.java | 3 +-
.../plan/relational/planner/LogicalPlanner.java | 16 ++--
.../relational/planner/RelationalModelPlanner.java | 19 ++---
.../plan/relational/sql/parser/AstBuilder.java | 4 +-
9 files changed, 223 insertions(+), 28 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/StatementMemorySourceVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/StatementMemorySourceVisitor.java
index 7a37902dbb9..20bce13a41b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/StatementMemorySourceVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/StatementMemorySourceVisitor.java
@@ -100,6 +100,10 @@ public class StatementMemorySourceVisitor
new PlanGraphPrinter.GraphContext(
context.getQueryContext().getTypeProvider().getTemplatedInfo()));
+ return getStatementMemorySource(header, lines);
+ }
+
+ static StatementMemorySource getStatementMemorySource(DatasetHeader header,
List<String> lines) {
TsBlockBuilder builder = new
TsBlockBuilder(Collections.singletonList(TSDataType.TEXT));
lines.forEach(
line -> {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceContext.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceContext.java
new file mode 100644
index 00000000000..a4b849fb385
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceContext.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.execution.memory;
+
+import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
+import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Analysis;
+
+public class TableModelStatementMemorySourceContext {
+ private final MPPQueryContext queryContext;
+ private final Analysis analysis;
+
+ public TableModelStatementMemorySourceContext(MPPQueryContext queryContext,
Analysis analysis) {
+ this.queryContext = queryContext;
+ this.analysis = analysis;
+ }
+
+ public MPPQueryContext getQueryContext() {
+ return queryContext;
+ }
+
+ public Analysis getAnalysis() {
+ return analysis;
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
new file mode 100644
index 00000000000..43cca971e2e
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.execution.memory;
+
+import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
+import org.apache.iotdb.db.queryengine.common.header.DatasetHeader;
+import org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector;
+import org.apache.iotdb.db.queryengine.plan.analyze.ClusterPartitionFetcher;
+import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.LogicalQueryPlan;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanGraphPrinter;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
+import
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute.ExchangeNodeGenerator;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Explain;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Node;
+
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.block.TsBlock;
+
+import java.util.Collections;
+import java.util.List;
+
+import static
org.apache.iotdb.db.queryengine.common.header.DatasetHeader.EMPTY_HEADER;
+import static
org.apache.iotdb.db.queryengine.plan.execution.memory.StatementMemorySourceVisitor.getStatementMemorySource;
+
+public class TableModelStatementMemorySourceVisitor
+ extends AstVisitor<StatementMemorySource,
TableModelStatementMemorySourceContext> {
+
+ @Override
+ public StatementMemorySource visitNode(
+ Node node, TableModelStatementMemorySourceContext context) {
+ DatasetHeader datasetHeader = context.getAnalysis().getRespDatasetHeader();
+ return new StatementMemorySource(
+ new TsBlock(0), datasetHeader == null ? EMPTY_HEADER : datasetHeader);
+ }
+
+ @Override
+ public StatementMemorySource visitExplain(
+ Explain node, TableModelStatementMemorySourceContext context) {
+ context.getAnalysis().setStatement(node.getStatement());
+ DatasetHeader header =
+ new DatasetHeader(
+ Collections.singletonList(
+ new ColumnHeader(IoTDBConstant.COLUMN_DISTRIBUTION_PLAN,
TSDataType.TEXT)),
+ true);
+ LogicalQueryPlan logicalPlan =
+ new
org.apache.iotdb.db.queryengine.plan.relational.planner.LogicalPlanner(
+ context.getQueryContext(),
+ LocalExecutionPlanner.getInstance().metadata,
+ context.getQueryContext().getSession(),
+ ClusterPartitionFetcher.getInstance(),
+ WarningCollector.NOOP)
+ .plan(context.getAnalysis());
+
+ // TODO(beyyes) adapt this logic after optimize ExchangeNodeAdder
+ ExchangeNodeGenerator.PlanContext exchangeContext =
+ new ExchangeNodeGenerator.PlanContext(context.getQueryContext());
+ List<PlanNode> distributedPlanNodeResult =
+ new ExchangeNodeGenerator().visitPlan(logicalPlan.getRootNode(),
exchangeContext);
+
+ List<String> lines =
+ distributedPlanNodeResult
+ .get(0)
+ .accept(
+ new PlanGraphPrinter(),
+ new PlanGraphPrinter.GraphContext(
+
context.getQueryContext().getTypeProvider().getTemplatedInfo()));
+
+ return getStatementMemorySource(header, lines);
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
index 308e2afd22f..232c12ba34f 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
@@ -66,6 +66,7 @@ import
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.AggregationDe
import
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.CrossSeriesAggregationDescriptor;
import
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.DeviceViewIntoPathDescriptor;
import
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.IntoPathDescriptor;
+import
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode;
import org.apache.commons.lang3.Validate;
import org.apache.tsfile.utils.Pair;
@@ -598,6 +599,59 @@ public class PlanGraphPrinter extends
PlanVisitor<List<String>, PlanGraphPrinter
return render(node, boxValue, context);
}
+ // =============== Methods below are used for table model ================
+ @Override
+ public List<String> visitTableScan(TableScanNode node, GraphContext context)
{
+ List<String> boxValue = new ArrayList<>();
+ boxValue.add(String.format("TableScan-%s", node.getPlanNodeId().getId()));
+ boxValue.add(String.format("QualifiedTableName: %s",
node.getQualifiedTableName()));
+ boxValue.add(String.format("OutputSymbols: %s", node.getOutputSymbols()));
+ boxValue.add(String.format("DeviceEntriesSize: %s",
node.getDeviceEntries().size()));
+ boxValue.add(String.format("ScanOrder: %s", node.getScanOrder()));
+ if (node.getPushDownPredicate() != null) {
+ boxValue.add(String.format("PushDownPredicate: %s",
node.getOutputSymbols()));
+ }
+ if (node.getPushDownOffset() > 0) {
+ boxValue.add(String.format("PushDownOffset: %s",
node.getPushDownOffset()));
+ }
+ if (node.getPushDownLimit() > 0) {
+ boxValue.add(String.format("PushDownLimit: %s",
node.getPushDownLimit()));
+ }
+ boxValue.add(String.format("RegionId: %s",
node.getRegionReplicaSet().getRegionId().getId()));
+ return render(node, boxValue, context);
+ }
+
+ @Override
+ public List<String> visitFilter(
+ org.apache.iotdb.db.queryengine.plan.relational.planner.node.FilterNode
node,
+ GraphContext context) {
+ List<String> boxValue = new ArrayList<>();
+ boxValue.add(String.format("Filter-%s", node.getPlanNodeId().getId()));
+ boxValue.add(String.format("Predicate: %s", node.getPredicate()));
+ return render(node, boxValue, context);
+ }
+
+ @Override
+ public List<String> visitProject(
+ org.apache.iotdb.db.queryengine.plan.relational.planner.node.ProjectNode
node,
+ GraphContext context) {
+ List<String> boxValue = new ArrayList<>();
+ boxValue.add(String.format("Project-%s", node.getPlanNodeId().getId()));
+ boxValue.add(String.format("OutputSymbols: %s", node.getOutputSymbols()));
+ boxValue.add(String.format("Expressions: %s",
node.getAssignments().getMap().values()));
+ return render(node, boxValue, context);
+ }
+
+ @Override
+ public List<String> visitOutput(
+ org.apache.iotdb.db.queryengine.plan.relational.planner.node.OutputNode
node,
+ GraphContext context) {
+ List<String> boxValue = new ArrayList<>();
+ boxValue.add(String.format("Output-%s", node.getPlanNodeId().getId()));
+ boxValue.add(String.format("OutputSymbols: %s", node.getOutputSymbols()));
+ return render(node, boxValue, context);
+ }
+
private String printRegion(TRegionReplicaSet regionReplicaSet) {
return String.format(
"Partition: %s",
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
index c4708ad1960..4d019248d86 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
@@ -27,6 +27,8 @@ import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
import org.apache.iotdb.db.queryengine.common.header.DatasetHeader;
import org.apache.iotdb.db.queryengine.plan.analyze.IAnalysis;
import
org.apache.iotdb.db.queryengine.plan.execution.memory.StatementMemorySource;
+import
org.apache.iotdb.db.queryengine.plan.execution.memory.TableModelStatementMemorySourceContext;
+import
org.apache.iotdb.db.queryengine.plan.execution.memory.TableModelStatementMemorySourceVisitor;
import org.apache.iotdb.db.queryengine.plan.planner.plan.TimePredicate;
import
org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema;
@@ -86,11 +88,10 @@ import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import static java.util.Collections.unmodifiableSet;
import static java.util.Objects.requireNonNull;
-import static
org.apache.iotdb.db.queryengine.common.header.DatasetHeader.EMPTY_HEADER;
public class Analysis implements IAnalysis {
- @Nullable private final Statement root;
+ @Nullable private Statement root;
private final Map<NodeRef<Parameter>, Expression> parameters;
@@ -269,6 +270,10 @@ public class Analysis implements IAnalysis {
return getScope(root);
}
+ public void setStatement(Statement statement) {
+ this.root = statement;
+ }
+
public void setScope(Node node, Scope scope) {
scopes.put(NodeRef.of(node), scope);
}
@@ -614,11 +619,12 @@ public class Analysis implements IAnalysis {
@Override
public TsBlock constructResultForMemorySource(MPPQueryContext context) {
- StatementMemorySource source =
- new StatementMemorySource(
- new TsBlock(0), respDatasetHeader == null ? EMPTY_HEADER :
respDatasetHeader);
- setRespDatasetHeader(source.getDatasetHeader());
- return source.getTsBlock();
+ requireNonNull(getStatement(), "root statement is analysis is null");
+ StatementMemorySource memorySource =
+ new TableModelStatementMemorySourceVisitor()
+ .process(getStatement(), new
TableModelStatementMemorySourceContext(context, this));
+ setRespDatasetHeader(memorySource.getDatasetHeader());
+ return memorySource.getTsBlock();
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index a15ed482daa..1fcc4e89024 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -359,7 +359,8 @@ public class StatementAnalyzer {
@Override
protected Scope visitExplain(Explain node, Optional<Scope> context) {
- throw new SemanticException("Explain statement is not supported yet.");
+ analysis.setFinishQueryAfterAnalyze();
+ return visitQuery((Query) node.getStatement(), context);
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
index 719ede30231..a7537c4e680 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
@@ -14,7 +14,6 @@
package org.apache.iotdb.db.queryengine.plan.relational.planner;
-import org.apache.iotdb.commons.exception.IoTDBException;
import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
import org.apache.iotdb.db.queryengine.common.SessionInfo;
import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
@@ -34,6 +33,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.Pru
import
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.RelationalPlanOptimizer;
import
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.RemoveRedundantIdentityProjections;
import
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.SimplifyExpressions;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Explain;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Query;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Table;
@@ -84,7 +84,7 @@ public class LogicalPlanner {
new IndexScan());
}
- public LogicalQueryPlan plan(Analysis analysis) throws IoTDBException {
+ public LogicalQueryPlan plan(Analysis analysis) {
PlanNode planNode = planStatement(analysis, analysis.getStatement());
relationalPlanOptimizers.forEach(
@@ -95,17 +95,19 @@ public class LogicalPlanner {
return new LogicalQueryPlan(context, planNode);
}
- private PlanNode planStatement(Analysis analysis, Statement statement)
throws IoTDBException {
+ private PlanNode planStatement(Analysis analysis, Statement statement) {
return createOutputPlan(planStatementWithoutOutput(analysis, statement),
analysis);
}
- private RelationPlan planStatementWithoutOutput(Analysis analysis, Statement
statement)
- throws IoTDBException {
+ private RelationPlan planStatementWithoutOutput(Analysis analysis, Statement
statement) {
if (statement instanceof Query) {
return createRelationPlan(analysis, (Query) statement);
}
- throw new IoTDBException(
- "Unsupported statement type " + statement.getClass().getSimpleName(),
-1);
+ if (statement instanceof Explain) {
+ return createRelationPlan(analysis, (Query) ((Explain)
statement).getStatement());
+ }
+ throw new IllegalStateException(
+ "Unsupported statement type: " + statement.getClass().getSimpleName());
}
private PlanNode createOutputPlan(RelationPlan plan, Analysis analysis) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationalModelPlanner.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationalModelPlanner.java
index b936555d401..60189c42f63 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationalModelPlanner.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationalModelPlanner.java
@@ -24,7 +24,6 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.client.IClientManager;
import
org.apache.iotdb.commons.client.async.AsyncDataNodeInternalServiceClient;
import org.apache.iotdb.commons.client.sync.SyncDataNodeInternalServiceClient;
-import org.apache.iotdb.commons.exception.IoTDBException;
import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
import org.apache.iotdb.db.queryengine.execution.QueryStateMachine;
import org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector;
@@ -108,17 +107,13 @@ public class RelationalModelPlanner implements IPlanner {
@Override
public LogicalQueryPlan doLogicalPlan(IAnalysis analysis, MPPQueryContext
context) {
- try {
- return new LogicalPlanner(
- context,
- metadata,
- context.getSession(),
- ClusterPartitionFetcher.getInstance(),
- warningCollector)
- .plan((Analysis) analysis);
- } catch (IoTDBException e) {
- throw new RuntimeException(e);
- }
+ return new LogicalPlanner(
+ context,
+ metadata,
+ context.getSession(),
+ ClusterPartitionFetcher.getInstance(),
+ warningCollector)
+ .plan((Analysis) analysis);
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
index 02d98c5fac7..41e7fd6d33e 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
@@ -50,6 +50,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DropIndex;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DropTable;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Except;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ExistsPredicate;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Explain;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericDataType;
@@ -103,6 +104,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SimpleCaseExpress
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SimpleGroupBy;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SingleColumn;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SortItem;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.StringLiteral;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SubqueryExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Table;
@@ -502,7 +504,7 @@ public class AstBuilder extends
RelationalSqlBaseVisitor<Node> {
@Override
public Node visitExplain(RelationalSqlParser.ExplainContext ctx) {
- return super.visitExplain(ctx);
+ return new Explain(getLocation(ctx), (Statement) visit(ctx.query()));
}
@Override