You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2024/10/09 11:47:13 UTC

(shardingsphere) branch master updated: Refactor ProjectionIdentifierExtractEngine (#33192)

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 8a37b1a5b8c Refactor ProjectionIdentifierExtractEngine (#33192)
8a37b1a5b8c is described below

commit 8a37b1a5b8c96448349c66419ffd10652479933c
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Wed Oct 9 19:47:07 2024 +0800

    Refactor ProjectionIdentifierExtractEngine (#33192)
    
    * Add more test cases on ProjectionsContext
    
    * Refactor ProjectionIdentifierExtractEngine
    
    * Refactor ProjectionIdentifierExtractEngine
---
 .../DialectProjectionIdentifierExtractor.java      |  2 ++
 .../ProjectionIdentifierExtractEngine.java         | 22 ++++++++++------------
 .../ProjectionIdentifierExtractEngineTest.java     | 21 +++++++++++++++++++++
 3 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/extractor/DialectProjectionIdentifierExtractor.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/extractor/DialectProjectionIdentifierExtractor.java
index 73da997261c..23603c89028 100644
--- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/extractor/DialectProjectionIdentifierExtractor.java
+++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/extractor/DialectProjectionIdentifierExtractor.java
@@ -18,12 +18,14 @@
 package org.apache.shardingsphere.infra.binder.context.segment.select.projection.extractor;
 
 import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPI;
+import org.apache.shardingsphere.infra.spi.annotation.SingletonSPI;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 
 /**
  * Dialect projection identifier extractor.
  */
+@SingletonSPI
 public interface DialectProjectionIdentifierExtractor extends DatabaseTypedSPI {
     
     /**
diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/extractor/ProjectionIdentifierExtractEngine.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/extractor/ProjectionIdentifierExtractEngine.java
index 422f43a9418..5d69ad1c42e 100644
--- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/extractor/ProjectionIdentifierExtractEngine.java
+++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/extractor/ProjectionIdentifierExtractEngine.java
@@ -17,25 +17,20 @@
 
 package org.apache.shardingsphere.infra.binder.context.segment.select.projection.extractor;
 
+import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
 import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 
-import java.util.Optional;
-
 /**
  * Projection identifier extract engine.
  */
+@RequiredArgsConstructor
 public final class ProjectionIdentifierExtractEngine {
     
-    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
-    private final Optional<DialectProjectionIdentifierExtractor> projectionIdentifierExtractor;
-    
-    public ProjectionIdentifierExtractEngine(final DatabaseType databaseType) {
-        projectionIdentifierExtractor = DatabaseTypedSPILoader.findService(DialectProjectionIdentifierExtractor.class, databaseType);
-    }
+    private final DatabaseType databaseType;
     
     /**
      * Get identifier value.
@@ -47,7 +42,8 @@ public final class ProjectionIdentifierExtractEngine {
         if (QuoteCharacter.NONE != identifierValue.getQuoteCharacter()) {
             return identifierValue.getValue();
         }
-        return projectionIdentifierExtractor.map(optional -> optional.getIdentifierValue(identifierValue)).orElseGet(identifierValue::getValue);
+        return DatabaseTypedSPILoader.findService(DialectProjectionIdentifierExtractor.class, databaseType)
+                .map(optional -> optional.getIdentifierValue(identifierValue)).orElseGet(identifierValue::getValue);
     }
     
     /**
@@ -58,7 +54,8 @@ public final class ProjectionIdentifierExtractEngine {
      * @return column name
      */
     public String getColumnNameFromFunction(final String functionName, final String functionExpression) {
-        return projectionIdentifierExtractor.map(optional -> optional.getColumnNameFromFunction(functionName, functionExpression)).orElse(functionExpression);
+        return DatabaseTypedSPILoader.findService(DialectProjectionIdentifierExtractor.class, databaseType)
+                .map(optional -> optional.getColumnNameFromFunction(functionName, functionExpression)).orElse(functionExpression);
     }
     
     /**
@@ -68,7 +65,7 @@ public final class ProjectionIdentifierExtractEngine {
      * @return column name
      */
     public String getColumnNameFromExpression(final String expression) {
-        return projectionIdentifierExtractor.map(optional -> optional.getColumnNameFromExpression(expression)).orElse(expression);
+        return DatabaseTypedSPILoader.findService(DialectProjectionIdentifierExtractor.class, databaseType).map(optional -> optional.getColumnNameFromExpression(expression)).orElse(expression);
     }
     
     /**
@@ -78,6 +75,7 @@ public final class ProjectionIdentifierExtractEngine {
      * @return column name
      */
     public String getColumnNameFromSubquery(final SubqueryProjectionSegment subquerySegment) {
-        return projectionIdentifierExtractor.map(optional -> optional.getColumnNameFromSubquery(subquerySegment)).orElseGet(subquerySegment::getText);
+        return DatabaseTypedSPILoader.findService(DialectProjectionIdentifierExtractor.class, databaseType)
+                .map(optional -> optional.getColumnNameFromSubquery(subquerySegment)).orElseGet(subquerySegment::getText);
     }
 }
diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/select/projection/extractor/ProjectionIdentifierExtractEngineTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/select/projection/extractor/ProjectionIdentifierExtractEngineTest.java
index e7ccb3eab58..3f172eb8980 100644
--- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/select/projection/extractor/ProjectionIdentifierExtractEngineTest.java
+++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/select/projection/extractor/ProjectionIdentifierExtractEngineTest.java
@@ -21,11 +21,14 @@ import org.apache.shardingsphere.infra.binder.context.segment.select.projection.
 import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 import org.junit.jupiter.api.Test;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
 
 class ProjectionIdentifierExtractEngineTest {
     
@@ -51,4 +54,22 @@ class ProjectionIdentifierExtractEngineTest {
         assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "MySQL")).getColumnNameFromFunction(functionName, functionExpression),
                 is("FunctionExpression"));
     }
+    
+    @Test
+    void assertGetColumnNameFromExpression() {
+        String expression = "expression";
+        assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "PostgreSQL")).getColumnNameFromExpression(expression), is("?column?"));
+        assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "openGauss")).getColumnNameFromExpression(expression), is("?column?"));
+        assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "Oracle")).getColumnNameFromExpression(expression), is("EXPRESSION"));
+        assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "MySQL")).getColumnNameFromExpression(expression), is("expression"));
+    }
+    
+    @Test
+    void assertGetColumnNameFromSubquery() {
+        SubqueryProjectionSegment projectionSegment = new SubqueryProjectionSegment(mock(SubquerySegment.class), "text");
+        assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "PostgreSQL")).getColumnNameFromSubquery(projectionSegment), is("text"));
+        assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "openGauss")).getColumnNameFromSubquery(projectionSegment), is("text"));
+        assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "Oracle")).getColumnNameFromSubquery(projectionSegment), is("TEXT"));
+        assertThat(new ProjectionIdentifierExtractEngine(TypedSPILoader.getService(DatabaseType.class, "MySQL")).getColumnNameFromSubquery(projectionSegment), is("text"));
+    }
 }