mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve sqlparser
This commit is contained in:
@@ -534,4 +534,87 @@ public class MySqlLexer extends Lexer {
|
||||
private boolean isIdentifierChar(char c) {
|
||||
return c != '#' && CharTypes.isIdentifierChar(c);
|
||||
}
|
||||
|
||||
public void scanNumber() {
|
||||
mark = pos;
|
||||
|
||||
if (ch == '-') {
|
||||
bufPos++;
|
||||
ch = charAt(++pos);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
bufPos++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
ch = charAt(++pos);
|
||||
}
|
||||
|
||||
boolean isDouble = false;
|
||||
|
||||
if (ch == '.') {
|
||||
if (charAt(pos + 1) == '.') {
|
||||
token = Token.LITERAL_INT;
|
||||
return;
|
||||
}
|
||||
bufPos++;
|
||||
ch = charAt(++pos);
|
||||
isDouble = true;
|
||||
|
||||
for (;;) {
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
bufPos++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
ch = charAt(++pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (ch == 'e' || ch == 'E') {
|
||||
bufPos++;
|
||||
ch = charAt(++pos);
|
||||
|
||||
if (ch == '+' || ch == '-') {
|
||||
bufPos++;
|
||||
ch = charAt(++pos);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
bufPos++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
ch = charAt(++pos);
|
||||
}
|
||||
|
||||
isDouble = true;
|
||||
}
|
||||
|
||||
if (isDouble) {
|
||||
token = Token.LITERAL_FLOAT;
|
||||
} else {
|
||||
if (isFirstIdentifierChar(ch) && !(ch == 'b' && bufPos == 1 && charAt(pos - 1) == '0')) {
|
||||
bufPos++;
|
||||
for (;;) {
|
||||
ch = charAt(++pos);
|
||||
|
||||
if (!isIdentifierChar(ch)) {
|
||||
break;
|
||||
}
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
stringVal = addSymbol();
|
||||
token = Token.IDENTIFIER;
|
||||
} else {
|
||||
token = Token.LITERAL_INT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ public class Lexer {
|
||||
return;
|
||||
case '.':
|
||||
scanChar();
|
||||
if (isDigit(ch)) {
|
||||
if (isDigit(ch) && !isFirstIdentifierChar(charAt(pos - 2))) {
|
||||
unscan();
|
||||
scanNumber();
|
||||
return;
|
||||
|
||||
@@ -13,7 +13,7 @@ public class BigSqlTest extends TestCase {
|
||||
String sql = "SELECT c from sbtest where id=0";
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
sql += "or id=0";
|
||||
sql += " or id=0";
|
||||
}
|
||||
WallConfig config = new WallConfig();
|
||||
Assert.assertTrue(WallUtils.isValidateMySql(sql, config));
|
||||
@@ -23,7 +23,7 @@ public class BigSqlTest extends TestCase {
|
||||
String sql = "SELECT c from sbtest where id=0";
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
sql += "and id=0";
|
||||
sql += " and id=0";
|
||||
}
|
||||
WallConfig config = new WallConfig();
|
||||
Assert.assertTrue(WallUtils.isValidateMySql(sql, config));
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.mysql;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
|
||||
public class IdentifierTest extends TestCase {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "SELECT t.1c FROM tab t";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT t.1c\nFROM tab t;", text);
|
||||
}
|
||||
|
||||
public void test_1() throws Exception {
|
||||
String sql = "SELECT tid,seller_nick,jdp_response from 2df1479e96cb4ac8b57f2502b5425bb5";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT tid, seller_nick, jdp_response\nFROM 2df1479e96cb4ac8b57f2502b5425bb5;", text);
|
||||
}
|
||||
|
||||
public void test_2() throws Exception {
|
||||
String sql = "SELECT 1 ^ 1";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT 1 ^ 1;", text);
|
||||
}
|
||||
|
||||
public void test_3() throws Exception {
|
||||
String sql = "SELECT 1 ^ 0";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT 1 ^ 0;", text);
|
||||
}
|
||||
|
||||
public void test_4() throws Exception {
|
||||
String sql = "SELECT 1 << 2";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT 1 << 2;", text);
|
||||
}
|
||||
|
||||
public void test_5() throws Exception {
|
||||
String sql = "SELECT 4 >> 2";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT 4 >> 2;", text);
|
||||
}
|
||||
|
||||
public void test_6() throws Exception {
|
||||
String sql = "SELECT 5 & ~1";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT 5 & ~1;", text);
|
||||
}
|
||||
|
||||
public void test_7() throws Exception {
|
||||
String sql = "SELECT BIT_COUNT(29), BIT_COUNT(b'101010');";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT BIT_COUNT(29), BIT_COUNT(b'101010');", text);
|
||||
}
|
||||
|
||||
public void test_8() throws Exception {
|
||||
String sql = "SET @v2 = CAST(0b1000001 AS UNSIGNED), @v3 = 0b1000001+0;";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SET @v2 = CAST(b'1000001' AS UNSIGNED), @v3 = b'1000001' + 0;", text);
|
||||
}
|
||||
|
||||
public void test_9() throws Exception {
|
||||
String sql = "SELECT b+0, BIN(b+0), OCT(b+0), HEX(b+0) FROM t;";
|
||||
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
|
||||
String text = output(stmtList);
|
||||
|
||||
Assert.assertEquals("SELECT b + 0, BIN(b + 0), OCT(b + 0), HEX(b + 0)\nFROM t;", text);
|
||||
}
|
||||
|
||||
private String output(List<SQLStatement> stmtList) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
stmt.accept(new MySqlOutputVisitor(out));
|
||||
out.append(";");
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user