diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java index 6b1c1dd6734435..b6b09348046cea 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java @@ -713,6 +713,9 @@ public String getExplainString(ExplainOptions explainOptions) { + "========== OPTIMIZED PLAN " + getTimeMetricString(SummaryProfile::getPrettyNereidsOptimizeTime) + " ==========\n" + optimizedPlan.treeString() + "\n\n"; + if (cascadesContext != null && cascadesContext.getMemo() != null) { + plan += "========== MEMO " + cascadesContext.getMemo().toString() + "\n\n"; + } if (distributedPlans != null && !distributedPlans.isEmpty()) { plan += "========== DISTRIBUTED PLAN " diff --git a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy index f5d811514b375d..16cc6bbd21b003 100644 --- a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy +++ b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy @@ -71,6 +71,7 @@ import java.util.concurrent.Future import java.util.concurrent.ThreadFactory import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicBoolean +import java.util.regex.Pattern import java.util.stream.Collectors import java.util.stream.LongStream import static org.apache.doris.regression.util.DataUtils.sortByToString @@ -263,7 +264,7 @@ class Suite implements GroovyInterceptable { } public T connect(String user = context.config.jdbcUser, String password = context.config.jdbcPassword, - String url = context.config.jdbcUrl, Closure actionSupplier) { + String url = context.config.jdbcUrl, Closure actionSupplier) { return context.connect(user, password, url, actionSupplier) } @@ -640,7 +641,7 @@ class Suite implements GroovyInterceptable { } long getTableVersion(long dbId, String tableName) { - def result = sql_return_maparray """show proc '/dbs/${dbId}'""" + def result = sql_return_maparray """show proc '/dbs/${dbId}'""" for (def res : result) { if(res.TableName.equals(tableName)) { log.info(res.toString()) @@ -989,7 +990,7 @@ class Suite implements GroovyInterceptable { if (exitcode != 0) { staticLogger.info("exit code: ${exitcode}, output\n: ${proc.text}") if (mustSuc == true) { - Assert.assertEquals(0, exitcode) + Assert.assertEquals(0, exitcode) } } } catch (IOException e) { @@ -1119,7 +1120,7 @@ class Suite implements GroovyInterceptable { Connection getTargetConnection() { return context.getTargetConnection(this) } - + boolean deleteFile(String filePath) { def file = new File(filePath) file.delete() @@ -1142,7 +1143,7 @@ class Suite implements GroovyInterceptable { ) DISTRIBUTED BY HASH(id) BUCKETS 1 PROPERTIES ( - "replication_num" = "${backends.size()}" + "replication_num" = "${backends.size()}" ) """ @@ -1314,13 +1315,24 @@ class Suite implements GroovyInterceptable { throw new IllegalStateException("Check tag '${tag}' failed, sql:\n${arg}", t) } if (errorMsg != null) { + def allPlan = "" + if (arg instanceof String) { + def query = (String) arg; + def pattern = Pattern.compile("^\\s*explain\\s+shape\\s*plan\\s*", Pattern.MULTILINE) + if (query =~ pattern) { + def physical = query.replaceAll(pattern, "explain all plan ") + try { + allPlan = JdbcUtils.executeToStringList(context.getConnection(), physical)[0].join('\n') + } catch (Throwable ignore) {} + } + } String csvRealResult = realResults.stream() - .map {row -> OutputUtils.toCsvString(row)} - .collect(Collectors.joining("\n")) + .map { row -> OutputUtils.toCsvString(row) } + .collect(Collectors.joining("\n")) def outputFilePath = context.outputFile.getCanonicalPath().substring(context.config.dataPath.length() + 1) def line = expectCsvResults.currentLine() logger.warn("expect results in file: ${outputFilePath}, line: ${line}\nrealResults:\n" + csvRealResult) - throw new IllegalStateException("Check tag '${tag}' failed:\n${errorMsg}\n\nsql:\n${arg}") + throw new IllegalStateException("Check tag '${tag}' failed:\n${errorMsg}\n\nsql:\n${arg}\n\n${allPlan}") } } }