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 e5f9841  Refactor getShowLikePattern (#12140)
e5f9841 is described below

commit e5f9841889a1bceb25de57ef1452e8e23f81cc3a
Author: Zhengqiang Duan <duanzhengqi...@apache.org>
AuthorDate: Wed Sep 1 16:55:35 2021 +0800

    Refactor getShowLikePattern (#12140)
    
    * Optimize name of getShowLikePattern method
    
    * optimize code
    
    * optimize sql pattern escape
    
    * optimize variable name
    
    * fix test case
    
    * optimize code
---
 .../mysql/executor/ShowDatabasesExecutor.java      |  2 +-
 .../admin/mysql/executor/ShowTablesExecutor.java   |  2 +-
 .../sql/parser/sql/common/util/SQLUtil.java        | 29 +++++++++++----
 .../sql/parser/sql/common/util/SQLUtilTest.java    | 42 ++++++++++++++++++++++
 4 files changed, 67 insertions(+), 8 deletions(-)

diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/executor/ShowDatabasesExecutor.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/executor/ShowDatabasesExecutor.java
index 272731c..594a9d8 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/executor/ShowDatabasesExecutor.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/executor/ShowDatabasesExecutor.java
@@ -65,7 +65,7 @@ public final class ShowDatabasesExecutor implements 
DatabaseAdminQueryExecutor {
     }
     
     private boolean checkLikePattern(final String schemaName) {
-        Optional<String> pattern = 
showDatabasesStatement.getLike().map(SQLUtil::getShowLikePattern);
+        Optional<String> pattern = showDatabasesStatement.getLike().map(each 
-> SQLUtil.convertLikePatternToRegex(each.getPattern()));
         return !pattern.isPresent() || schemaName.matches(pattern.get());
     }
     
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/executor/ShowTablesExecutor.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/executor/ShowTablesExecutor.java
index 8fe8e73..b7b0e9b 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/executor/ShowTablesExecutor.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/executor/ShowTablesExecutor.java
@@ -69,7 +69,7 @@ public final class ShowTablesExecutor implements 
DatabaseAdminQueryExecutor {
     
     private Collection<String> getAllTableNames(final String schemaName) {
         Collection<String> allTableNames = 
ProxyContext.getInstance().getMetaData(schemaName).getSchema().getAllTableNames();
-        Optional<String> pattern = 
showTablesStatement.getLike().map(SQLUtil::getShowLikePattern);
+        Optional<String> pattern = showTablesStatement.getLike().map(each -> 
SQLUtil.convertLikePatternToRegex(each.getPattern()));
         return pattern.isPresent() ? allTableNames.stream().filter(each -> 
each.matches(pattern.get())).collect(Collectors.toList()) : allTableNames;
     }
     
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SQLUtil.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SQLUtil.java
index 68ad3c6..f75527a 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SQLUtil.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SQLUtil.java
@@ -23,7 +23,6 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode;
 import org.apache.shardingsphere.sql.parser.sql.common.constant.Paren;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dal.ShowLikeSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
@@ -60,6 +59,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.regex.Pattern;
 
 /**
  * SQL utility class.
@@ -73,6 +73,14 @@ public final class SQLUtil {
     
     private static final String COMMENT_SUFFIX = "*/";
     
+    private static final Pattern SINGLE_CHARACTER_PATTERN = 
Pattern.compile("^_|([^\\\\])_");
+    
+    private static final Pattern SINGLE_CHARACTER_ESCAPE_PATTERN = 
Pattern.compile("\\\\_");
+    
+    private static final Pattern ANY_CHARACTER_PATTERN = 
Pattern.compile("^%|([^\\\\])%");
+    
+    private static final Pattern ANY_CHARACTER_ESCAPE_PATTERN = 
Pattern.compile("\\\\%");
+    
     /**
      * Get exactly number value and type.
      *
@@ -280,12 +288,21 @@ public final class SQLUtil {
     }
     
     /**
-     * Get show like pattern.
+     * Convert like pattern to regex.
      * 
-     * @param showLike show like segment
-     * @return pattern
+     * @param pattern like pattern
+     * @return regex
      */
-    public static String getShowLikePattern(final ShowLikeSegment showLike) {
-        return showLike.getPattern().replaceAll("_", ".{1}").replaceAll("%", 
".*");
+    public static String convertLikePatternToRegex(final String pattern) {
+        String result = pattern;
+        if (pattern.contains("_")) {
+            result = 
SINGLE_CHARACTER_PATTERN.matcher(result).replaceAll("$1.");    
+            result = 
SINGLE_CHARACTER_ESCAPE_PATTERN.matcher(result).replaceAll("_");    
+        }
+        if (pattern.contains("%")) {
+            result = ANY_CHARACTER_PATTERN.matcher(result).replaceAll("$1.*");
+            result = 
ANY_CHARACTER_ESCAPE_PATTERN.matcher(result).replaceAll("%");
+        }
+        return result;
     }
 }
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/util/SQLUtilTest.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/util/SQLUtilTest.java
index ac8adc3..c877f13 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/util/SQLUtilTest.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/util/SQLUtilTest.java
@@ -90,4 +90,46 @@ public final class SQLUtilTest {
         assertThat(SQLUtil.getExpressionWithoutOutsideParentheses("((a + 
b*c))"), is("a + b*c"));
         assertThat(SQLUtil.getExpressionWithoutOutsideParentheses(""), is(""));
     }
+    
+    @Test
+    public void assertConvertLikePatternToRegexWhenEndWithPattern() {
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding_'"), is("SHOW DATABASES LIKE 'sharding.'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding%'"), is("SHOW DATABASES LIKE 'sharding.*'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding%_'"), is("SHOW DATABASES LIKE 'sharding.*.'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding\\_'"), is("SHOW DATABASES LIKE 'sharding_'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding\\%'"), is("SHOW DATABASES LIKE 'sharding%'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding\\%\\_'"), is("SHOW DATABASES LIKE 'sharding%_'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding_\\_'"), is("SHOW DATABASES LIKE 'sharding._'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding%\\%'"), is("SHOW DATABASES LIKE 'sharding.*%'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding_\\%'"), is("SHOW DATABASES LIKE 'sharding.%'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding\\_%'"), is("SHOW DATABASES LIKE 'sharding_.*'"));
+    }
+    
+    @Test
+    public void assertConvertLikePatternToRegexWhenStartWithPattern() {
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'_sharding'"), is("SHOW DATABASES LIKE '.sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'%sharding'"), is("SHOW DATABASES LIKE '.*sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'%_sharding'"), is("SHOW DATABASES LIKE '.*.sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'\\_sharding'"), is("SHOW DATABASES LIKE '_sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'\\%sharding'"), is("SHOW DATABASES LIKE '%sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'\\%\\_sharding'"), is("SHOW DATABASES LIKE '%_sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'_\\_sharding'"), is("SHOW DATABASES LIKE '._sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'%\\%sharding'"), is("SHOW DATABASES LIKE '.*%sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'_\\%sharding'"), is("SHOW DATABASES LIKE '.%sharding'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'\\_%sharding'"), is("SHOW DATABASES LIKE '_.*sharding'"));
+    }
+    
+    @Test
+    public void assertConvertLikePatternToRegexWhenContainsPattern() {
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding_db'"), is("SHOW DATABASES LIKE 'sharding.db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding%db'"), is("SHOW DATABASES LIKE 'sharding.*db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding%_db'"), is("SHOW DATABASES LIKE 'sharding.*.db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding\\_db'"), is("SHOW DATABASES LIKE 'sharding_db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding\\%db'"), is("SHOW DATABASES LIKE 'sharding%db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding\\%\\_db'"), is("SHOW DATABASES LIKE 'sharding%_db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding_\\_db'"), is("SHOW DATABASES LIKE 'sharding._db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding%\\%db'"), is("SHOW DATABASES LIKE 'sharding.*%db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding_\\%db'"), is("SHOW DATABASES LIKE 'sharding.%db'"));
+        assertThat(SQLUtil.convertLikePatternToRegex("SHOW DATABASES LIKE 
'sharding\\_%db'"), is("SHOW DATABASES LIKE 'sharding_.*db'"));
+    }
 }

Reply via email to