You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2022/03/17 11:56:11 UTC

[shardingsphere] branch master updated: Intercept set statement in ShardingSphere-Proxy PostgreSQL (#16149)

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

panjuan 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 10ad25e  Intercept set statement in ShardingSphere-Proxy PostgreSQL (#16149)
10ad25e is described below

commit 10ad25e750da79917e1cf3c84626754c1d5a65ff
Author: 吴伟杰 <wu...@apache.org>
AuthorDate: Thu Mar 17 19:54:43 2022 +0800

    Intercept set statement in ShardingSphere-Proxy PostgreSQL (#16149)
---
 .../postgresql/PostgreSQLAdminExecutorFactory.java | 17 ++++--
 .../PostgreSQLAdminExecutorFactoryTest.java        | 63 ++++++++++++++++++++++
 2 files changed, 76 insertions(+), 4 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 d1641e8..6337f33 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
@@ -75,8 +75,17 @@ public final class PostgreSQLAdminExecutorFactory implements DatabaseAdminExecut
                 return Optional.of(new DefaultDatabaseMetadataExecutor(sql));
             }
         }
-        if (sqlStatement instanceof SetStatement && isSetClientEncoding((SetStatement) sqlStatement)) {
-            return Optional.of(new PostgreSQLSetCharsetExecutor((SetStatement) sqlStatement));
+        if (sqlStatement instanceof SetStatement) {
+            SetStatement setStatement = (SetStatement) sqlStatement;
+            // TODO Consider refactoring this with SPI.
+            switch (getSetConfigurationParameter(setStatement)) {
+                case "client_encoding":
+                    return Optional.of(new PostgreSQLSetCharsetExecutor(setStatement));
+                case "extra_float_digits":
+                case "application_name":
+                    return Optional.of(connectionSession -> { });
+                default:
+            }
         }
         return Optional.empty();
     }
@@ -99,9 +108,9 @@ public final class PostgreSQLAdminExecutorFactory implements DatabaseAdminExecut
                 .map(each -> ((SimpleTableSegment) each).getTableName().getIdentifier().getValue()).collect(Collectors.toCollection(LinkedList::new));
     }
     
-    private boolean isSetClientEncoding(final SetStatement setStatement) {
+    private String getSetConfigurationParameter(final SetStatement setStatement) {
         Iterator<VariableAssignSegment> iterator = setStatement.getVariableAssigns().iterator();
-        return iterator.hasNext() && "client_encoding".equalsIgnoreCase(iterator.next().getVariable().getVariable());
+        return iterator.hasNext() ? iterator.next().getVariable().getVariable().toLowerCase() : "";
     }
     
     @Override
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorFactoryTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorFactoryTest.java
index a837796..91e0513 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorFactoryTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/postgresql/PostgreSQLAdminExecutorFactoryTest.java
@@ -17,20 +17,31 @@
 
 package org.apache.shardingsphere.proxy.backend.text.admin.postgresql;
 
+import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import org.apache.shardingsphere.proxy.backend.text.admin.executor.DatabaseAdminExecutor;
+import org.apache.shardingsphere.proxy.backend.text.admin.postgresql.executor.PostgreSQLSetCharsetExecutor;
 import org.apache.shardingsphere.proxy.backend.text.admin.postgresql.executor.SelectDatabaseExecutor;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dal.VariableAssignSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dal.VariableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
+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 org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.postgresql.dal.PostgreSQLSetStatement;
 import org.junit.Test;
 
+import java.sql.SQLException;
 import java.util.Optional;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 
 public final class PostgreSQLAdminExecutorFactoryTest {
@@ -48,4 +59,56 @@ public final class PostgreSQLAdminExecutorFactoryTest {
         assertThat(executorOptional.get(), instanceOf(SelectDatabaseExecutor.class));
     }
     
+    @Test
+    public void assertNewInstanceWithSQLStatementOnly() {
+        assertFalse(postgreSQLAdminExecutorFactory.newInstance(null).isPresent());
+    }
+    
+    @Test
+    public void assertNewInstanceWithUnknownStatement() {
+        assertFalse(postgreSQLAdminExecutorFactory.newInstance(mock(SQLStatement.class), null, Optional.empty()).isPresent());
+    }
+    
+    @Test
+    public void assertType() {
+        assertThat(postgreSQLAdminExecutorFactory.getType(), is("PostgreSQL"));
+    }
+    
+    @Test
+    public void assertNewInstanceWithSetClientEncoding() {
+        SetStatement setStatement = createSetStatement("client_encoding");
+        Optional<DatabaseAdminExecutor> actual = postgreSQLAdminExecutorFactory.newInstance(setStatement, null, Optional.empty());
+        assertTrue(actual.isPresent());
+        assertTrue(actual.get() instanceof PostgreSQLSetCharsetExecutor);
+    }
+    
+    @Test
+    public void assertNewInstanceWithSetExtraFloatDigits() throws SQLException {
+        SetStatement setStatement = createSetStatement("extra_float_digits");
+        Optional<DatabaseAdminExecutor> actual = postgreSQLAdminExecutorFactory.newInstance(setStatement, null, Optional.empty());
+        assertTrue(actual.isPresent());
+        ConnectionSession connectionSession = mock(ConnectionSession.class);
+        actual.get().execute(connectionSession);
+        verifyNoInteractions(connectionSession);
+    }
+    
+    @Test
+    public void assertNewInstanceWithSetApplicationName() throws SQLException {
+        SetStatement setStatement = createSetStatement("application_name");
+        Optional<DatabaseAdminExecutor> actual = postgreSQLAdminExecutorFactory.newInstance(setStatement, null, Optional.empty());
+        assertTrue(actual.isPresent());
+        ConnectionSession connectionSession = mock(ConnectionSession.class);
+        actual.get().execute(connectionSession);
+        verifyNoInteractions(connectionSession);
+    }
+    
+    private SetStatement createSetStatement(final String configurationParameter) {
+        VariableSegment variableSegment = new VariableSegment();
+        variableSegment.setVariable(configurationParameter);
+        VariableAssignSegment variableAssignSegment = new VariableAssignSegment();
+        variableAssignSegment.setVariable(variableSegment);
+        SetStatement setStatement = new PostgreSQLSetStatement();
+        setStatement.getVariableAssigns().add(variableAssignSegment);
+        return setStatement;
+    }
 }