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

zhangliang 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 7baf88f14b0 Add more test cases on 
PostgreSQLCommandExecutorFactoryTest (#37921)
7baf88f14b0 is described below

commit 7baf88f14b0367fa16c9ea6a0cd77cb5f960b5fa
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Feb 1 13:05:04 2026 +0800

    Add more test cases on PostgreSQLCommandExecutorFactoryTest (#37921)
    
    * Add more test cases on PostgreSQLComQueryExecutorTest
    
    * Add more test cases on PostgreSQLCommandExecutorFactoryTest
    
    * Add more test cases on PostgreSQLCommandExecutorFactoryTest
    
    * Add more test cases on PostgreSQLCommandExecutorFactoryTest
---
 .../query/simple/PostgreSQLComQueryExecutor.java   |   3 +-
 .../PostgreSQLCommandExecutorFactoryTest.java      |   2 +-
 .../simple/PostgreSQLComQueryExecutorTest.java     | 158 +++++++++++++++++----
 3 files changed, 134 insertions(+), 29 deletions(-)

diff --git 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutor.java
 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutor.java
index 54199123ffd..06167baf41e 100644
--- 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutor.java
+++ 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutor.java
@@ -106,7 +106,8 @@ public final class PostgreSQLComQueryExecutor implements 
QueryCommandExecutor {
         if (sqlStatement instanceof SetStatement) {
             return createParameterStatusResponse((SetStatement) sqlStatement);
         }
-        return Collections.singletonList(sqlStatement instanceof 
EmptyStatement ? new PostgreSQLEmptyQueryResponsePacket()
+        return Collections.singletonList(sqlStatement instanceof EmptyStatement
+                ? new PostgreSQLEmptyQueryResponsePacket()
                 : new 
PostgreSQLCommandCompletePacket(PostgreSQLCommand.valueOf(sqlStatement.getClass()).map(PostgreSQLCommand::getTag).orElse(""),
 updateResponseHeader.getUpdateCount()));
     }
     
diff --git 
a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactoryTest.java
 
b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactoryTest.java
index 813869ceb20..6f6791e6f44 100644
--- 
a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactoryTest.java
+++ 
b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactoryTest.java
@@ -75,7 +75,7 @@ class PostgreSQLCommandExecutorFactoryTest {
     @Mock
     private PortalContext portalContext;
     
-    @ParameterizedTest(name = "[{index}] {0}")
+    @ParameterizedTest(name = "{0}")
     @MethodSource("provideNonAggregatedCommandCases")
     void assertNonAggregatedCommand(final String name, final 
PostgreSQLCommandPacketType commandPacketType, final PostgreSQLCommandPacket 
packet,
                                     final Class<? extends CommandExecutor> 
expectedClass) throws SQLException {
diff --git 
a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutorTest.java
 
b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutorTest.java
index 9131fe582f9..7193faa4643 100644
--- 
a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutorTest.java
+++ 
b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutorTest.java
@@ -17,14 +17,21 @@
 
 package 
org.apache.shardingsphere.proxy.frontend.postgresql.command.query.simple;
 
-import lombok.SneakyThrows;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.database.protocol.packet.DatabasePacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.PostgreSQLPacket;
+import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLColumnDescription;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLDataRowPacket;
+import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLEmptyQueryResponsePacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLRowDescriptionPacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.simple.PostgreSQLComQueryPacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.generic.PostgreSQLCommandCompletePacket;
+import 
org.apache.shardingsphere.database.protocol.postgresql.packet.handshake.PostgreSQLParameterStatusPacket;
+import org.apache.shardingsphere.infra.hint.HintValueContext;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandlerFactory;
+import org.apache.shardingsphere.proxy.backend.handler.ProxySQLComQueryParser;
 import org.apache.shardingsphere.proxy.backend.response.data.QueryResponseRow;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryResponseHeader;
@@ -32,89 +39,154 @@ import 
org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResp
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import org.apache.shardingsphere.proxy.frontend.command.executor.ResponseType;
 import 
org.apache.shardingsphere.proxy.frontend.postgresql.command.PortalContext;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dal.VariableAssignSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dal.VariableSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.EmptyStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.SetStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.CommitStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.RollbackStatement;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.Mock;
 import org.mockito.internal.configuration.plugins.Plugins;
-import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
 
 import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Stream;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.isA;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(MockitoExtension.class)
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings({ProxySQLComQueryParser.class, 
ProxyBackendHandlerFactory.class})
+@MockitoSettings(strictness = Strictness.LENIENT)
 class PostgreSQLComQueryExecutorTest {
     
+    private static final DatabaseType DATABASE_TYPE = 
TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");
+    
     @Mock
     private PortalContext portalContext;
     
     @Mock
     private ProxyBackendHandler proxyBackendHandler;
     
+    @Mock
+    private PostgreSQLComQueryPacket queryPacket;
+    
+    @Mock
+    private ConnectionSession connectionSession;
+    
     private PostgreSQLComQueryExecutor queryExecutor;
     
     @BeforeEach
     void setUp() throws SQLException {
-        PostgreSQLComQueryPacket queryPacket = 
mock(PostgreSQLComQueryPacket.class);
-        ConnectionSession connectionSession = mock(ConnectionSession.class);
-        when(queryPacket.getSQL()).thenReturn("");
+        when(queryPacket.getSQL()).thenReturn("select 1");
+        when(queryPacket.getHintValueContext()).thenReturn(new 
HintValueContext());
+        SQLStatement sqlStatement = new SQLStatement(DATABASE_TYPE);
+        when(ProxySQLComQueryParser.parse(queryPacket.getSQL(), DATABASE_TYPE, 
connectionSession)).thenReturn(sqlStatement);
+        when(ProxyBackendHandlerFactory.newInstance(DATABASE_TYPE, 
queryPacket.getSQL(), sqlStatement, connectionSession, 
queryPacket.getHintValueContext())).thenReturn(proxyBackendHandler);
         queryExecutor = new PostgreSQLComQueryExecutor(portalContext, 
queryPacket, connectionSession);
-        setMockFieldIntoExecutor(queryExecutor);
-    }
-    
-    @SneakyThrows(ReflectiveOperationException.class)
-    private void setMockFieldIntoExecutor(final PostgreSQLComQueryExecutor 
executor) {
-        
Plugins.getMemberAccessor().set(PostgreSQLComQueryExecutor.class.getDeclaredField("proxyBackendHandler"),
 executor, proxyBackendHandler);
     }
     
     @Test
-    void assertExecuteQueryAndReturnEmptyResult() throws SQLException {
+    void assertExecuteQueryWithColumnDescription() throws SQLException, 
ReflectiveOperationException {
         QueryResponseHeader queryResponseHeader = 
mock(QueryResponseHeader.class);
+        
when(queryResponseHeader.getQueryHeaders()).thenReturn(Collections.singletonList(new
 QueryHeader("schema", "table", "label", "column", 1, "type", 2, 3, true, true, 
true, true)));
         when(proxyBackendHandler.execute()).thenReturn(queryResponseHeader);
         Collection<DatabasePacket> actual = queryExecutor.execute();
+        PostgreSQLRowDescriptionPacket rowDescriptionPacket = 
(PostgreSQLRowDescriptionPacket) actual.iterator().next();
+        Collection<PostgreSQLColumnDescription> columnDescriptions = 
getColumnDescriptions(rowDescriptionPacket);
+        PostgreSQLColumnDescription columnDescription = 
columnDescriptions.iterator().next();
         assertThat(actual.size(), is(1));
-        assertThat(actual.iterator().next(), 
is(isA(PostgreSQLRowDescriptionPacket.class)));
+        assertThat(columnDescriptions.size(), is(1));
+        assertThat(columnDescription.getColumnName(), is("label"));
+        assertThat(columnDescription.getColumnIndex(), is(1));
+        assertThat(columnDescription.getColumnLength(), is(2));
+        assertThat(columnDescription.getTypeOID(), is(new 
PostgreSQLColumnDescription("column", 1, 1, 2, "type").getTypeOID()));
         assertThat(queryExecutor.getResponseType(), is(ResponseType.QUERY));
-        verify(queryResponseHeader).getQueryHeaders();
     }
     
     @Test
-    void assertExecuteQueryAndReturnResult() throws SQLException {
+    void assertExecuteQueryWithEmptyColumns() throws SQLException, 
ReflectiveOperationException {
         QueryResponseHeader queryResponseHeader = 
mock(QueryResponseHeader.class);
-        
when(queryResponseHeader.getQueryHeaders()).thenReturn(Collections.singletonList(new
 QueryHeader("schema", "table", "label", "column", 1, "type", 2, 3, true, true, 
true, true)));
+        
when(queryResponseHeader.getQueryHeaders()).thenReturn(Collections.emptyList());
         when(proxyBackendHandler.execute()).thenReturn(queryResponseHeader);
         Collection<DatabasePacket> actual = queryExecutor.execute();
-        assertThat(actual.size(), is(1));
-        assertThat(actual.iterator().next(), 
is(isA(PostgreSQLRowDescriptionPacket.class)));
+        PostgreSQLRowDescriptionPacket rowDescriptionPacket = 
(PostgreSQLRowDescriptionPacket) actual.iterator().next();
+        Collection<PostgreSQLColumnDescription> columnDescriptions = 
getColumnDescriptions(rowDescriptionPacket);
+        assertThat(columnDescriptions.size(), is(0));
         assertThat(queryExecutor.getResponseType(), is(ResponseType.QUERY));
-        verify(queryResponseHeader).getQueryHeaders();
     }
     
-    @Test
-    void assertExecuteUpdate() throws SQLException {
-        when(proxyBackendHandler.execute()).thenReturn(new 
UpdateResponseHeader(mock(InsertStatement.class)));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("updateScenarios")
+    void assertExecuteUpdate(final String testName, final SQLStatement 
sqlStatement, final Class<? extends DatabasePacket> expectedPacketType,
+                             final String expectedTag, final boolean 
expectCloseAll) throws SQLException, ReflectiveOperationException {
+        when(proxyBackendHandler.execute()).thenReturn(new 
UpdateResponseHeader(sqlStatement));
         Collection<DatabasePacket> actual = queryExecutor.execute();
+        DatabasePacket packet = actual.iterator().next();
         assertThat(actual.size(), is(1));
-        assertThat(actual.iterator().next(), 
is(isA(PostgreSQLCommandCompletePacket.class)));
+        assertThat(packet, isA(expectedPacketType));
+        if (packet instanceof PostgreSQLCommandCompletePacket && null != 
expectedTag) {
+            assertThat(getSqlCommand((PostgreSQLCommandCompletePacket) 
packet), is(expectedTag));
+        }
         assertThat(queryExecutor.getResponseType(), is(ResponseType.UPDATE));
+        if (expectCloseAll) {
+            verify(portalContext).closeAll();
+        } else {
+            verify(portalContext, never()).closeAll();
+        }
+    }
+    
+    @Test
+    void assertExecuteUpdateWithSetStatement() throws SQLException, 
ReflectiveOperationException {
+        VariableSegment searchPathVariable = new VariableSegment(0, 0, 
"search_path");
+        VariableSegment workMemVariable = new VariableSegment(1, 1, 
"work_mem");
+        List<VariableAssignSegment> variableAssigns = new ArrayList<>(2);
+        variableAssigns.add(new VariableAssignSegment(0, 0, 
searchPathVariable, null));
+        variableAssigns.add(new VariableAssignSegment(1, 1, workMemVariable, 
"'64MB'"));
+        UpdateResponseHeader updateResponseHeader = new 
UpdateResponseHeader(new SetStatement(DATABASE_TYPE, variableAssigns));
+        when(proxyBackendHandler.execute()).thenReturn(updateResponseHeader);
+        Collection<DatabasePacket> actual = queryExecutor.execute();
+        Iterator<DatabasePacket> iterator = actual.iterator();
+        PostgreSQLCommandCompletePacket commandCompletePacket = 
(PostgreSQLCommandCompletePacket) iterator.next();
+        PostgreSQLParameterStatusPacket firstStatusPacket = 
(PostgreSQLParameterStatusPacket) iterator.next();
+        assertThat(actual.size(), is(3));
+        assertThat(getSqlCommand(commandCompletePacket), is("SET"));
+        assertThat(getParameterStatusKey(firstStatusPacket), 
is("search_path"));
+        assertNull(getParameterStatusValue(firstStatusPacket));
+        PostgreSQLParameterStatusPacket secondStatusPacket = 
(PostgreSQLParameterStatusPacket) iterator.next();
+        assertThat(getParameterStatusKey(secondStatusPacket), is("work_mem"));
+        assertThat(getParameterStatusValue(secondStatusPacket), is("64MB"));
+        assertThat(queryExecutor.getResponseType(), is(ResponseType.UPDATE));
+        verify(portalContext, never()).closeAll();
     }
     
     @Test
     void assertNext() throws SQLException {
-        when(proxyBackendHandler.next()).thenReturn(true, false);
+        when(proxyBackendHandler.next()).thenReturn(true);
         assertTrue(queryExecutor.next());
-        assertFalse(queryExecutor.next());
     }
     
     @Test
@@ -123,4 +195,36 @@ class PostgreSQLComQueryExecutorTest {
         PostgreSQLPacket actual = queryExecutor.getQueryRowPacket();
         assertThat(actual, is(isA(PostgreSQLDataRowPacket.class)));
     }
+    
+    @Test
+    void assertClose() throws SQLException {
+        queryExecutor.close();
+        verify(proxyBackendHandler).close();
+    }
+    
+    @SuppressWarnings("unchecked")
+    private Collection<PostgreSQLColumnDescription> 
getColumnDescriptions(final PostgreSQLRowDescriptionPacket packet) throws 
ReflectiveOperationException {
+        return (Collection<PostgreSQLColumnDescription>) 
Plugins.getMemberAccessor().get(PostgreSQLRowDescriptionPacket.class.getDeclaredField("columnDescriptions"),
 packet);
+    }
+    
+    private String getSqlCommand(final PostgreSQLCommandCompletePacket packet) 
throws ReflectiveOperationException {
+        return (String) 
Plugins.getMemberAccessor().get(PostgreSQLCommandCompletePacket.class.getDeclaredField("sqlCommand"),
 packet);
+    }
+    
+    private String getParameterStatusKey(final PostgreSQLParameterStatusPacket 
packet) throws ReflectiveOperationException {
+        return (String) 
Plugins.getMemberAccessor().get(PostgreSQLParameterStatusPacket.class.getDeclaredField("key"),
 packet);
+    }
+    
+    private String getParameterStatusValue(final 
PostgreSQLParameterStatusPacket packet) throws ReflectiveOperationException {
+        return (String) 
Plugins.getMemberAccessor().get(PostgreSQLParameterStatusPacket.class.getDeclaredField("value"),
 packet);
+    }
+    
+    private static Stream<Arguments> updateScenarios() {
+        return Stream.of(
+                Arguments.of("commit statement", new 
CommitStatement(DATABASE_TYPE), PostgreSQLCommandCompletePacket.class, 
"COMMIT", true),
+                Arguments.of("rollback statement", new 
RollbackStatement(DATABASE_TYPE), PostgreSQLCommandCompletePacket.class, 
"ROLLBACK", true),
+                Arguments.of("recognized command", new 
InsertStatement(DATABASE_TYPE), PostgreSQLCommandCompletePacket.class, 
"INSERT", false),
+                Arguments.of("empty statement", new 
EmptyStatement(DATABASE_TYPE), PostgreSQLEmptyQueryResponsePacket.class, null, 
false),
+                Arguments.of("unrecognized statement", new 
SQLStatement(DATABASE_TYPE), PostgreSQLCommandCompletePacket.class, "", false));
+    }
 }

Reply via email to