From fc222e6172fe4786fb2c68d21d9ef79937042e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Tue, 15 May 2012 16:30:39 +0800 Subject: [PATCH] refactor && enhance mysql sql parser support --- .../sql/ast/expr/SQLBitStringLiteralExpr.java | 3 +- .../sql/ast/expr/SQLDateLiteralExpr.java | 3 +- .../druid/sql/ast/expr/SQLDefaultExpr.java | 3 +- .../druid/sql/ast/expr/SQLHexExpr.java | 9 +- .../sql/ast/expr/SQLHexStringLiteralExpr.java | 3 +- .../sql/ast/expr/SQLIntervalLiteralExpr.java | 3 +- .../druid/sql/ast/expr/SQLLiteralExpr.java | 9 +- .../druid/sql/ast/expr/SQLNullExpr.java | 3 +- .../sql/ast/expr/SQLNumericLiteralExpr.java | 4 +- .../sql/ast/expr/SQLTextLiteralExpr.java | 4 +- .../druid/sql/ast/expr/SQLVariantRefExpr.java | 16 +- .../mysql/ast/expr/MySqlBinaryExpr.java | 4 +- .../mysql/ast/expr/MySqlBooleanExpr.java | 4 +- .../dialect/mysql/ast/expr/MySqlExprImpl.java | 10 + .../mysql/ast/expr/MySqlHexadecimalExpr.java | 16 + ...SetTransactionIsolationLevelStatement.java | 34 + .../dialect/mysql/parser/MySqlExprParser.java | 47 + .../sql/dialect/mysql/parser/MySqlLexer.java | 66 +- .../mysql/parser/MySqlStatementParser.java | 105 +- .../mysql/visitor/MySqlASTVisitor.java | 5 + .../mysql/visitor/MySqlASTVisitorAdapter.java | 11 + .../mysql/visitor/MySqlOutputVisitor.java | 100 +- .../mysql/visitor/MySqlSchemaStatVisitor.java | 11 + .../oracle/ast/expr/OracleDateExpr.java | 3 +- .../oracle/ast/expr/OracleIntervalExpr.java | 3 +- .../oracle/ast/expr/OracleTimestampExpr.java | 3 +- .../druid/sql/parser/SQLExprParser.java | 54 +- .../alibaba/druid/sql/parser/SQLParser.java | 8 + .../druid/sql/parser/SQLStatementParser.java | 7 +- .../java/com/alibaba/druid/util/HexBin.java | 112 ++ .../druid/bvt/sql/cobar/DALParserTest.java | 1034 +++++++++++++++++ .../bvt/sql/cobar/LiteralHexadecimalTest.java | 51 + 32 files changed, 1660 insertions(+), 88 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlExprImpl.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlHexadecimalExpr.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionIsolationLevelStatement.java create mode 100644 src/main/java/com/alibaba/druid/util/HexBin.java create mode 100755 src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/cobar/LiteralHexadecimalTest.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBitStringLiteralExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBitStringLiteralExpr.java index 24eba90388..4e7ecfbe0f 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBitStringLiteralExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBitStringLiteralExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLDateLiteralExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLDateLiteralExpr.java index 4c857510e8..039e352c4a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLDateLiteralExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLDateLiteralExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLDefaultExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLDefaultExpr.java index 3695dc50f8..8e8ba73aa7 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLDefaultExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLDefaultExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLHexExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLHexExpr.java index 9836b5c438..971b77a4d0 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLHexExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLHexExpr.java @@ -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); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLHexStringLiteralExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLHexStringLiteralExpr.java index 81eb5f8e1f..247b11a5fb 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLHexStringLiteralExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLHexStringLiteralExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIntervalLiteralExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIntervalLiteralExpr.java index f8af11c9bb..7e367e5637 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIntervalLiteralExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIntervalLiteralExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLLiteralExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLLiteralExpr.java index e012935ce2..c5b6a20d58 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLLiteralExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLLiteralExpr.java @@ -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(){ - - } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java index b9a8787f58..b90cb8ab47 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNumericLiteralExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNumericLiteralExpr.java index f2cc0c4c92..1024e9e032 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNumericLiteralExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNumericLiteralExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLTextLiteralExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLTextLiteralExpr.java index b9dacb3420..8b4bed1044 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLTextLiteralExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLTextLiteralExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLVariantRefExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLVariantRefExpr.java index 6d3735d922..8df34b6112 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLVariantRefExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLVariantRefExpr.java @@ -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; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlBinaryExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlBinaryExpr.java index 7563b8c65a..6b848ca81a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlBinaryExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlBinaryExpr.java @@ -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); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlBooleanExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlBooleanExpr.java index 1aaea5d4ef..654b35ec47 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlBooleanExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlBooleanExpr.java @@ -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); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlExprImpl.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlExprImpl.java new file mode 100644 index 0000000000..d9c3f4dd92 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlExprImpl.java @@ -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; + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlHexadecimalExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlHexadecimalExpr.java new file mode 100644 index 0000000000..96d8bd0370 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlHexadecimalExpr.java @@ -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) { + + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionIsolationLevelStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionIsolationLevelStatement.java new file mode 100644 index 0000000000..9b4c12bb44 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionIsolationLevelStatement.java @@ -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; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java index 588ea7e6e9..8bfc891b93 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java @@ -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; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index be1bf08bfc..ffc7ed152b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 214daa10c0..e9920766ec 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -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; + } + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java index 6bf3cdfb98..9d558d99d1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java @@ -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); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java index 7df300fe62..75338f7dda 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java @@ -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) { + + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index acb3909377..d38757500e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -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()); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index b7d20efc91..9b59630700 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -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) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDateExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDateExpr.java index 9b152f6415..caf5458bc9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDateExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDateExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleIntervalExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleIntervalExpr.java index 820c64f877..71eeed7846 100755 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleIntervalExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleIntervalExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleTimestampExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleTimestampExpr.java index f0af35f2f2..fb72dc89e3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleTimestampExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleTimestampExpr.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 240a5acd1b..3c1ee41ae7 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -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; + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java index 8cb160cfdc..6394b628c9 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -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; } } + } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index aeed53c8fe..2c15ce5c60 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -294,11 +294,7 @@ public class SQLStatementParser extends SQLParser { public void parseAssignItems(List 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(); diff --git a/src/main/java/com/alibaba/druid/util/HexBin.java b/src/main/java/com/alibaba/druid/util/HexBin.java new file mode 100644 index 0000000000..ccf3d4df27 --- /dev/null +++ b/src/main/java/com/alibaba/druid/util/HexBin.java @@ -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; iQIU Shuo + */ +public class DALParserTest extends TestCase { + + public void testdesc() throws Exception { + String sql = "desc tb1"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlDescribeStatement desc = parser.parseDescribe(); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(desc); + Assert.assertEquals("DESC tb1", output); + } + + public void testdesc_1() throws Exception { + String sql = "desc db.tb1"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlDescribeStatement desc = parser.parseDescribe(); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(desc); + Assert.assertEquals("DESC db.tb1", output); + } + + public void testSet_1() throws Exception { + String sql = "seT sysVar1 = ? "; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET @@sysVar1 = ?", output); + } + + public void testSet_2() throws Exception { + String sql = "SET `sysVar1` = ?, @@gloBal . `var2` :=1"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET @@`sysVar1` = ?, @@global.`var2` = 1", output); + } + + public void testSet_3() throws Exception { + String sql = "SET @usrVar1 := ?, @@`var2` =1, @@var3:=?, @'var\\'3'=?"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET @usrVar1 = ?, @@`var2` = 1, @@var3 = ?, @'var\\'3' = ?", output); + } + + public void testSet_4() throws Exception { + String sql = "SET GLOBAL var1=1, SESSION var2:=2"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET @@global.var1 = 1, @@var2 = 2", output); + } + + public void testSet_5() throws Exception { + String sql = "SET @@GLOBAL. var1=1, SESSION var2:=2"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET @@global.var1 = 1, @@var2 = 2", output); + } + + public void testSetTxn_0() throws Exception { + String sql = "SET transaction ISOLATION LEVEL READ UNCOMMITTED"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlSetTransactionIsolationLevelStatement set = (MySqlSetTransactionIsolationLevelStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED", output); + } + + public void testSetTxn_1() throws Exception { + String sql = "SET global transaction ISOLATION LEVEL READ COMMITTED"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlSetTransactionIsolationLevelStatement set = (MySqlSetTransactionIsolationLevelStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED", output); + } + + public void testSetTxn_2() throws Exception { + String sql = "SET transaction ISOLATION LEVEL REPEATABLE READ "; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlSetTransactionIsolationLevelStatement set = (MySqlSetTransactionIsolationLevelStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ", output); + } + + public void testSetTxn_3() throws Exception { + String sql = "SET session transaction ISOLATION LEVEL SERIALIZABLE"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlSetTransactionIsolationLevelStatement set = (MySqlSetTransactionIsolationLevelStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(set); + Assert.assertEquals("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE", output); + } + +// public void testSet() throws Exception { +// +// +// sql = "SET names default "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// set = (DALSetNamesStatement) parser.set(); +// parser.match(Token.EOF); +// output = output2MySQL(set, sql); +// Assert.assertEquals("SET NAMES DEFAULT", output); +// +// sql = "SET NAMEs 'utf8' collatE \"latin1_danish_ci\" "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// set = (DALSetNamesStatement) parser.set(); +// parser.match(Token.EOF); +// output = output2MySQL(set, sql); +// Assert.assertEquals("SET NAMES utf8 COLLATE latin1_danish_ci", output); +// +// sql = "SET NAMEs utf8 "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// set = (DALSetNamesStatement) parser.set(); +// parser.match(Token.EOF); +// output = output2MySQL(set, sql); +// Assert.assertEquals("SET NAMES utf8", output); +// +// sql = "SET CHARACTEr SEt 'utf8' "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// set = (DALSetCharacterSetStatement) parser.set(); +// parser.match(Token.EOF); +// output = output2MySQL(set, sql); +// Assert.assertEquals("SET CHARACTER SET utf8", output); +// +// sql = "SET CHARACTEr SEt DEFaULT "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// set = (DALSetCharacterSetStatement) parser.set(); +// parser.match(Token.EOF); +// output = output2MySQL(set, sql); +// Assert.assertEquals("SET CHARACTER SET DEFAULT", output); +// } +// +// public void testShow() throws Exception { +// String sql = "shoW authors "; +// SQLLexer lexer = new SQLLexer(sql); +// DALParser parser = new DALParser(lexer, new SQLExprParser(lexer)); +// DALShowStatement show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// String output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW AUTHORS", output); +// +// sql = "SHOW BINARY LOGS "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW BINARY LOGS", output); +// +// sql = "SHOW MASTER LOGS "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW BINARY LOGS", output); +// +// sql = "SHOW binlog events in 'a' from 1 limit 1,2 "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW BINLOG EVENTS IN 'a' FROM 1 LIMIT 1, 2", output); +// +// sql = "SHOW binlog events from 1 limit 1,2 "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW BINLOG EVENTS FROM 1 LIMIT 1, 2", output); +// +// sql = "SHOW binlog events "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW BINLOG EVENTS", output); +// +// sql = "SHOW CHARACTER SET like 'var' "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CHARACTER SET LIKE 'var'", output); +// +// sql = "SHOW CHARACTER SET where (select a from tb)in(a) "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CHARACTER SET WHERE (SELECT a FROM tb) IN (a)", output); +// +// sql = "SHOW CHARACTER SET "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CHARACTER SET", output); +// +// sql = "SHOW collation "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW COLLATION", output); +// +// sql = "SHOW Collation like 'var1' "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW COLLATION LIKE 'var1'", output); +// +// sql = "SHOW collation where avg((select * from (tb1,tb2)))!=100 "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW COLLATION WHERE AVG(SELECT * FROM tb1, tb2) != 100", output); +// +// sql = "SHOW full columns from tb1 from db1 like 'var' "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FULL COLUMNS FROM db1.tb1 LIKE 'var'", output); +// +// sql = "SHOW full columns from tb1 from db1 where count(col)>10 "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FULL COLUMNS FROM db1.tb1 WHERE COUNT(col) > 10", output); +// +// sql = "SHOW columns from tb1 from db1 like 'var' "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW COLUMNS FROM db1.tb1 LIKE 'var'", output); +// +// sql = "SHOW columns from tb1 like 'var' "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW COLUMNS FROM tb1 LIKE 'var'", output); +// +// sql = "SHOW full columns from tb1 from db1 "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FULL COLUMNS FROM db1.tb1", output); +// +// sql = "SHOW contributors "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CONTRIBUTORS", output); +// +// sql = "SHOW CREATE DATABASE db_name "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CREATE DATABASE db_name", output); +// +// sql = "SHOW create event expr "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CREATE EVENT expr", output); +// +// sql = "SHOW create function func "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CREATE FUNCTION func", output); +// +// sql = "SHOW create procedure pro "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CREATE PROCEDURE pro", output); +// +// sql = "SHOW create table tb "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CREATE TABLE tb", output); +// +// sql = "SHOW create trigger tri "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CREATE TRIGGER tri", output); +// +// sql = "SHOW create view view"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW CREATE VIEW view", output); +// +// sql = "SHOW databases like 'var'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW DATABASES LIKE 'var'", output); +// +// sql = "SHOW databases where (select * from `select`)is not null"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW DATABASES WHERE (SELECT * FROM `select`) IS NOT NULL", output); +// +// sql = "SHOW databases "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW DATABASES", output); +// +// sql = "SHOW engine innodb status"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW ENGINE INNODB STATUS", output); +// +// sql = "SHOW engine innodb mutex"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW ENGINE INNODB MUTEX", output); +// +// sql = "SHOW engine performance_schema status"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW ENGINE PERFORMANCE SCHEMA STATUS", output); +// +// sql = "SHOW engines"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW ENGINES", output); +// +// sql = "SHOW storage engines"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW ENGINES", output); +// +// sql = "SHOW errors"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW ERRORS", output); +// +// sql = "SHOW errors limit 1 "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW ERRORS LIMIT 0, 1", output); +// +// sql = "SHOW count(*) errors"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW COUNT(*) ERRORS", output); +// +// sql = "SHOW events"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW EVENTS", output); +// +// sql = "SHOW events from expr like 'var' "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW EVENTS FROM expr LIKE 'var'", output); +// +// sql = "SHOW events from expr where expr1"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW EVENTS FROM expr WHERE expr1", output); +// +// sql = "SHOW function code expr"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FUNCTION CODE expr", output); +// +// sql = "SHOW function status like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FUNCTION STATUS LIKE 'expr'", output); +// +// sql = "SHOW function status where a is true"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FUNCTION STATUS WHERE a IS TRUE", output); +// +// sql = "SHOW function status "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FUNCTION STATUS", output); +// +// sql = "SHOW grants for 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW GRANTS FOR 'expr'", output); +// +// sql = "SHOW grants"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW GRANTS", output); +// +// sql = "SHOW index from tb1 from db"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW INDEX IN db.tb1", output); +// +// sql = "SHOW index from tb1 in db"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW INDEX IN db.tb1", output); +// +// sql = "SHOW index in tb1 from db"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW INDEX IN db.tb1", output); +// +// sql = "SHOW index in tb1 in db"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW INDEX IN db.tb1", output); +// +// sql = "SHOW indexes from tb1"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW INDEXES IN tb1", output); +// +// sql = "SHOW keys in tb1"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW KEYS IN tb1", output); +// +// sql = "SHOW master status"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW MASTER STATUS", output); +// +// sql = "SHOW open tables from db like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW OPEN TABLES FROM db LIKE 'expr'", output); +// +// sql = "SHOW open tables from db where tb is not null"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW OPEN TABLES FROM db WHERE tb IS NOT NULL", output); +// +// sql = "SHOW open tables from db"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW OPEN TABLES FROM db", output); +// +// sql = "SHOW open tables in db"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW OPEN TABLES FROM db", output); +// +// sql = "SHOW open tables"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW OPEN TABLES", output); +// +// sql = "SHOW plugins"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PLUGINS", output); +// +// sql = "SHOW privileges"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PRIVILEGES", output); +// +// sql = "SHOW procedure code proc"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROCEDURE CODE proc", output); +// +// sql = "SHOW procedure status like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROCEDURE STATUS LIKE 'expr'", output); +// +// sql = "SHOW procedure status where (a||b)*(a&&b)"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROCEDURE STATUS WHERE (a OR b) * (a AND b)", output); +// +// sql = "SHOW procedure status"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROCEDURE STATUS", output); +// +// sql = "SHOW processlist"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROCESSLIST", output); +// +// sql = "SHOW full processlist"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FULL PROCESSLIST", output); +// +// sql = "SHOW profiles"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROFILES", output); +// +// sql = +// "SHOW profile all,block io,context switches,cpu,ipc,memory," +// + "page faults,source,swaps for query 2 limit 1 offset 2"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROFILE ALL, BLOCK IO, CONTEXT SWITCHES, CPU, IPC, MEMORY, " +// + "PAGE FAULTS, SOURCE, SWAPS FOR QUERY 2 LIMIT 2, 1", output); +// +// sql = "SHOW profile"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROFILE", output); +// +// sql = "SHOW profile all,block io,context switches,cpu,ipc," + "memory,page faults,source,swaps for query 2"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROFILE ALL, BLOCK IO, CONTEXT SWITCHES, CPU, IPC, " +// + "MEMORY, PAGE FAULTS, SOURCE, SWAPS FOR QUERY 2", output); +// +// sql = "SHOW profile all for query 2"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW PROFILE ALL FOR QUERY 2", output); +// +// sql = "SHOW slave hosts"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SLAVE HOSTS", output); +// +// sql = "SHOW slave status"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SLAVE STATUS", output); +// +// sql = "SHOW global status like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW GLOBAL STATUS LIKE 'expr'", output); +// +// sql = "SHOW global status where ${abc}"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW GLOBAL STATUS WHERE ${abc}", output); +// +// sql = "SHOW session status like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION STATUS LIKE 'expr'", output); +// +// sql = "SHOW session status where ?"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION STATUS WHERE ?", output); +// +// sql = "SHOW status like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION STATUS LIKE 'expr'", output); +// +// sql = "SHOW status where 0b10^b'11'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION STATUS WHERE b'10' ^ b'11'", output); +// +// sql = "SHOW status"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION STATUS", output); +// +// sql = "SHOW global status"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW GLOBAL STATUS", output); +// +// sql = "SHOW session status"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION STATUS", output); +// +// sql = "SHOW table status from db like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLE STATUS FROM db LIKE 'expr'", output); +// +// sql = "SHOW table status in db where (select a)>(select b)"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLE STATUS FROM db WHERE (SELECT a) > (SELECT b)", output); +// +// sql = "SHOW table status from db where id1=a||b"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLE STATUS FROM db WHERE id1 = a OR b", output); +// +// sql = "SHOW table status "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLE STATUS", output); +// +// sql = "SHOW tables from db like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLES FROM db LIKE 'expr'", output); +// +// sql = "SHOW tables in db where !a"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLES FROM db WHERE ! a", output); +// +// sql = "SHOW tables like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLES LIKE 'expr'", output); +// +// sql = "SHOW tables where log((select a))=b"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLES WHERE LOG(SELECT a) = b", output); +// +// sql = "SHOW tables "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TABLES", output); +// +// sql = "SHOW full tables from db like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FULL TABLES FROM db LIKE 'expr'", output); +// +// sql = "SHOW full tables in db where id1=abs((select a))"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FULL TABLES FROM db WHERE id1 = ABS(SELECT a)", output); +// +// sql = "SHOW full tables "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW FULL TABLES", output); +// +// sql = "SHOW triggers from db like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TRIGGERS FROM db LIKE 'expr'", output); +// +// sql = "SHOW triggers in db where strcmp('test1','test2')"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TRIGGERS FROM db WHERE STRCMP('test1', 'test2')", output); +// +// sql = "SHOW triggers "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW TRIGGERS", output); +// +// sql = "SHOW global variables like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW GLOBAL VARIABLES LIKE 'expr'", output); +// +// sql = "SHOW global variables where ~a is null"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW GLOBAL VARIABLES WHERE ~ a IS NULL", output); +// +// sql = "SHOW session variables like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION VARIABLES LIKE 'expr'", output); +// +// sql = "SHOW session variables where a*b+1=c"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION VARIABLES WHERE a * b + 1 = c", output); +// +// sql = "SHOW variables like 'expr'"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION VARIABLES LIKE 'expr'", output); +// +// sql = "SHOW variables where a&&b"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION VARIABLES WHERE a AND b", output); +// +// sql = "SHOW variables"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION VARIABLES", output); +// +// sql = "SHOW global variables"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW GLOBAL VARIABLES", output); +// +// sql = "SHOW session variables"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW SESSION VARIABLES", output); +// +// sql = "SHOW warnings limit 1,2 "; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW WARNINGS LIMIT 1, 2", output); +// +// sql = "SHOW warnings"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW WARNINGS", output); +// +// sql = "SHOW count(*) warnings"; +// lexer = new SQLLexer(sql); +// parser = new DALParser(lexer, new SQLExprParser(lexer)); +// show = (DALShowStatement) parser.show(); +// parser.match(Token.EOF); +// output = output2MySQL(show, sql); +// Assert.assertEquals("SHOW COUNT(*) WARNINGS", output); +// } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/cobar/LiteralHexadecimalTest.java b/src/test/java/com/alibaba/druid/bvt/sql/cobar/LiteralHexadecimalTest.java new file mode 100644 index 0000000000..61cc682062 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/cobar/LiteralHexadecimalTest.java @@ -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 QIU Shuo + */ +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")); + } +}