[MysqlProtocol] Support MySQL multiple statements protocol (#3050)

2 Changes in this CL:

## Support multiple statements in one request like:

```
select 10; select 20; select 30;
```
ISSUE: #3049 

For simple testing this CL, you can using mysql-client shell command tools:

```
mysql> delimiter //
mysql> select 1; select 2; //
+------+
| 1    |
+------+
|    1 |
+------+
1 row in set (0.01 sec)

+------+
| 2    |
+------+
|    2 |
+------+
1 row in set (0.02 sec)

Query OK, 0 rows affected (0.02 sec)
```

I add a new class called `OriginStatement.java`, to save the origin statement in string format with an index. This class is mainly for the following cases:

1. User send a multi-statement to the non-master FE:
      `DDL1; DDL2; DDL3`

2. Currently we cannot separate the original string of a single statement from multiple statements. So we have to forward the entire statement to the Master FE. So I add an index in the forward request. `DDL1`'s index is 0,  `DDL2`'s index is 1,...

3. When the Master FE handle the forwarded request, it will parse the entire statement, got 3 DDL statements, and using the `index` to get the  specified the statement.

## Optimized the display of syntax errors
I have also optimized the display of syntax errors so that longer syntax errors can be fully displayed.
This commit is contained in:
Mingyu Chen
2020-03-13 22:21:40 +08:00
committed by GitHub
parent 9832024995
commit 4c98596283
38 changed files with 499 additions and 161 deletions

View File

@ -17,6 +17,8 @@
package org.apache.doris.analysis;
import org.apache.doris.common.util.SqlParserUtils;
import org.junit.Assert;
import org.junit.Test;
@ -56,7 +58,7 @@ public class AdminShowReplicaTest {
SqlParser parser = new SqlParser(new SqlScanner(new StringReader(stmt)));
AdminShowReplicaStatusStmt showStmt = null;
try {
showStmt = (AdminShowReplicaStatusStmt) parser.parse().value;
showStmt = (AdminShowReplicaStatusStmt) SqlParserUtils.getFirstStmt(parser);
} catch (Error e) {
Assert.fail(e.getMessage());
} catch (Exception e) {

View File

@ -17,11 +17,6 @@
package org.apache.doris.analysis;
import com.google.common.collect.Lists;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Database;
@ -32,12 +27,16 @@ import org.apache.doris.catalog.SinglePartitionInfo;
import org.apache.doris.catalog.View;
import org.apache.doris.common.UserException;
import org.apache.doris.common.jmockit.Deencapsulation;
import org.apache.doris.common.util.SqlParserUtils;
import org.apache.doris.mysql.privilege.PaloAuth;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.persist.AlterViewInfo;
import org.apache.doris.persist.CreateTableInfo;
import org.apache.doris.persist.EditLog;
import org.apache.doris.qe.ConnectContext;
import com.google.common.collect.Lists;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -46,6 +45,11 @@ import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
public class AlterViewStmtTest {
private Analyzer analyzer;
@ -155,7 +159,7 @@ public class AlterViewStmtTest {
SqlParser parser = new SqlParser(new SqlScanner(new StringReader(alterStmt)));
QueryStmt alterQueryStmt = null;
try {
alterQueryStmt = (QueryStmt) parser.parse().value;
alterQueryStmt = (QueryStmt) SqlParserUtils.getFirstStmt(parser);
} catch (Error e) {
Assert.fail(e.getMessage());
} catch (Exception e) {

View File

@ -104,5 +104,4 @@ public class LoadStmtTest {
Assert.fail("No exception throws.");
}
}

View File

@ -1,15 +1,16 @@
package org.apache.doris.analysis;
import java.io.StringReader;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.util.SqlParserUtils;
import org.apache.doris.mysql.privilege.MockedAuth;
import org.apache.doris.mysql.privilege.PaloAuth;
import org.apache.doris.qe.ConnectContext;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.StringReader;
import mockit.Mocked;
public class SetOperationStmtTest {
@ -31,28 +32,28 @@ public class SetOperationStmtTest {
String sql = "select k1,k2 from t where k1='a' union select k1,k2 from t where k1='b';";
SqlScanner input = new SqlScanner(new StringReader(sql));
SqlParser parser = new SqlParser(input);
SetOperationStmt stmt = (SetOperationStmt) parser.parse().value;
SetOperationStmt stmt = (SetOperationStmt) SqlParserUtils.getFirstStmt(parser);
Assert.assertEquals(SetOperationStmt.Operation.UNION, stmt.getOperands().get(1).getOperation());
sql = "select k1,k2 from t where k1='a' intersect select k1,k2 from t where k1='b';";
input = new SqlScanner(new StringReader(sql));
parser = new SqlParser(input);
stmt = (SetOperationStmt) parser.parse().value;
stmt = (SetOperationStmt) SqlParserUtils.getFirstStmt(parser);
Assert.assertEquals(SetOperationStmt.Operation.INTERSECT, stmt.getOperands().get(1).getOperation());
sql = "select k1,k2 from t where k1='a' except select k1,k2 from t where k1='b';";
input = new SqlScanner(new StringReader(sql));
parser = new SqlParser(input);
stmt = (SetOperationStmt) parser.parse().value;
stmt = (SetOperationStmt) SqlParserUtils.getFirstStmt(parser);
Assert.assertEquals(SetOperationStmt.Operation.EXCEPT, stmt.getOperands().get(1).getOperation());
sql = "select k1,k2 from t where k1='a' minus select k1,k2 from t where k1='b';";
input = new SqlScanner(new StringReader(sql));
parser = new SqlParser(input);
stmt = (SetOperationStmt) parser.parse().value;
stmt = (SetOperationStmt) SqlParserUtils.getFirstStmt(parser);
Assert.assertEquals(SetOperationStmt.Operation.EXCEPT, stmt.getOperands().get(1).getOperation());
sql = "select k1,k2 from t where k1='a' union select k1,k2 from t where k1='b' intersect select k1,k2 from t "
+ "where k1='c' except select k1,k2 from t where k1='d';";
input = new SqlScanner(new StringReader(sql));
parser = new SqlParser(input);
stmt = (SetOperationStmt) parser.parse().value;
stmt = (SetOperationStmt) SqlParserUtils.getFirstStmt(parser);
Assert.assertEquals(SetOperationStmt.Operation.UNION, stmt.getOperands().get(1).getOperation());
Assert.assertEquals(SetOperationStmt.Operation.INTERSECT, stmt.getOperands().get(2).getOperation());
Assert.assertEquals(SetOperationStmt.Operation.EXCEPT, stmt.getOperands().get(3).getOperation());

View File

@ -18,8 +18,10 @@
package org.apache.doris.analysis;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.SqlParserUtils;
import org.apache.doris.qe.SqlModeHelper;
import org.apache.doris.rewrite.ExprRewriter;
import org.junit.Assert;
import org.junit.Test;
@ -35,7 +37,7 @@ public class SqlModeTest {
SqlParser parser = new SqlParser(new SqlScanner(new StringReader(stmt)));
SelectStmt selectStmt = null;
try {
selectStmt = (SelectStmt) parser.parse().value;
selectStmt = (SelectStmt) SqlParserUtils.getFirstStmt(parser);
} catch (Exception e) {
Assert.fail(e.getMessage());
}
@ -43,7 +45,7 @@ public class SqlModeTest {
parser = new SqlParser(new SqlScanner(new StringReader(stmt), SqlModeHelper.MODE_DEFAULT));
try {
selectStmt = (SelectStmt) parser.parse().value;
selectStmt = (SelectStmt) SqlParserUtils.getFirstStmt(parser);
} catch (Exception e) {
Assert.fail(e.getMessage());
}
@ -57,7 +59,7 @@ public class SqlModeTest {
SqlParser parser = new SqlParser(new SqlScanner(new StringReader(stmt), SqlModeHelper.MODE_PIPES_AS_CONCAT));
SelectStmt selectStmt = null;
try {
selectStmt = (SelectStmt) parser.parse().value;
selectStmt = (SelectStmt) SqlParserUtils.getFirstStmt(parser);
} catch (Exception e) {
Assert.fail(e.getMessage());
}
@ -70,7 +72,7 @@ public class SqlModeTest {
// Mode DeActive
parser = new SqlParser(new SqlScanner(new StringReader(stmt), SqlModeHelper.MODE_DEFAULT));
try {
selectStmt = (SelectStmt) parser.parse().value;
selectStmt = (SelectStmt) SqlParserUtils.getFirstStmt(parser);
} catch (Exception e) {
Assert.fail(e.getMessage());
}
@ -88,7 +90,7 @@ public class SqlModeTest {
SqlParser parser = new SqlParser(new SqlScanner(new StringReader(stmt), SqlModeHelper.MODE_PIPES_AS_CONCAT));
SelectStmt parsedStmt = null;
try {
parsedStmt = (SelectStmt) parser.parse().value;
parsedStmt = (SelectStmt) SqlParserUtils.getFirstStmt(parser);
} catch (Exception e) {
Assert.fail(e.getMessage());
}

View File

@ -35,6 +35,7 @@ import org.apache.doris.load.EtlJobType;
import org.apache.doris.load.EtlStatus;
import org.apache.doris.load.Load;
import org.apache.doris.load.Source;
import org.apache.doris.qe.OriginStatement;
import org.apache.doris.task.MasterTaskExecutor;
import org.apache.doris.transaction.TransactionState;
@ -96,7 +97,7 @@ public class BrokerLoadJobTest {
};
try {
BrokerLoadJob brokerLoadJob = BrokerLoadJob.fromLoadStmt(loadStmt, originStmt);
BrokerLoadJob brokerLoadJob = BrokerLoadJob.fromLoadStmt(loadStmt, new OriginStatement(originStmt, 0));
Assert.fail();
} catch (DdlException e) {
System.out.println("could not find table named " + tableName);
@ -161,7 +162,7 @@ public class BrokerLoadJobTest {
};
try {
BrokerLoadJob brokerLoadJob = BrokerLoadJob.fromLoadStmt(loadStmt, originStmt);
BrokerLoadJob brokerLoadJob = BrokerLoadJob.fromLoadStmt(loadStmt, new OriginStatement(originStmt, 0));
Assert.assertEquals(Long.valueOf(dbId), Deencapsulation.getField(brokerLoadJob, "dbId"));
Assert.assertEquals(label, Deencapsulation.getField(brokerLoadJob, "label"));
Assert.assertEquals(JobState.PENDING, Deencapsulation.getField(brokerLoadJob, "state"));

View File

@ -40,6 +40,7 @@ import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.persist.EditLog;
import org.apache.doris.persist.RoutineLoadOperation;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.OriginStatement;
import org.apache.doris.system.SystemInfoService;
import org.apache.doris.thrift.TResourceInfo;
@ -115,7 +116,7 @@ public class RoutineLoadManagerTest {
}
};
RoutineLoadManager routineLoadManager = new RoutineLoadManager();
routineLoadManager.createRoutineLoadJob(createRoutineLoadStmt, "dummy");
routineLoadManager.createRoutineLoadJob(createRoutineLoadStmt, new OriginStatement("dummy", 0));
Map<String, RoutineLoadJob> idToRoutineLoadJob =
Deencapsulation.getField(routineLoadManager, "idToRoutineLoadJob");
@ -175,7 +176,7 @@ public class RoutineLoadManagerTest {
};
RoutineLoadManager routineLoadManager = new RoutineLoadManager();
try {
routineLoadManager.createRoutineLoadJob(createRoutineLoadStmt, "dummy");
routineLoadManager.createRoutineLoadJob(createRoutineLoadStmt, new OriginStatement("dummy", 0));
Assert.fail();
} catch (LoadException | DdlException e) {
Assert.fail();

View File

@ -17,6 +17,8 @@
package org.apache.doris.mysql;
import org.apache.doris.qe.QueryState;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -33,7 +35,7 @@ public class MysqlEofPacketTest {
@Test
public void testWrite() {
MysqlEofPacket packet = new MysqlEofPacket(null);
MysqlEofPacket packet = new MysqlEofPacket(new QueryState());
MysqlSerializer serializer = MysqlSerializer.newInstance(capability);
packet.writeTo(serializer);

View File

@ -20,6 +20,7 @@ package org.apache.doris.planner;
import org.apache.doris.analysis.CreateDbStmt;
import org.apache.doris.analysis.CreateTableStmt;
import org.apache.doris.analysis.StatementBase;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Type;
import org.apache.doris.qe.ConnectContext;
@ -32,6 +33,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.util.List;
import java.util.UUID;
public class QueryPlanTest {
@ -288,6 +290,25 @@ public class QueryPlanTest {
String sql = "select * from test.baseall a where k1 in (select k1 from test.bigtable b where k2 > 0 and k1 = 1);";
UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
Assert.assertEquals(MysqlStateType.EOF, connectContext.getState().getStateType());
sql = "SHOW VARIABLES LIKE 'lower_case_%'; SHOW VARIABLES LIKE 'sql_mode'";
List<StatementBase> stmts = UtFrameUtils.parseAndAnalyzeStmts(sql, connectContext);
Assert.assertEquals(2, stmts.size());
}
@Test
public void testMultiStmts() throws Exception {
String sql = "SHOW VARIABLES LIKE 'lower_case_%'; SHOW VARIABLES LIKE 'sql_mode'";
List<StatementBase>stmts = UtFrameUtils.parseAndAnalyzeStmts(sql, connectContext);
Assert.assertEquals(2, stmts.size());
sql = "SHOW VARIABLES LIKE 'lower_case_%';;;";
stmts = UtFrameUtils.parseAndAnalyzeStmts(sql, connectContext);
Assert.assertEquals(4, stmts.size());
sql = "SHOW VARIABLES LIKE 'lower_case_%'";
stmts = UtFrameUtils.parseAndAnalyzeStmts(sql, connectContext);
Assert.assertEquals(1, stmts.size());
}
@Test

View File

@ -17,13 +17,18 @@
package org.apache.doris.planner;
import mockit.Expectations;
import org.apache.doris.analysis.Analyzer;
import org.apache.doris.analysis.CompoundPredicate;
import org.apache.doris.analysis.ImportColumnsStmt;
import org.apache.doris.analysis.ImportWhereStmt;
import org.apache.doris.analysis.SqlParser;
import org.apache.doris.analysis.SqlScanner;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Database;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.SqlParserUtils;
import org.apache.doris.task.StreamLoadTask;
import org.apache.doris.thrift.TFileFormatType;
import org.apache.doris.thrift.TFileType;
@ -32,10 +37,13 @@ import org.apache.doris.thrift.TUniqueId;
import com.google.common.collect.Lists;
import org.junit.Assert;
import org.junit.Test;
import java.io.StringReader;
import java.util.List;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
@ -83,4 +91,17 @@ public class StreamLoadPlannerTest {
StreamLoadPlanner planner = new StreamLoadPlanner(db, destTable, streamLoadTask);
planner.plan(streamLoadTask.getId());
}
@Test
public void testParseStmt() throws Exception {
String sql = new String("COLUMNS (k1, k2, k3=abc(), k4=default_value())");
SqlParser parser = new SqlParser(new SqlScanner(new StringReader(sql)));
ImportColumnsStmt columnsStmt = (ImportColumnsStmt) SqlParserUtils.getFirstStmt(parser);
Assert.assertEquals(4, columnsStmt.getColumns().size());
sql = new String("WHERE k1 > 2 and k3 < 4");
parser = new SqlParser(new SqlScanner(new StringReader(sql)));
ImportWhereStmt whereStmt = (ImportWhereStmt) SqlParserUtils.getFirstStmt(parser);
Assert.assertTrue(whereStmt.getExpr() instanceof CompoundPredicate);
}
}

View File

@ -17,8 +17,6 @@
package org.apache.doris.qe;
import mockit.Expectations;
import mockit.Mocked;
import org.apache.doris.analysis.AccessTestUtil;
import org.apache.doris.analysis.Analyzer;
import org.apache.doris.analysis.DdlStmt;
@ -60,6 +58,8 @@ import java.util.SortedMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java_cup.runtime.Symbol;
import mockit.Expectations;
import mockit.Mocked;
public class StmtExecutorTest {
private ConnectContext ctx;
@ -205,7 +205,7 @@ public class StmtExecutorTest {
queryStmt.rewriteExprs((ExprRewriter) any);
minTimes = 0;
Symbol symbol = new Symbol(0, queryStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(queryStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -259,7 +259,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = null;
Symbol symbol = new Symbol(0, showStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(showStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -294,7 +294,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = null;
Symbol symbol = new Symbol(0, showStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(showStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -329,7 +329,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, killStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(killStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -371,7 +371,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, killStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(killStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -427,7 +427,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, killStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(killStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -478,7 +478,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, killStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(killStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -509,7 +509,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, setStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(setStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -537,7 +537,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, setStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(setStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -566,7 +566,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, ddlStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(ddlStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -577,7 +577,7 @@ public class StmtExecutorTest {
new Expectations(ddlExecutor) {
{
// Mock ddl
DdlExecutor.execute((Catalog) any, (DdlStmt) any, anyString);
DdlExecutor.execute((Catalog) any, (DdlStmt) any, (OriginStatement) any);
minTimes = 0;
}
};
@ -599,7 +599,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, ddlStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(ddlStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -610,7 +610,7 @@ public class StmtExecutorTest {
new Expectations(ddlExecutor) {
{
// Mock ddl
DdlExecutor.execute((Catalog) any, (DdlStmt) any, anyString);
DdlExecutor.execute((Catalog) any, (DdlStmt) any, (OriginStatement) any);
minTimes = 0;
result = new DdlException("ddl fail");
}
@ -633,7 +633,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = RedirectStatus.NO_FORWARD;
Symbol symbol = new Symbol(0, ddlStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(ddlStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -644,7 +644,7 @@ public class StmtExecutorTest {
new Expectations(ddlExecutor) {
{
// Mock ddl
DdlExecutor.execute((Catalog) any, (DdlStmt) any, anyString);
DdlExecutor.execute((Catalog) any, (DdlStmt) any, (OriginStatement) any);
minTimes = 0;
result = new Exception("bug");
}
@ -675,7 +675,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = "testCluster";
Symbol symbol = new Symbol(0, useStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(useStmt));
parser.parse();
minTimes = 0;
result = symbol;
@ -707,7 +707,7 @@ public class StmtExecutorTest {
minTimes = 0;
result = "testCluster";
Symbol symbol = new Symbol(0, useStmt);
Symbol symbol = new Symbol(0, Lists.newArrayList(useStmt));
parser.parse();
minTimes = 0;
result = symbol;

View File

@ -17,13 +17,13 @@
package org.apache.doris.utframe;
import org.apache.commons.io.FileUtils;
import org.apache.doris.analysis.CreateDbStmt;
import org.apache.doris.analysis.CreateTableStmt;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Database;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.FeConstants;
import org.apache.doris.common.Pair;
import org.apache.doris.planner.OlapScanNode;
import org.apache.doris.planner.PlanFragment;
@ -47,7 +47,6 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
@ -78,6 +77,7 @@ public class AnotherDemoTest {
@BeforeClass
public static void beforeClass() throws EnvVarNotSetException, IOException,
FeStartException, NotInitException, DdlException, InterruptedException {
FeConstants.default_scheduler_interval_millisecond = 10;
// get DORIS_HOME
String dorisHome = System.getenv("DORIS_HOME");
if (Strings.isNullOrEmpty(dorisHome)) {

View File

@ -64,7 +64,7 @@ public class DemoTest {
@BeforeClass
public static void beforeClass() throws EnvVarNotSetException, IOException,
FeStartException, NotInitException, DdlException, InterruptedException {
FeConstants.default_scheduler_interval_millisecond = 1000;
FeConstants.default_scheduler_interval_millisecond = 10;
UtFrameUtils.createMinDorisCluster(runningDir);
}

View File

@ -26,6 +26,7 @@ import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.Pair;
import org.apache.doris.common.util.SqlParserUtils;
import org.apache.doris.mysql.privilege.PaloAuth;
import org.apache.doris.planner.Planner;
import org.apache.doris.qe.ConnectContext;
@ -80,7 +81,7 @@ public class UtFrameUtils {
Analyzer analyzer = new Analyzer(ctx.getCatalog(), ctx);
StatementBase statementBase = null;
try {
statementBase = (StatementBase) parser.parse().value;
statementBase = SqlParserUtils.getFirstStmt(parser);
} catch (AnalysisException e) {
String errorMessage = parser.getErrorMsg(originStmt);
System.err.println("parse failed: " + errorMessage);
@ -94,6 +95,30 @@ public class UtFrameUtils {
return statementBase;
}
// for analyzing multi statements
public static List<StatementBase> parseAndAnalyzeStmts(String originStmt, ConnectContext ctx) throws Exception {
System.out.println("begin to parse stmts: " + originStmt);
SqlScanner input = new SqlScanner(new StringReader(originStmt), ctx.getSessionVariable().getSqlMode());
SqlParser parser = new SqlParser(input);
Analyzer analyzer = new Analyzer(ctx.getCatalog(), ctx);
List<StatementBase> statementBases = null;
try {
statementBases = SqlParserUtils.getMultiStmts(parser);
} catch (AnalysisException e) {
String errorMessage = parser.getErrorMsg(originStmt);
System.err.println("parse failed: " + errorMessage);
if (errorMessage == null) {
throw e;
} else {
throw new AnalysisException(errorMessage, e);
}
}
for (StatementBase stmt : statementBases) {
stmt.analyze(analyzer);
}
return statementBases;
}
public static int startFEServer(String runningDir) throws EnvVarNotSetException, IOException,
FeStartException, NotInitException, DdlException, InterruptedException {
// get DORIS_HOME