This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push:
new 688b97e183f [enhancement](Nereids) support reuse sql cache between
different comment (#40065)
688b97e183f is described below
commit 688b97e183f6bc7933d95acc52904f0fed598624
Author: 924060929 <[email protected]>
AuthorDate: Wed Aug 28 22:15:55 2024 +0800
[enhancement](Nereids) support reuse sql cache between different comment
(#40065)
cherry pick from #40049
---
.../doris/common/NereidsSqlCacheManager.java | 11 ++++--
.../apache/doris/nereids/parser/NereidsParser.java | 39 ++++++++++++++++++++++
.../doris/regression/util/LoggerUtils.groovy | 29 +++++++++++++---
regression-test/plugins/test_helper.groovy | 2 ++
.../cache/parse_sql_from_sql_cache.groovy | 20 ++++++++---
5 files changed, 89 insertions(+), 12 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/common/NereidsSqlCacheManager.java
b/fe/fe-core/src/main/java/org/apache/doris/common/NereidsSqlCacheManager.java
index e6a72d069b4..77f1d929dd5 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/common/NereidsSqlCacheManager.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/common/NereidsSqlCacheManager.java
@@ -38,6 +38,7 @@ import org.apache.doris.nereids.SqlCacheContext.FullTableName;
import org.apache.doris.nereids.SqlCacheContext.ScanTable;
import org.apache.doris.nereids.StatementContext;
import org.apache.doris.nereids.analyzer.UnboundVariable;
+import org.apache.doris.nereids.parser.NereidsParser;
import org.apache.doris.nereids.properties.PhysicalProperties;
import org.apache.doris.nereids.rules.analysis.ExpressionAnalyzer;
import org.apache.doris.nereids.rules.analysis.UserAuthentication;
@@ -127,7 +128,7 @@ public class NereidsSqlCacheManager {
SqlCacheContext sqlCacheContext = sqlCacheContextOpt.get();
UserIdentity currentUserIdentity =
connectContext.getCurrentUserIdentity();
String key = sqlCacheContext.getCacheKeyType() == CacheKeyType.SQL
- ? currentUserIdentity.toString() + ":" + sql.trim()
+ ? currentUserIdentity.toString() + ":" +
normalizeSql(sql.trim())
: currentUserIdentity.toString() + ":" +
DebugUtil.printId(sqlCacheContext.getOrComputeCacheKeyMd5());
if (sqlCaches.getIfPresent(key) == null &&
sqlCacheContext.getOrComputeCacheKeyMd5() != null
&& sqlCacheContext.getResultSetInFe().isPresent()) {
@@ -147,7 +148,7 @@ public class NereidsSqlCacheManager {
SqlCacheContext sqlCacheContext = sqlCacheContextOpt.get();
UserIdentity currentUserIdentity =
connectContext.getCurrentUserIdentity();
String key = sqlCacheContext.getCacheKeyType() == CacheKeyType.SQL
- ? currentUserIdentity.toString() + ":" + sql.trim()
+ ? currentUserIdentity.toString() + ":" +
normalizeSql(sql.trim())
: currentUserIdentity.toString() + ":" +
DebugUtil.printId(sqlCacheContext.getOrComputeCacheKeyMd5());
if (sqlCaches.getIfPresent(key) == null &&
sqlCacheContext.getOrComputeCacheKeyMd5() != null) {
SqlCache cache = (SqlCache) analyzer.getCache();
@@ -168,7 +169,7 @@ public class NereidsSqlCacheManager {
/** tryParseSql */
public Optional<LogicalSqlCache> tryParseSql(ConnectContext
connectContext, String sql) {
UserIdentity currentUserIdentity =
connectContext.getCurrentUserIdentity();
- String key = currentUserIdentity + ":" + sql.trim();
+ String key = currentUserIdentity + ":" + normalizeSql(sql.trim());
SqlCacheContext sqlCacheContext = sqlCaches.getIfPresent(key);
if (sqlCacheContext == null) {
return Optional.empty();
@@ -201,6 +202,10 @@ public class NereidsSqlCacheManager {
}
}
+ private String normalizeSql(String sql) {
+ return NereidsParser.removeCommentAndTrimBlank(sql);
+ }
+
private Optional<LogicalSqlCache> tryParseSqlWithoutCheckVariable(
ConnectContext connectContext, String key,
SqlCacheContext sqlCacheContext, UserIdentity currentUserIdentity)
{
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/NereidsParser.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/NereidsParser.java
index edcbb76ad84..203407d448e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/NereidsParser.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/NereidsParser.java
@@ -40,6 +40,7 @@ import com.google.common.collect.Maps;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenSource;
import org.antlr.v4.runtime.atn.PredictionMode;
@@ -334,4 +335,42 @@ public class NereidsParser {
}
return tree;
}
+
+ /**
+ * removeCommentAndTrimBlank
+ *
+ * for example: select \/*+SET_VAR(key=value)*\/ \/* trace_id: 1234 *\/
*, a, \n b from table
+ *
+ * will be normalized to: select \/*+SET_VAR(key=value)*\/ * , a, b from
table
+ */
+ public static String removeCommentAndTrimBlank(String sql) {
+ DorisLexer lexer = new DorisLexer(new
CaseInsensitiveStream(CharStreams.fromString(sql)));
+ CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+ tokenStream.fill();
+
+ // maybe add more space char
+ StringBuilder newSql = new StringBuilder((int) (sql.length() * 1.2));
+
+ for (Token token : tokenStream.getTokens()) {
+ int tokenType = token.getType();
+ switch (tokenType) {
+ case DorisLexer.SIMPLE_COMMENT:
+ case DorisLexer.WS:
+ case Recognizer.EOF:
+ break;
+ case DorisLexer.BRACKETED_COMMENT:
+ String bracketedComment = token.getText();
+ // append hint
+ if (bracketedComment.startsWith("/*+")) {
+ newSql.append(bracketedComment);
+ newSql.append(" ");
+ }
+ break;
+ default:
+ newSql.append(token.getText());
+ newSql.append(" ");
+ }
+ }
+ return newSql.toString().trim();
+ }
}
diff --git
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/util/LoggerUtils.groovy
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/util/LoggerUtils.groovy
index 2bc01e6f4ba..bcb04e8e9ea 100644
---
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/util/LoggerUtils.groovy
+++
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/util/LoggerUtils.groovy
@@ -17,15 +17,15 @@
package org.apache.doris.regression.util
+import com.google.common.collect.Sets
+
class LoggerUtils {
static Tuple2<Integer, String> getErrorInfo(Throwable t, File file) {
if (file.name.endsWith(".groovy")) {
+ def st = findRootErrorStackTrace(t, Sets.newLinkedHashSet(), file)
int lineNumber = -1
- for (def st : t.getStackTrace()) {
- if (Objects.equals(st.fileName, file.name)) {
- lineNumber = st.getLineNumber()
- break
- }
+ if (!st.is(null)) {
+ lineNumber = st.getLineNumber()
}
if (lineNumber == -1) {
return new Tuple2<Integer, String>(null, null)
@@ -40,4 +40,23 @@ class LoggerUtils {
return new Tuple2<Integer, String>(null, null)
}
}
+
+ static StackTraceElement findRootErrorStackTrace(Throwable t,
Set<Throwable> throwables, File file) {
+ throwables.add(t)
+
+ def cause = t.getCause()
+ if (!cause.is(null) && !throwables.contains(cause)) {
+ def foundStackTrace = findRootErrorStackTrace(cause, throwables,
file)
+ if (!foundStackTrace.is(null)) {
+ return foundStackTrace
+ }
+ }
+
+ for (def st : t.getStackTrace()) {
+ if (Objects.equals(st.fileName, file.name)) {
+ return st
+ }
+ }
+ return null
+ }
}
diff --git a/regression-test/plugins/test_helper.groovy
b/regression-test/plugins/test_helper.groovy
index 4f7eeb3c09b..60fb9d2c8ed 100644
--- a/regression-test/plugins/test_helper.groovy
+++ b/regression-test/plugins/test_helper.groovy
@@ -57,6 +57,8 @@ Suite.metaClass.createTestTable = { String tableName, boolean
uniqueTable = fals
(4, 1), (4, 2),
(5, 1), (5, 2)
"""
+
+ sql "sync"
}
diff --git
a/regression-test/suites/nereids_p0/cache/parse_sql_from_sql_cache.groovy
b/regression-test/suites/nereids_p0/cache/parse_sql_from_sql_cache.groovy
index 2c17da24661..2c8660ab7c0 100644
--- a/regression-test/suites/nereids_p0/cache/parse_sql_from_sql_cache.groovy
+++ b/regression-test/suites/nereids_p0/cache/parse_sql_from_sql_cache.groovy
@@ -674,10 +674,7 @@ suite("parse_sql_from_sql_cache") {
def result2 = sql "select * from (select $randomInt as id)a"
assertTrue(result2.size() == 1)
- assertNoCache "select * from test_use_plan_cache20 limit 0"
- def result3 = sql "select * from test_use_plan_cache20 limit 0"
- assertTrue(result3.isEmpty())
-
+ sql "select * from test_use_plan_cache20 limit 0"
assertHasCache "select * from test_use_plan_cache20 limit 0"
def result4 = sql "select * from test_use_plan_cache20 limit 0"
assertTrue(result4.isEmpty())
@@ -723,6 +720,21 @@ suite("parse_sql_from_sql_cache") {
assertNoCache "select * from test_use_plan_cache21"
def result2 = sql "select * from test_use_plan_cache21"
assertTrue(result2.size() == 1)
+ }),
+ extraThread("remove_comment", {
+ createTestTable "test_use_plan_cache22"
+
+ // after partition changed 10s, the sql cache can be used
+ sleep(10000)
+
+ sql "set enable_nereids_planner=true"
+ sql "set enable_fallback_to_original_planner=false"
+ sql "set enable_sql_cache=true"
+
+ assertNoCache "select /*+SET_VAR(disable_nereids_rules='')*/
/*comment2*/ * from test_use_plan_cache22 order by 1, 2"
+ sql "select /*+SET_VAR(disable_nereids_rules='')*/ /*comment1*/ *
from test_use_plan_cache22 order by 1, 2"
+
+ assertHasCache "select /*+SET_VAR(disable_nereids_rules='')*/
/*comment2*/ * from test_use_plan_cache22 order by 1, 2"
})
).get()
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]