You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2021/11/19 08:57:39 UTC

[shardingsphere] branch master updated: Support pgAdmin. (#13692)

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 742b65b  Support pgAdmin. (#13692)
742b65b is described below

commit 742b65ba4c9517815d787111ff51db7df772c9f0
Author: lanchengx <52...@users.noreply.github.com>
AuthorDate: Fri Nov 19 02:56:53 2021 -0600

    Support pgAdmin. (#13692)
    
    * Support pgAdmin.
    
    * Rename method.
    
    * Support to get the table Name of the subquery.
---
 .../postgresql/PostgreSQLAdminExecutorFactory.java | 26 +++++++++++++++++++---
 .../executor/SelectDatabaseExecutor.java           | 22 +++++++++++++++++-
 .../postgresql/executor/SelectTableExecutor.java   |  6 ++++-
 .../src/main/antlr4/imports/postgresql/BaseRule.g4 |  1 +
 4 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorFactory.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorFactory.java
index 7ad3603..7768bef 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorFactory.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorFactory.java
@@ -24,11 +24,14 @@ import org.apache.shardingsphere.proxy.backend.text.admin.postgresql.executor.Se
 import org.apache.shardingsphere.proxy.backend.text.admin.postgresql.executor.SelectTableExecutor;
 import org.apache.shardingsphere.sql.parser.sql.common.extractor.TableExtractor;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 
 import java.util.Collection;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -41,7 +44,13 @@ public final class PostgreSQLAdminExecutorFactory implements DatabaseAdminExecut
     
     private static final String PG_DATABASE = "pg_database";
     
-    private static final String PG_NAMESPACE = "pg_namespace";
+    private static final String PG_TRIGGER = "pg_trigger";
+    
+    private static final String PG_INHERITS = "pg_inherits";
+    
+    private static final String PG_CLASS = "pg_class";
+    
+    private static final String PG_PREFIX = "pg_";
     
     @Override
     public Optional<DatabaseAdminExecutor> newInstance(final SQLStatement sqlStatement) {
@@ -55,19 +64,30 @@ public final class PostgreSQLAdminExecutorFactory implements DatabaseAdminExecut
             if (selectedTableNames.contains(PG_DATABASE)) {
                 return Optional.of(new SelectDatabaseExecutor((SelectStatement) sqlStatement, sql));
             }
-            if (selectedTableNames.contains(PG_TABLESPACE)) {
+            if (isQueryPgTable(selectedTableNames)) {
                 return Optional.of(new SelectTableExecutor(sql));
             }
-            if (selectedTableNames.contains(PG_NAMESPACE)) {
+            if (selectedTableNames.stream().anyMatch(each -> each.startsWith(PG_PREFIX))) {
                 return Optional.of(new DefaultDatabaseMetadataExecutor(sql));
             }
         }
         return Optional.empty();
     }
     
+    private boolean isQueryPgTable(final Collection<String> selectedTableNames) {
+        boolean isComplexQueryTable = selectedTableNames.contains(PG_CLASS) && selectedTableNames.contains(PG_TRIGGER) && selectedTableNames.contains(PG_INHERITS);
+        return selectedTableNames.contains(PG_TABLESPACE) || isComplexQueryTable;
+    }
+    
     private Collection<String> getSelectedTableNames(final SelectStatement sqlStatement) {
         TableExtractor extractor = new TableExtractor();
         extractor.extractTablesFromSelect(sqlStatement);
+        List<TableSegment> subQueryTableSegment = extractor.getTableContext().stream().filter(each -> each instanceof SubqueryTableSegment).map(each -> {
+            TableExtractor subExtractor = new TableExtractor();
+            subExtractor.extractTablesFromSelect(((SubqueryTableSegment) each).getSubquery().getSelect());
+            return subExtractor.getTableContext();
+        }).flatMap(Collection::stream).collect(Collectors.toList());
+        extractor.getTableContext().addAll(subQueryTableSegment);
         return extractor.getTableContext().stream().filter(each -> each instanceof SimpleTableSegment)
                 .map(each -> ((SimpleTableSegment) each).getTableName().getIdentifier().getValue()).collect(Collectors.toCollection(LinkedList::new));
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/executor/SelectDatabaseExecutor.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/executor/SelectDatabaseExecutor.java
index eaea1ee..eeff69f 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/executor/SelectDatabaseExecutor.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/executor/SelectDatabaseExecutor.java
@@ -41,12 +41,18 @@ public final class SelectDatabaseExecutor extends DefaultDatabaseMetadataExecuto
     
     private static final String DATABASE_NAME = "databasename";
     
+    private static final String DATNAME = "datname";
+    
+    private static final String NAME = "name";
+    
     private final Set<String> columnNames = new LinkedHashSet<>();
     
     private final SelectStatement sqlStatement;
     
     private String databaseNameAlias = DATABASE_NAME;
     
+    private boolean isQueryDatabase;
+    
     public SelectDatabaseExecutor(final SelectStatement sqlStatement, final String sql) {
         super(sql);
         this.sqlStatement = sqlStatement;
@@ -54,11 +60,24 @@ public final class SelectDatabaseExecutor extends DefaultDatabaseMetadataExecuto
     
     @Override
     protected void createPreProcessing() {
+        removeDuplicatedRow();
+        addDefaultRow();
+    }
+    
+    private void addDefaultRow() {
         LinkedList<String> schemaWithoutDataSource = ProxyContext.getInstance().getAllSchemaNames().stream()
                 .filter(each -> !hasDatasource(each)).collect(Collectors.toCollection(LinkedList::new));
         schemaWithoutDataSource.forEach(each -> getRows().addLast(getDefaultRowData(each)));
     }
     
+    private void removeDuplicatedRow() {
+        if (isQueryDatabase) {
+            List<Map<String, Object>> toBeRemovedRow = getRows().stream().collect(Collectors.groupingBy(each -> each.get(databaseNameAlias), Collectors.toCollection(LinkedList::new)))
+                    .values().stream().filter(each -> each.size() > 1).map(LinkedList::getLast).collect(Collectors.toList());
+            toBeRemovedRow.forEach(each -> getRows().remove(each));
+        }
+    }
+    
     @Override
     protected List<String> getSchemaNames() {
         Collection<String> schemaNames = ProxyContext.getInstance().getAllSchemaNames();
@@ -70,8 +89,9 @@ public final class SelectDatabaseExecutor extends DefaultDatabaseMetadataExecuto
         buildColumnNames(aliasMap);
         ShardingSphereResource resource = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData(schemaName).getResource();
         Set<String> catalogs = resource.getDataSources().keySet().stream().map(each -> resource.getDataSourcesMetaData().getDataSourceMetaData(each).getCatalog()).collect(Collectors.toSet());
-        databaseNameAlias = aliasMap.getOrDefault(DATABASE_NAME, "");
+        databaseNameAlias = aliasMap.getOrDefault(DATABASE_NAME, aliasMap.getOrDefault(DATNAME, aliasMap.getOrDefault(NAME, "")));
         String rowValue = rowMap.getOrDefault(databaseNameAlias, "").toString();
+        isQueryDatabase = !rowValue.isEmpty();
         if (catalogs.contains(rowValue)) {
             rowMap.replace(databaseNameAlias, schemaName);
         } else {
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/executor/SelectTableExecutor.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/executor/SelectTableExecutor.java
index 366774d..d28914b 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/executor/SelectTableExecutor.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/executor/SelectTableExecutor.java
@@ -35,8 +35,12 @@ public final class SelectTableExecutor extends DefaultDatabaseMetadataExecutor {
     
     private static final String REL_NAME = "relname";
     
+    private static final String REF_NAME = "refname";
+    
     private static final String TABLE_NAME = "tablename";
     
+    private static final String NAME = "name";
+    
     private String actualTableName = "";
     
     private List<String> tableNames;
@@ -59,7 +63,7 @@ public final class SelectTableExecutor extends DefaultDatabaseMetadataExecutor {
     @Override
     protected void rowPostProcessing(final String schemaName, final Map<String, Object> rowMap, final Map<String, String> aliasMap) {
         if (actualTableName.isEmpty()) {
-            actualTableName = aliasMap.getOrDefault(REL_NAME, aliasMap.getOrDefault(TABLE_NAME, ""));
+            actualTableName = aliasMap.getOrDefault(REL_NAME, aliasMap.getOrDefault(TABLE_NAME, aliasMap.getOrDefault(NAME, aliasMap.getOrDefault(REF_NAME, ""))));
         }
     }
     
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/BaseRule.g4 b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/BaseRule.g4
index 8e09e61..7afb2d9 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/BaseRule.g4
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/BaseRule.g4
@@ -421,6 +421,7 @@ unreservedWord
     | ZONE
     | JSON
     | PARAM
+    | TABLE
     ;
 
 typeFuncNameKeyword