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'")); + } }