This is an automated email from the ASF dual-hosted git repository.

jianglongtao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new c6070c4  Support `COUNT INSTANCE RULES` syntax. (#15589)
c6070c4 is described below

commit c6070c4931917c03b772b444f4447de7fde363c2
Author: TaoTaos068 <[email protected]>
AuthorDate: Mon Mar 7 15:31:55 2022 +0800

    Support `COUNT INSTANCE RULES` syntax. (#15589)
    
    * Support `COUNT INSTANCE RULES` syntax.
    
    * Add `COUNT INSTANCE RULES` parse test.
    
    * Rename.
    
    Co-authored-by: lanchengx <[email protected]>
---
 .../src/main/antlr4/imports/RALStatement.g4        |   6 +-
 .../parser/autogen/CommonDistSQLStatement.g4       |   1 +
 .../core/common/CommonDistSQLStatementVisitor.java |   7 +
 .../queryable/CountInstanceRulesStatement.java     |  28 +++
 .../text/distsql/ral/RALBackendHandlerFactory.java |   3 +
 .../queryable/CountInstanceRulesHandler.java       | 191 ++++++++++++++++++
 .../common/queryable/CountInstanceRulesTest.java   | 214 +++++++++++++++++++++
 .../jaxb/cases/domain/SQLParserTestCases.java      |   5 +
 .../ral/CountInstanceRulesStatementTestCase.java   |  30 +++
 .../src/main/resources/case/ral/common.xml         |   1 +
 .../main/resources/sql/supported/ral/common.xml    |   1 +
 11 files changed, 486 insertions(+), 1 deletion(-)

diff --git 
a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/RALStatement.g4
 
b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/RALStatement.g4
index 4e81f25..70a0375 100644
--- 
a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/RALStatement.g4
+++ 
b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/RALStatement.g4
@@ -102,7 +102,11 @@ labelInstance
 unlabelInstance
     : UNLABEL INSTANCE (instanceDefination | instanceId) (WITH label (COMMA 
label)*)?
     ;
-    
+
+countInstanceRules
+    : COUNT INSTANCE RULES (FROM schemaName)?
+    ;
+
 trafficRuleDefinition
     : ruleName LP (labelDefinition COMMA)? trafficAlgorithmDefinition (COMMA 
loadBalancerDefinition)? RP
     ;
diff --git 
a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
 
b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
index c9918ae..9bd2a3b 100644
--- 
a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
+++ 
b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
@@ -35,6 +35,7 @@ execute
     | showInstanceMode
     | labelInstance
     | unlabelInstance
+    | countInstanceRules
     | countSchemaRules
     | prepareDistSQL
     | applyDistSQL
diff --git 
a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/common/CommonDistSQLStatementVisitor.java
 
b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/common/CommonDistSQLStatementVisitor.java
index 4b7c895..cef9f42 100644
--- 
a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/common/CommonDistSQLStatementVisitor.java
+++ 
b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/common/CommonDistSQLStatementVisitor.java
@@ -31,6 +31,7 @@ import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementPa
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.ApplyDistSQLContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.CacheOptionContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.ClearHintContext;
+import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.CountInstanceRulesContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.CountSchemaRulesContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.CreateDefaultSingleTableRuleContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.CreateTrafficRuleContext;
@@ -79,6 +80,7 @@ import 
org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
 import org.apache.shardingsphere.distsql.parser.segment.TrafficRuleSegment;
 import 
org.apache.shardingsphere.distsql.parser.segment.TransactionProviderSegment;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.hint.ClearHintStatement;
+import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.CountInstanceRulesStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.ExportSchemaConfigurationStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.ShowAuthorityRuleStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.ShowInstanceModeStatement;
@@ -235,6 +237,11 @@ public final class CommonDistSQLStatementVisitor extends 
CommonDistSQLStatementB
     }
     
     @Override
+    public ASTNode visitCountInstanceRules(final CountInstanceRulesContext 
ctx) {
+        return new CountInstanceRulesStatement();
+    }
+    
+    @Override
     public ASTNode visitCountSchemaRules(final CountSchemaRulesContext ctx) {
         return new CountSchemaRulesStatement(null == ctx.schemaName() ? null : 
(SchemaSegment) visit(ctx.schemaName()));
     }
diff --git 
a/shardingsphere-distsql/shardingsphere-distsql-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/common/queryable/CountInstanceRulesStatement.java
 
b/shardingsphere-distsql/shardingsphere-distsql-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/common/queryable/CountInstanceRulesStatement.java
new file mode 100644
index 0000000..531bbea
--- /dev/null
+++ 
b/shardingsphere-distsql/shardingsphere-distsql-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/common/queryable/CountInstanceRulesStatement.java
@@ -0,0 +1,28 @@
+/*
+ * 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.shardingsphere.distsql.parser.statement.ral.common.queryable;
+
+import lombok.Getter;
+import 
org.apache.shardingsphere.distsql.parser.statement.ral.QueryableRALStatement;
+
+/**
+ * Count schema rules statement.
+ */
+@Getter
+public final class CountInstanceRulesStatement extends QueryableRALStatement {
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/RALBackendHandlerFactory.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/RALBackendHandlerFactory.java
index 96d89e0..f0acf8e 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/RALBackendHandlerFactory.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/RALBackendHandlerFactory.java
@@ -24,6 +24,7 @@ import 
org.apache.shardingsphere.distsql.parser.statement.ral.advanced.FormatSta
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.advanced.ParseStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.advanced.PreviewStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.HintDistSQLStatement;
+import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.CountInstanceRulesStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.ExportSchemaConfigurationStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.ShowAuthorityRuleStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.ShowInstanceModeStatement;
@@ -56,6 +57,7 @@ import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.advanced.FormatH
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.advanced.ParseDistSQLBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.advanced.PreviewDistSQLBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.HintDistSQLBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.queryable.CountInstanceRulesHandler;
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.queryable.ExportSchemaConfigurationHandler;
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.queryable.ShowAuthorityRuleHandler;
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.queryable.ShowInstanceHandler;
@@ -124,6 +126,7 @@ public final class RALBackendHandlerFactory {
     private static void initQueryableHandlerMap() {
         QUERYABLE_HANDLER_MAP.put(ShowInstanceStatement.class.getName(), 
ShowInstanceHandler.class);
         QUERYABLE_HANDLER_MAP.put(ShowInstanceModeStatement.class.getName(), 
ShowInstanceModeHandler.class);
+        QUERYABLE_HANDLER_MAP.put(CountInstanceRulesStatement.class.getName(), 
CountInstanceRulesHandler.class);
         QUERYABLE_HANDLER_MAP.put(ShowVariableStatement.class.getName(), 
ShowVariableHandler.class);
         
QUERYABLE_HANDLER_MAP.put(ShowReadwriteSplittingReadResourcesStatement.class.getName(),
 ShowReadwriteSplittingReadResourcesHandler.class);
         QUERYABLE_HANDLER_MAP.put(ShowAuthorityRuleStatement.class.getName(), 
ShowAuthorityRuleHandler.class);
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/CountInstanceRulesHandler.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/CountInstanceRulesHandler.java
new file mode 100644
index 0000000..37bedb7
--- /dev/null
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/CountInstanceRulesHandler.java
@@ -0,0 +1,191 @@
+/*
+ * 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.shardingsphere.proxy.backend.text.distsql.ral.common.queryable;
+
+import 
org.apache.shardingsphere.dbdiscovery.api.config.DatabaseDiscoveryRuleConfiguration;
+import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.CountInstanceRulesStatement;
+import org.apache.shardingsphere.encrypt.api.config.EncryptRuleConfiguration;
+import org.apache.shardingsphere.infra.config.RuleConfiguration;
+import org.apache.shardingsphere.infra.distsql.constant.ExportableConstants;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.QueryableRALBackendHandler;
+import 
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
+import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
+import org.apache.shardingsphere.singletable.rule.SingleTableRule;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+
+/**
+ * Count instance rules handler.
+ */
+public final class CountInstanceRulesHandler extends 
QueryableRALBackendHandler<CountInstanceRulesStatement, 
CountInstanceRulesHandler> {
+    
+    private static final int DEFAULT_COUNT = 0;
+    
+    private static final String SINGLE_TABLE = "single_table";
+    
+    private static final String SHARDING = "sharding";
+    
+    private static final String READWRITE_SPLITTING = "readwrite_splitting";
+    
+    private static final String DB_DISCOVERY = "db_discovery";
+    
+    private static final String ENCRYPT = "encrypt";
+    
+    private static final String SHADOW = "shadow";
+    
+    private static final String SHARDING_TABLE = "sharding_table";
+    
+    private static final String BINDING_TABLE = "binding_table";
+    
+    private static final String BROADCAST_TABLE = "broadcast_table";
+    
+    private static final String DATA_SOURCE = "data_source";
+    
+    private static final String TABLE = "table";
+    
+    private static final Map<String, Class<? extends RuleConfiguration>> 
FEATURE_MAP = new HashMap<>(5, 1);
+    
+    static {
+        FEATURE_MAP.put(SHARDING, ShardingRuleConfiguration.class);
+        FEATURE_MAP.put(READWRITE_SPLITTING, 
ReadwriteSplittingRuleConfiguration.class);
+        FEATURE_MAP.put(DB_DISCOVERY, 
DatabaseDiscoveryRuleConfiguration.class);
+        FEATURE_MAP.put(ENCRYPT, EncryptRuleConfiguration.class);
+        FEATURE_MAP.put(SHADOW, ShadowRuleConfiguration.class);
+    }
+    
+    @Override
+    public Collection<String> getColumnNames() {
+        return Arrays.asList("feature", "type", "count");
+    }
+    
+    @Override
+    protected Collection<List<Object>> getRows(final ContextManager 
contextManager) throws SQLException {
+        Map<String, List<Object>> dataMap = new LinkedHashMap<>();
+        ProxyContext.getInstance().getAllSchemaNames().forEach(each -> {
+            addSchemaData(dataMap, 
ProxyContext.getInstance().getMetaData(each));
+        });
+        return dataMap.values();
+    }
+    
+    private void addSchemaData(final Map<String, List<Object>> dataMap, final 
ShardingSphereMetaData metaData) {
+        addSingleTableData(dataMap, 
metaData.getRuleMetaData().findRules(SingleTableRule.class));
+        if (hasRuleConfiguration(metaData)) {
+            addConfigurationData(dataMap, 
metaData.getRuleMetaData().getConfigurations());
+        } else {
+            addDefaultData(dataMap);
+        }
+    }
+    
+    private void addSingleTableData(final Map<String, List<Object>> dataMap, 
final Collection<SingleTableRule> rules) {
+        Optional<Integer> count = rules.stream().map(each -> (Collection) 
each.export(ExportableConstants.EXPORTABLE_KEY_SINGLE_TABLES).orElse(Collections.emptyMap()))
+                .map(Collection::size).reduce(Integer::sum);
+        dataMap.compute(SINGLE_TABLE, (key, value) -> buildRow(value, 
SINGLE_TABLE, TABLE, count.orElse(DEFAULT_COUNT)));
+    }
+    
+    private boolean hasRuleConfiguration(final ShardingSphereMetaData 
metaData) {
+        Collection<RuleConfiguration> configurations = 
metaData.getRuleMetaData().getConfigurations();
+        return null != configurations && !configurations.isEmpty();
+    }
+    
+    private void addDefaultData(final Map<String, List<Object>> dataMap) {
+        addShardingData(dataMap, null);
+        addReadwriteSplittingData(dataMap, null);
+        addDBDiscoveryData(dataMap, null);
+        addEncryptData(dataMap, null);
+        addShadowData(dataMap, null);
+    }
+    
+    private void addConfigurationData(final Map<String, List<Object>> dataMap, 
final Collection<RuleConfiguration> configurations) {
+        configurations.forEach(each -> {
+            addShardingData(dataMap, each);
+            addReadwriteSplittingData(dataMap, each);
+            addDBDiscoveryData(dataMap, each);
+            addEncryptData(dataMap, each);
+            addShadowData(dataMap, each);
+        });
+    }
+    
+    private void addShardingData(final Map<String, List<Object>> dataMap, 
final RuleConfiguration ruleConfiguration) {
+        addData(dataMap, String.join("_", SHARDING, SHARDING_TABLE), SHARDING, 
SHARDING_TABLE, ruleConfiguration,
+            config -> ((ShardingRuleConfiguration) config).getTables().size() 
+ ((ShardingRuleConfiguration) config).getAutoTables().size());
+        addData(dataMap, String.join("_", SHARDING, BINDING_TABLE), SHARDING, 
BINDING_TABLE, ruleConfiguration, config -> ((ShardingRuleConfiguration) 
config).getBindingTableGroups().size());
+        addData(dataMap, String.join("_", SHARDING, BROADCAST_TABLE), 
SHARDING, BROADCAST_TABLE, ruleConfiguration, config -> 
((ShardingRuleConfiguration) config).getBroadcastTables().size());
+    }
+    
+    private void addReadwriteSplittingData(final Map<String, List<Object>> 
dataMap, final RuleConfiguration ruleConfiguration) {
+        addData(dataMap, READWRITE_SPLITTING, DATA_SOURCE, ruleConfiguration, 
config -> ((ReadwriteSplittingRuleConfiguration) 
config).getDataSources().size());
+    }
+    
+    private void addDBDiscoveryData(final Map<String, List<Object>> dataMap, 
final RuleConfiguration ruleConfiguration) {
+        addData(dataMap, DB_DISCOVERY, DATA_SOURCE, ruleConfiguration, config 
-> ((DatabaseDiscoveryRuleConfiguration) config).getDataSources().size());
+    }
+    
+    private void addEncryptData(final Map<String, List<Object>> dataMap, final 
RuleConfiguration ruleConfiguration) {
+        addData(dataMap, ENCRYPT, TABLE, ruleConfiguration, config -> 
((EncryptRuleConfiguration) config).getTables().size());
+    }
+    
+    private void addShadowData(final Map<String, List<Object>> dataMap, final 
RuleConfiguration ruleConfiguration) {
+        addData(dataMap, SHADOW, DATA_SOURCE, ruleConfiguration, config -> 
((ShadowRuleConfiguration) config).getDataSources().size());
+    }
+    
+    private void addData(final Map<String, List<Object>> dataMap, final String 
feature, final String type,
+                         final RuleConfiguration ruleConfiguration, final 
Function<RuleConfiguration, Integer> apply) {
+        addData(dataMap, feature, feature, type, ruleConfiguration, apply);
+    }
+    
+    private void addData(final Map<String, List<Object>> dataMap, final String 
dataKey, final String feature, final String type,
+                         final RuleConfiguration ruleConfiguration, final 
Function<RuleConfiguration, Integer> apply) {
+        if (null == ruleConfiguration) {
+            dataMap.putIfAbsent(dataKey, buildRow(feature, type, 
DEFAULT_COUNT));
+            return;
+        }
+        Class<? extends RuleConfiguration> clz = FEATURE_MAP.get(feature);
+        if 
(!(ruleConfiguration.getClass().getCanonicalName().equals(clz.getCanonicalName())))
 {
+            dataMap.putIfAbsent(dataKey, buildRow(feature, type, 
DEFAULT_COUNT));
+            return;
+        }
+        dataMap.compute(dataKey, (key, value) -> buildRow(value, feature, 
type, apply.apply(ruleConfiguration)));
+    }
+    
+    private List<Object> buildRow(final Collection<Object> value, final String 
type, final String name, final Integer count) {
+        if (value == null) {
+            return Arrays.asList(type, name, count);
+        } else {
+            Integer oldCount = (Integer) new LinkedList<>(value).getLast();
+            return Arrays.asList(type, name, Integer.sum(oldCount, count));
+        }
+    }
+    
+    private List<Object> buildRow(final String type, final String name, final 
Integer count) {
+        return Arrays.asList(type, name, count);
+    }
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/CountInstanceRulesTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/CountInstanceRulesTest.java
new file mode 100644
index 0000000..49eedfa
--- /dev/null
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/CountInstanceRulesTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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.shardingsphere.proxy.backend.text.distsql.ral.common.queryable;
+
+import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.CountInstanceRulesStatement;
+import org.apache.shardingsphere.encrypt.api.config.EncryptRuleConfiguration;
+import 
org.apache.shardingsphere.encrypt.api.config.rule.EncryptTableRuleConfiguration;
+import org.apache.shardingsphere.infra.config.RuleConfiguration;
+import org.apache.shardingsphere.infra.distsql.constant.ExportableConstants;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import 
org.apache.shardingsphere.infra.metadata.rule.ShardingSphereRuleMetaData;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import 
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
+import 
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
+import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
+import 
org.apache.shardingsphere.sharding.api.config.rule.ShardingAutoTableRuleConfiguration;
+import 
org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
+import org.apache.shardingsphere.singletable.rule.SingleTableRule;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Properties;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public final class CountInstanceRulesTest {
+    
+    @Mock
+    private ShardingSphereMetaData shardingSphereMetaData1;
+    
+    @Mock
+    private ShardingSphereMetaData shardingSphereMetaData2;
+    
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private ContextManager contextManager;
+    
+    @Before
+    public void before() {
+        Collection<ShardingSphereRule> rules = new LinkedList<>();
+        rules.add(mockSingleTableRule());
+        ShardingSphereRuleMetaData ruleMetaData = 
mock(ShardingSphereRuleMetaData.class);
+        when(ruleMetaData.findRules(any())).thenReturn(rules);
+        Collection<RuleConfiguration> ruleConfiguration = new LinkedList<>();
+        ruleConfiguration.add(mockShardingTableRule());
+        ruleConfiguration.add(mockReadwriteSplittingRule());
+        ruleConfiguration.add(mockEncryptRule());
+        when(ruleMetaData.getConfigurations()).thenReturn(ruleConfiguration);
+        
when(shardingSphereMetaData1.getRuleMetaData()).thenReturn(ruleMetaData);
+        
when(shardingSphereMetaData2.getRuleMetaData()).thenReturn(ruleMetaData);
+        
when(contextManager.getMetaDataContexts().getAllSchemaNames()).thenReturn(Arrays.asList("schema_1",
 "schema_2"));
+        
when(contextManager.getMetaDataContexts().getMetaData("schema_1")).thenReturn(shardingSphereMetaData1);
+        
when(contextManager.getMetaDataContexts().getMetaData("schema_2")).thenReturn(shardingSphereMetaData2);
+        ProxyContext.getInstance().init(contextManager);
+    }
+    
+    private SingleTableRule mockSingleTableRule() {
+        SingleTableRule result = mock(SingleTableRule.class);
+        
when(result.export(ExportableConstants.EXPORTABLE_KEY_SINGLE_TABLES)).thenReturn(java.util.Optional.of(Arrays.asList("single_table_1",
 "single_table_2")));
+        return result;
+    }
+    
+    private RuleConfiguration mockShardingTableRule() {
+        ShardingRuleConfiguration result = 
mock(ShardingRuleConfiguration.class);
+        when(result.getTables()).thenReturn(Collections.singletonList(new 
ShardingTableRuleConfiguration("sharding_table")));
+        when(result.getAutoTables()).thenReturn(Collections.singletonList(new 
ShardingAutoTableRuleConfiguration("sharding_auto_table")));
+        
when(result.getBindingTableGroups()).thenReturn(Collections.singletonList("binding_table_1,binding_table_2"));
+        
when(result.getBroadcastTables()).thenReturn(Arrays.asList("broadcast_table_1", 
"broadcast_table_2"));
+        return result;
+    }
+    
+    private RuleConfiguration mockReadwriteSplittingRule() {
+        ReadwriteSplittingRuleConfiguration result = 
mock(ReadwriteSplittingRuleConfiguration.class);
+        when(result.getDataSources()).thenReturn(Collections.singletonList(new 
ReadwriteSplittingDataSourceRuleConfiguration("readwrite_splitting", "", new 
Properties(), "")));
+        return result;
+    }
+    
+    private RuleConfiguration mockEncryptRule() {
+        EncryptRuleConfiguration result = mock(EncryptRuleConfiguration.class);
+        when(result.getTables()).thenReturn(Collections.singletonList(new 
EncryptTableRuleConfiguration("encrypt_table", Collections.emptyList(), 
false)));
+        return result;
+    }
+    
+    @Test
+    public void assertGetRowData() throws SQLException {
+        CountInstanceRulesHandler handler = new 
CountInstanceRulesHandler().initStatement(new CountInstanceRulesStatement());
+        handler.execute();
+        handler.next();
+        Collection<Object> actual = handler.getRowData();
+        assertThat(actual.size(), is(3));
+        Iterator<Object> rowData = actual.iterator();
+        assertThat(rowData.next(), is("single_table"));
+        assertThat(rowData.next(), is("table"));
+        assertThat(rowData.next(), is(4));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("sharding"));
+        assertThat(rowData.next(), is("sharding_table"));
+        assertThat(rowData.next(), is(4));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("sharding"));
+        assertThat(rowData.next(), is("binding_table"));
+        assertThat(rowData.next(), is(2));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("sharding"));
+        assertThat(rowData.next(), is("broadcast_table"));
+        assertThat(rowData.next(), is(4));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("readwrite_splitting"));
+        assertThat(rowData.next(), is("data_source"));
+        assertThat(rowData.next(), is(2));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("db_discovery"));
+        assertThat(rowData.next(), is("data_source"));
+        assertThat(rowData.next(), is(0));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("encrypt"));
+        assertThat(rowData.next(), is("table"));
+        assertThat(rowData.next(), is(2));
+    }
+    
+    @Test
+    public void assertGetRowDataWithoutConfiguration() throws SQLException {
+        CountInstanceRulesHandler handler = new 
CountInstanceRulesHandler().initStatement(new CountInstanceRulesStatement());
+        
when(shardingSphereMetaData1.getRuleMetaData().getConfigurations()).thenReturn(Collections.emptyList());
+        
when(shardingSphereMetaData2.getRuleMetaData().getConfigurations()).thenReturn(Collections.emptyList());
+        handler.execute();
+        handler.next();
+        Collection<Object> actual = handler.getRowData();
+        assertThat(actual.size(), is(3));
+        Iterator<Object> rowData = actual.iterator();
+        assertThat(rowData.next(), is("single_table"));
+        assertThat(rowData.next(), is("table"));
+        assertThat(rowData.next(), is(4));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("sharding"));
+        assertThat(rowData.next(), is("sharding_table"));
+        assertThat(rowData.next(), is(0));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("sharding"));
+        assertThat(rowData.next(), is("binding_table"));
+        assertThat(rowData.next(), is(0));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("sharding"));
+        assertThat(rowData.next(), is("broadcast_table"));
+        assertThat(rowData.next(), is(0));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("readwrite_splitting"));
+        assertThat(rowData.next(), is("data_source"));
+        assertThat(rowData.next(), is(0));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("db_discovery"));
+        assertThat(rowData.next(), is("data_source"));
+        assertThat(rowData.next(), is(0));
+        handler.next();
+        actual = handler.getRowData();
+        rowData = actual.iterator();
+        assertThat(rowData.next(), is("encrypt"));
+        assertThat(rowData.next(), is("table"));
+        assertThat(rowData.next(), is(0));
+    }
+}
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
index 31869ba..8748380 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
@@ -173,6 +173,7 @@ import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ClearHintStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ClearReadwriteSplittingHintStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ClearShardingHintStatementTestCase;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.CountInstanceRulesStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.CreateTrafficRuleStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.DiscardDistSQLStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.DropTrafficRuleStatementTestCase;
@@ -887,6 +888,9 @@ public final class SQLParserTestCases {
     @XmlElement(name = "show-instance")
     private final List<ShowInstanceStatementTestCase> 
showInstanceStatementTestCases = new LinkedList<>();
     
+    @XmlElement(name = "count-instance-rules")
+    private final List<CountInstanceRulesStatementTestCase> 
countInstanceRulesStatementTestCases = new LinkedList<>();
+    
     @XmlElement(name = "clone")
     private final List<CloneStatementTestCase> cloneStatementTestCases = new 
LinkedList<>();
     
@@ -1330,6 +1334,7 @@ public final class SQLParserTestCases {
         putAll(flushStatementTestCase, result);
         putAll(installPluginStatementTestCase, result);
         putAll(showInstanceStatementTestCases, result);
+        putAll(countInstanceRulesStatementTestCases, result);
         putAll(cloneStatementTestCases, result);
         putAll(showReadwriteSplittingReadResourcesStatementTestCases, result);
         putAll(uninstallComponentStatementTestCases, result);
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/ral/CountInstanceRulesStatementTestCase.java
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/ral/CountInstanceRulesStatementTestCase.java
new file mode 100644
index 0000000..8f9990b
--- /dev/null
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/ral/CountInstanceRulesStatementTestCase.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.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral;
+
+import lombok.Getter;
+import lombok.Setter;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.SQLParserTestCase;
+
+/**
+ * Count instance rules statement test case.
+ */
+@Getter
+@Setter
+public final class CountInstanceRulesStatementTestCase extends 
SQLParserTestCase {
+}
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/ral/common.xml
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/ral/common.xml
index 7632746..b063c73 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/ral/common.xml
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/ral/common.xml
@@ -30,6 +30,7 @@
     <show-readwrite-splitting-hint-source 
sql-case-id="show-readwrite-splitting-hint-source" />
     <show-sharding-hint-status sql-case-id="show-sharding-hint-status" />
     <show-instance sql-case-id="show-instance" />
+    <count-instance-rules sql-case-id="count-instance-rules" />
     <show-readwrite-splitting-read-resources 
sql-case-id="show-readwrite-splitting-read-resources" />
     <show-table-metadata sql-case-id="show-table-metadata" >
         <table-name>t_order</table-name>
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/ral/common.xml
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/ral/common.xml
index 7c75700..4726068 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/ral/common.xml
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/ral/common.xml
@@ -30,6 +30,7 @@
     <distsql-case id="show-readwrite-splitting-hint-source" value="SHOW 
READWRITE_SPLITTING HINT STATUS" />
     <distsql-case id="show-sharding-hint-status" value="SHOW SHARDING HINT 
STATUS" />
     <distsql-case id="show-instance" value="SHOW INSTANCE LIST" />
+    <distsql-case id="count-instance-rules" value="COUNT INSTANCE RULES" />
     <distsql-case id="show-readwrite-splitting-read-resources" value="show 
readwrite_splitting read resources" />
     <distsql-case id="show-table-metadata" value="SHOW TABLE METADATA t_order 
FROM schema_name" />
     <distsql-case id="refresh-table-metadata" value="refresh table metadata" />

Reply via email to