mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve sql parser
This commit is contained in:
@@ -19,7 +19,7 @@ public final class VERSION {
|
||||
|
||||
public final static int MajorVersion = 1;
|
||||
public final static int MinorVersion = 2;
|
||||
public final static int RevisionVersion = 9;
|
||||
public final static int RevisionVersion = 10;
|
||||
|
||||
public static String getVersionNumber() {
|
||||
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion;
|
||||
|
||||
+14
@@ -665,4 +665,18 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement
|
||||
}
|
||||
addOption("ENGINE", x);
|
||||
}
|
||||
|
||||
public void setPageChecksum(SQLExpr x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
addOption("PAGE_CHECKSUM", x);
|
||||
}
|
||||
|
||||
public void setTransactional(SQLExpr x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
addOption("TRANSACTIONAL", x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,6 +396,28 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("PAGE_CHECKSUM")) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.EQ) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
SQLExpr expr = this.exprParser.expr();
|
||||
stmt.setPageChecksum(expr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("TRANSACTIONAL")) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.EQ) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
SQLExpr expr = this.exprParser.expr();
|
||||
stmt.setTransactional(expr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.BLOCK_SIZE)) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.EQ) {
|
||||
|
||||
@@ -1686,7 +1686,15 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
|
||||
SQLPartition partitionDef = new SQLPartition();
|
||||
|
||||
partitionDef.setName(this.name());
|
||||
SQLName name;
|
||||
if (lexer.token() == Token.LITERAL_INT) {
|
||||
Number number = lexer.integerValue();
|
||||
name = new SQLIdentifierExpr(number.toString());
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
name = this.name();
|
||||
}
|
||||
partitionDef.setName(name);
|
||||
|
||||
SQLPartitionValue values = this.parsePartitionValues();
|
||||
if (values != null) {
|
||||
|
||||
@@ -527,7 +527,7 @@ public class SQLParserUtils {
|
||||
lexer.config(SQLParserFeature.SkipComments, false);
|
||||
lexer.config(SQLParserFeature.KeepComments, true);
|
||||
|
||||
boolean set = false;
|
||||
boolean set = false, paiOrJar = false;
|
||||
int start = 0;
|
||||
Token token = lexer.token;
|
||||
for (;lexer.token != Token.EOF;) {
|
||||
@@ -535,7 +535,9 @@ public class SQLParserUtils {
|
||||
int len = lexer.startPos - start;
|
||||
if (len > 0) {
|
||||
String lineSql = sql.substring(start, lexer.startPos);
|
||||
String splitSql = set ? lineSql.trim() : removeComment(lineSql, dbType
|
||||
String splitSql = set
|
||||
? removeLeftComment(lineSql, dbType)
|
||||
: removeComment(lineSql, dbType
|
||||
).trim();
|
||||
if (!splitSql.isEmpty()) {
|
||||
list.add(splitSql);
|
||||
@@ -569,6 +571,15 @@ public class SQLParserUtils {
|
||||
lexer.nextTokenForSet();
|
||||
token = lexer.token;
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("pai") || lexer.identifierEquals("jar")) {
|
||||
if (lexer.startPos - start > 0) {
|
||||
String str = sql.substring(start, lexer.startPos).trim();
|
||||
if (str.isEmpty()) {
|
||||
lexer.startPos = sql.length();
|
||||
paiOrJar = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token == Token.SET) {
|
||||
@@ -580,10 +591,14 @@ public class SQLParserUtils {
|
||||
}
|
||||
|
||||
if (start != sql.length() && token != Token.SEMI) {
|
||||
String splitSql = removeComment(
|
||||
sql.substring(start, lexer.startPos)
|
||||
, dbType
|
||||
).trim();
|
||||
String splitSql = sql.substring(start, lexer.startPos).trim();
|
||||
if (!paiOrJar) {
|
||||
splitSql = removeComment(splitSql, dbType).trim();
|
||||
} else {
|
||||
if (splitSql.endsWith(";")) {
|
||||
splitSql = splitSql.substring(0, splitSql.length() - 1).trim();
|
||||
}
|
||||
}
|
||||
if (!splitSql.isEmpty()) {
|
||||
list.add(splitSql);
|
||||
}
|
||||
@@ -592,6 +607,58 @@ public class SQLParserUtils {
|
||||
return list;
|
||||
}
|
||||
|
||||
public static String removeLeftComment(String sql, DbType dbType) {
|
||||
if (dbType == null) {
|
||||
dbType = DbType.other;
|
||||
}
|
||||
|
||||
sql = sql.trim();
|
||||
if (sql.startsWith("jar")) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
boolean containsComment = false;
|
||||
{
|
||||
Lexer lexer = createLexer(sql, dbType);
|
||||
lexer.config(SQLParserFeature.SkipComments, false);
|
||||
lexer.config(SQLParserFeature.KeepComments, true);
|
||||
|
||||
while (lexer.token != Token.EOF) {
|
||||
if (lexer.token == Token.LINE_COMMENT || lexer.token == Token.MULTI_LINE_COMMENT) {
|
||||
containsComment = true;
|
||||
break;
|
||||
}
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (!containsComment) {
|
||||
return sql;
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
Lexer lexer = createLexer(sql, dbType);
|
||||
lexer.config(SQLParserFeature.SkipComments, false);
|
||||
lexer.config(SQLParserFeature.KeepComments, true);
|
||||
lexer.nextToken();
|
||||
|
||||
int start = 0;
|
||||
for (; lexer.token != Token.EOF; lexer.nextToken()) {
|
||||
if (lexer.token == Token.LINE_COMMENT || lexer.token == Token.MULTI_LINE_COMMENT) {
|
||||
continue;
|
||||
}
|
||||
start = lexer.startPos;
|
||||
break;
|
||||
}
|
||||
|
||||
if (start != sql.length()) {
|
||||
sb.append(sql.substring(start, sql.length()));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String removeComment(String sql, DbType dbType) {
|
||||
if (dbType == null) {
|
||||
dbType = DbType.other;
|
||||
|
||||
@@ -25,4 +25,25 @@ public class PGSelectTest86
|
||||
"from xxx_point point\n" +
|
||||
"\tinner join xxx_cc cc on point.id = cc.point_id", stmt.toLowerCaseString());
|
||||
}
|
||||
|
||||
public void test_1() throws Exception {
|
||||
String sql = "select\n" +
|
||||
" COUNT(1) res\n" +
|
||||
" from TB_EXPERIENCE exp\n" +
|
||||
" where exp.creatdate>DATE_SUB(CURDATE(), interval 1 MONTH)\n" +
|
||||
" and exp.cstatus = 1";
|
||||
|
||||
final List<SQLStatement> statements = SQLUtils.parseStatements(sql, JdbcConstants.POSTGRESQL);
|
||||
assertEquals(1, statements.size());
|
||||
final SQLStatement stmt = statements.get(0);
|
||||
|
||||
assertEquals("SELECT *\n" +
|
||||
"FROM xxx_point point\n" +
|
||||
"\tINNER JOIN xxx_cc cc ON point.id = cc.point_id"
|
||||
, stmt.toString());
|
||||
|
||||
assertEquals("select *\n" +
|
||||
"from xxx_point point\n" +
|
||||
"\tinner join xxx_cc cc on point.id = cc.point_id", stmt.toLowerCaseString());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user