mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
refactor && enhance mysql sql parser support
This commit is contained in:
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
*
|
||||
* @author WENSHAO
|
||||
*/
|
||||
public class SQLBitStringLiteralExpr extends SQLLiteralExpr {
|
||||
public class SQLBitStringLiteralExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLDateLiteralExpr extends SQLLiteralExpr {
|
||||
public class SQLDateLiteralExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLDefaultExpr extends SQLLiteralExpr {
|
||||
public class SQLDefaultExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.util.HexBin;
|
||||
import com.alibaba.druid.util.IOUtils;
|
||||
|
||||
public class SQLHexExpr extends SQLLiteralExpr {
|
||||
public class SQLHexExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -76,4 +79,8 @@ public class SQLHexExpr extends SQLLiteralExpr {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public byte[] toBytes() {
|
||||
return HexBin.decode(this.hex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLHexStringLiteralExpr extends SQLLiteralExpr {
|
||||
public class SQLHexStringLiteralExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
/**
|
||||
@@ -22,7 +23,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
*
|
||||
* @author WENSHAO
|
||||
*/
|
||||
public class SQLIntervalLiteralExpr extends SQLLiteralExpr {
|
||||
public class SQLIntervalLiteralExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -15,14 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
|
||||
public abstract class SQLLiteralExpr extends SQLExprImpl {
|
||||
public interface SQLLiteralExpr extends SQLExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SQLLiteralExpr(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLNullExpr extends SQLLiteralExpr {
|
||||
public class SQLNullExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
public abstract class SQLNumericLiteralExpr extends SQLLiteralExpr {
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
|
||||
public abstract class SQLNumericLiteralExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
public abstract class SQLTextLiteralExpr extends SQLLiteralExpr {
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
|
||||
public abstract class SQLTextLiteralExpr extends SQLExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -24,10 +24,16 @@ public class SQLVariantRefExpr extends SQLExprImpl {
|
||||
|
||||
private String name;
|
||||
|
||||
public SQLVariantRefExpr(String name){
|
||||
private boolean global = false;
|
||||
|
||||
public SQLVariantRefExpr(String name){
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SQLVariantRefExpr(String name, boolean global){
|
||||
this.name = name;
|
||||
this.global = global;
|
||||
}
|
||||
|
||||
public SQLVariantRefExpr(){
|
||||
|
||||
@@ -82,4 +88,12 @@ public class SQLVariantRefExpr extends SQLExprImpl {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return global;
|
||||
}
|
||||
|
||||
public void setGlobal(boolean global) {
|
||||
this.global = global;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class MySqlBinaryExpr extends SQLLiteralExpr implements MySqlExpr {
|
||||
public class MySqlBinaryExpr extends MySqlExprImpl implements MySqlExpr, SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class MySqlBinaryExpr extends SQLLiteralExpr implements MySqlExpr {
|
||||
this.accept0((MySqlASTVisitor) visitor);
|
||||
}
|
||||
|
||||
protected void accept0(MySqlASTVisitor visitor) {
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
||||
visitor.endVisit(this);
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class MySqlBooleanExpr extends SQLLiteralExpr implements MySqlExpr {
|
||||
public class MySqlBooleanExpr extends MySqlExprImpl implements MySqlExpr, SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -46,7 +46,7 @@ public class MySqlBooleanExpr extends SQLLiteralExpr implements MySqlExpr {
|
||||
this.accept0((MySqlASTVisitor) visitor);
|
||||
}
|
||||
|
||||
protected void accept0(MySqlASTVisitor visitor) {
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
||||
visitor.endVisit(this);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
|
||||
|
||||
public abstract class MySqlExprImpl extends MySqlObjectImpl implements SQLExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
|
||||
public class MySqlHexadecimalExpr extends MySqlExprImpl implements SQLLiteralExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
public class MySqlSetTransactionIsolationLevelStatement extends MySqlStatementImpl {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Boolean global;
|
||||
|
||||
private String level;
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public Boolean getGlobal() {
|
||||
return global;
|
||||
}
|
||||
|
||||
public void setGlobal(Boolean global) {
|
||||
this.global = global;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBinaryExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
|
||||
@@ -132,6 +133,21 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
String aliasValue = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
return primaryRest(new SQLCharExpr(aliasValue));
|
||||
case VARIANT:
|
||||
SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
if (varRefExpr.getName().equalsIgnoreCase("@@global")) {
|
||||
accept(Token.DOT);
|
||||
varRefExpr = new SQLVariantRefExpr(lexer.stringVal(), true);
|
||||
lexer.nextToken();
|
||||
} else if (varRefExpr.getName().equals("@") && lexer.token() == Token.LITERAL_CHARS) {
|
||||
varRefExpr.setName("@'" + lexer.stringVal() + "'");
|
||||
lexer.nextToken();
|
||||
} else if (varRefExpr.getName().equals("@@") && lexer.token() == Token.LITERAL_CHARS) {
|
||||
varRefExpr.setName("@@'" + lexer.stringVal() + "'");
|
||||
lexer.nextToken();
|
||||
}
|
||||
return primaryRest(varRefExpr);
|
||||
default:
|
||||
return super.primary();
|
||||
}
|
||||
@@ -496,4 +512,35 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
public SQLAssignItem parseAssignItem() {
|
||||
SQLAssignItem item = new SQLAssignItem();
|
||||
|
||||
SQLExpr var = primary();
|
||||
|
||||
if (var instanceof SQLIdentifierExpr) {
|
||||
String ident = ((SQLIdentifierExpr) var).getName();
|
||||
|
||||
if ("GLOBAL".equalsIgnoreCase(ident)) {
|
||||
ident = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
var = new SQLVariantRefExpr(ident, true);
|
||||
} else if ("SESSION".equalsIgnoreCase(ident)) {
|
||||
ident = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
var = new SQLVariantRefExpr(ident, false);
|
||||
} else {
|
||||
var = new SQLVariantRefExpr(ident);
|
||||
}
|
||||
}
|
||||
item.setTarget(var);
|
||||
if (lexer.token() == Token.COLONEQ) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
accept(Token.EQ);
|
||||
}
|
||||
item.setValue(expr());
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,6 @@ public class MySqlLexer extends Lexer {
|
||||
map.put("CAST", Token.CAST);
|
||||
map.put("IN", Token.IN);
|
||||
map.put("ASC", Token.ASC);
|
||||
map.put("DESC", Token.DESC);
|
||||
map.put("LIKE", Token.LIKE);
|
||||
map.put("ESCAPE", Token.ESCAPE);
|
||||
map.put("BETWEEN", Token.BETWEEN);
|
||||
@@ -128,6 +127,71 @@ public class MySqlLexer extends Lexer {
|
||||
super.keywods = DEFAULT_MYSQL_KEYWORDS;
|
||||
}
|
||||
|
||||
public void scanVariable() {
|
||||
final char first = ch;
|
||||
|
||||
if (ch != '@' && ch != ':' && ch != '#') {
|
||||
throw new SQLParseException("illegal variable");
|
||||
}
|
||||
|
||||
int hash = first;
|
||||
|
||||
np = bp;
|
||||
sp = 1;
|
||||
|
||||
if (buf[bp + 1] == '@') {
|
||||
ch = buf[++bp];
|
||||
hash = 31 * hash + ch;
|
||||
|
||||
sp++;
|
||||
}
|
||||
|
||||
if (buf[bp + 1] == '`') {
|
||||
++bp;
|
||||
++sp;
|
||||
char ch;
|
||||
for (;;) {
|
||||
ch = buf[++bp];
|
||||
|
||||
if (ch == '`') {
|
||||
sp++;
|
||||
ch = buf[++bp];
|
||||
break;
|
||||
} else if (ch == EOI) {
|
||||
throw new SQLParseException("illegal identifier");
|
||||
}
|
||||
|
||||
hash = 31 * hash + ch;
|
||||
|
||||
sp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.ch = buf[bp];
|
||||
|
||||
stringVal = symbolTable.addSymbol(buf, np, sp, hash);
|
||||
token = Token.VARIANT;
|
||||
} else {
|
||||
for (;;) {
|
||||
ch = buf[++bp];
|
||||
|
||||
if (!isIdentifierChar(ch)) {
|
||||
break;
|
||||
}
|
||||
|
||||
hash = 31 * hash + ch;
|
||||
|
||||
sp++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
this.ch = buf[bp];
|
||||
|
||||
stringVal = symbolTable.addSymbol(buf, np, sp, hash);
|
||||
token = Token.VARIANT;
|
||||
}
|
||||
|
||||
public void scanIdentifier() {
|
||||
final char first = ch;
|
||||
|
||||
|
||||
+90
-15
@@ -25,10 +25,12 @@ import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
@@ -50,6 +52,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplicateStatement
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement;
|
||||
@@ -84,11 +87,11 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
public SQLSelectStatement parseSelect() throws ParserException {
|
||||
return new SQLSelectStatement(new MySqlSelectParser(lexer).select());
|
||||
}
|
||||
|
||||
|
||||
public SQLUpdateStatement parseUpdateStatement() throws ParserException {
|
||||
MySqlUpdateStatement stmt = (MySqlUpdateStatement) super.parseUpdateStatement();
|
||||
|
||||
if (lexer.token() == Token.LIMIT) {
|
||||
MySqlUpdateStatement stmt = (MySqlUpdateStatement) super.parseUpdateStatement();
|
||||
|
||||
if (lexer.token() == Token.LIMIT) {
|
||||
lexer.nextToken();
|
||||
|
||||
MySqlSelectQueryBlock.Limit limit = new MySqlSelectQueryBlock.Limit();
|
||||
@@ -105,16 +108,16 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
} else {
|
||||
limit.setRowCount(temp);
|
||||
}
|
||||
|
||||
|
||||
stmt.setLimit(limit);
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
protected MySqlUpdateStatement createUpdateStatement() {
|
||||
return new MySqlUpdateStatement();
|
||||
}
|
||||
|
||||
protected MySqlUpdateStatement createUpdateStatement() {
|
||||
return new MySqlUpdateStatement();
|
||||
}
|
||||
|
||||
public MySqlDeleteStatement parseDeleteStatement() throws ParserException {
|
||||
MySqlDeleteStatement deleteStatement = new MySqlDeleteStatement();
|
||||
@@ -375,7 +378,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (identifierEquals("DESCRIBE")) {
|
||||
if (identifierEquals("DESC") || identifierEquals("DESCRIBE")) {
|
||||
SQLStatement stmt = parseDescribe();
|
||||
statementList.add(stmt);
|
||||
return true;
|
||||
@@ -384,8 +387,12 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
return false;
|
||||
}
|
||||
|
||||
public SQLStatement parseDescribe() throws ParserException {
|
||||
acceptIdentifier("DESCRIBE");
|
||||
public MySqlDescribeStatement parseDescribe() throws ParserException {
|
||||
if (identifierEquals("DESC") || identifierEquals("DESCRIBE")) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
throw new ParserException("expect DESC, actual " + lexer.token());
|
||||
}
|
||||
|
||||
MySqlDescribeStatement stmt = new MySqlDescribeStatement();
|
||||
stmt.setObject(this.exprParser.name());
|
||||
@@ -1067,4 +1074,72 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
public SQLSelectParser createSQLSelectParser() {
|
||||
return new MySqlSelectParser(this.lexer);
|
||||
}
|
||||
|
||||
public SQLStatement parseSet() throws ParserException {
|
||||
accept(Token.SET);
|
||||
|
||||
Boolean global = null;
|
||||
if (identifierEquals("GLOBAL")) {
|
||||
global = Boolean.TRUE;
|
||||
lexer.nextToken();
|
||||
} else if (identifierEquals("SESSION")) {
|
||||
global = Boolean.FALSE;
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (identifierEquals("TRANSACTION")) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("ISOLATION");
|
||||
acceptIdentifier("LEVEL");
|
||||
|
||||
MySqlSetTransactionIsolationLevelStatement stmt = new MySqlSetTransactionIsolationLevelStatement();
|
||||
stmt.setGlobal(global);
|
||||
|
||||
if (identifierEquals("READ")) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (identifierEquals("UNCOMMITTED")) {
|
||||
stmt.setLevel("READ UNCOMMITTED");
|
||||
lexer.nextToken();
|
||||
} else if (identifierEquals("WRITE")) {
|
||||
stmt.setLevel("READ WRITE");
|
||||
lexer.nextToken();
|
||||
} else if (identifierEquals("ONLY")) {
|
||||
stmt.setLevel("READ ONLY");
|
||||
lexer.nextToken();
|
||||
} else if (identifierEquals("COMMITTED")) {
|
||||
stmt.setLevel("READ COMMITTED");
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal());
|
||||
}
|
||||
} else if (identifierEquals("SERIALIZABLE")) {
|
||||
stmt.setLevel("SERIALIZABLE");
|
||||
lexer.nextToken();
|
||||
} else if (identifierEquals("REPEATABLE")) {
|
||||
lexer.nextToken();
|
||||
if (identifierEquals("READ")) {
|
||||
stmt.setLevel("REPEATABLE READ");
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal());
|
||||
}
|
||||
} else {
|
||||
throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal());
|
||||
}
|
||||
|
||||
return stmt;
|
||||
} else {
|
||||
SQLSetStatement stmt = new SQLSetStatement();
|
||||
|
||||
parseAssignItems(stmt.getItems());
|
||||
|
||||
if (global != null && global.booleanValue()) {
|
||||
SQLVariantRefExpr varRef = (SQLVariantRefExpr) stmt.getItems().get(0).getTarget();
|
||||
varRef.setGlobal(true);
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement;
|
||||
@@ -206,4 +207,8 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(MySqlUpdateStatement x);
|
||||
|
||||
void endVisit(MySqlUpdateStatement x);
|
||||
|
||||
boolean visit(MySqlSetTransactionIsolationLevelStatement x);
|
||||
|
||||
void endVisit(MySqlSetTransactionIsolationLevelStatement x);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement;
|
||||
@@ -444,4 +445,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlSetTransactionIsolationLevelStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlSetTransactionIsolationLevelStatement x) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSQLColumnDefinitio
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement;
|
||||
@@ -100,7 +101,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
if (x.getOrderBy() != null) {
|
||||
x.getOrderBy().setParent(x);
|
||||
}
|
||||
|
||||
|
||||
print("SELECT ");
|
||||
|
||||
if (SQLSetQuantifier.ALL == x.getDistionOption()) print("ALL ");
|
||||
@@ -425,7 +426,30 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
|
||||
public boolean visit(SQLVariantRefExpr x) {
|
||||
print(x.getName());
|
||||
if (x.isGlobal()) {
|
||||
print("@@global.");
|
||||
} else {
|
||||
if ((!x.getName().startsWith("@")) && (!x.getName().equals("?"))) {
|
||||
print("@@");
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < x.getName().length(); ++i) {
|
||||
char ch = x.getName().charAt(i);
|
||||
if (ch == '\'') {
|
||||
if (x.getName().startsWith("@@") && i == 2) {
|
||||
print(ch);
|
||||
} else if (x.getName().startsWith("@") && i == 1) {
|
||||
print(ch);
|
||||
} else if (i != 0 && i != x.getName().length() - 1) {
|
||||
print("\\'");
|
||||
} else {
|
||||
print(ch);
|
||||
}
|
||||
} else {
|
||||
print(ch);
|
||||
}
|
||||
}
|
||||
|
||||
String collate = (String) x.getAttribute("COLLATE");
|
||||
if (collate != null) {
|
||||
@@ -1250,12 +1274,12 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
@Override
|
||||
public boolean visit(UserSpecification x) {
|
||||
x.getUser().accept(this);
|
||||
|
||||
|
||||
if (x.getPassword() != null) {
|
||||
print(" IDENTIFIED BY ");
|
||||
x.getPassword().accept(this);
|
||||
}
|
||||
|
||||
|
||||
if (x.getAuthPlugin() != null) {
|
||||
print(" IDENTIFIED WITH ");
|
||||
x.getAuthPlugin().accept(this);
|
||||
@@ -1265,7 +1289,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlDropUser x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1277,7 +1301,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlDropTableStatement x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1286,14 +1310,14 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
if (x.isIfExists()) {
|
||||
print("IF EXISTS ");
|
||||
}
|
||||
|
||||
|
||||
printAndAccept(x.getTableSources(), ", ");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlPartitionByKey x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1301,7 +1325,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
print("PARTITION BY KEY (");
|
||||
printAndAccept(x.getColumns(), ", ");
|
||||
print(")");
|
||||
|
||||
|
||||
if (x.getPartitionCount() != null) {
|
||||
print(" PARTITIONS ");
|
||||
x.getPartitionCount().accept(this);
|
||||
@@ -1311,21 +1335,20 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlSelectQueryBlock x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlOutFileExpr x) {
|
||||
print("OUTFILE ");
|
||||
x.getFile().accept(this);
|
||||
|
||||
|
||||
if (x.getCharset() != null) {
|
||||
print(" CHARACTER SET ");
|
||||
print(x.getCharset());
|
||||
}
|
||||
|
||||
if (x.getColumnsTerminatedBy() != null || x.getColumnsEnclosedBy() != null
|
||||
|| x.getColumnsEscaped() != null) {
|
||||
if (x.getColumnsTerminatedBy() != null || x.getColumnsEnclosedBy() != null || x.getColumnsEscaped() != null) {
|
||||
print(" COLUMNS");
|
||||
if (x.getColumnsTerminatedBy() != null) {
|
||||
print(" TERMINATED BY ");
|
||||
@@ -1358,39 +1381,56 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
x.getLinesTerminatedBy().accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlOutFileExpr x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlDescribeStatement x) {
|
||||
print("DESCRIBE ");
|
||||
print("DESC ");
|
||||
x.getObject().accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlDescribeStatement x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlUpdateStatement x) {
|
||||
super.visit((SQLUpdateStatement) x);
|
||||
if (x.getLimit() != null) {
|
||||
println();
|
||||
x.getLimit().accept(this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean visit(MySqlUpdateStatement x) {
|
||||
super.visit((SQLUpdateStatement) x);
|
||||
if (x.getLimit() != null) {
|
||||
println();
|
||||
x.getLimit().accept(this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlUpdateStatement x) {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void endVisit(MySqlUpdateStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlSetTransactionIsolationLevelStatement x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlSetTransactionIsolationLevelStatement x) {
|
||||
if (x.getGlobal() == null) {
|
||||
print("SET TRANSACTION ISOLATION LEVEL ");
|
||||
} else if (x.getGlobal().booleanValue()) {
|
||||
print("SET GLOBAL TRANSACTION ISOLATION LEVEL ");
|
||||
} else {
|
||||
print("SET SESSION TRANSACTION ISOLATION LEVEL ");
|
||||
}
|
||||
print(x.getLevel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement;
|
||||
@@ -505,4 +506,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
|
||||
public void endVisit(MySqlUpdateStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlSetTransactionIsolationLevelStatement x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlSetTransactionIsolationLevelStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleDateExpr extends SQLLiteralExpr implements OracleExpr {
|
||||
public class OracleDateExpr extends SQLExprImpl implements SQLLiteralExpr, OracleExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleIntervalExpr extends SQLLiteralExpr implements OracleExpr {
|
||||
public class OracleIntervalExpr extends SQLExprImpl implements SQLLiteralExpr, OracleExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private SQLExpr value;
|
||||
|
||||
+2
-1
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleTimestampExpr extends SQLLiteralExpr implements OracleExpr {
|
||||
public class OracleTimestampExpr extends SQLExprImpl implements SQLLiteralExpr, OracleExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String literal;
|
||||
|
||||
@@ -55,6 +55,7 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.NotNullConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCharactorDataType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
|
||||
@@ -195,8 +196,16 @@ public class SQLExprParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
break;
|
||||
case VARIANT:
|
||||
sqlExpr = new SQLVariantRefExpr(lexer.stringVal());
|
||||
SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
if (varRefExpr.getName().equals("@") && lexer.token() == Token.LITERAL_CHARS) {
|
||||
varRefExpr.setName("@'" + lexer.stringVal() + "'");
|
||||
lexer.nextToken();
|
||||
} else if (varRefExpr.getName().equals("@@") && lexer.token() == Token.LITERAL_CHARS) {
|
||||
varRefExpr.setName("@@'" + lexer.stringVal() + "'");
|
||||
lexer.nextToken();
|
||||
}
|
||||
sqlExpr = varRefExpr;
|
||||
break;
|
||||
case DEFAULT:
|
||||
sqlExpr = new SQLDefaultExpr();
|
||||
@@ -473,10 +482,6 @@ public class SQLExprParser extends SQLParser {
|
||||
|
||||
expr = dotRest(expr);
|
||||
return primaryRest(expr);
|
||||
} else if (lexer.token() == Token.COLONEQ) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp);
|
||||
} else {
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
return methodRest(expr, true);
|
||||
@@ -779,6 +784,10 @@ public class SQLExprParser extends SQLParser {
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp);
|
||||
} else if (lexer.token() == Token.COLONEQ) {
|
||||
lexer.nextToken();
|
||||
rightExp = expr();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp);
|
||||
}
|
||||
|
||||
return expr;
|
||||
@@ -920,40 +929,40 @@ public class SQLExprParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThan, rightExp);
|
||||
// expr = relationalRest(expr);
|
||||
// expr = relationalRest(expr);
|
||||
} else if (lexer.token() == Token.LTEQ) {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
|
||||
// rightExp = relationalRest(rightExp);
|
||||
// rightExp = relationalRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqual, rightExp);
|
||||
} else if (lexer.token() == Token.LTEQGT) {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
|
||||
// rightExp = relationalRest(rightExp);
|
||||
// rightExp = relationalRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqualOrGreaterThan, rightExp);
|
||||
} else if (lexer.token() == Token.GT) {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
|
||||
// rightExp = relationalRest(rightExp);
|
||||
// rightExp = relationalRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThan, rightExp);
|
||||
} else if (lexer.token() == Token.GTEQ) {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
|
||||
// rightExp = relationalRest(rightExp);
|
||||
// rightExp = relationalRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThanOrEqual, rightExp);
|
||||
} else if (lexer.token() == Token.BANGLT) {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
|
||||
// rightExp = relationalRest(rightExp);
|
||||
// rightExp = relationalRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLessThan, rightExp);
|
||||
} else if (lexer.token() == Token.BANGGT) {
|
||||
@@ -967,14 +976,14 @@ public class SQLExprParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
|
||||
// rightExp = relationalRest(rightExp);
|
||||
// rightExp = relationalRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrGreater, rightExp);
|
||||
} else if (lexer.token() == Token.LIKE) {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
|
||||
// rightExp = relationalRest(rightExp);
|
||||
// rightExp = relationalRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Like, rightExp);
|
||||
|
||||
@@ -1168,4 +1177,23 @@ public class SQLExprParser extends SQLParser {
|
||||
public SQLPrimaryKey parsePrimaryKey() {
|
||||
throw new ParserException("TODO");
|
||||
}
|
||||
|
||||
public SQLAssignItem parseAssignItem() {
|
||||
SQLAssignItem item = new SQLAssignItem();
|
||||
|
||||
SQLExpr var = primary();
|
||||
|
||||
if (var instanceof SQLIdentifierExpr) {
|
||||
var = new SQLVariantRefExpr(((SQLIdentifierExpr) var).getName());
|
||||
}
|
||||
item.setTarget(var);
|
||||
if (lexer.token() == Token.COLONEQ) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
accept(Token.EQ);
|
||||
}
|
||||
item.setValue(expr());
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,13 @@ public class SQLParser {
|
||||
}
|
||||
}
|
||||
|
||||
public void match(Token token) {
|
||||
if (lexer.token() != token) {
|
||||
throw new SQLParseException("syntax error, expect " + token + ", actual " + lexer.token() + " "
|
||||
+ lexer.stringVal());
|
||||
}
|
||||
}
|
||||
|
||||
private int errorEndPos = -1;
|
||||
|
||||
protected void setErrorEndPos(int errPos) {
|
||||
@@ -131,4 +138,5 @@ public class SQLParser {
|
||||
errorEndPos = errPos;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -294,11 +294,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
|
||||
public void parseAssignItems(List<SQLAssignItem> items) {
|
||||
for (;;) {
|
||||
SQLAssignItem item = new SQLAssignItem();
|
||||
item.setTarget(exprParser.primary());
|
||||
accept(Token.EQ);
|
||||
item.setValue(exprParser.expr());
|
||||
|
||||
SQLAssignItem item = exprParser.parseAssignItem();
|
||||
items.add(item);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
@@ -310,6 +306,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SQLStatement parseCreate() throws ParserException {
|
||||
char mark_ch = lexer.current();
|
||||
int mark_bp = lexer.bp();
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 1999-2002,2004 The Apache Software Foundation.
|
||||
*
|
||||
* 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.util;
|
||||
|
||||
|
||||
/**
|
||||
* format validation
|
||||
*
|
||||
* This class encodes/decodes hexadecimal data
|
||||
*
|
||||
* @xerces.internal
|
||||
*
|
||||
* @author Jeffrey Rodriguez
|
||||
* @version $Id: HexBin.java,v 1.4 2007/07/19 04:38:32 ofung Exp $
|
||||
*/
|
||||
public final class HexBin {
|
||||
static private final int BASELENGTH = 128;
|
||||
static private final int LOOKUPLENGTH = 16;
|
||||
static final private byte [] hexNumberTable = new byte[BASELENGTH];
|
||||
static final private char [] lookUpHexAlphabet = new char[LOOKUPLENGTH];
|
||||
|
||||
|
||||
static {
|
||||
for (int i = 0; i < BASELENGTH; i++ ) {
|
||||
hexNumberTable[i] = -1;
|
||||
}
|
||||
for ( int i = '9'; i >= '0'; i--) {
|
||||
hexNumberTable[i] = (byte) (i-'0');
|
||||
}
|
||||
for ( int i = 'F'; i>= 'A'; i--) {
|
||||
hexNumberTable[i] = (byte) ( i-'A' + 10 );
|
||||
}
|
||||
for ( int i = 'f'; i>= 'a'; i--) {
|
||||
hexNumberTable[i] = (byte) ( i-'a' + 10 );
|
||||
}
|
||||
|
||||
for(int i = 0; i<10; i++ ) {
|
||||
lookUpHexAlphabet[i] = (char)('0'+i);
|
||||
}
|
||||
for(int i = 10; i<=15; i++ ) {
|
||||
lookUpHexAlphabet[i] = (char)('A'+i -10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a byte array to hex string
|
||||
*
|
||||
* @param binaryData array of byte to encode
|
||||
* @return return encoded string
|
||||
*/
|
||||
static public String encode(byte[] binaryData) {
|
||||
if (binaryData == null)
|
||||
return null;
|
||||
int lengthData = binaryData.length;
|
||||
int lengthEncode = lengthData * 2;
|
||||
char[] encodedData = new char[lengthEncode];
|
||||
int temp;
|
||||
for (int i = 0; i < lengthData; i++) {
|
||||
temp = binaryData[i];
|
||||
if (temp < 0)
|
||||
temp += 256;
|
||||
encodedData[i*2] = lookUpHexAlphabet[temp >> 4];
|
||||
encodedData[i*2+1] = lookUpHexAlphabet[temp & 0xf];
|
||||
}
|
||||
return new String(encodedData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode hex string to a byte array
|
||||
*
|
||||
* @param encoded encoded string
|
||||
* @return return array of byte to encode
|
||||
*/
|
||||
static public byte[] decode(String encoded) {
|
||||
if (encoded == null)
|
||||
return null;
|
||||
int lengthData = encoded.length();
|
||||
if (lengthData % 2 != 0)
|
||||
return null;
|
||||
|
||||
char[] binaryData = encoded.toCharArray();
|
||||
int lengthDecode = lengthData / 2;
|
||||
byte[] decodedData = new byte[lengthDecode];
|
||||
byte temp1, temp2;
|
||||
char tempChar;
|
||||
for( int i = 0; i<lengthDecode; i++ ){
|
||||
tempChar = binaryData[i*2];
|
||||
temp1 = (tempChar < BASELENGTH) ? hexNumberTable[tempChar] : -1;
|
||||
if (temp1 == -1)
|
||||
return null;
|
||||
tempChar = binaryData[i*2+1];
|
||||
temp2 = (tempChar < BASELENGTH) ? hexNumberTable[tempChar] : -1;
|
||||
if (temp2 == -1)
|
||||
return null;
|
||||
decodedData[i] = (byte)((temp1 << 4) | temp2);
|
||||
}
|
||||
return decodedData;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* (created at 2011-11-11)
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.cobar;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.sql.ast.expr.SQLHexExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlExprParser;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:shuo.qius@alibaba-inc.com">QIU Shuo</a>
|
||||
*/
|
||||
public class LiteralHexadecimalTest extends TestCase {
|
||||
public void test_0() throws Exception {
|
||||
String sql = "x'E982B1E7A195275C73'";
|
||||
SQLHexExpr hex = (SQLHexExpr) new MySqlExprParser(sql).expr();
|
||||
Assert.assertEquals("邱硕'\\s", new String(hex.toBytes(), "utf-8"));
|
||||
}
|
||||
|
||||
public void test_1() throws Exception {
|
||||
String sql = "x'0D0A'";
|
||||
SQLHexExpr hex = (SQLHexExpr) new MySqlExprParser(sql).expr();
|
||||
Assert.assertEquals("\r\n", new String(hex.toBytes(), "utf-8"));
|
||||
}
|
||||
|
||||
public void test_2() throws Exception {
|
||||
String sql = "X'4D7953514C'";
|
||||
SQLHexExpr hex = (SQLHexExpr) new MySqlExprParser(sql).expr();
|
||||
Assert.assertEquals("MySQL", new String(hex.toBytes(), "utf-8"));
|
||||
}
|
||||
|
||||
public void test_3() throws Exception {
|
||||
String sql = "0x5061756c";
|
||||
SQLHexExpr hex = (SQLHexExpr) new MySqlExprParser(sql).expr();
|
||||
Assert.assertEquals("Paul", new String(hex.toBytes(), "utf-8"));
|
||||
}
|
||||
|
||||
public void test_4() throws Exception {
|
||||
String sql = "0x41";
|
||||
SQLHexExpr hex = (SQLHexExpr) new MySqlExprParser(sql).expr();
|
||||
Assert.assertEquals("A", new String(hex.toBytes(), "utf-8"));
|
||||
}
|
||||
|
||||
public void test_5() throws Exception {
|
||||
String sql = "0x636174";
|
||||
SQLHexExpr hex = (SQLHexExpr) new MySqlExprParser(sql).expr();
|
||||
Assert.assertEquals("cat", new String(hex.toBytes(), "utf-8"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user