diff --git a/proxy/backend/type/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussAdminExecutorCreator.java b/proxy/backend/type/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussAdminExecutorCreator.java index fe0ce1089aa46..fa5165d79bcc6 100644 --- a/proxy/backend/type/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussAdminExecutorCreator.java +++ b/proxy/backend/type/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussAdminExecutorCreator.java @@ -26,6 +26,8 @@ import org.apache.shardingsphere.proxy.backend.postgresql.handler.admin.PostgreSQLAdminExecutorCreator; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment; +import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.dal.ShowStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; import java.util.Collection; @@ -66,7 +68,11 @@ public final class OpenGaussAdminExecutorCreator implements DatabaseAdminExecuto @Override public Optional create(final SQLStatementContext sqlStatementContext) { - return delegated.create(sqlStatementContext); + SQLStatement sqlStatement = sqlStatementContext.getSqlStatement(); + if (sqlStatement instanceof ShowStatement) { + return Optional.of(new OpenGaussShowVariableExecutor((ShowStatement) sqlStatement)); + } + return Optional.empty(); } @Override diff --git a/proxy/backend/type/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussShowVariableExecutor.java b/proxy/backend/type/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussShowVariableExecutor.java new file mode 100644 index 0000000000000..80c1619cfd6ed --- /dev/null +++ b/proxy/backend/type/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussShowVariableExecutor.java @@ -0,0 +1,88 @@ +/* + * 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.opengauss.handler.admin; + +import com.cedarsoftware.util.CaseInsensitiveMap; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData; +import org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.metadata.RawQueryResultColumnMetaData; +import org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.metadata.RawQueryResultMetaData; +import org.apache.shardingsphere.infra.merge.result.MergedResult; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataMergedResult; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; +import org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminQueryExecutor; +import org.apache.shardingsphere.proxy.backend.postgresql.handler.admin.executor.PostgreSQLShowVariableExecutor; +import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; +import org.apache.shardingsphere.sql.parser.statement.core.statement.dal.ShowStatement; + +import java.sql.Types; +import java.util.Collections; +import java.util.Locale; +import java.util.Map; + +/** + * OpenGauss show variable executor. + */ +@RequiredArgsConstructor +public final class OpenGaussShowVariableExecutor implements DatabaseAdminQueryExecutor { + + private static final Map VARIABLE_ROW_DATA_GENERATORS = new CaseInsensitiveMap<>(1, 1F); + + static { + VARIABLE_ROW_DATA_GENERATORS.put("sql_compatibility", connectionSession -> new String[]{"sql_compatibility", "PG", "Show sql_compatibility value."}); + } + + private final ShowStatement showStatement; + + private final PostgreSQLShowVariableExecutor delegated; + + @Getter + private QueryResultMetaData queryResultMetaData; + + @Getter + private MergedResult mergedResult; + + public OpenGaussShowVariableExecutor(final ShowStatement showStatement) { + this.showStatement = showStatement; + delegated = new PostgreSQLShowVariableExecutor(showStatement); + } + + @Override + public void execute(final ConnectionSession connectionSession) { + String name = showStatement.getName().orElse("").toLowerCase(Locale.ROOT); + if (VARIABLE_ROW_DATA_GENERATORS.containsKey(name)) { + queryResultMetaData = new RawQueryResultMetaData(Collections.singletonList(new RawQueryResultColumnMetaData("", "", name, Types.VARCHAR, "VARCHAR", -1, 0))); + OpenGaussShowVariableExecutor.VariableRowDataGenerator variableRowDataGenerator = VARIABLE_ROW_DATA_GENERATORS.getOrDefault(name, unused -> new String[]{"", "", ""}); + mergedResult = new LocalDataMergedResult(Collections.singletonList(new LocalDataQueryResultRow(variableRowDataGenerator.getVariable(connectionSession)[1]))); + } else { + delegated(connectionSession); + } + } + + private void delegated(final ConnectionSession connectionSession) { + delegated.execute(connectionSession); + queryResultMetaData = delegated.getQueryResultMetaData(); + mergedResult = delegated.getMergedResult(); + } + + private interface VariableRowDataGenerator { + + Object[] getVariable(ConnectionSession connectionSession); + } +} diff --git a/proxy/backend/type/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussAdminExecutorFactoryTest.java b/proxy/backend/type/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussAdminExecutorFactoryTest.java index 19fbb3bd3a0b9..2d7f9536c042c 100644 --- a/proxy/backend/type/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussAdminExecutorFactoryTest.java +++ b/proxy/backend/type/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussAdminExecutorFactoryTest.java @@ -22,6 +22,7 @@ import org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutor; import org.apache.shardingsphere.proxy.backend.postgresql.handler.admin.PostgreSQLAdminExecutorCreator; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; +import org.apache.shardingsphere.sql.parser.statement.opengauss.dal.OpenGaussShowStatement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -55,13 +56,11 @@ void setup() throws ReflectiveOperationException { } @Test - void assertNewInstanceWithSQLStatementContextOnly() { + void assertNewInstanceWithSQLStatementContext() { SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class); - DatabaseAdminExecutor expected = mock(DatabaseAdminExecutor.class); - when(postgresqlAdminExecutorFactory.create(sqlStatementContext)).thenReturn(Optional.of(expected)); + when(sqlStatementContext.getSqlStatement()).thenReturn(new OpenGaussShowStatement("all")); Optional actual = openGaussAdminExecutorFactory.create(sqlStatementContext); assertTrue(actual.isPresent()); - assertThat(actual.get(), is(expected)); } @Test diff --git a/proxy/backend/type/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussShowVariableExecutorTest.java b/proxy/backend/type/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussShowVariableExecutorTest.java new file mode 100644 index 0000000000000..83fc0557f9e22 --- /dev/null +++ b/proxy/backend/type/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/OpenGaussShowVariableExecutorTest.java @@ -0,0 +1,80 @@ +/* + * 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.opengauss.handler.admin; + +import org.apache.shardingsphere.infra.autogen.version.ShardingSphereVersion; +import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData; +import org.apache.shardingsphere.infra.merge.result.MergedResult; +import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; +import org.apache.shardingsphere.sql.parser.statement.opengauss.dal.OpenGaussShowStatement; +import org.junit.jupiter.api.Test; + +import java.sql.SQLException; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; + +class OpenGaussShowVariableExecutorTest { + + @Test + void assertExecuteShowAll() throws SQLException { + ConnectionSession connectionSession = mock(ConnectionSession.class); + OpenGaussShowVariableExecutor executor = new OpenGaussShowVariableExecutor(new OpenGaussShowStatement("ALL")); + executor.execute(connectionSession); + QueryResultMetaData actualMetaData = executor.getQueryResultMetaData(); + assertThat(actualMetaData.getColumnCount(), is(3)); + assertThat(actualMetaData.getColumnLabel(1), is("name")); + assertThat(actualMetaData.getColumnLabel(2), is("setting")); + assertThat(actualMetaData.getColumnLabel(3), is("description")); + MergedResult actualResult = executor.getMergedResult(); + Map expected = new LinkedHashMap<>(7, 1F); + expected.put("application_name", "PostgreSQL"); + expected.put("client_encoding", "UTF8"); + expected.put("integer_datetimes", "on"); + expected.put("TimeZone", "Etc/UTC"); + expected.put("transaction_isolation", "read committed"); + expected.put("transaction_read_only", "off"); + expected.put("server_version", ShardingSphereVersion.VERSION); + for (Entry entry : expected.entrySet()) { + assertTrue(actualResult.next()); + assertThat(actualResult.getValue(1, String.class), is(entry.getKey())); + assertThat(actualResult.getValue(2, String.class), is(entry.getValue())); + } + assertFalse(actualResult.next()); + } + + @Test + void assertExecuteShowOne() throws SQLException { + ConnectionSession connectionSession = mock(ConnectionSession.class); + OpenGaussShowVariableExecutor executor = new OpenGaussShowVariableExecutor(new OpenGaussShowStatement("sql_compatibility")); + executor.execute(connectionSession); + QueryResultMetaData actualMetaData = executor.getQueryResultMetaData(); + assertThat(actualMetaData.getColumnCount(), is(1)); + assertThat(actualMetaData.getColumnLabel(1), is("sql_compatibility")); + MergedResult actualResult = executor.getMergedResult(); + assertTrue(actualResult.next()); + assertThat(actualResult.getValue(1, String.class), is("PG")); + assertFalse(actualResult.next()); + } +}