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)

Reply via email to