diff --git a/fe/src/main/java/org/apache/doris/common/util/SqlParserUtils.java b/fe/src/main/java/org/apache/doris/common/util/SqlParserUtils.java index 878b6bf96a..a5219ba200 100644 --- a/fe/src/main/java/org/apache/doris/common/util/SqlParserUtils.java +++ b/fe/src/main/java/org/apache/doris/common/util/SqlParserUtils.java @@ -17,6 +17,7 @@ package org.apache.doris.common.util; +import org.apache.doris.analysis.EmptyStmt; import org.apache.doris.analysis.SqlParser; import org.apache.doris.analysis.StatementBase; import org.apache.doris.common.AnalysisException; @@ -46,6 +47,33 @@ public class SqlParserUtils { // get all parsed statements as a list public static List getMultiStmts(SqlParser parser) throws Exception { - return (List) parser.parse().value; + List stmts = (List) parser.parse().value; + /* + * When user execute query by some client library such as python MysqlDb, if user execute like: + * + * "select * from tbl1;" (with a comma at the end of statement) + * + * The sql parser will produce 2 statements: SelectStmt and EmptyStmt. + * Here we discard the second EmptyStmt to make it act like one single statement. + * This is for some compatibility. Because in python MysqlDb, if the first SelectStmt results in + * some warnings, it will try to execute a 'SHOW WARNINGS' statement right after the SelectStmt, + * but before the execution of EmptyStmt. So there will be an exception: + * + * (2014, "Commands out of sync; you can't run this command now") + * + * I though it is a flaw of python MysqlDb. + * However, in order to maintain the consistency of user use, here we remove all EmptyStmt + * at the end to prevent errors.(Leave at least one statement) + * + * But if user execute statements like: + * + * "select * from tbl1;;select 2" + * + * If first "select * from tbl1" has warnings, python MysqlDb will still throw exception. + */ + while (stmts.size() > 1 && stmts.get(stmts.size() - 1) instanceof EmptyStmt) { + stmts.remove(stmts.size() - 1); + } + return stmts; } } diff --git a/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java b/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java index 3ecf767970..2eaf6dd38d 100644 --- a/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java +++ b/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java @@ -19,7 +19,6 @@ package org.apache.doris.planner; import org.apache.doris.analysis.CreateDbStmt; -import org.apache.doris.analysis.CreateDbStmtTest; import org.apache.doris.analysis.CreateTableStmt; import org.apache.doris.analysis.DropDbStmt; import org.apache.doris.analysis.ShowCreateDbStmt; @@ -30,7 +29,6 @@ import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.QueryState.MysqlStateType; import org.apache.doris.utframe.UtFrameUtils; -import org.codehaus.jackson.map.ser.StdSerializers; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -308,6 +306,10 @@ public class QueryPlanTest { sql = "SHOW VARIABLES LIKE 'lower_case_%';;;"; stmts = UtFrameUtils.parseAndAnalyzeStmts(sql, connectContext); + Assert.assertEquals(1, stmts.size()); + + sql = "SHOW VARIABLES LIKE 'lower_case_%';;;SHOW VARIABLES LIKE 'lower_case_%';"; + stmts = UtFrameUtils.parseAndAnalyzeStmts(sql, connectContext); Assert.assertEquals(4, stmts.size()); sql = "SHOW VARIABLES LIKE 'lower_case_%'";