[Syntax] Remove all EmptyStmt from the end of multi-statements list (#3140)
to resolve the ISSUE: #3139 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 `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.
This commit is contained in:
@ -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<StatementBase> getMultiStmts(SqlParser parser) throws Exception {
|
||||
return (List<StatementBase>) parser.parse().value;
|
||||
List<StatementBase> stmts = (List<StatementBase>) 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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_%'";
|
||||
|
||||
Reference in New Issue
Block a user