You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/07/28 05:33:04 UTC
[shardingsphere] branch master updated: Replace stream with loop in PostgreSQLAdminExecutorCreator (#19629)
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: 吴伟杰 <wu...@apache.org>
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"));
+ }
+}