mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
fix #4812
This commit is contained in:
+18
-25
@@ -1752,8 +1752,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
if (lexer.token() == Token.IDENTIFIER) {
|
||||
String label = lexer.stringVal();
|
||||
char ch = lexer.current();
|
||||
int bp = lexer.bp();
|
||||
Lexer.SavePoint savePoint = lexer.markOut();
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.VARIANT && lexer.stringVal().equals(":")) {
|
||||
lexer.nextToken();
|
||||
@@ -1773,7 +1772,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
lexer.reset(bp, ch, Token.IDENTIFIER);
|
||||
lexer.reset(savePoint);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7909,26 +7908,24 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
if (dbType != DbType.mysql) {
|
||||
while (lexer.token() == Token.COMMA) {
|
||||
char markChar = lexer.current();
|
||||
int markBp = lexer.bp();
|
||||
|
||||
Lexer.SavePoint savePoint = lexer.markOut();
|
||||
lexer.nextToken();
|
||||
if (lexer.identifierEquals(FnvHash.Constants.CHANGE)
|
||||
|| lexer.identifierEquals(FnvHash.Constants.MODIFY)) {
|
||||
lexer.reset(markBp, markChar, Token.COMMA);
|
||||
lexer.reset(savePoint);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.IDENTIFIER) {
|
||||
if ("ADD".equalsIgnoreCase(lexer.stringVal())) {
|
||||
lexer.reset(markBp, markChar, Token.COMMA);
|
||||
lexer.reset(savePoint);
|
||||
break;
|
||||
}
|
||||
name = exprParser.name();
|
||||
name.setParent(item);
|
||||
item.addColumn(name);
|
||||
} else {
|
||||
lexer.reset(markBp, markChar, Token.COMMA);
|
||||
lexer.reset(savePoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -8718,12 +8715,11 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
// select
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
char ch = lexer.current();
|
||||
int bp = lexer.bp();
|
||||
Lexer.SavePoint savePoint = lexer.markOut();
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.SELECT) {
|
||||
lexer.reset(bp, ch, Token.LPAREN);
|
||||
lexer.reset(savePoint);
|
||||
statementList.add(this.parseSelect());
|
||||
continue;
|
||||
} else {
|
||||
@@ -8811,8 +8807,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
if (lexer.token() == Token.IDENTIFIER) {
|
||||
String label = lexer.stringVal();
|
||||
char ch = lexer.current();
|
||||
int bp = lexer.bp();
|
||||
Lexer.SavePoint savePoint = lexer.markOut();
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.VARIANT && lexer.stringVal().equals(":")) {
|
||||
lexer.nextToken();
|
||||
@@ -8831,7 +8826,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
lexer.reset(bp, ch, Token.IDENTIFIER);
|
||||
lexer.reset(savePoint);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9040,30 +9035,29 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
* parse declare statement
|
||||
*/
|
||||
public SQLStatement parseDeclare() {
|
||||
char markChar = lexer.current();
|
||||
int markBp = lexer.bp();
|
||||
Lexer.SavePoint savePoint = lexer.markOut();
|
||||
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.CONTINUE) {
|
||||
lexer.reset(markBp, markChar, Token.DECLARE);
|
||||
lexer.reset(savePoint);
|
||||
return this.parseDeclareHandler();
|
||||
}
|
||||
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.CURSOR) {
|
||||
lexer.reset(markBp, markChar, Token.DECLARE);
|
||||
lexer.reset(savePoint);
|
||||
return this.parseCursorDeclare();
|
||||
} else if (lexer.identifierEquals("HANDLER")) {
|
||||
//DECLARE异常处理程序 [add by zhujun 2016-04-16]
|
||||
lexer.reset(markBp, markChar, Token.DECLARE);
|
||||
lexer.reset(savePoint);
|
||||
return this.parseDeclareHandler();
|
||||
} else if (lexer.token() == Token.CONDITION) {
|
||||
//DECLARE异常 [add by zhujun 2016-04-17]
|
||||
lexer.reset(markBp, markChar, Token.DECLARE);
|
||||
lexer.reset(savePoint);
|
||||
return this.parseDeclareCondition();
|
||||
} else {
|
||||
lexer.reset(markBp, markChar, Token.DECLARE);
|
||||
lexer.reset(savePoint);
|
||||
}
|
||||
|
||||
MySqlDeclareStatement stmt = new MySqlDeclareStatement();
|
||||
@@ -9274,12 +9268,11 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
// select
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
char ch = lexer.current();
|
||||
int bp = lexer.bp();
|
||||
Lexer.SavePoint savePoint = lexer.markOut();
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.SELECT) {
|
||||
lexer.reset(bp, ch, Token.LPAREN);
|
||||
lexer.reset(savePoint);
|
||||
return this.parseSelect();
|
||||
} else {
|
||||
throw new ParserException("TODO. " + lexer.info());
|
||||
|
||||
@@ -178,6 +178,7 @@ public class Lexer {
|
||||
|
||||
public static class SavePoint {
|
||||
int bp;
|
||||
int startPos;
|
||||
int sp;
|
||||
int np;
|
||||
char ch;
|
||||
@@ -191,7 +192,13 @@ public class Lexer {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
//出现多次调用mark()后调用reset()会有问题
|
||||
@Deprecated
|
||||
public SavePoint mark() {
|
||||
return this.savePoint = markOut();
|
||||
}
|
||||
|
||||
public SavePoint markOut() {
|
||||
SavePoint savePoint = new SavePoint();
|
||||
savePoint.bp = pos;
|
||||
savePoint.sp = bufPos;
|
||||
@@ -201,9 +208,11 @@ public class Lexer {
|
||||
savePoint.stringVal = stringVal;
|
||||
savePoint.hash = hash;
|
||||
savePoint.hash_lower = hash_lower;
|
||||
return this.savePoint = savePoint;
|
||||
savePoint.startPos = startPos;
|
||||
return savePoint;
|
||||
}
|
||||
|
||||
|
||||
public void reset(SavePoint savePoint) {
|
||||
this.pos = savePoint.bp;
|
||||
this.bufPos = savePoint.sp;
|
||||
@@ -213,8 +222,10 @@ public class Lexer {
|
||||
this.stringVal = savePoint.stringVal;
|
||||
this.hash = savePoint.hash;
|
||||
this.hash_lower = savePoint.hash_lower;
|
||||
this.startPos = savePoint.startPos;
|
||||
}
|
||||
|
||||
//出现多次调用mark()后调用reset()会有问题
|
||||
@Deprecated
|
||||
public void reset() {
|
||||
this.reset(this.savePoint);
|
||||
}
|
||||
@@ -3123,6 +3134,8 @@ public class Lexer {
|
||||
return this.ch;
|
||||
}
|
||||
|
||||
//todo fix reset reset字段会导致lexer的游标不对齐 不建议使用
|
||||
@Deprecated
|
||||
public void reset(int mark, char markChar, Token token) {
|
||||
this.pos = mark;
|
||||
this.ch = markChar;
|
||||
|
||||
@@ -87,6 +87,7 @@ public class SQLSelectListCache {
|
||||
queryBlock.setCachedSelectList(entry.printSql, entry.printSqlHash);
|
||||
|
||||
int len = pos + block.length();
|
||||
//todo fix reset
|
||||
lexer.reset(len, text.charAt(len), Token.FROM);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -570,8 +570,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
char markChar = lexer.current();
|
||||
int markBp = lexer.bp();
|
||||
Lexer.SavePoint savePoint = lexer.markOut();
|
||||
|
||||
int parenCount = 0;
|
||||
do {
|
||||
@@ -585,7 +584,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
|
||||
if (lexer.token == Token.SELECT) {
|
||||
lexer.reset(markBp, markChar, Token.LPAREN);
|
||||
lexer.reset(savePoint);
|
||||
SQLStatement stmt = parseSelect();
|
||||
statementList.add(stmt);
|
||||
continue;
|
||||
|
||||
@@ -15,7 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SQLLexerTest2 extends TestCase {
|
||||
|
||||
@@ -67,5 +72,24 @@ public class SQLLexerTest2 extends TestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void test_lexer_error_info(){
|
||||
String line1 ="SELECT *";
|
||||
String line2 ="FORM a";
|
||||
String sql = line1 + "\n"+line2;
|
||||
MySqlStatementParser parser=new MySqlStatementParser(sql);
|
||||
Exception exception = null;
|
||||
try {
|
||||
parser.parseStatementList();
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
assert exception != null;
|
||||
Assert.assertEquals("not supported.pos 13, line 2, column 2, token IDENTIFIER FORM", exception.getMessage());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user