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

duanzhengqiang 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 4427ff99f30 Replace stream with loop in PostgreSQLAdminExecutorCreator 
(#19629)
4427ff99f30 is described below

commit 4427ff99f30487c35964358a2b2601371cbcf621
Author: 吴伟杰 <[email protected]>
AuthorDate: Thu Jul 28 13:32:56 2022 +0800

    Replace stream with loop in PostgreSQLAdminExecutorCreator (#19629)
    
    * Replace stream with loop in PostgreSQLAdminExecutorCreator
    
    * Add PostgreSQLAdminExecutorCreatorTest
---
 .../postgresql/PostgreSQLAdminExecutorCreator.java |  34 ++++--
 .../PostgreSQLAdminExecutorCreatorTest.java        | 132 +++++++++++++++++++++
 2 files changed, 154 insertions(+), 12 deletions(-)

diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorCreator.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorCreator.java
index 099bbf998a3..dd6d9eb937f 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorCreator.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorCreator.java
@@ -31,10 +31,11 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dal.SetStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
-import java.util.stream.Collectors;
 
 /**
  * Database admin executor creator for PostgreSQL.
@@ -69,8 +70,10 @@ public final class PostgreSQLAdminExecutorCreator implements 
DatabaseAdminExecut
             if (isQueryPgTable(selectedTableNames)) {
                 return Optional.of(new SelectTableExecutor(sql));
             }
-            if (selectedTableNames.stream().anyMatch(each -> 
each.startsWith(PG_PREFIX))) {
-                return Optional.of(new DefaultDatabaseMetadataExecutor(sql));
+            for (String each : selectedTableNames) {
+                if (each.startsWith(PG_PREFIX)) {
+                    return Optional.of(new 
DefaultDatabaseMetadataExecutor(sql));
+                }
             }
         }
         return sqlStatement instanceof SetStatement ? Optional.of(new 
PostgreSQLSetVariableAdminExecutor((SetStatement) sqlStatement)) : 
Optional.empty();
@@ -78,20 +81,27 @@ public final class PostgreSQLAdminExecutorCreator 
implements DatabaseAdminExecut
     
     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;
+        return isComplexQueryTable || 
selectedTableNames.contains(PG_TABLESPACE);
     }
     
     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.toList());
+        List<TableSegment> extracted = new 
LinkedList<>(extractor.getTableContext());
+        for (TableSegment each : extractor.getTableContext()) {
+            if (each instanceof SubqueryTableSegment) {
+                TableExtractor subExtractor = new TableExtractor();
+                subExtractor.extractTablesFromSelect(((SubqueryTableSegment) 
each).getSubquery().getSelect());
+                extracted.addAll(subExtractor.getTableContext());
+            }
+        }
+        List<String> result = new ArrayList<>(extracted.size());
+        for (TableSegment each : extracted) {
+            if (each instanceof SimpleTableSegment) {
+                result.add(((SimpleTableSegment) 
each).getTableName().getIdentifier().getValue());
+            }
+        }
+        return result;
     }
     
     @Override
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorCreatorTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorCreatorTest.java
new file mode 100644
index 00000000000..e0ed83e0350
--- /dev/null
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorCreatorTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.admin.postgresql;
+
+import 
org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContext;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.DeleteStatementContext;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+import org.apache.shardingsphere.parser.config.SQLParserRuleConfiguration;
+import org.apache.shardingsphere.parser.rule.SQLParserRule;
+import 
org.apache.shardingsphere.proxy.backend.text.admin.executor.AbstractDatabaseMetadataExecutor.DefaultDatabaseMetadataExecutor;
+import 
org.apache.shardingsphere.proxy.backend.text.admin.executor.DatabaseAdminExecutor;
+import 
org.apache.shardingsphere.proxy.backend.text.admin.postgresql.executor.SelectDatabaseExecutor;
+import 
org.apache.shardingsphere.proxy.backend.text.admin.postgresql.executor.SelectTableExecutor;
+import org.apache.shardingsphere.sql.parser.api.CacheOption;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.postgresql.dal.PostgreSQLSetStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.postgresql.dml.PostgreSQLDeleteStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.postgresql.dml.PostgreSQLSelectStatement;
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public final class PostgreSQLAdminExecutorCreatorTest {
+    
+    private static final String PSQL_SELECT_DATABASES = "SELECT d.datname as 
\"Name\",\n"
+            + "       pg_catalog.pg_get_userbyid(d.datdba) as \"Owner\",\n"
+            + "       pg_catalog.pg_encoding_to_char(d.encoding) as 
\"Encoding\",\n"
+            + "       d.datcollate as \"Collate\",\n"
+            + "       d.datctype as \"Ctype\",\n"
+            + "       pg_catalog.array_to_string(d.datacl, E'\\n') AS \"Access 
privileges\"\n"
+            + "FROM pg_catalog.pg_database d\n"
+            + "ORDER BY 1";
+    
+    private static final String PSQL_SELECT_TABLESPACES = "SELECT spcname AS 
\"Name\",\n"
+            + "  pg_catalog.pg_get_userbyid(spcowner) AS \"Owner\",\n"
+            + "  pg_catalog.pg_tablespace_location(oid) AS \"Location\"\n"
+            + "FROM pg_catalog.pg_tablespace\n"
+            + "ORDER BY 1";
+    
+    private static final String SELECT_PG_CATALOG_WITH_SUBQUERY = "select * 
from (select * from pg_catalog.pg_namespace) t;";
+    
+    @Test
+    public void assertCreateWithSQLStatementContextOnly() {
+        assertThat(new PostgreSQLAdminExecutorCreator().create(null), 
is(Optional.empty()));
+    }
+    
+    @Test
+    public void assertCreateWithSelectDatabase() {
+        SQLStatement sqlStatement = parseSQL(PSQL_SELECT_DATABASES);
+        SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class);
+        
when(selectStatementContext.getSqlStatement()).thenReturn((SelectStatement) 
sqlStatement);
+        Optional<DatabaseAdminExecutor> actual = new 
PostgreSQLAdminExecutorCreator().create(selectStatementContext, 
PSQL_SELECT_DATABASES, "");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), instanceOf(SelectDatabaseExecutor.class));
+    }
+    
+    @Test
+    public void assertCreateWithSelectTablespace() {
+        SQLStatement sqlStatement = parseSQL(PSQL_SELECT_TABLESPACES);
+        SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class);
+        
when(selectStatementContext.getSqlStatement()).thenReturn((SelectStatement) 
sqlStatement);
+        Optional<DatabaseAdminExecutor> actual = new 
PostgreSQLAdminExecutorCreator().create(selectStatementContext, 
PSQL_SELECT_TABLESPACES, "");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), instanceOf(SelectTableExecutor.class));
+    }
+    
+    @Test
+    public void assertCreateWithSelectPgCatalogWithSubquery() {
+        SQLStatement sqlStatement = parseSQL(SELECT_PG_CATALOG_WITH_SUBQUERY);
+        SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class);
+        
when(selectStatementContext.getSqlStatement()).thenReturn((SelectStatement) 
sqlStatement);
+        Optional<DatabaseAdminExecutor> actual = new 
PostgreSQLAdminExecutorCreator().create(selectStatementContext, 
SELECT_PG_CATALOG_WITH_SUBQUERY, "");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), 
instanceOf(DefaultDatabaseMetadataExecutor.class));
+    }
+    
+    private static SQLStatement parseSQL(final String sql) {
+        CacheOption cacheOption = new CacheOption(0, 0);
+        SQLParserRule sqlParserRule = new SQLParserRule(new 
SQLParserRuleConfiguration(false, cacheOption, cacheOption));
+        return sqlParserRule.getSQLParserEngine("PostgreSQL").parse(sql, 
false);
+    }
+    
+    @Test
+    public void assertCreateWithSelectNonPgCatalog() {
+        SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class);
+        when(selectStatementContext.getSqlStatement()).thenReturn(new 
PostgreSQLSelectStatement());
+        assertThat(new 
PostgreSQLAdminExecutorCreator().create(selectStatementContext, "select 1", 
""), is(Optional.empty()));
+    }
+    
+    @Test
+    public void assertCreateWithSetStatement() {
+        PostgreSQLSetStatement setStatement = new PostgreSQLSetStatement();
+        CommonSQLStatementContext<PostgreSQLSetStatement> sqlStatementContext 
= new CommonSQLStatementContext<>(setStatement);
+        Optional<DatabaseAdminExecutor> actual = new 
PostgreSQLAdminExecutorCreator().create(sqlStatementContext, "SET 
client_encoding = utf8", "");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), 
instanceOf(PostgreSQLSetVariableAdminExecutor.class));
+    }
+    
+    @Test
+    public void assertCreateWithDMLStatement() {
+        DeleteStatementContext sqlStatementContext = new 
DeleteStatementContext(new PostgreSQLDeleteStatement());
+        assertThat(new 
PostgreSQLAdminExecutorCreator().create(sqlStatementContext, "delete from t 
where id = 1", ""), is(Optional.empty()));
+    }
+    
+    @Test
+    public void assertGetType() {
+        assertThat(new PostgreSQLAdminExecutorCreator().getType(), 
is("PostgreSQL"));
+    }
+}

Reply via email to