This is an automated email from the ASF dual-hosted git repository.
jackietien 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 815ea9c069d Implemented query for schema related Information schema &
Fixed the bug that the deviceEntry get from cache does not reserve query memory
815ea9c069d is described below
commit 815ea9c069dff66fe7102e5ea94867bcc04c6eed
Author: Caideyipi <[email protected]>
AuthorDate: Thu Jan 9 14:07:44 2025 +0800
Implemented query for schema related Information schema & Fixed the bug
that the deviceEntry get from cache does not reserve query memory
---
.../relational/it/schema/IoTDBDatabaseIT.java | 41 +++
.../consensus/request/ConfigPhysicalPlanType.java | 2 +
.../table/DescTable4InformationSchemaPlan.java | 29 ++
.../table/ShowTable4InformationSchemaPlan.java | 30 ++
.../table/DescTable4InformationSchemaResp.java | 42 +++
.../table/ShowTable4InformationSchemaResp.java | 44 +++
.../iotdb/confignode/manager/ConfigManager.java | 18 +
.../apache/iotdb/confignode/manager/IManager.java | 6 +
.../manager/schema/ClusterSchemaManager.java | 32 ++
.../persistence/executor/ConfigPlanExecutor.java | 4 +
.../persistence/schema/ClusterSchemaInfo.java | 77 +++++
.../confignode/persistence/schema/ConfigMTree.java | 16 +
.../thrift/ConfigNodeRPCServiceProcessor.java | 12 +
.../iotdb/db/protocol/client/ConfigNodeClient.java | 14 +
.../InformationSchemaContentSupplierFactory.java | 372 ++++++++++++++++++---
.../iotdb/db/queryengine/plan/Coordinator.java | 4 +
.../config/metadata/relational/ShowDBTask.java | 4 +-
.../plan/planner/TableOperatorGenerator.java | 9 +-
.../metadata/fetcher/TableDeviceSchemaFetcher.java | 10 +-
.../DataNodeLocationSupplierFactory.java | 11 +
.../sql/ast/AbstractQueryDeviceWithCache.java | 2 +
.../plan/relational/sql/ast/AstVisitor.java | 4 +
.../plan/relational/sql/ast/CountStatement.java | 86 +++++
.../plan/relational/sql/parser/AstBuilder.java | 36 +-
.../plan/relational/sql/rewrite/ShowRewrite.java | 51 ++-
.../schemaengine/table/InformationSchemaUtils.java | 9 +-
.../src/main/thrift/confignode.thrift | 19 ++
27 files changed, 912 insertions(+), 72 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
index 4b3738a07d1..c98421e2772 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
@@ -406,6 +406,47 @@ public class IoTDBDatabaseIT {
"datanode_id,INT32,ATTRIBUTE,",
"elapsed_time,FLOAT,ATTRIBUTE,",
"statement,STRING,ATTRIBUTE,")));
+
+ // Test table query
+ statement.execute("create database test");
+ statement.execute("create table test.test (a tag, b attribute, c
int32)");
+
+ TestUtils.assertResultSetEqual(
+ statement.executeQuery("select * from databases"),
+
"database,ttl(ms),schema_replication_factor,data_replication_factor,time_partition_interval,schema_region_group_num,data_region_group_num,",
+ new HashSet<>(
+ Arrays.asList(
+ "information_schema,INF,null,null,null,null,null,",
+ "test,INF,1,1,604800000,0,0,")));
+ TestUtils.assertResultSetEqual(
+ statement.executeQuery("show devices from tables where status =
'USING'"),
+ "database,table_name,ttl(ms),status,",
+ new HashSet<>(
+ Arrays.asList(
+ "information_schema,databases,INF,USING,",
+ "information_schema,tables,INF,USING,",
+ "information_schema,columns,INF,USING,",
+ "information_schema,queries,INF,USING,",
+ "test,test,INF,USING,")));
+ TestUtils.assertResultSetEqual(
+ statement.executeQuery("count devices from tables where status =
'USING'"),
+ "count(devices),",
+ Collections.singleton("5,"));
+ TestUtils.assertResultSetEqual(
+ statement.executeQuery(
+ "select * from columns where table_name = 'queries' or database
= 'test'"),
+ "database,table_name,column_name,datatype,category,status,",
+ new HashSet<>(
+ Arrays.asList(
+ "information_schema,queries,query_id,STRING,TAG,USING,",
+
"information_schema,queries,start_time,TIMESTAMP,ATTRIBUTE,USING,",
+
"information_schema,queries,datanode_id,INT32,ATTRIBUTE,USING,",
+
"information_schema,queries,elapsed_time,FLOAT,ATTRIBUTE,USING,",
+
"information_schema,queries,statement,STRING,ATTRIBUTE,USING,",
+ "test,test,time,TIMESTAMP,TIME,USING,",
+ "test,test,a,STRING,TAG,USING,",
+ "test,test,b,STRING,ATTRIBUTE,USING,",
+ "test,test,c,INT32,FIELD,USING,")));
}
}
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
index 5d3bdcc6710..15236010654 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
@@ -171,6 +171,8 @@ public enum ConfigPhysicalPlanType {
PreDeleteColumn((short) 860),
CommitDeleteColumn((short) 861),
DescTable((short) 862),
+ ShowTable4InformationSchema((short) 863),
+ DescTable4InformationSchema((short) 864),
/** Deprecated types for sync, restored them for upgrade. */
@Deprecated
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/table/DescTable4InformationSchemaPlan.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/table/DescTable4InformationSchemaPlan.java
new file mode 100644
index 00000000000..27b7bcad87c
--- /dev/null
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/table/DescTable4InformationSchemaPlan.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.consensus.request.read.table;
+
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import
org.apache.iotdb.confignode.consensus.request.read.ConfigPhysicalReadPlan;
+
+public class DescTable4InformationSchemaPlan extends ConfigPhysicalReadPlan {
+ public DescTable4InformationSchemaPlan() {
+ super(ConfigPhysicalPlanType.DescTable4InformationSchema);
+ }
+}
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/table/ShowTable4InformationSchemaPlan.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/table/ShowTable4InformationSchemaPlan.java
new file mode 100644
index 00000000000..4dc45233043
--- /dev/null
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/table/ShowTable4InformationSchemaPlan.java
@@ -0,0 +1,30 @@
+/*
+ * 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.confignode.consensus.request.read.table;
+
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import
org.apache.iotdb.confignode.consensus.request.read.ConfigPhysicalReadPlan;
+
+public class ShowTable4InformationSchemaPlan extends ConfigPhysicalReadPlan {
+
+ public ShowTable4InformationSchemaPlan() {
+ super(ConfigPhysicalPlanType.ShowTable4InformationSchema);
+ }
+}
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/table/DescTable4InformationSchemaResp.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/table/DescTable4InformationSchemaResp.java
new file mode 100644
index 00000000000..5fc5fe851df
--- /dev/null
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/table/DescTable4InformationSchemaResp.java
@@ -0,0 +1,42 @@
+/*
+ * 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.confignode.consensus.response.table;
+
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.confignode.rpc.thrift.TDescTable4InformationSchemaResp;
+import org.apache.iotdb.confignode.rpc.thrift.TTableColumnInfo;
+import org.apache.iotdb.consensus.common.DataSet;
+
+import java.util.Map;
+
+public class DescTable4InformationSchemaResp implements DataSet {
+ private final TSStatus status;
+ private final Map<String, Map<String, TTableColumnInfo>> tableColumnInfoMap;
+
+ public DescTable4InformationSchemaResp(
+ final TSStatus status, final Map<String, Map<String, TTableColumnInfo>>
tableColumnInfoMap) {
+ this.status = status;
+ this.tableColumnInfoMap = tableColumnInfoMap;
+ }
+
+ public TDescTable4InformationSchemaResp
convertToTDescTable4InformationSchemaResp() {
+ return new
TDescTable4InformationSchemaResp(status).setTableColumnInfoMap(tableColumnInfoMap);
+ }
+}
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/table/ShowTable4InformationSchemaResp.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/table/ShowTable4InformationSchemaResp.java
new file mode 100644
index 00000000000..a0cbe756d5a
--- /dev/null
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/table/ShowTable4InformationSchemaResp.java
@@ -0,0 +1,44 @@
+/*
+ * 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.confignode.consensus.response.table;
+
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.confignode.rpc.thrift.TShowTable4InformationSchemaResp;
+import org.apache.iotdb.confignode.rpc.thrift.TTableInfo;
+import org.apache.iotdb.consensus.common.DataSet;
+
+import java.util.List;
+import java.util.Map;
+
+public class ShowTable4InformationSchemaResp implements DataSet {
+ private final TSStatus status;
+ private final Map<String, List<TTableInfo>> databaseTableInfoMap;
+
+ public ShowTable4InformationSchemaResp(
+ final TSStatus status, final Map<String, List<TTableInfo>>
databaseTableInfoMap) {
+ this.status = status;
+ this.databaseTableInfoMap = databaseTableInfoMap;
+ }
+
+ public TShowTable4InformationSchemaResp
convertToTShowTable4InformationSchemaResp() {
+ return new TShowTable4InformationSchemaResp(status)
+ .setDatabaseTableInfoMap(databaseTableInfoMap);
+ }
+}
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index 432784737c7..130f1dcd15c 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -163,6 +163,7 @@ import
org.apache.iotdb.confignode.rpc.thrift.TDeleteLogicalViewReq;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceReq;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceResp;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTimeSeriesReq;
+import org.apache.iotdb.confignode.rpc.thrift.TDescTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TDescTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TDropCQReq;
import org.apache.iotdb.confignode.rpc.thrift.TDropFunctionReq;
@@ -218,6 +219,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TShowPipeReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowPipeResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp;
+import org.apache.iotdb.confignode.rpc.thrift.TShowTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowThrottleReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowTopicReq;
@@ -2650,6 +2652,14 @@ public class ConfigManager implements IManager {
: new TShowTableResp(status);
}
+ @Override
+ public TShowTable4InformationSchemaResp showTables4InformationSchema() {
+ final TSStatus status = confirmLeader();
+ return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()
+ ? clusterSchemaManager.showTables4InformationSchema()
+ : new TShowTable4InformationSchemaResp(status);
+ }
+
@Override
public TDescTableResp describeTable(
final String database, final String tableName, final boolean isDetails) {
@@ -2659,6 +2669,14 @@ public class ConfigManager implements IManager {
: new TDescTableResp(status);
}
+ @Override
+ public TDescTable4InformationSchemaResp describeTable4InformationSchema() {
+ final TSStatus status = confirmLeader();
+ return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()
+ ? clusterSchemaManager.describeTables4InformationSchema()
+ : new TDescTable4InformationSchemaResp(status);
+ }
+
@Override
public TFetchTableResp fetchTables(final Map<String, Set<String>>
fetchTableMap) {
final TSStatus status = confirmLeader();
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
index cae5fe9c956..63e527440ed 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
@@ -87,6 +87,7 @@ import
org.apache.iotdb.confignode.rpc.thrift.TDeleteLogicalViewReq;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceReq;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceResp;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTimeSeriesReq;
+import org.apache.iotdb.confignode.rpc.thrift.TDescTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TDescTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TDropCQReq;
import org.apache.iotdb.confignode.rpc.thrift.TDropFunctionReq;
@@ -141,6 +142,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TShowPipeReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowPipeResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp;
+import org.apache.iotdb.confignode.rpc.thrift.TShowTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTopicReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowTopicResp;
@@ -843,8 +845,12 @@ public interface IManager {
TShowTableResp showTables(final String database, final boolean isDetails);
+ TShowTable4InformationSchemaResp showTables4InformationSchema();
+
TDescTableResp describeTable(
final String database, final String tableName, final boolean isDetails);
+ TDescTable4InformationSchemaResp describeTable4InformationSchema();
+
TFetchTableResp fetchTables(final Map<String, Set<String>> fetchTableMap);
}
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
index 353d97995b0..9a6c06c2673 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
@@ -40,8 +40,10 @@ import org.apache.iotdb.confignode.conf.ConfigNodeConfig;
import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
import
org.apache.iotdb.confignode.consensus.request.read.database.CountDatabasePlan;
import
org.apache.iotdb.confignode.consensus.request.read.database.GetDatabasePlan;
+import
org.apache.iotdb.confignode.consensus.request.read.table.DescTable4InformationSchemaPlan;
import org.apache.iotdb.confignode.consensus.request.read.table.DescTablePlan;
import org.apache.iotdb.confignode.consensus.request.read.table.FetchTablePlan;
+import
org.apache.iotdb.confignode.consensus.request.read.table.ShowTable4InformationSchemaPlan;
import org.apache.iotdb.confignode.consensus.request.read.table.ShowTablePlan;
import
org.apache.iotdb.confignode.consensus.request.read.template.GetAllSchemaTemplatePlan;
import
org.apache.iotdb.confignode.consensus.request.read.template.GetAllTemplateSetInfoPlan;
@@ -67,8 +69,10 @@ import
org.apache.iotdb.confignode.consensus.request.write.template.UnsetSchemaT
import
org.apache.iotdb.confignode.consensus.response.database.CountDatabaseResp;
import
org.apache.iotdb.confignode.consensus.response.database.DatabaseSchemaResp;
import org.apache.iotdb.confignode.consensus.response.partition.PathInfoResp;
+import
org.apache.iotdb.confignode.consensus.response.table.DescTable4InformationSchemaResp;
import org.apache.iotdb.confignode.consensus.response.table.DescTableResp;
import org.apache.iotdb.confignode.consensus.response.table.FetchTableResp;
+import
org.apache.iotdb.confignode.consensus.response.table.ShowTable4InformationSchemaResp;
import org.apache.iotdb.confignode.consensus.response.table.ShowTableResp;
import
org.apache.iotdb.confignode.consensus.response.template.AllTemplateSetInfoResp;
import
org.apache.iotdb.confignode.consensus.response.template.TemplateInfoResp;
@@ -82,12 +86,14 @@ import
org.apache.iotdb.confignode.manager.partition.PartitionMetrics;
import org.apache.iotdb.confignode.persistence.schema.ClusterSchemaInfo;
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseInfo;
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
+import org.apache.iotdb.confignode.rpc.thrift.TDescTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TDescTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TFetchTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TGetAllTemplatesResp;
import org.apache.iotdb.confignode.rpc.thrift.TGetPathsSetTemplatesResp;
import org.apache.iotdb.confignode.rpc.thrift.TGetTemplateResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowDatabaseResp;
+import org.apache.iotdb.confignode.rpc.thrift.TShowTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTableResp;
import org.apache.iotdb.consensus.exception.ConsensusException;
import org.apache.iotdb.db.schemaengine.template.Template;
@@ -1092,6 +1098,19 @@ public class ClusterSchemaManager {
}
}
+ public TShowTable4InformationSchemaResp showTables4InformationSchema() {
+ try {
+ return ((ShowTable4InformationSchemaResp)
+ configManager.getConsensusManager().read(new
ShowTable4InformationSchemaPlan()))
+ .convertToTShowTable4InformationSchemaResp();
+ } catch (final ConsensusException e) {
+ LOGGER.warn("Failed in the read API executing the consensus layer due
to: ", e);
+ final TSStatus res = new
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
+ res.setMessage(e.getMessage());
+ return new TShowTable4InformationSchemaResp(res);
+ }
+ }
+
public TDescTableResp describeTable(
final String database, final String tableName, final boolean isDetails) {
try {
@@ -1108,6 +1127,19 @@ public class ClusterSchemaManager {
}
}
+ public TDescTable4InformationSchemaResp describeTables4InformationSchema() {
+ try {
+ return ((DescTable4InformationSchemaResp)
+ configManager.getConsensusManager().read(new
DescTable4InformationSchemaPlan()))
+ .convertToTDescTable4InformationSchemaResp();
+ } catch (final ConsensusException e) {
+ LOGGER.warn("Failed in the read API executing the consensus layer due
to: ", e);
+ final TSStatus res = new
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
+ res.setMessage(e.getMessage());
+ return new TDescTable4InformationSchemaResp(res);
+ }
+ }
+
public TFetchTableResp fetchTables(final Map<String, Set<String>>
fetchTableMap) {
try {
return ((FetchTableResp)
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
index 712d8e3bf4c..07a75a0720b 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
@@ -322,10 +322,14 @@ public class ConfigPlanExecutor {
return clusterSchemaInfo.getTemplateSetInfo((GetTemplateSetInfoPlan)
req);
case ShowTable:
return clusterSchemaInfo.showTables((ShowTablePlan) req);
+ case ShowTable4InformationSchema:
+ return clusterSchemaInfo.showTables4InformationSchema();
case FetchTable:
return clusterSchemaInfo.fetchTables((FetchTablePlan) req);
case DescTable:
return clusterSchemaInfo.descTable((DescTablePlan) req);
+ case DescTable4InformationSchema:
+ return clusterSchemaInfo.descTable4InformationSchema();
case GetTriggerTable:
return triggerInfo.getTriggerTable((GetTriggerTablePlan) req);
case GetTriggerLocation:
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
index 069c5d99400..debf7510699 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
@@ -29,6 +29,7 @@ import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathPatternTree;
import org.apache.iotdb.commons.schema.table.TsTable;
+import org.apache.iotdb.commons.schema.table.TsTableInternalRPCUtil;
import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
import org.apache.iotdb.commons.utils.PathUtils;
import org.apache.iotdb.commons.utils.StatusUtils;
@@ -70,14 +71,17 @@ import
org.apache.iotdb.confignode.consensus.request.write.template.UnsetSchemaT
import
org.apache.iotdb.confignode.consensus.response.database.CountDatabaseResp;
import
org.apache.iotdb.confignode.consensus.response.database.DatabaseSchemaResp;
import org.apache.iotdb.confignode.consensus.response.partition.PathInfoResp;
+import
org.apache.iotdb.confignode.consensus.response.table.DescTable4InformationSchemaResp;
import org.apache.iotdb.confignode.consensus.response.table.DescTableResp;
import org.apache.iotdb.confignode.consensus.response.table.FetchTableResp;
+import
org.apache.iotdb.confignode.consensus.response.table.ShowTable4InformationSchemaResp;
import org.apache.iotdb.confignode.consensus.response.table.ShowTableResp;
import
org.apache.iotdb.confignode.consensus.response.template.AllTemplateSetInfoResp;
import
org.apache.iotdb.confignode.consensus.response.template.TemplateInfoResp;
import
org.apache.iotdb.confignode.consensus.response.template.TemplateSetInfoResp;
import org.apache.iotdb.confignode.exception.DatabaseNotExistsException;
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
+import org.apache.iotdb.confignode.rpc.thrift.TTableColumnInfo;
import org.apache.iotdb.confignode.rpc.thrift.TTableInfo;
import org.apache.iotdb.db.exception.metadata.SchemaQuotaExceededException;
import org.apache.iotdb.db.exception.sql.SemanticException;
@@ -1200,6 +1204,34 @@ public class ClusterSchemaInfo implements
SnapshotProcessor {
}
}
+ public ShowTable4InformationSchemaResp showTables4InformationSchema() {
+ databaseReadWriteLock.readLock().lock();
+ try {
+ return new ShowTable4InformationSchemaResp(
+ StatusUtils.OK,
+ tableModelMTree.getAllTables().entrySet().stream()
+ .collect(
+ Collectors.toMap(
+ Map.Entry::getKey,
+ entry ->
+ entry.getValue().stream()
+ .map(
+ pair -> {
+ final TTableInfo info =
+ new TTableInfo(
+ pair.getLeft().getTableName(),
+ pair.getLeft()
+ .getPropValue(TTL_PROPERTY)
+ .orElse(TTL_INFINITE));
+ info.setState(pair.getRight().ordinal());
+ return info;
+ })
+ .collect(Collectors.toList()))));
+ } finally {
+ databaseReadWriteLock.readLock().unlock();
+ }
+ }
+
public FetchTableResp fetchTables(final FetchTablePlan plan) {
databaseReadWriteLock.readLock().lock();
try {
@@ -1241,6 +1273,51 @@ public class ClusterSchemaInfo implements
SnapshotProcessor {
}
}
+ public DescTable4InformationSchemaResp descTable4InformationSchema() {
+ databaseReadWriteLock.readLock().lock();
+ try {
+ return new DescTable4InformationSchemaResp(
+ StatusUtils.OK,
+ tableModelMTree.getAllDatabasePaths(true).stream()
+ .collect(
+ Collectors.toMap(
+ databasePath ->
PathUtils.unQualifyDatabaseName(databasePath.getFullPath()),
+ databasePath -> {
+ try {
+ return tableModelMTree
+ .getAllTablesUnderSpecificDatabase(databasePath)
+ .stream()
+ .map(
+ pair -> {
+ try {
+ return
tableModelMTree.getTableSchemaDetails(
+ databasePath,
pair.getLeft().getTableName());
+ } catch (final MetadataException ignore) {
+ // Table path must exist because the
"getTableSchemaDetails()"
+ // is called in
databaseReadWriteLock.readLock().
+ }
+ return new Pair<TsTable,
Set<String>>(null, null);
+ })
+ .collect(
+ Collectors.toMap(
+ pair -> pair.getLeft().getTableName(),
+ pair ->
+ new TTableColumnInfo()
+ .setTableInfo(
+
TsTableInternalRPCUtil.serializeSingleTsTable(
+ pair.getLeft()))
+
.setPreDeletedColumns(pair.getRight())));
+ } catch (final MetadataException ignore) {
+ // Database path must exist because the
"getAllDatabasePaths()" is called
+ // in databaseReadWriteLock.readLock().
+ }
+ return Collections.emptyMap();
+ })));
+ } finally {
+ databaseReadWriteLock.readLock().unlock();
+ }
+ }
+
public Map<String, List<TsTable>> getAllUsingTables() {
databaseReadWriteLock.readLock().lock();
try {
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
index bb6474258bd..45e6fda8fcd 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
@@ -752,6 +752,22 @@ public class ConfigMTree {
return result;
}
+ public Map<String, List<Pair<TsTable, TableNodeStatus>>> getAllTables() {
+ return getAllDatabasePaths(true).stream()
+ .collect(
+ Collectors.toMap(
+ databasePath ->
PathUtils.unQualifyDatabaseName(databasePath.getFullPath()),
+ databasePath -> {
+ try {
+ return getAllTablesUnderSpecificDatabase(databasePath);
+ } catch (final MetadataException ignore) {
+ // Database path must exist because the
"getAllDatabasePaths()" is called in
+ // databaseReadWriteLock.readLock().
+ }
+ return Collections.emptyList();
+ }));
+ }
+
public Map<String, List<TsTable>> getAllUsingTables() {
return getAllDatabasePaths(true).stream()
.collect(
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
index 5d3de28a26a..2961a5f7c42 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
@@ -128,6 +128,7 @@ import
org.apache.iotdb.confignode.rpc.thrift.TDeleteLogicalViewReq;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceReq;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceResp;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTimeSeriesReq;
+import org.apache.iotdb.confignode.rpc.thrift.TDescTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TDescTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TDropCQReq;
import org.apache.iotdb.confignode.rpc.thrift.TDropFunctionReq;
@@ -192,6 +193,7 @@ import
org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTTLResp;
+import org.apache.iotdb.confignode.rpc.thrift.TShowTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowThrottleReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowTopicReq;
@@ -1311,12 +1313,22 @@ public class ConfigNodeRPCServiceProcessor implements
IConfigNodeRPCService.Ifac
return configManager.showTables(database, isDetails);
}
+ @Override
+ public TShowTable4InformationSchemaResp showTables4InformationSchema() {
+ return configManager.showTables4InformationSchema();
+ }
+
@Override
public TDescTableResp describeTable(
final String database, final String tableName, final boolean isDetails) {
return configManager.describeTable(database, tableName, isDetails);
}
+ @Override
+ public TDescTable4InformationSchemaResp descTables4InformationSchema() {
+ return configManager.describeTable4InformationSchema();
+ }
+
@Override
public TFetchTableResp fetchTables(final Map<String, Set<String>>
fetchTableMap) {
return configManager.fetchTables(fetchTableMap);
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
index 8854c0df3c5..5fd09f22a9a 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
@@ -91,6 +91,7 @@ import
org.apache.iotdb.confignode.rpc.thrift.TDeleteLogicalViewReq;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceReq;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceResp;
import org.apache.iotdb.confignode.rpc.thrift.TDeleteTimeSeriesReq;
+import org.apache.iotdb.confignode.rpc.thrift.TDescTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TDescTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TDropCQReq;
import org.apache.iotdb.confignode.rpc.thrift.TDropFunctionReq;
@@ -155,6 +156,7 @@ import
org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTTLResp;
+import org.apache.iotdb.confignode.rpc.thrift.TShowTable4InformationSchemaResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTableResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowThrottleReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowTopicReq;
@@ -1288,6 +1290,12 @@ public class ConfigNodeClient implements
IConfigNodeRPCService.Iface, ThriftClie
() -> client.showTables(database, isDetails), resp ->
!updateConfigNodeLeader(resp.status));
}
+ @Override
+ public TShowTable4InformationSchemaResp showTables4InformationSchema()
throws TException {
+ return executeRemoteCallWithRetry(
+ () -> client.showTables4InformationSchema(), resp ->
!updateConfigNodeLeader(resp.status));
+ }
+
@Override
public TDescTableResp describeTable(
final String database, final String tableName, final boolean isDetails)
throws TException {
@@ -1296,6 +1304,12 @@ public class ConfigNodeClient implements
IConfigNodeRPCService.Iface, ThriftClie
resp -> !updateConfigNodeLeader(resp.status));
}
+ @Override
+ public TDescTable4InformationSchemaResp descTables4InformationSchema()
throws TException {
+ return executeRemoteCallWithRetry(
+ () -> client.descTables4InformationSchema(), resp ->
!updateConfigNodeLeader(resp.status));
+ }
+
@Override
public TFetchTableResp fetchTables(final Map<String, Set<String>>
fetchTableMap)
throws TException {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaContentSupplierFactory.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaContentSupplierFactory.java
index 41abb73f54e..ccb75ebb22f 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaContentSupplierFactory.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaContentSupplierFactory.java
@@ -19,76 +19,364 @@
package org.apache.iotdb.db.queryengine.execution.operator.source.relational;
+import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.commons.schema.table.InformationSchema;
+import org.apache.iotdb.commons.schema.table.TableNodeStatus;
+import org.apache.iotdb.commons.schema.table.TsTable;
+import org.apache.iotdb.commons.schema.table.TsTableInternalRPCUtil;
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
+import org.apache.iotdb.confignode.rpc.thrift.TDatabaseInfo;
+import org.apache.iotdb.confignode.rpc.thrift.TDescTable4InformationSchemaResp;
+import org.apache.iotdb.confignode.rpc.thrift.TGetDatabaseReq;
+import org.apache.iotdb.confignode.rpc.thrift.TShowDatabaseResp;
+import org.apache.iotdb.confignode.rpc.thrift.TTableInfo;
+import org.apache.iotdb.db.protocol.client.ConfigNodeClient;
+import org.apache.iotdb.db.protocol.client.ConfigNodeClientManager;
+import org.apache.iotdb.db.protocol.client.ConfigNodeInfo;
import org.apache.iotdb.db.protocol.session.IClientSession;
import org.apache.iotdb.db.queryengine.plan.Coordinator;
import org.apache.iotdb.db.queryengine.plan.execution.IQueryExecution;
+import org.apache.iotdb.db.schemaengine.table.InformationSchemaUtils;
import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.read.common.block.TsBlock;
import org.apache.tsfile.read.common.block.TsBlockBuilder;
import org.apache.tsfile.read.common.block.column.RunLengthEncodedColumn;
+import org.apache.tsfile.utils.Binary;
import org.apache.tsfile.utils.BytesUtils;
+import org.apache.tsfile.utils.Pair;
+import java.security.AccessControlException;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.apache.iotdb.commons.conf.IoTDBConstant.TTL_INFINITE;
+import static org.apache.iotdb.commons.schema.SchemaConstant.ALL_MATCH_SCOPE;
+import static org.apache.iotdb.commons.schema.SchemaConstant.ALL_RESULT_NODES;
+import static org.apache.iotdb.commons.schema.table.TsTable.TTL_PROPERTY;
public class InformationSchemaContentSupplierFactory {
private InformationSchemaContentSupplierFactory() {}
public static Iterator<TsBlock> getSupplier(
- final String tableName, final List<TSDataType> dataTypes) {
- if (tableName.equals(InformationSchema.QUERIES)) {
- return new Iterator<TsBlock>() {
- private final TsBlockBuilder resultBuilder = new
TsBlockBuilder(dataTypes);
- private final ColumnBuilder[] columnBuilders =
resultBuilder.getValueColumnBuilders();
+ final String tableName, final List<TSDataType> dataTypes, final String
userName) {
+ switch (tableName) {
+ case InformationSchema.QUERIES:
+ return new QueriesSupplier(dataTypes);
+ case InformationSchema.DATABASES:
+ return new DatabaseSupplier(dataTypes, userName);
+ case InformationSchema.TABLES:
+ return new TableSupplier(dataTypes, userName);
+ case InformationSchema.COLUMNS:
+ return new ColumnSupplier(dataTypes, userName);
+ default:
+ throw new UnsupportedOperationException("Unknown table: " + tableName);
+ }
+ }
+
+ private static class QueriesSupplier extends TsBlockSupplier {
+ private final long currTime = System.currentTimeMillis();
+ // We initialize it later for the convenience of data preparation
+ protected int totalSize;
+ protected int nextConsumedIndex;
+ private final List<IQueryExecution> queryExecutions =
+ Coordinator.getInstance().getAllQueryExecutions();
+
+ private QueriesSupplier(final List<TSDataType> dataTypes) {
+ super(dataTypes);
+ this.totalSize = queryExecutions.size();
+ }
+
+ @Override
+ protected void constructLine() {
+ IQueryExecution queryExecution = queryExecutions.get(nextConsumedIndex);
+
+ if
(queryExecution.getSQLDialect().equals(IClientSession.SqlDialect.TABLE)) {
+ String[] splits = queryExecution.getQueryId().split("_");
+ int dataNodeId = Integer.parseInt(splits[splits.length - 1]);
+
+
columnBuilders[0].writeBinary(BytesUtils.valueOf(queryExecution.getQueryId()));
+ columnBuilders[1].writeLong(queryExecution.getStartExecutionTime());
+ columnBuilders[2].writeInt(dataNodeId);
+ columnBuilders[3].writeFloat(
+ (float) (currTime - queryExecution.getStartExecutionTime()) /
1000);
+ columnBuilders[4].writeBinary(
+
BytesUtils.valueOf(queryExecution.getExecuteSQL().orElse("UNKNOWN")));
+ resultBuilder.declarePosition();
+ }
+ nextConsumedIndex++;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return nextConsumedIndex < totalSize;
+ }
+ }
+
+ private static class DatabaseSupplier extends TsBlockSupplier {
+ private Iterator<Map.Entry<String, TDatabaseInfo>> iterator;
+ private TDatabaseInfo currentDatabase;
+ private final String userName;
+ private boolean hasShownInformationSchema;
+
+ private DatabaseSupplier(final List<TSDataType> dataTypes, final String
userName) {
+ super(dataTypes);
+ this.userName = userName;
+ try (final ConfigNodeClient client =
+
ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID))
{
+ final TShowDatabaseResp resp =
+ client.showDatabase(
+ new TGetDatabaseReq(Arrays.asList(ALL_RESULT_NODES),
ALL_MATCH_SCOPE.serialize())
+ .setIsTableModel(true));
+ iterator = resp.getDatabaseInfoMap().entrySet().iterator();
+ } catch (final Exception e) {
+ lastException = e;
+ }
+ }
+
+ @Override
+ protected void constructLine() {
+ if (!hasShownInformationSchema) {
+ InformationSchemaUtils.buildDatabaseTsBlock(s -> true, resultBuilder,
true, false);
+ hasShownInformationSchema = true;
+ return;
+ }
+ columnBuilders[0].writeBinary(
+ new Binary(currentDatabase.getName(), TSFileConfig.STRING_CHARSET));
+
+ if (Long.MAX_VALUE == currentDatabase.getTTL()) {
+ columnBuilders[1].writeBinary(
+ new Binary(IoTDBConstant.TTL_INFINITE,
TSFileConfig.STRING_CHARSET));
+ } else {
+ columnBuilders[1].writeBinary(
+ new Binary(String.valueOf(currentDatabase.getTTL()),
TSFileConfig.STRING_CHARSET));
+ }
+ columnBuilders[2].writeInt(currentDatabase.getSchemaReplicationFactor());
+ columnBuilders[3].writeInt(currentDatabase.getDataReplicationFactor());
+ columnBuilders[4].writeLong(currentDatabase.getTimePartitionInterval());
+ columnBuilders[5].writeInt(currentDatabase.getSchemaRegionNum());
+ columnBuilders[6].writeInt(currentDatabase.getDataRegionNum());
+ resultBuilder.declarePosition();
+ currentDatabase = null;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (!hasShownInformationSchema) {
+ if (!canShowDB(userName, InformationSchema.INFORMATION_DATABASE)) {
+ hasShownInformationSchema = true;
+ } else {
+ return true;
+ }
+ }
+ while (iterator.hasNext()) {
+ final Map.Entry<String, TDatabaseInfo> result = iterator.next();
+ if (!canShowDB(userName, result.getKey())) {
+ continue;
+ }
+ currentDatabase = result.getValue();
+ break;
+ }
+ return Objects.nonNull(currentDatabase);
+ }
+ }
- private final List<IQueryExecution> queryExecutions =
- Coordinator.getInstance().getAllQueryExecutions();
+ private static class TableSupplier extends TsBlockSupplier {
+ private Iterator<Map.Entry<String, List<TTableInfo>>> dbIterator;
+ private Iterator<TTableInfo> tableInfoIterator = null;
+ private String dbName;
+ private final String userName;
- private final long currTime = System.currentTimeMillis();
+ private TableSupplier(final List<TSDataType> dataTypes, final String
userName) {
+ super(dataTypes);
+ this.userName = userName;
+ try (final ConfigNodeClient client =
+
ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID))
{
+ final Map<String, List<TTableInfo>> databaseTableInfoMap =
+ client.showTables4InformationSchema().getDatabaseTableInfoMap();
+ databaseTableInfoMap.put(
+ InformationSchema.INFORMATION_DATABASE,
+ InformationSchema.getSchemaTables().values().stream()
+ .map(
+ table -> {
+ final TTableInfo info =
+ new TTableInfo(
+ table.getTableName(),
+
table.getPropValue(TTL_PROPERTY).orElse(TTL_INFINITE));
+ info.setState(TableNodeStatus.USING.ordinal());
+ return info;
+ })
+ .collect(Collectors.toList()));
+ dbIterator = databaseTableInfoMap.entrySet().iterator();
+ } catch (final Exception e) {
+ lastException = e;
+ }
+ }
- private final int totalSize = queryExecutions.size();
- private int nextConsumedIndex;
+ @Override
+ protected void constructLine() {
+ final TTableInfo info = tableInfoIterator.next();
+ columnBuilders[0].writeBinary(new Binary(dbName,
TSFileConfig.STRING_CHARSET));
+ columnBuilders[1].writeBinary(new Binary(info.getTableName(),
TSFileConfig.STRING_CHARSET));
+ columnBuilders[2].writeBinary(new Binary(info.getTTL(),
TSFileConfig.STRING_CHARSET));
+ columnBuilders[3].writeBinary(
+ new Binary(
+ TableNodeStatus.values()[info.getState()].toString(),
TSFileConfig.STRING_CHARSET));
+ resultBuilder.declarePosition();
+ }
- @Override
- public boolean hasNext() {
- return nextConsumedIndex < totalSize;
+ @Override
+ public boolean hasNext() {
+ // Get next table info iterator
+ while (Objects.isNull(tableInfoIterator) ||
!tableInfoIterator.hasNext()) {
+ if (!dbIterator.hasNext()) {
+ return false;
}
+ final Map.Entry<String, List<TTableInfo>> entry = dbIterator.next();
+ dbName = entry.getKey();
+ if (!canShowDB(userName, dbName)) {
+ continue;
+ }
+ tableInfoIterator = entry.getValue().iterator();
+ }
+ return true;
+ }
+ }
- @Override
- public TsBlock next() {
- while (nextConsumedIndex < totalSize && !resultBuilder.isFull()) {
-
- IQueryExecution queryExecution =
queryExecutions.get(nextConsumedIndex);
-
- if
(queryExecution.getSQLDialect().equals(IClientSession.SqlDialect.TABLE)) {
- String[] splits = queryExecution.getQueryId().split("_");
- int dataNodeId = Integer.parseInt(splits[splits.length - 1]);
-
-
columnBuilders[0].writeBinary(BytesUtils.valueOf(queryExecution.getQueryId()));
-
columnBuilders[1].writeLong(queryExecution.getStartExecutionTime());
- columnBuilders[2].writeInt(dataNodeId);
- columnBuilders[3].writeFloat(
- (float) (currTime - queryExecution.getStartExecutionTime())
/ 1000);
- columnBuilders[4].writeBinary(
-
BytesUtils.valueOf(queryExecution.getExecuteSQL().orElse("UNKNOWN")));
- resultBuilder.declarePosition();
- }
- nextConsumedIndex++;
+ private static class ColumnSupplier extends TsBlockSupplier {
+ private Iterator<Map.Entry<String, Map<String, Pair<TsTable,
Set<String>>>>> dbIterator;
+ private Iterator<Map.Entry<String, Pair<TsTable, Set<String>>>>
tableInfoIterator;
+ private Iterator<TsTableColumnSchema> columnSchemaIterator;
+ private String dbName;
+ private String tableName;
+ private Set<String> preDeletedColumns;
+ private final String userName;
+
+ private ColumnSupplier(final List<TSDataType> dataTypes, final String
userName) {
+ super(dataTypes);
+ this.userName = userName;
+ try (final ConfigNodeClient client =
+
ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID))
{
+ final TDescTable4InformationSchemaResp resp =
client.descTables4InformationSchema();
+ final Map<String, Map<String, Pair<TsTable, Set<String>>>> resultMap =
+ resp.getTableColumnInfoMap().entrySet().stream()
+ .collect(
+ Collectors.toMap(
+ Map.Entry::getKey,
+ entry ->
+ entry.getValue().entrySet().stream()
+ .collect(
+ Collectors.toMap(
+ Map.Entry::getKey,
+ tableEntry ->
+ new Pair<>(
+
TsTableInternalRPCUtil.deserializeSingleTsTable(
+
tableEntry.getValue().getTableInfo()),
+
tableEntry.getValue().getPreDeletedColumns())))));
+ resultMap.put(
+ InformationSchema.INFORMATION_DATABASE,
+ InformationSchema.getSchemaTables().values().stream()
+ .collect(
+ Collectors.toMap(
+ TsTable::getTableName,
+ table -> new Pair<>(table, Collections.emptySet()))));
+ dbIterator = resultMap.entrySet().iterator();
+ } catch (final Exception e) {
+ lastException = e;
+ }
+ }
+
+ @Override
+ protected void constructLine() {
+ final TsTableColumnSchema schema = columnSchemaIterator.next();
+ columnBuilders[0].writeBinary(new Binary(dbName,
TSFileConfig.STRING_CHARSET));
+ columnBuilders[1].writeBinary(new Binary(tableName,
TSFileConfig.STRING_CHARSET));
+ columnBuilders[2].writeBinary(
+ new Binary(schema.getColumnName(), TSFileConfig.STRING_CHARSET));
+ columnBuilders[3].writeBinary(
+ new Binary(schema.getDataType().name(),
TSFileConfig.STRING_CHARSET));
+ columnBuilders[4].writeBinary(
+ new Binary(schema.getColumnCategory().name(),
TSFileConfig.STRING_CHARSET));
+ columnBuilders[5].writeBinary(
+ new Binary(
+ preDeletedColumns.contains(schema.getColumnName()) ?
"PRE_DELETE" : "USING",
+ TSFileConfig.STRING_CHARSET));
+ resultBuilder.declarePosition();
+ }
+
+ @Override
+ public boolean hasNext() {
+ while (Objects.isNull(columnSchemaIterator) ||
!columnSchemaIterator.hasNext()) {
+ while (Objects.isNull(tableInfoIterator) ||
!tableInfoIterator.hasNext()) {
+ if (!dbIterator.hasNext()) {
+ return false;
+ }
+ final Map.Entry<String, Map<String, Pair<TsTable, Set<String>>>>
entry =
+ dbIterator.next();
+ dbName = entry.getKey();
+ if (!canShowDB(userName, dbName)) {
+ continue;
}
- TsBlock result =
- resultBuilder.build(
- new RunLengthEncodedColumn(
- TableScanOperator.TIME_COLUMN_TEMPLATE,
resultBuilder.getPositionCount()));
- resultBuilder.reset();
- return result;
+ tableInfoIterator = entry.getValue().entrySet().iterator();
}
- };
- } else {
- throw new UnsupportedOperationException("Unknown table: " + tableName);
+ final Map.Entry<String, Pair<TsTable, Set<String>>> tableEntry =
tableInfoIterator.next();
+ tableName = tableEntry.getKey();
+ preDeletedColumns = tableEntry.getValue().getRight();
+ columnSchemaIterator =
tableEntry.getValue().getLeft().getColumnList().iterator();
+ }
+ return true;
}
}
+
+ private static boolean canShowDB(final String userName, final String dbName)
{
+ try {
+
Coordinator.getInstance().getAccessControl().checkCanShowOrUseDatabase(userName,
dbName);
+ } catch (final AccessControlException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private abstract static class TsBlockSupplier implements Iterator<TsBlock> {
+
+ protected final TsBlockBuilder resultBuilder;
+ protected final ColumnBuilder[] columnBuilders;
+ protected Exception lastException;
+
+ private TsBlockSupplier(final List<TSDataType> dataTypes) {
+ this.resultBuilder = new TsBlockBuilder(dataTypes);
+ this.columnBuilders = resultBuilder.getValueColumnBuilders();
+ }
+
+ @Override
+ public TsBlock next() {
+ if (Objects.nonNull(lastException)) {
+ throw new NoSuchElementException(lastException.getMessage());
+ }
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ while (hasNext() && !resultBuilder.isFull()) {
+ constructLine();
+ }
+ final TsBlock result =
+ resultBuilder.build(
+ new RunLengthEncodedColumn(
+ TableScanOperator.TIME_COLUMN_TEMPLATE,
resultBuilder.getPositionCount()));
+ resultBuilder.reset();
+ return result;
+ }
+
+ protected abstract void constructLine();
+ }
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java
index 9151ca14cba..1b122523442 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java
@@ -527,6 +527,10 @@ public class Coordinator {
return INSTANCE;
}
+ public AccessControl getAccessControl() {
+ return accessControl;
+ }
+
public void recordExecutionTime(long queryId, long executionTime) {
IQueryExecution queryExecution = getQueryExecution(queryId);
if (queryExecution != null) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
index 364f15d1f06..2f5141ff071 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
@@ -84,7 +84,7 @@ public class ShowDBTask implements IConfigTask {
.collect(Collectors.toList());
final TsBlockBuilder builder = new TsBlockBuilder(outputDataTypes);
- InformationSchemaUtils.buildDatabaseTsBlock(canSeenDB, builder, false);
+ InformationSchemaUtils.buildDatabaseTsBlock(canSeenDB, builder, false,
true);
for (final Map.Entry<String, TDatabaseInfo> entry :
storageGroupInfoMap.entrySet()) {
final String dbName = entry.getKey();
if (Boolean.FALSE.equals(canSeenDB.test(dbName))) {
@@ -124,7 +124,7 @@ public class ShowDBTask implements IConfigTask {
.collect(Collectors.toList());
final TsBlockBuilder builder = new TsBlockBuilder(outputDataTypes);
- InformationSchemaUtils.buildDatabaseTsBlock(canSeenDB, builder, true);
+ InformationSchemaUtils.buildDatabaseTsBlock(canSeenDB, builder, true,
true);
for (final Map.Entry<String, TDatabaseInfo> entry :
storageGroupInfoMap.entrySet()) {
final String dbName = entry.getKey();
if (!canSeenDB.test(dbName)) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
index d1cf042ef52..fbba891ffce 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
@@ -628,7 +628,14 @@ public class TableOperatorGenerator extends
PlanVisitor<Operator, LocalExecution
return new InformationSchemaTableScanOperator(
operatorContext,
node.getPlanNodeId(),
- getSupplier(node.getQualifiedObjectName().getObjectName(), dataTypes));
+ getSupplier(
+ node.getQualifiedObjectName().getObjectName(),
+ dataTypes,
+ context
+ .getDriverContext()
+ .getFragmentInstanceContext()
+ .getSessionInfo()
+ .getUserName()));
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java
index 294a4d78a7b..ae5362cd08f 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java
@@ -261,7 +261,8 @@ public class TableDeviceSchemaFetcher {
check,
attributeColumns,
fetchPaths,
- isDirectDeviceQuery)) {
+ isDirectDeviceQuery,
+ queryContext)) {
idSingleMatchPredicateNotInCache.add(index);
}
}
@@ -312,8 +313,9 @@ public class TableDeviceSchemaFetcher {
final Predicate<DeviceEntry> check,
final List<String> attributeColumns,
final List<IDeviceID> fetchPaths,
- final boolean isDirectDeviceQuery) {
- String[] idValues = new String[tableInstance.getIdNums()];
+ final boolean isDirectDeviceQuery,
+ final MPPQueryContext queryContext) {
+ final String[] idValues = new String[tableInstance.getIdNums()];
for (final List<SchemaFilter> schemaFilters : idFilters.values()) {
final IdFilter idFilter = (IdFilter) schemaFilters.get(0);
final SchemaFilter childFilter = idFilter.getChild();
@@ -347,6 +349,8 @@ public class TableDeviceSchemaFetcher {
// because now we do not support combining memory source and other
sources
if (isDirectDeviceQuery) {
fetchPaths.add(deviceID);
+ } else {
+ queryContext.reserveMemoryForFrontEnd(deviceEntry.ramBytesUsed());
}
}
return true;
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DataNodeLocationSupplierFactory.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DataNodeLocationSupplierFactory.java
index 1d21d91e429..b91c9eecaf4 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DataNodeLocationSupplierFactory.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DataNodeLocationSupplierFactory.java
@@ -24,18 +24,25 @@ import
org.apache.iotdb.commons.client.exception.ClientManagerException;
import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
import org.apache.iotdb.commons.schema.table.InformationSchema;
import org.apache.iotdb.confignode.rpc.thrift.TGetDataNodeLocationsResp;
+import org.apache.iotdb.db.conf.IoTDBConfig;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.protocol.client.ConfigNodeClient;
import org.apache.iotdb.db.protocol.client.ConfigNodeClientManager;
import org.apache.iotdb.db.protocol.client.ConfigNodeInfo;
+import org.apache.iotdb.db.queryengine.common.DataNodeEndPoints;
import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.thrift.TException;
+import java.util.Collections;
import java.util.List;
import static org.apache.iotdb.rpc.TSStatusCode.QUERY_PROCESS_ERROR;
public class DataNodeLocationSupplierFactory {
+
+ private static final IoTDBConfig config =
IoTDBDescriptor.getInstance().getConfig();
+
private DataNodeLocationSupplierFactory() {}
public static DataNodeLocationSupplier getSupplier() {
@@ -82,6 +89,10 @@ public class DataNodeLocationSupplierFactory {
public List<TDataNodeLocation> getDataNodeLocations(final String
tableName) {
if (tableName.equals(InformationSchema.QUERIES)) {
return getReadableDataNodeLocations();
+ } else if (tableName.equals(InformationSchema.DATABASES)
+ || tableName.equals(InformationSchema.TABLES)
+ || tableName.equals(InformationSchema.COLUMNS)) {
+ return
Collections.singletonList(DataNodeEndPoints.getLocalDataNodeLocation());
} else {
throw new UnsupportedOperationException("Unknown table: " + tableName);
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractQueryDeviceWithCache.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractQueryDeviceWithCache.java
index 6617999b4b5..7f43347a0a1 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractQueryDeviceWithCache.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractQueryDeviceWithCache.java
@@ -61,6 +61,8 @@ public abstract class AbstractQueryDeviceWithCache extends
AbstractTraverseDevic
final boolean needFetch =
super.parseRawExpression(entries, tableInstance, attributeColumns,
context);
if (!needFetch) {
+ context.reserveMemoryForFrontEnd(
+ entries.stream().map(DeviceEntry::ramBytesUsed).reduce(0L,
Long::sum));
results =
entries.stream()
.map(
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
index 43bc9223b11..43cc625c855 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
@@ -613,6 +613,10 @@ public abstract class AstVisitor<R, C> {
return visitStatement(node, context);
}
+ protected R visitCountStatement(CountStatement node, C context) {
+ return visitStatement(node, context);
+ }
+
protected R visitKillQuery(KillQuery node, C context) {
return visitStatement(node, context);
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CountStatement.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CountStatement.java
new file mode 100644
index 00000000000..146b2467aa4
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CountStatement.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.queryengine.plan.relational.sql.ast;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static java.util.Objects.requireNonNull;
+
+public class CountStatement extends Statement {
+ private final String tableName;
+
+ private final Optional<Expression> where;
+
+ public CountStatement(
+ final NodeLocation location, final String tableName, final
Optional<Expression> where) {
+ super(requireNonNull(location, "location is null"));
+ this.tableName = tableName;
+ this.where = where;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public Optional<Expression> getWhere() {
+ return where;
+ }
+
+ @Override
+ public <R, C> R accept(final AstVisitor<R, C> visitor, final C context) {
+ return visitor.visitCountStatement(this, context);
+ }
+
+ @Override
+ public List<Node> getChildren() {
+ return ImmutableList.of();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final CountStatement that = (CountStatement) o;
+ return Objects.equals(tableName, that.tableName) && Objects.equals(where,
that.where);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(tableName, where);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("tableName", tableName)
+ .add("where", where.orElse(null))
+ .omitNullValues()
+ .toString();
+ }
+}
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 d3b38af0f58..17412241cc6 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.CoalesceExpressio
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ColumnDefinition;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ComparisonExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CountDevice;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CountStatement;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateDB;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateFunction;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateIndex;
@@ -1022,21 +1023,36 @@ public class AstBuilder extends
RelationalSqlBaseVisitor<Node> {
@Override
public Node visitShowDevicesStatement(final
RelationalSqlParser.ShowDevicesStatementContext ctx) {
- return new ShowDevice(
- getLocation(ctx),
- new Table(getLocation(ctx), getQualifiedName(ctx.qualifiedName())),
- visitIfPresent(ctx.where, Expression.class).orElse(null),
- visitIfPresent(ctx.limitOffsetClause().offset,
Offset.class).orElse(null),
- visitIfPresent(ctx.limitOffsetClause().limit,
Node.class).orElse(null));
+ final QualifiedName name = getQualifiedName(ctx.tableName);
+ return InformationSchema.INFORMATION_DATABASE.equals(
+
name.getPrefix().map(QualifiedName::toString).orElse(clientSession.getDatabaseName()))
+ ? new ShowStatement(
+ getLocation(ctx),
+ name.getSuffix(),
+ visitIfPresent(ctx.where, Expression.class),
+ Optional.empty(),
+ visitIfPresent(ctx.limitOffsetClause().offset, Offset.class),
+ visitIfPresent(ctx.limitOffsetClause().limit, Node.class))
+ : new ShowDevice(
+ getLocation(ctx),
+ new Table(getLocation(ctx), name),
+ visitIfPresent(ctx.where, Expression.class).orElse(null),
+ visitIfPresent(ctx.limitOffsetClause().offset,
Offset.class).orElse(null),
+ visitIfPresent(ctx.limitOffsetClause().limit,
Node.class).orElse(null));
}
@Override
public Node visitCountDevicesStatement(
final RelationalSqlParser.CountDevicesStatementContext ctx) {
- return new CountDevice(
- getLocation(ctx),
- new Table(getLocation(ctx), getQualifiedName(ctx.qualifiedName())),
- visitIfPresent(ctx.where, Expression.class).orElse(null));
+ final QualifiedName name = getQualifiedName(ctx.tableName);
+ return InformationSchema.INFORMATION_DATABASE.equals(
+
name.getPrefix().map(QualifiedName::toString).orElse(clientSession.getDatabaseName()))
+ ? new CountStatement(
+ getLocation(ctx), name.getSuffix(), visitIfPresent(ctx.where,
Expression.class))
+ : new CountDevice(
+ getLocation(ctx),
+ new Table(getLocation(ctx), name),
+ visitIfPresent(ctx.where, Expression.class).orElse(null));
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/rewrite/ShowRewrite.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/rewrite/ShowRewrite.java
index ff0a426657a..d852319169d 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/rewrite/ShowRewrite.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/rewrite/ShowRewrite.java
@@ -26,14 +26,20 @@ import
org.apache.iotdb.db.queryengine.plan.relational.analyzer.StatementAnalyze
import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllColumns;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CountStatement;
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.Identifier;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Node;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Parameter;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.QualifiedName;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Relation;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Select;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowStatement;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SingleColumn;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -50,7 +56,7 @@ public final class ShowRewrite implements
StatementRewrite.Rewrite {
// private final SqlParser parser;
// private final AccessControl accessControl;
- public ShowRewrite(Metadata metadata) {
+ public ShowRewrite(final Metadata metadata) {
this.metadata = requireNonNull(metadata, "metadata is null");
// this.parser = requireNonNull(parser, "parser is null");
// this.accessControl = requireNonNull(accessControl, "accessControl is
null");
@@ -58,13 +64,13 @@ public final class ShowRewrite implements
StatementRewrite.Rewrite {
@Override
public Statement rewrite(
- StatementAnalyzerFactory analyzerFactory,
- SessionInfo session,
- Statement node,
- List<Expression> parameters,
- Map<NodeRef<Parameter>, Expression> parameterLookup,
- WarningCollector warningCollector) {
- Visitor visitor = new Visitor(metadata, session);
+ final StatementAnalyzerFactory analyzerFactory,
+ final SessionInfo session,
+ final Statement node,
+ final List<Expression> parameters,
+ final Map<NodeRef<Parameter>, Expression> parameterLookup,
+ final WarningCollector warningCollector) {
+ final Visitor visitor = new Visitor(metadata, session);
return (Statement) visitor.process(node, null);
}
@@ -72,13 +78,13 @@ public final class ShowRewrite implements
StatementRewrite.Rewrite {
private final Metadata metadata;
private final SessionInfo session;
- public Visitor(Metadata metadata, SessionInfo session) {
+ public Visitor(final Metadata metadata, final SessionInfo session) {
this.metadata = requireNonNull(metadata, "metadata is null");
this.session = requireNonNull(session, "session is null");
}
@Override
- protected Node visitShowStatement(ShowStatement showStatement, Void
context) {
+ protected Node visitShowStatement(final ShowStatement showStatement, final
Void context) {
// CatalogSchemaName schema = createCatalogSchemaName(session,
showQueries,
// showQueries.getSchema());
@@ -96,12 +102,33 @@ public final class ShowRewrite implements
StatementRewrite.Rewrite {
showStatement.getLimit());
}
- private static Relation from(String db, String table) {
+ @Override
+ protected Node visitCountStatement(final CountStatement countStatement,
final Void context) {
+ return simpleQuery(
+ new Select(
+ false,
+ Collections.singletonList(
+ new SingleColumn(
+ new FunctionCall(
+ QualifiedName.of(Collections.singletonList(new
Identifier("count"))),
+ Collections.emptyList()),
+ new Identifier("count(devices)")))),
+ from(INFORMATION_DATABASE, countStatement.getTableName()),
+ countStatement.getWhere(),
+ Optional.empty(),
+ Optional.empty(),
+ Optional.empty(),
+ Optional.empty(),
+ Optional.empty(),
+ Optional.empty());
+ }
+
+ private static Relation from(final String db, final String table) {
return table(QualifiedName.of(db, table));
}
@Override
- protected Node visitNode(Node node, Void context) {
+ protected Node visitNode(final Node node, final Void context) {
return node;
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/InformationSchemaUtils.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/InformationSchemaUtils.java
index 2e0d8b7612d..2b3875114bd 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/InformationSchemaUtils.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/InformationSchemaUtils.java
@@ -57,11 +57,16 @@ public class InformationSchemaUtils {
}
public static void buildDatabaseTsBlock(
- final Predicate<String> canSeenDB, final TsBlockBuilder builder, final
boolean details) {
+ final Predicate<String> canSeenDB,
+ final TsBlockBuilder builder,
+ final boolean details,
+ final boolean withTime) {
if (!canSeenDB.test(INFORMATION_DATABASE)) {
return;
}
- builder.getTimeColumnBuilder().writeLong(0L);
+ if (withTime) {
+ builder.getTimeColumnBuilder().writeLong(0L);
+ }
builder
.getColumnBuilder(0)
.writeBinary(new Binary(INFORMATION_DATABASE,
TSFileConfig.STRING_CHARSET));
diff --git a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
index 7d8d22a0a3a..26b1b426082 100644
--- a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
+++ b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
@@ -1071,12 +1071,27 @@ struct TShowTableResp {
2: optional list<TTableInfo> tableInfoList
}
+struct TShowTable4InformationSchemaResp {
+ 1: required common.TSStatus status
+ 2: optional map<string, list<TTableInfo>> databaseTableInfoMap
+}
+
struct TDescTableResp {
1: required common.TSStatus status
2: optional binary tableInfo
3: optional set<string> preDeletedColumns
}
+struct TDescTable4InformationSchemaResp {
+ 1: required common.TSStatus status
+ 2: optional map<string, map<string, TTableColumnInfo>> tableColumnInfoMap
+}
+
+struct TTableColumnInfo {
+ 1: required binary tableInfo
+ 2: optional set<string> preDeletedColumns
+}
+
struct TFetchTableResp {
1: required common.TSStatus status
2: optional binary tableInfoMap
@@ -1825,8 +1840,12 @@ service IConfigNodeRPCService {
TShowTableResp showTables(string database, bool isDetails)
+ TShowTable4InformationSchemaResp showTables4InformationSchema()
+
TDescTableResp describeTable(string database, string tableName, bool
isDetails)
+ TDescTable4InformationSchemaResp descTables4InformationSchema()
+
TFetchTableResp fetchTables(map<string, set<string>> fetchTableMap)
TDeleteTableDeviceResp deleteDevice(TDeleteTableDeviceReq req)