From 168518e0e59d468441bd418cfb7bb482c4547804 Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 19 Jul 2017 17:55:24 +0800 Subject: [PATCH] improved sql parser. --- .../java/com/alibaba/druid/sql/SQLUtils.java | 2 +- .../statement/SQLCreateTableStatement.java | 129 ++------ .../druid/sql/ast/statement/SQLSelect.java | 1 + .../dialect/db2/parser/DB2SelectParser.java | 2 +- .../mysql/parser/MySqlCreateTableParser.java | 6 +- .../dialect/mysql/parser/MySqlExprParser.java | 31 +- .../sql/dialect/mysql/parser/MySqlLexer.java | 12 +- .../mysql/parser/MySqlSelectIntoParser.java | 2 +- .../mysql/parser/MySqlSelectParser.java | 4 +- .../mysql/parser/MySqlStatementParser.java | 74 ++--- .../odps/parser/OdpsCreateTableParser.java | 6 +- .../sql/dialect/odps/parser/OdpsLexer.java | 4 +- .../odps/parser/OdpsStatementParser.java | 8 +- .../ast/clause/OracleLobStorageClause.java | 11 + .../parser/OracleCreateTableParser.java | 6 +- .../oracle/parser/OracleExprParser.java | 191 ++++++------ .../dialect/oracle/parser/OracleLexer.java | 6 +- .../oracle/parser/OracleSelectParser.java | 22 +- .../oracle/parser/OracleStatementParser.java | 50 +-- .../oracle/parser/OracleUpdateParser.java | 2 +- .../oracle/visitor/OracleOutputVisitor.java | 6 + .../parser/PGSQLStatementParser.java | 4 +- .../postgresql/parser/PGSelectParser.java | 8 +- .../parser/SQLServerSelectParser.java | 2 +- .../parser/SQLServerStatementParser.java | 8 +- .../com/alibaba/druid/sql/parser/Lexer.java | 20 +- .../sql/parser/SQLCreateTableParser.java | 6 +- .../druid/sql/parser/SQLDDLParser.java | 6 +- .../druid/sql/parser/SQLExprParser.java | 26 +- .../alibaba/druid/sql/parser/SQLParser.java | 8 +- .../druid/sql/parser/SQLSelectParser.java | 4 +- .../druid/sql/parser/SQLStatementParser.java | 22 +- .../java/com/alibaba/druid/util/ListDG.java | 289 ++++++++++++++++++ .../META-INF/druid/parser/mysql/keywords | 1 + .../druid/bvt/sql/CreateCompareTest.java | 31 +- .../druid/bvt/sql/CreateCompareTest_1.java | 105 +++++++ .../sql/oracle/select/OracleSelectTest69.java | 289 ++++++++++++++++++ 37 files changed, 1017 insertions(+), 387 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/util/ListDG.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest_1.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest69.java diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index cec85b97c5..4b8a915000 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -428,7 +428,7 @@ public class SQLUtils { SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType, keepComments); List stmtList = parser.parseStatementList(); if (parser.getLexer().token() != Token.EOF) { - throw new ParserException("syntax error : " + sql); + throw new ParserException("syntax error. " + sql); } return stmtList; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java index 9f69deb3e6..7c1ea74d12 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java @@ -18,14 +18,11 @@ package com.alibaba.druid.sql.ast.statement; import java.util.*; import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.SQLDataType; -import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.SQLName; -import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.ast.*; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex; import com.alibaba.druid.sql.visitor.SQLASTVisitor; -import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.ListDG; import com.alibaba.druid.util.lang.Consumer; public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement { @@ -173,6 +170,8 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS } public SQLColumnDefinition findColumn(String columName) { + columName = SQLUtils.normalize(columName); + for (SQLTableElement element : tableElementList) { if (element instanceof SQLColumnDefinition) { SQLColumnDefinition column = (SQLColumnDefinition) element; @@ -284,116 +283,42 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS return false; } - public static class DependencyComparator implements Comparator { - private final Map tables = new HashMap(); - private final Set referencedTableNames = new HashSet(); + public static void sort(List stmtList) { + Map tables = new HashMap(); - public void add(SQLCreateTableStatement stmt) { - String tableName = stmt.getName().getSimpleName(); - tableName = SQLUtils.normalize(tableName).toLowerCase(); - tables.put(tableName, stmt); + for (SQLStatement stmt : stmtList) { + if (stmt instanceof SQLCreateTableStatement) { + SQLCreateTableStatement createTableStmt = (SQLCreateTableStatement) stmt; + String tableName = createTableStmt.getName().getSimpleName(); + tableName = SQLUtils.normalize(tableName).toLowerCase(); + tables.put(tableName, createTableStmt); + } + } - for (SQLTableElement element : stmt.tableElementList) { + List edges = new ArrayList(); + + for (SQLCreateTableStatement stmt : tables.values()) { + for (SQLTableElement element : stmt.getTableElementList()) { if (element instanceof SQLForeignKeyConstraint) { SQLForeignKeyConstraint fk = (SQLForeignKeyConstraint) element; String refTableName = fk.getReferencedTableName().getSimpleName(); refTableName = SQLUtils.normalize(refTableName).toLowerCase(); - referencedTableNames.add(refTableName); - } - } - } - public int compare(Object a, Object b) { - return compareStmt((SQLCreateTableStatement)a, (SQLCreateTableStatement) b); - } - - public int compareStmt(SQLCreateTableStatement a, SQLCreateTableStatement b) { - if (a == b) { - return 0; - } - - if (a == null) { - return -1; - } - - if (b == null) { - return 1; - } - - int refVal = isReferenced(a, b); - if (refVal == -1) { - return 1; - } - - - refVal = isReferenced(b, a); - - if (refVal == -1) { - return -1; - } - - boolean a_referenced = isReferenced(a); - boolean b_referenced = isReferenced(b); - - if (a_referenced != b_referenced) { - return a_referenced ? 1 : -1; - } - - return 0; - } - - boolean isReferenced(SQLCreateTableStatement stmt) { - String tableName = stmt.getName().getSimpleName(); - tableName = SQLUtils.normalize(tableName).toLowerCase(); - return referencedTableNames.contains(tableName); - } - - int isReferenced(SQLCreateTableStatement a, SQLCreateTableStatement b) { - if (a == b) { - return 0; - } - - if (a.isReferenced(b.getName())) { - return -1; - } - - for (SQLTableElement element : a.tableElementList) { - if (element instanceof SQLForeignKeyConstraint) { - SQLForeignKeyConstraint fk = (SQLForeignKeyConstraint) element; - SQLName refTableName = fk.getReferencedTableName(); - - SQLCreateTableStatement refStmt = findStatement(refTableName); - if (refStmt != null) { - int refVal = isReferenced(refStmt, b); - if (refVal != 0) { - return refVal; - } + SQLCreateTableStatement refTable = tables.get(refTableName); + if (refTable != null) { + Object[] edge = new Object[] {stmt, refTable}; + edges.add(edge); } - } } - - return 0; } - public SQLCreateTableStatement findStatement(SQLName name) { - if (name == null) { - return null; - } + ListDG dg = new ListDG(stmtList, edges); - String refTableName = name.getSimpleName(); - refTableName = SQLUtils.normalize(refTableName).toLowerCase(); - return tables.get(refTableName); + SQLStatement[] tops = new SQLStatement[stmtList.size()]; + dg.topologicalSort(tops); + for (int i = 0, size = stmtList.size(); i < size; ++i) { + stmtList.set(i, tops[size - i - 1]); } } - - public static void sort(List stmtList) { - final DependencyComparator comparator = new DependencyComparator(); - - for (SQLCreateTableStatement stmt : stmtList) { - comparator.add(stmt); - } - - Collections.sort(stmtList, comparator); - } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelect.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelect.java index f2212d304a..d6e3518a6d 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelect.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelect.java @@ -98,6 +98,7 @@ public class SQLSelect extends SQLObjectImpl { protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { + acceptChild(visitor, this.withSubQuery); acceptChild(visitor, this.query); acceptChild(visitor, this.restriction); acceptChild(visitor, this.orderBy); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java index e8030b951c..a31e83e661 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java @@ -110,7 +110,7 @@ public class DB2SelectParser extends SQLSelectParser { } else if (identifierEquals("UR")) { queryBlock.setIsolation(Isolation.UR); } else { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } lexer.nextToken(); continue; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java index 2154439042..ebddf7bfbe 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java @@ -503,7 +503,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser { partitionClauseRest(clause); } else { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO. " + lexer.info()); } if (lexer.token() == Token.LPAREN) { @@ -532,7 +532,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser { } if (lexer.token() == (Token.ON)) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } if (lexer.token() == (Token.AS)) { @@ -839,6 +839,6 @@ public class MySqlCreateTableParser extends SQLCreateTableParser { return (SQLTableConstraint) fk; } - throw new ParserException("TODO :" + lexer.token()); + throw new ParserException("TODO. " + lexer.info()); } } 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 c8f36eef54..06ddde12e4 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 @@ -158,7 +158,7 @@ public class MySqlExprParser extends SQLExprParser { case VALUES: lexer.nextToken(); if (lexer.token() != Token.LPAREN) { - throw new ParserException("syntax error, illegal values clause"); + throw new ParserException("syntax error, illegal values clause. " + lexer.info()); } return this.methodRest(new SQLIdentifierExpr("VALUES"), true); case BINARY: @@ -234,7 +234,7 @@ public class MySqlExprParser extends SQLExprParser { if ("USING".equalsIgnoreCase(lexer.stringVal())) { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("syntax error, illegal hex"); + throw new ParserException("syntax error, illegal hex. " + lexer.info()); } String charSet = lexer.stringVal(); lexer.nextToken(); @@ -250,7 +250,7 @@ public class MySqlExprParser extends SQLExprParser { } if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } String collate = lexer.stringVal(); @@ -267,7 +267,7 @@ public class MySqlExprParser extends SQLExprParser { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } String collate = lexer.stringVal(); @@ -297,7 +297,7 @@ public class MySqlExprParser extends SQLExprParser { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } String unitVal = lexer.stringVal(); @@ -340,7 +340,7 @@ public class MySqlExprParser extends SQLExprParser { } else if (lexer.token() == Token.RPAREN) { break; } else { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } } @@ -415,10 +415,10 @@ public class MySqlExprParser extends SQLExprParser { acceptIdentifier("MODE"); matchAgainstExpr.setSearchModifier(SearchModifier.IN_BOOLEAN_MODE); } else { - throw new ParserException("TODO"); + throw new ParserException("syntax error. " + lexer.info()); } } else if (lexer.token() == Token.WITH) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } accept(Token.RPAREN); @@ -437,7 +437,7 @@ public class MySqlExprParser extends SQLExprParser { if (identifierEquals("USING")) { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } String charset = lexer.stringVal(); lexer.nextToken(); @@ -484,8 +484,7 @@ public class MySqlExprParser extends SQLExprParser { } if (lexer.token() == Token.ERROR) { - throw new ParserException("syntax error, token: " + lexer.token() + " " + lexer.stringVal() + ", pos : " - + lexer.pos()); + throw new ParserException("syntax error. " + lexer.info()); } return super.primaryRest(expr); @@ -527,7 +526,7 @@ public class MySqlExprParser extends SQLExprParser { SQLExpr value = expr(); if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("Syntax error"); + throw new ParserException("Syntax error. " + lexer.info()); } String unit = lexer.stringVal(); @@ -580,7 +579,7 @@ public class MySqlExprParser extends SQLExprParser { } if (lexer.token() == Token.PARTITION) { - throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("syntax error " + lexer.info()); } if (identifierEquals("STORAGE")) { @@ -900,7 +899,7 @@ public class MySqlExprParser extends SQLExprParser { fk.setOnUpdate(option); } else { throw new ParserException("syntax error, expect DELETE or UPDATE, actual " + lexer.token() + " " - + lexer.stringVal()); + + lexer.info()); } } return fk; @@ -925,11 +924,11 @@ public class MySqlExprParser extends SQLExprParser { lexer.nextToken(); } else { throw new ParserException("syntax error, expect ACTION, actual " + lexer.token() + " " - + lexer.stringVal()); + + lexer.info()); } } else { throw new ParserException("syntax error, expect ACTION, actual " + lexer.token() + " " - + lexer.stringVal()); + + lexer.info()); } return option; 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 d7bd5a0812..f1b72099b0 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 @@ -83,7 +83,7 @@ public class MySqlLexer extends Lexer { public void scanSharp() { if (ch != '#') { - throw new ParserException("illegal stat"); + throw new ParserException("illegal stat. " + info()); } if (charAt(pos + 1) == '{') { @@ -139,7 +139,7 @@ public class MySqlLexer extends Lexer { public void scanVariable() { if (ch != '@' && ch != ':' && ch != '#' && ch != '$') { - throw new ParserException("illegal variable"); + throw new ParserException("illegal variable. " + info()); } mark = pos; @@ -162,7 +162,7 @@ public class MySqlLexer extends Lexer { ch = charAt(++pos); break; } else if (ch == EOI) { - throw new ParserException("illegal identifier"); + throw new ParserException("illegal identifier. " + info()); } bufPos++; @@ -185,7 +185,7 @@ public class MySqlLexer extends Lexer { ch = charAt(++pos); break; } else if (ch == EOI) { - throw new ParserException("illegal identifier"); + throw new ParserException("illegal identifier. " + info()); } bufPos++; @@ -231,7 +231,7 @@ public class MySqlLexer extends Lexer { ch = charAt(++pos); break; } else if (ch == EOI) { - throw new ParserException("illegal identifier"); + throw new ParserException("illegal identifier. " + info()); } bufPos++; @@ -251,7 +251,7 @@ public class MySqlLexer extends Lexer { final boolean firstFlag = isFirstIdentifierChar(first); if (!firstFlag) { - throw new ParserException("illegal identifier"); + throw new ParserException("illegal identifier. " + info()); } mark = pos; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectIntoParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectIntoParser.java index 0b34bff260..d93a0ecc2f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectIntoParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectIntoParser.java @@ -160,7 +160,7 @@ public class MySqlSelectIntoParser extends SQLSelectParser { if (lexer.token() == Token.PROCEDURE) { lexer.nextToken(); - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } parseInto(queryBlock); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index 3374558612..e4ce665892 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -175,7 +175,7 @@ public class MySqlSelectParser extends SQLSelectParser { if (lexer.token() == Token.PROCEDURE) { lexer.nextToken(); - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } parseInto(queryBlock); @@ -240,7 +240,7 @@ public class MySqlSelectParser extends SQLSelectParser { } if (lexer.token() == Token.SELECT) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } SQLExprTableSource tableReference = new SQLExprTableSource(); 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 64859cbf1b..1ab8d8a611 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 @@ -250,7 +250,7 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); deleteStatement.setTableSource(createSQLSelectParser().parseTableSource()); } else { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } if (identifierEquals("USING")) { @@ -422,7 +422,7 @@ public class MySqlStatementParser extends SQLStatementParser { stmt.setUsing("HASH"); lexer.nextToken(); } else { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } } } @@ -487,7 +487,7 @@ public class MySqlStatementParser extends SQLStatementParser { } else if (lexer.token() == Token.LITERAL_INT) { // skip } else { - throw new ParserException("not support kill type " + lexer.token()); + throw new ParserException("not support kill type " + lexer.token() + ". " + lexer.info()); } this.exprParser.exprList(stmt.getThreadIds(), stmt); @@ -657,7 +657,7 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); } else { setErrorEndPos(lexer.pos()); - throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token()); + throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token() + ", " + lexer.info()); } MySqlLockTableStatement stmt = new MySqlLockTableStatement(); @@ -678,7 +678,7 @@ public class MySqlStatementParser extends SQLStatementParser { acceptIdentifier(WRITE); stmt.setLockType(LockType.LOW_PRIORITY_WRITE); } else { - throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token()); + throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token() + ", " + lexer.info()); } if (lexer.token() == Token.HINT) { @@ -698,7 +698,7 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); } else { setErrorEndPos(lexer.pos()); - throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token()); + throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token() + ", " + lexer.info()); } return true; } @@ -784,7 +784,7 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); describe.setDescribe(true); } else { - throw new ParserException("expect one of {DESCRIBE | DESC} , actual " + lexer.token()); + throw new ParserException("expect one of {DESCRIBE | DESC} , actual " + lexer.token() + ", " + lexer.info()); } return parseExplain(describe); @@ -798,7 +798,7 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.EXPLAIN) { lexer.nextToken(); } else { - throw new ParserException("expect EXPLAIN , actual " + lexer.token()); + throw new ParserException("expect EXPLAIN , actual " + lexer.token() + ", " + lexer.info()); } return parseExplain(explain); @@ -1142,7 +1142,7 @@ public class MySqlStatementParser extends SQLStatementParser { return stmt; } - throw new ParserException("TODO " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } if (identifierEquals(ENGINE)) { @@ -1522,7 +1522,7 @@ public class MySqlStatementParser extends SQLStatementParser { } // MySqlShowSlaveHostsStatement - throw new ParserException("TODO " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } private MySqlShowStatusStatement parseShowStatus() { @@ -1829,7 +1829,7 @@ public class MySqlStatementParser extends SQLStatementParser { return stmt; } - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } protected MySqlLoadXmlStatement parseLoadXml() { @@ -1878,7 +1878,7 @@ public class MySqlStatementParser extends SQLStatementParser { accept(Token.SET); if (lexer.token() != Token.LITERAL_CHARS) { - throw new ParserException("syntax error, illegal charset"); + throw new ParserException("syntax error, illegal charset. " + lexer.info()); } String charset = lexer.stringVal(); @@ -1895,11 +1895,11 @@ public class MySqlStatementParser extends SQLStatementParser { } if (identifierEquals(IGNORE)) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } if (lexer.token() == Token.SET) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } return stmt; @@ -1952,7 +1952,7 @@ public class MySqlStatementParser extends SQLStatementParser { accept(Token.SET); if (lexer.token() != Token.LITERAL_CHARS) { - throw new ParserException("syntax error, illegal charset"); + throw new ParserException("syntax error, illegal charset. " + lexer.info()); } String charset = lexer.stringVal(); @@ -2188,7 +2188,7 @@ public class MySqlStatementParser extends SQLStatementParser { private void parseValueClause(List valueClauseList, int columnSize) { for (int i = 0; ; ++i) { if (lexer.token() != Token.LPAREN) { - throw new ParserException("syntax error, expect ')'"); + throw new ParserException("syntax error, expect ')', " + lexer.info()); } lexer.nextTokenValue(); @@ -2246,7 +2246,7 @@ public class MySqlStatementParser extends SQLStatementParser { } if (lexer.token() != Token.RPAREN) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } if (!parseCompleteValues && valueClauseList.size() >= parseValuesSize) { @@ -2321,7 +2321,7 @@ public class MySqlStatementParser extends SQLStatementParser { stmt.setIsolationLevel("READ COMMITTED"); lexer.nextToken(); } else { - throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal() + ", " + lexer.info()); } } else if (identifierEquals("SERIALIZABLE")) { stmt.setIsolationLevel("SERIALIZABLE"); @@ -2332,10 +2332,10 @@ public class MySqlStatementParser extends SQLStatementParser { stmt.setIsolationLevel("REPEATABLE READ"); lexer.nextToken(); } else { - throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal() + ", " + lexer.info()); } } else { - throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal() + ", " + lexer.info()); } } else if (identifierEquals(READ)) { lexer.nextToken(); @@ -2346,7 +2346,7 @@ public class MySqlStatementParser extends SQLStatementParser { stmt.setAccessModel("WRITE"); lexer.nextToken(); } else { - throw new ParserException("UNKOWN ACCESS MODEL : " + lexer.stringVal()); + throw new ParserException("UNKOWN ACCESS MODEL : " + lexer.stringVal() + ", " + lexer.info()); } } @@ -2433,7 +2433,7 @@ public class MySqlStatementParser extends SQLStatementParser { return parseAlterDatabase(); } - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } protected SQLStatement parseAlterTable(boolean ignore) { @@ -2508,7 +2508,7 @@ public class MySqlStatementParser extends SQLStatementParser { SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(unique); stmt.addItem(item); } else { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } } else if (lexer.token() == Token.PARTITION) { lexer.nextToken(); @@ -2529,9 +2529,9 @@ public class MySqlStatementParser extends SQLStatementParser { stmt.addItem(item); } else if (identifierEquals(FULLTEXT)) { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } else if (identifierEquals(SPATIAL)) { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } else { parseAlterTableAddColumn(stmt); } @@ -2653,7 +2653,7 @@ public class MySqlStatementParser extends SQLStatementParser { return renameStmt; } else if (lexer.token() == Token.ORDER) { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } else if (identifierEquals("CONVERT")) { lexer.nextToken(); accept(Token.TO); @@ -2672,7 +2672,7 @@ public class MySqlStatementParser extends SQLStatementParser { stmt.addItem(item); } else if (lexer.token() == Token.DEFAULT) { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } else if (identifierEquals("DISCARD")) { lexer.nextToken(); @@ -2742,7 +2742,7 @@ public class MySqlStatementParser extends SQLStatementParser { } stmt.addItem(item); } else if (identifierEquals("FORCE")) { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } else if (identifierEquals("COALESCE")) { lexer.nextToken(); accept(Token.PARTITION); @@ -2776,7 +2776,7 @@ public class MySqlStatementParser extends SQLStatementParser { accept(Token.RPAREN); stmt.addItem(item); } else if (identifierEquals("EXCHANGE")) { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } else if (lexer.token() == Token.OPTIMIZE) { lexer.nextToken(); @@ -2902,7 +2902,7 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); stmt.getTableOptions().put("ROW_FORMAT", rowFormat); } else { - throw new ParserException("illegal syntax."); + throw new ParserException("illegal syntax. " + lexer.info()); } } else { @@ -3486,7 +3486,7 @@ public class MySqlStatementParser extends SQLStatementParser { statementList.add(this.parseSelect()); continue; } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO. " + lexer.info()); } } // assign statement @@ -3589,7 +3589,7 @@ public class MySqlStatementParser extends SQLStatementParser { } } - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO, " + lexer.info()); } } @@ -3814,7 +3814,7 @@ public class MySqlStatementParser extends SQLStatementParser { break; } else { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } } return stmt; @@ -4009,7 +4009,7 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.reset(bp, ch, Token.LPAREN); return this.parseSelect(); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO. " + lexer.info()); } } // assign statement @@ -4017,7 +4017,7 @@ public class MySqlStatementParser extends SQLStatementParser { return parseAssign(); } - throw new ParserException("error sp_statement"); + throw new ParserException("error sp_statement. " + lexer.info()); } /** @@ -4042,7 +4042,7 @@ public class MySqlStatementParser extends SQLStatementParser { } else if (lexer.token() == Token.UNDO) { stmt.setHandleType(MySqlHandlerType.CONTINUE); } else { - throw new ParserException("unkown handle type"); + throw new ParserException("unkown handle type. " + lexer.info()); } lexer.nextToken(); @@ -4140,7 +4140,7 @@ public class MySqlStatementParser extends SQLStatementParser { condition.setValue(lexer.integerValue().toString()); lexer.nextToken(); } else { - throw new ParserException("declare condition grammer error."); + throw new ParserException("declare condition grammer error. " + lexer.info()); } stmt.setConditionValue(condition); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java index 73a2211a0f..4bb09c3f0e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java @@ -79,7 +79,7 @@ public class OdpsCreateTableParser extends SQLCreateTableParser { for (;;) { if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("expect identifier"); + throw new ParserException("expect identifier. " + lexer.info()); } SQLColumnDefinition column = this.exprParser.parseColumn(); @@ -114,7 +114,7 @@ public class OdpsCreateTableParser extends SQLCreateTableParser { for (;;) { if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("expect identifier"); + throw new ParserException("expect identifier. " + lexer.info()); } SQLColumnDefinition column = this.exprParser.parseColumn(); @@ -159,7 +159,7 @@ public class OdpsCreateTableParser extends SQLCreateTableParser { stmt.setBuckets(lexer.integerValue().intValue()); lexer.nextToken(); } else { - throw new ParserException("into buckets must be integer."); + throw new ParserException("into buckets must be integer. " + lexer.info()); } acceptIdentifier("BUCKETS"); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsLexer.java index 66d44afdc3..43223e97b5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsLexer.java @@ -197,7 +197,7 @@ public class OdpsLexer extends Lexer { ch = charAt(++pos); break; } else if (ch == EOI) { - throw new ParserException("illegal identifier"); + throw new ParserException("illegal identifier. " + info()); } bufPos++; @@ -214,7 +214,7 @@ public class OdpsLexer extends Lexer { final boolean firstFlag = isFirstIdentifierChar(first); if (!firstFlag) { - throw new ParserException("illegal identifier"); + throw new ParserException("illegal identifier. " + info()); } mark = pos; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java index d34f4b66ca..3af696f102 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java @@ -122,7 +122,7 @@ public class OdpsStatementParser extends SQLStatementParser { return true; } - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } if (identifierEquals("REMOVE")) { @@ -137,7 +137,7 @@ public class OdpsStatementParser extends SQLStatementParser { return true; } - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } if (identifierEquals("READ")) { @@ -222,7 +222,7 @@ public class OdpsStatementParser extends SQLStatementParser { expr_condition.setExpr(this.exprParser.expr()); return expr_condition; } else { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } } @@ -378,7 +378,7 @@ public class OdpsStatementParser extends SQLStatementParser { return stmt; } - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } public SQLStatement parseSet() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleLobStorageClause.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleLobStorageClause.java index 1e03fc04c6..bb921118db 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleLobStorageClause.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleLobStorageClause.java @@ -28,6 +28,8 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class OracleLobStorageClause extends OracleSegmentAttributesImpl implements OracleSQLObject { + private SQLName segementName; + private final List items = new ArrayList(); private boolean secureFile = false; @@ -56,6 +58,7 @@ public class OracleLobStorageClause extends OracleSegmentAttributesImpl implemen @Override public void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { + acceptChild(visitor, segementName); acceptChild(visitor, items); acceptChild(visitor, tablespace); } @@ -159,4 +162,12 @@ public class OracleLobStorageClause extends OracleSegmentAttributesImpl implemen } this.pctversion = pctversion; } + + public SQLName getSegementName() { + return segementName; + } + + public void setSegementName(SQLName segementName) { + this.segementName = segementName; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java index 845d9fc8d3..5914cc710d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java @@ -199,7 +199,7 @@ public class OracleCreateTableParser extends SQLCreateTableParser { lexer.nextToken(); break; } - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } stmt.setPartitioning(partitionByHash); @@ -210,7 +210,7 @@ public class OracleCreateTableParser extends SQLCreateTableParser { stmt.setPartitioning(partitionByList); continue; } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } break; @@ -493,7 +493,7 @@ public class OracleCreateTableParser extends SQLCreateTableParser { return byList; } - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } protected void parseCreateTableSupplementalLogingProps(SQLCreateTableStatement stmt) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index 8b801d568b..b441816fbc 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -257,7 +257,7 @@ public class OracleExprParser extends SQLExprParser { lexer.nextToken(); typeName += "%ROWTYPE"; } else { - throw new ParserException("syntax error : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("syntax error : " + lexer.info()); } } @@ -298,9 +298,9 @@ public class OracleExprParser extends SQLExprParser { lexer.nextToken(); return new SQLVariantRefExpr(":" + name); } - throw new ParserException("syntax error : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("syntax error : " + lexer.info()); } else { - throw new ParserException("syntax error : " + lexer.token()); + throw new ParserException("syntax error : " + lexer.info()); } case LITERAL_ALIAS: String alias = '"' + lexer.stringVal() + '"'; @@ -404,7 +404,7 @@ public class OracleExprParser extends SQLExprParser { sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr); break; default: - throw new ParserException("TODO " + lexer.token()); + throw new ParserException("TODO " + lexer.info()); } return primaryRest(sqlExpr); @@ -619,7 +619,7 @@ public class OracleExprParser extends SQLExprParser { if (lexer.token() == Token.LPAREN) { lexer.nextToken(); if (lexer.token() != Token.LITERAL_INT) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } interval.setPrecision(lexer.integerValue().intValue()); lexer.nextToken(); @@ -639,7 +639,7 @@ public class OracleExprParser extends SQLExprParser { if (lexer.token() == Token.LPAREN) { lexer.nextToken(); if (lexer.token() != Token.LITERAL_INT) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } interval.setFactionalSecondsPrecision(lexer.integerValue().intValue()); lexer.nextToken(); @@ -825,7 +825,7 @@ public class OracleExprParser extends SQLExprParser { windowing.setExpr(new SQLIdentifierExpr("CURRENT ROW")); over.setWindowing(windowing); } - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } if (lexer.stringVal().equalsIgnoreCase("UNBOUNDED")) { lexer.nextToken(); @@ -833,7 +833,7 @@ public class OracleExprParser extends SQLExprParser { lexer.nextToken(); windowing.setExpr(new SQLIdentifierExpr("UNBOUNDED PRECEDING")); } else { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } } @@ -868,7 +868,7 @@ public class OracleExprParser extends SQLExprParser { if (currentTokenUpperValue.equals("SECOND")) { return OracleIntervalType.SECOND; } - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } @Override @@ -894,7 +894,7 @@ public class OracleExprParser extends SQLExprParser { if (lexer.token() == Token.LPAREN) { lexer.nextToken(); if (lexer.token() != Token.LITERAL_INT) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } interval.setPrecision(lexer.integerValue().intValue()); lexer.nextToken(); @@ -902,7 +902,7 @@ public class OracleExprParser extends SQLExprParser { if (lexer.token() == Token.COMMA) { lexer.nextToken(); if (lexer.token() != Token.LITERAL_INT) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } interval.setFactionalSecondsPrecision(lexer.integerValue().intValue()); lexer.nextToken(); @@ -918,7 +918,7 @@ public class OracleExprParser extends SQLExprParser { if (lexer.token() == Token.LPAREN) { lexer.nextToken(); if (lexer.token() != Token.LITERAL_INT) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } interval.setToFactionalSecondsPrecision(lexer.integerValue().intValue()); lexer.nextToken(); @@ -962,7 +962,7 @@ public class OracleExprParser extends SQLExprParser { if (lexer.token() == Token.MONKEYS_AT) { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("syntax error, expect identifier, but " + lexer.token()); + throw new ParserException("syntax error, expect identifier, but " + lexer.token() + ", " + lexer.info()); } OracleDbLinkExpr dbLink = new OracleDbLinkExpr(); dbLink.setExpr(name); @@ -1164,89 +1164,90 @@ public class OracleExprParser extends SQLExprParser { accept(Token.STORE); accept(Token.AS); - for (;;) { - if (identifierEquals("SECUREFILE")) { - lexer.nextToken(); - clause.setSecureFile(true); - continue; - } - - if (identifierEquals("BASICFILE")) { - lexer.nextToken(); - clause.setBasicFile(true); - continue; - } - - if (lexer.token() == Token.LPAREN) { - lexer.nextToken(); - - for (;;) { - this.parseSegmentAttributes(clause); - - if (lexer.token() == Token.ENABLE) { - lexer.nextToken(); - accept(Token.STORAGE); - accept(Token.IN); - accept(Token.ROW); - clause.setEnable(true); - continue; - } else if (lexer.token() == Token.DISABLE) { - lexer.nextToken(); - accept(Token.STORAGE); - accept(Token.IN); - accept(Token.ROW); - clause.setEnable(false); - continue; - } - - if (lexer.token() == Token.CHUNK) { - lexer.nextToken(); - clause.setChunk(this.primary()); - continue; - } - - if (lexer.token() == Token.NOCACHE) { - lexer.nextToken(); - clause.setCache(false); - if (lexer.token() == Token.LOGGING) { - lexer.nextToken(); - clause.setLogging(true); - } - continue; - } - if (lexer.token() == Token.KEEP_DUPLICATES) { - lexer.nextToken(); - clause.setKeepDuplicate(true); - continue; - } - - if (identifierEquals("PCTVERSION")) { - lexer.nextToken(); - clause.setPctversion(this.expr()); - continue; - } - - if (identifierEquals("RETENTION")) { - lexer.nextToken(); - clause.setRetention(true); - continue; - } - - if (lexer.token() == Token.STORAGE) { - OracleStorageClause storageClause = this.parseStorage(); - clause.setStorageClause(storageClause); - continue; - } - - break; - } - - accept(Token.RPAREN); - } - - break; + if (identifierEquals("SECUREFILE")) { + lexer.nextToken(); + clause.setSecureFile(true); } + + if (identifierEquals("BASICFILE")) { + lexer.nextToken(); + clause.setBasicFile(true); + } + + if (lexer.token() == Token.IDENTIFIER || lexer.token() == Token.LITERAL_ALIAS) { + SQLName segmentName = this.name(); + clause.setSegementName(segmentName); + } + + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + + for (;;) { + this.parseSegmentAttributes(clause); + + if (lexer.token() == Token.ENABLE) { + lexer.nextToken(); + accept(Token.STORAGE); + accept(Token.IN); + accept(Token.ROW); + clause.setEnable(true); + continue; + } else if (lexer.token() == Token.DISABLE) { + lexer.nextToken(); + accept(Token.STORAGE); + accept(Token.IN); + accept(Token.ROW); + clause.setEnable(false); + continue; + } + + if (lexer.token() == Token.CHUNK) { + lexer.nextToken(); + clause.setChunk(this.primary()); + continue; + } + + if (lexer.token() == Token.NOCACHE) { + lexer.nextToken(); + clause.setCache(false); + if (lexer.token() == Token.LOGGING) { + lexer.nextToken(); + clause.setLogging(true); + } + continue; + } + + if (lexer.token() == Token.KEEP_DUPLICATES) { + lexer.nextToken(); + clause.setKeepDuplicate(true); + continue; + } + + if (identifierEquals("PCTVERSION")) { + lexer.nextToken(); + clause.setPctversion(this.expr()); + continue; + } + + if (identifierEquals("RETENTION")) { + lexer.nextToken(); + clause.setRetention(true); + continue; + } + + if (lexer.token() == Token.STORAGE) { + OracleStorageClause storageClause = this.parseStorage(); + clause.setStorageClause(storageClause); + continue; + } + + break; + } + + accept(Token.RPAREN); + } + return clause; } @@ -1407,7 +1408,7 @@ public class OracleExprParser extends SQLExprParser { constraint.setDeferrable(false); continue; } - throw new ParserException("TODO " + lexer.token()); + throw new ParserException("TODO " + lexer.info()); } if (identifierEquals("DEFERRABLE")) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java index 2c9a27b767..29683db60d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java @@ -142,7 +142,7 @@ public class OracleLexer extends Lexer { } if (ch != ':' && ch != '#' && ch != '$') { - throw new ParserException("illegal variable"); + throw new ParserException("illegal variable. " + info()); } mark = pos; @@ -174,13 +174,13 @@ public class OracleLexer extends Lexer { if (quoteFlag) { if (ch != '"') { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + info()); } ++pos; bufPos++; } else if (mybatisFlag) { if (ch != '}') { - throw new ParserException("syntax error"); + throw new ParserException("syntax error" + info()); } ++pos; bufPos++; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index 0918632a7e..e71d74cb04 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -83,7 +83,7 @@ public class OracleSelectParser extends SQLSelectParser { if (lexer.token() == (Token.FOR)) { if (queryBlock == null) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } lexer.nextToken(); @@ -124,7 +124,7 @@ public class OracleSelectParser extends SQLSelectParser { if (identifierEquals("ONLY")) { lexer.nextToken(); } else { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } select.setRestriction(new OracleSelectRestriction.ReadOnly()); @@ -134,14 +134,14 @@ public class OracleSelectParser extends SQLSelectParser { if (identifierEquals("OPTION")) { lexer.nextToken(); } else { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } OracleSelectRestriction.CheckOption checkOption = new OracleSelectRestriction.CheckOption(); if (lexer.token() == Token.CONSTRAINT) { lexer.nextToken(); - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } select.setRestriction(checkOption); @@ -588,7 +588,7 @@ public class OracleSelectParser extends SQLSelectParser { } else if (lexer.token() == (Token.LPAREN)) { tableSource = new OracleSelectSubqueryTableSource(select()); } else { - throw new ParserException("TODO :" + lexer.token()); + throw new ParserException("TODO :" + lexer.info()); } accept(Token.RPAREN); @@ -598,7 +598,7 @@ public class OracleSelectParser extends SQLSelectParser { } if (lexer.token() == (Token.SELECT)) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } OracleSelectTableReference tableReference = new OracleSelectTableReference(); @@ -705,7 +705,7 @@ public class OracleSelectParser extends SQLSelectParser { SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) exprParser.expr(); if (binaryExpr.getOperator() != SQLBinaryOperator.BooleanAnd) { - throw new ParserException("syntax error : " + binaryExpr.getOperator()); + throw new ParserException("syntax error : " + binaryExpr.getOperator() + ", " + lexer.info()); } start.setExpr(binaryExpr.getLeft()); @@ -891,11 +891,11 @@ public class OracleSelectParser extends SQLSelectParser { accept(Token.IN); accept(Token.LPAREN); if (lexer.token() == (Token.LPAREN)) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } if (lexer.token() == (Token.SELECT)) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } for (;;) { @@ -963,11 +963,11 @@ public class OracleSelectParser extends SQLSelectParser { accept(Token.IN); accept(Token.LPAREN); if (lexer.token() == (Token.LPAREN)) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } if (lexer.token() == (Token.SELECT)) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } for (;;) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 9645ec2b67..dbad76c252 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -542,7 +542,7 @@ public class OracleStatementParser extends SQLStatementParser { continue; } - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } if (lexer.token() == Token.NULL) { @@ -1031,7 +1031,7 @@ public class OracleStatementParser extends SQLStatementParser { lexer.nextToken(); parseAssignItems(stmt.getItems(), stmt); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } return stmt; } else if (lexer.token() == Token.PROCEDURE) { @@ -1195,7 +1195,7 @@ public class OracleStatementParser extends SQLStatementParser { lexer.nextToken(); file.setAutoExtendOn(this.exprParser.expr()); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } @@ -1211,16 +1211,16 @@ public class OracleStatementParser extends SQLStatementParser { stmt.setItem(item); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } return stmt; } - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } private SQLStatement parseAlterTable() { @@ -1251,7 +1251,7 @@ public class OracleStatementParser extends SQLStatementParser { SQLAlterTableAddColumn item = parseAlterTableAddColumn(); stmt.addItem(item); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } continue; @@ -1266,7 +1266,7 @@ public class OracleStatementParser extends SQLStatementParser { stmt.addItem(item); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } else if (identifierEquals("RENAME")) { stmt.addItem(parseAlterTableRename()); @@ -1306,7 +1306,7 @@ public class OracleStatementParser extends SQLStatementParser { item.setName(this.exprParser.name()); stmt.addItem(item); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } continue; } else if (lexer.token() == Token.DROP) { @@ -1320,7 +1320,7 @@ public class OracleStatementParser extends SQLStatementParser { item.setConstraintName(this.exprParser.name()); stmt.addItem(item); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } else if (lexer.token() == Token.ENABLE) { lexer.nextToken(); @@ -1330,7 +1330,7 @@ public class OracleStatementParser extends SQLStatementParser { item.setConstraintName(this.exprParser.name()); stmt.addItem(item); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } @@ -1345,7 +1345,7 @@ public class OracleStatementParser extends SQLStatementParser { acceptIdentifier("INDEXES"); stmt.setUpdateGlobalIndexes(true); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } @@ -1382,7 +1382,7 @@ public class OracleStatementParser extends SQLStatementParser { item.setIndexName(indexName); stmt.addItem(item); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } @@ -1399,7 +1399,7 @@ public class OracleStatementParser extends SQLStatementParser { this.exprParser.exprList(item.getAt(), item); accept(Token.RPAREN); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } if (lexer.token() == Token.INTO) { @@ -1418,21 +1418,21 @@ public class OracleStatementParser extends SQLStatementParser { spec.getSegmentAttributeItems().add(new TableSpaceItem(tablespace)); continue; } else if (identifierEquals("PCTREE")) { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } else if (identifierEquals("PCTUSED")) { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } else if (identifierEquals("INITRANS")) { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } else if (identifierEquals("STORAGE")) { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } else if (identifierEquals("LOGGING")) { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } else if (identifierEquals("NOLOGGING")) { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } else if (identifierEquals("FILESYSTEM_LIKE_LOGGING")) { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } @@ -1458,7 +1458,7 @@ public class OracleStatementParser extends SQLStatementParser { } stmt.addItem(item); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } } @@ -1896,11 +1896,11 @@ public class OracleStatementParser extends SQLStatementParser { deleteStatement.setReturning(clause); } if (identifierEquals("RETURN") || identifierEquals("RETURNING")) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } if (identifierEquals("LOG")) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } return deleteStatement; @@ -2068,7 +2068,7 @@ public class OracleStatementParser extends SQLStatementParser { lexer.nextToken(); break; } - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } break; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java index 2db8edbbfe..7544e6a73b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java @@ -66,7 +66,7 @@ public class OracleUpdateParser extends SQLStatementParser { private void parseErrorLoging(OracleUpdateStatement update) { if (identifierEquals("LOG")) { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index f6dcfd08ce..39bec5c7be 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -2852,6 +2852,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS if (x.isBasicFile()) { print0(ucase ? " BASICFILE" : " basicfile"); } + + SQLName segementName = x.getSegementName(); + if (segementName != null) { + print(' '); + segementName.accept(this); + } print0(" ("); incrementIndent(); printOracleSegmentAttributes(x); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java index f59780a76b..6f3a932c05 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java @@ -306,7 +306,7 @@ public class PGSQLStatementParser extends SQLStatementParser { } else if (lexer.token() == Token.VALUES) { query = this.parseSelect(); } else { - throw new ParserException("syntax error, support token '" + lexer.token() + "'"); + throw new ParserException("syntax error, support token '" + lexer.token() + "', " + lexer.info()); } withQuery.setQuery(query); @@ -347,7 +347,7 @@ public class PGSQLStatementParser extends SQLStatementParser { stmt.setWith(with); return stmt; } - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } protected SQLAlterTableAlterColumn parseAlterColumn() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java index 018a0ea7ea..13b3d3df25 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java @@ -197,7 +197,7 @@ public class PGSelectParser extends SQLSelectParser { } else if (lexer.token() == Token.NEXT) { fetch.setOption(PGSelectQueryBlock.FetchClause.Option.NEXT); } else { - throw new ParserException("expect 'FIRST' or 'NEXT'"); + throw new ParserException("expect 'FIRST' or 'NEXT'. " + lexer.info()); } SQLExpr count = expr(); @@ -206,13 +206,13 @@ public class PGSelectParser extends SQLSelectParser { if (lexer.token() == Token.ROW || lexer.token() == Token.ROWS) { lexer.nextToken(); } else { - throw new ParserException("expect 'ROW' or 'ROWS'"); + throw new ParserException("expect 'ROW' or 'ROWS'. " + lexer.info()); } if (lexer.token() == Token.ONLY) { lexer.nextToken(); } else { - throw new ParserException("expect 'ONLY'"); + throw new ParserException("expect 'ONLY'. " + lexer.info()); } queryBlock.setFetch(fetch); @@ -230,7 +230,7 @@ public class PGSelectParser extends SQLSelectParser { forClause.setOption(PGSelectQueryBlock.ForClause.Option.SHARE); lexer.nextToken(); } else { - throw new ParserException("expect 'FIRST' or 'NEXT'"); + throw new ParserException("expect 'FIRST' or 'NEXT'. " + lexer.info()); } if (lexer.token() == Token.OF) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java index 3e857e57a9..8945fe924a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java @@ -90,7 +90,7 @@ public class SQLServerSelectParser extends SQLSelectParser { } } } else { - throw new ParserException("syntax error, not support option : " + lexer.token()); + throw new ParserException("syntax error, not support option : " + lexer.token() + ", " + lexer.info()); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index 8d4f649371..f112ed445a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -186,7 +186,7 @@ public class SQLServerStatementParser extends SQLStatementParser { constraint.setParent(item); item.getTableElementList().add((SQLTableElement) constraint); } else if (lexer.token() == Token.TABLESPACE) { - throw new ParserException("TODO " + lexer.token()); + throw new ParserException("TODO " + lexer.info()); } else { SQLColumnDefinition column = this.exprParser.parseColumn(); item.getTableElementList().add(column); @@ -370,7 +370,7 @@ public class SQLServerStatementParser extends SQLStatementParser { stmt.setLevel("READ COMMITTED"); lexer.nextToken(); } else { - throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal() + ", " + lexer.info()); } } else if (identifierEquals("SERIALIZABLE")) { stmt.setLevel("SERIALIZABLE"); @@ -384,10 +384,10 @@ public class SQLServerStatementParser extends SQLStatementParser { stmt.setLevel("REPEATABLE READ"); lexer.nextToken(); } else { - throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal() + ", " + lexer.info()); } } else { - throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal() + ", " + lexer.info()); } return stmt; diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 0bf6fa13cb..98f4c0feab 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -525,7 +525,7 @@ public class Lexer { token = Token.SEMI; return; case '`': - throw new ParserException("TODO"); // TODO + throw new ParserException("TODO. " + info()); // TODO case '@': scanVariable(); return; @@ -737,7 +737,7 @@ public class Lexer { } break; default: - throw new ParserException("TODO"); + throw new ParserException("TODO. " + info()); } } @@ -806,7 +806,7 @@ public class Lexer { } if (endIndex == -1) { - throw new ParserException("unclosed str"); + throw new ParserException("unclosed str. " + info()); } String stringVal = subString(startIndex, endIndex - startIndex); @@ -978,7 +978,7 @@ public class Lexer { } if (endIndex == -1) { - throw new ParserException("unclosed str"); + throw new ParserException("unclosed str. " + info()); } String stringVal = subString(startIndex, endIndex - startIndex); @@ -1081,7 +1081,7 @@ public class Lexer { public void scanVariable() { if (ch != '@' && ch != ':' && ch != '#' && ch != '$') { - throw new ParserException("illegal variable"); + throw new ParserException("illegal variable. " + info()); } mark = pos; @@ -1120,7 +1120,7 @@ public class Lexer { } if (ch != '}') { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + info()); } ++pos; bufPos++; @@ -1181,7 +1181,7 @@ public class Lexer { // multiline comment结束符错误 if (ch == EOI) { - throw new ParserException("unterminated /* comment."); + throw new ParserException("unterminated /* comment. " + info()); } scanChar(); bufPos++; @@ -1230,7 +1230,7 @@ public class Lexer { // single line comment结束符错误 if (ch == EOI) { - throw new ParserException("syntax error at end of input."); + throw new ParserException("syntax error at end of input. " + info()); } scanChar(); @@ -1258,7 +1258,7 @@ public class Lexer { final boolean firstFlag = isFirstIdentifierChar(first); if (!firstFlag) { - throw new ParserException("illegal identifier"); + throw new ParserException("illegal identifier. " + info()); } mark = pos; @@ -1520,7 +1520,7 @@ public class Lexer { public BigDecimal decimalValue() { String value = subString(mark, bufPos); if (!StringUtils.isNumber(value)){ - throw new ParserException(value+" is not a number!"); + throw new ParserException(value+" is not a number! " + info()); } return new BigDecimal(value.toCharArray()); } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java index 458b27c5ae..a15e900ef7 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java @@ -67,7 +67,7 @@ public class SQLCreateTableParser extends SQLDDLParser { lexer.nextToken(); createTable.setType(SQLCreateTableStatement.Type.GLOBAL_TEMPORARY); } else { - throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("syntax error " + lexer.info()); } } else if (lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("LOCAL")) { lexer.nextToken(); @@ -75,7 +75,7 @@ public class SQLCreateTableParser extends SQLDDLParser { lexer.nextToken(); createTable.setType(SQLCreateTableStatement.Type.LOCAL_TEMPORARY); } else { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } } @@ -105,7 +105,7 @@ public class SQLCreateTableParser extends SQLDDLParser { constraint.setParent(createTable); createTable.getTableElementList().add((SQLTableElement) constraint); } else if (token == Token.TABLESPACE) { - throw new ParserException("TODO " + token); + throw new ParserException("TODO " + lexer.info()); } else { SQLColumnDefinition column = this.exprParser.parseColumn(); createTable.getTableElementList().add(column); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLDDLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLDDLParser.java index 6d6230cfc2..7ac2549640 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLDDLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLDDLParser.java @@ -34,16 +34,16 @@ public class SQLDDLParser extends SQLStatementParser { if (lexer.token() == Token.IDENTIFIER) { this.exprParser.name(); - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } if (lexer.token() == Token.PRIMARY) { lexer.nextToken(); accept(Token.KEY); - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } - throw new ParserException("TODO"); + throw new ParserException("TODO " + lexer.info()); } } 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 0282b3531d..fcfb17410b 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -238,7 +238,7 @@ public class SQLExprParser extends SQLParser { case INSERT: lexer.nextToken(); if (lexer.token() != Token.LPAREN) { - throw new ParserException("syntax error"); + throw new ParserException("syntax error. " + lexer.info()); } sqlExpr = new SQLIdentifierExpr("INSERT"); break; @@ -263,7 +263,7 @@ public class SQLExprParser extends SQLParser { } break; case NEW: - throw new ParserException("TODO"); + throw new ParserException("TODO " + lexer.info()); case LITERAL_INT: sqlExpr = new SQLIntegerExpr(lexer.integerValue()); lexer.nextToken(); @@ -520,7 +520,7 @@ public class SQLExprParser extends SQLParser { sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr); break; default: - throw new ParserException("TODO : " + lexer.token()); + throw new ParserException("TODO : " + lexer.info()); } break; case PLUS: @@ -546,7 +546,7 @@ public class SQLExprParser extends SQLParser { sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Plus, sqlExpr); break; default: - throw new ParserException("TODO"); + throw new ParserException("TODO " + lexer.info()); } break; case TILDE: @@ -702,7 +702,7 @@ public class SQLExprParser extends SQLParser { } protected SQLExpr parseInterval() { - throw new ParserException("TODO"); + throw new ParserException("TODO. " + lexer.info()); } public SQLSelectParser createSelectParser() { @@ -861,7 +861,7 @@ public class SQLExprParser extends SQLParser { return primaryRest(methodInvokeExpr); } - throw new ParserException("not support token:" + lexer.token()); + throw new ParserException("not support token:" + lexer.token() + ", " + lexer.info()); } protected SQLExpr dotRest(SQLExpr expr) { @@ -879,7 +879,7 @@ public class SQLExprParser extends SQLParser { name = lexer.stringVal(); lexer.nextToken(); } else { - throw new ParserException("error : " + lexer.stringVal()); + throw new ParserException("error : " + lexer.info()); } if (lexer.token() == Token.LPAREN) { @@ -1073,7 +1073,7 @@ public class SQLExprParser extends SQLParser { if (lexer.token() != Token.LITERAL_ALIAS && lexer.token() != Token.IDENTIFIER && (!lexer.getKeywods().containsValue(lexer.token()))) { - throw new ParserException("error, " + lexer.token()); + throw new ParserException("error, " + lexer.info()); } if (lexer.token() == Token.LITERAL_ALIAS) { @@ -1280,7 +1280,7 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); item.setNullsOrderType(SQLSelectOrderByItem.NullsOrderType.NullsLast); } else { - throw new ParserException("TODO " + lexer.token()); + throw new ParserException("TODO " + lexer.info()); } } @@ -1788,7 +1788,7 @@ public class SQLExprParser extends SQLParser { return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotILike, rightExp, getDbType()); } else { - throw new ParserException("TODO " + lexer.token()); + throw new ParserException("TODO " + lexer.info()); } return expr; } @@ -1932,7 +1932,7 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); } else { throw new ParserException("syntax error, expect " + token + ", actual " + lexer.token() + " " - + lexer.stringVal()); + + lexer.info()); } } @@ -2055,7 +2055,7 @@ public class SQLExprParser extends SQLParser { return parseColumnRest(column); } - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } if (lexer.token == Token.CHECK) { @@ -2224,7 +2224,7 @@ public class SQLExprParser extends SQLParser { } else if (lexer.token() == Token.CHECK) { constraint = parseCheck(); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.info()); } constraint.setName(name); 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 2b739ac56f..d666221696 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -56,7 +56,7 @@ public class SQLParser { lexer.nextToken(); } else { setErrorEndPos(lexer.pos()); - throw new ParserException("syntax error, expect " + text + ", actual " + lexer.token()); + throw new ParserException("syntax error, expect " + text + ", actual " + lexer.token() + ", " + lexer.info()); } } @@ -118,7 +118,7 @@ public class SQLParser { return null; } - throw new ParserException("Error : " + lexer.token()); + throw new ParserException("Error : " + lexer.info()); } if (lexer.token() == Token.LITERAL_ALIAS) { @@ -296,14 +296,14 @@ public class SQLParser { return intVal; } else { throw new ParserException("syntax error, expect int, actual " + lexer.token() + " " - + lexer.stringVal()); + + lexer.info()); } } public void match(Token token) { if (lexer.token() != token) { throw new ParserException("syntax error, expect " + token + ", actual " + lexer.token() + " " - + lexer.stringVal()); + + lexer.info()); } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index a54cebbd1b..11f5e7565a 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -419,7 +419,7 @@ public class SQLSelectParser extends SQLParser { } if (lexer.token() == Token.SELECT) { - throw new ParserException("TODO"); + throw new ParserException("TODO " + lexer.info()); } SQLExprTableSource tableReference = new SQLExprTableSource(); @@ -608,7 +608,7 @@ public class SQLSelectParser extends SQLParser { lexer.nextToken(); } else { setErrorEndPos(lexer.pos()); - throw new ParserException("syntax error, expect " + ident + ", actual " + lexer.token()); + throw new ParserException("syntax error, expect " + ident + ", actual " + lexer.token() + ", " + lexer.info()); } } 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 4aedf4d3d0..ca50f4c4ef 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -509,11 +509,11 @@ public class SQLStatementParser extends SQLParser { } public SQLStatement parseCommit() { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } public SQLStatement parseShow() { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } public SQLUseStatement parseUse() { @@ -947,7 +947,7 @@ public class SQLStatementParser extends SQLParser { stmt.addItem(addPartition); } else { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } } else if (lexer.token() == Token.DISABLE) { lexer.nextToken(); @@ -991,7 +991,7 @@ public class SQLStatementParser extends SQLParser { SQLAlterTableAlterColumn alterColumn = parseAlterColumn(); stmt.addItem(alterColumn); } else { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } } else if (identifierEquals("CHANGE")) { lexer.nextToken(); @@ -1055,7 +1055,7 @@ public class SQLStatementParser extends SQLParser { setLifecycle.setLifecycle(this.exprParser.primary()); stmt.addItem(setLifecycle); } else { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } } else if (lexer.token() == Token.PARTITION) { lexer.nextToken(); @@ -1151,9 +1151,9 @@ public class SQLStatementParser extends SQLParser { return stmt; } - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } protected SQLAlterTableItem parseAlterTableRename() { @@ -1175,7 +1175,7 @@ public class SQLStatementParser extends SQLParser { return item; } - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } protected SQLAlterTableAlterColumn parseAlterColumn() { @@ -1236,7 +1236,7 @@ public class SQLStatementParser extends SQLParser { item.setIndexName(indexName); stmt.addItem(item); } else { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } } @@ -1267,7 +1267,7 @@ public class SQLStatementParser extends SQLParser { } public SQLStatement parseRename() { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } protected SQLDropTableStatement parseDropTable(boolean acceptDrop) { @@ -1818,7 +1818,7 @@ public class SQLStatementParser extends SQLParser { } // lexer.reset(mark_bp, mark_ch, Token.CREATE); - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO " + lexer.info()); } else if (token == Token.DATABASE) { lexer.nextToken(); if (identifierEquals("LINK")) { diff --git a/src/main/java/com/alibaba/druid/util/ListDG.java b/src/main/java/com/alibaba/druid/util/ListDG.java new file mode 100644 index 0000000000..c01c3ee897 --- /dev/null +++ b/src/main/java/com/alibaba/druid/util/ListDG.java @@ -0,0 +1,289 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.util; + +/** + * Java: 无回路有向图(Directed Acyclic Graph)的拓扑排序 + * 该DAG图是通过邻接表实现的。 + * + * @author skywang + * @date 2014/04/22 + */ + +import java.util.*; + +public class ListDG { + // 邻接表中表对应的链表的顶点 + private class ENode { + int ivex; // 该边所指向的顶点的位置 + ENode nextEdge; // 指向下一条弧的指针 + } + + // 邻接表中表的顶点 + private class VNode { + Object data; // 顶点信息 + ENode firstEdge; // 指向第一条依附该顶点的弧 + }; + + private List mVexs; // 顶点数组 + + /* + * 创建图(用已提供的矩阵) + * + * 参数说明: + * vexs -- 顶点数组 + * edges -- 边数组 + */ + public ListDG(List vexs, List edges) { + + // 初始化"顶点数"和"边数" + int vlen = vexs.size(); + int elen = edges.size(); + + // 初始化"顶点" + mVexs = new ArrayList(); + for (int i = 0; i < vlen; i++) { + // 新建VNode + VNode vnode = new VNode(); + vnode.data = vexs.get(i); + vnode.firstEdge = null; + // 将vnode添加到数组mVexs中 + mVexs.add(vnode); + } + + // 初始化"边" + for (int i = 0; i < elen; i++) { + // 读取边的起始顶点和结束顶点 + Object c1 = edges.get(i)[0]; + Object c2 = edges.get(i)[1]; + // 读取边的起始顶点和结束顶点 + int p1 = getPosition(edges.get(i)[0]); + int p2 = getPosition(edges.get(i)[1]); + + // 初始化node1 + ENode node1 = new ENode(); + node1.ivex = p2; + // 将node1链接到"p1所在链表的末尾" + if(mVexs.get(p1).firstEdge == null) + mVexs.get(p1).firstEdge = node1; + else + linkLast(mVexs.get(p1).firstEdge, node1); + } + } + + /* + * 将node节点链接到list的最后 + */ + private void linkLast(ENode list, ENode node) { + ENode p = list; + + while(p.nextEdge!=null) + p = p.nextEdge; + p.nextEdge = node; + } + + /* + * 返回ch位置 + */ + private int getPosition(Object ch) { + for(int i=0; i queue; // 辅组队列 + + ins = new int[num]; + //tops = new Object[num]; + queue = new LinkedList(); + + // 统计每个顶点的入度数 + for(int i = 0; i < num; i++) { + + ENode node = mVexs.get(i).firstEdge; + while (node != null) { + ins[node.ivex]++; + node = node.nextEdge; + } + } + + // 将所有入度为0的顶点入队列 + for(int i = 0; i < num; i ++) + if(ins[i] == 0) + queue.offer(i); // 入队列 + + while (!queue.isEmpty()) { // 队列非空 + int j = queue.poll().intValue(); // 出队列。j是顶点的序号 + tops[index++] = mVexs.get(j).data; // 将该顶点添加到tops中,tops是排序结果 + ENode node = mVexs.get(j).firstEdge;// 获取以该顶点为起点的出边队列 + + // 将与"node"关联的节点的入度减1; + // 若减1之后,该节点的入度为0;则将该节点添加到队列中。 + while(node != null) { + // 将节点(序号为node.ivex)的入度减1。 + ins[node.ivex]--; + // 若节点的入度为0,则将其"入队列" + if( ins[node.ivex] == 0) + queue.offer(node.ivex); // 入队列 + + node = node.nextEdge; + } + } + + if(index != num) { + // System.out.printf("Graph has a cycle\n"); + return 1; + } + + // 打印拓扑排序结果 +// System.out.printf("== TopSort: "); +// for(int i = 0; i < num; i ++) { +// System.out.printf("%c ", tops[i]); +// } +// System.out.printf("\n"); + + return 0; + } + + public static void main(String[] args) { + Object[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G'}; + Object[][] edges = new Object[][]{ + {vexs[0], vexs[6]}, + {vexs[1], vexs[0]}, + {vexs[1], vexs[3]}, + {vexs[2], vexs[5]}, + {vexs[2], vexs[6]}, + {vexs[3], vexs[4]}, + {vexs[3], vexs[5]}}; + ListDG pG; + + // 自定义"图"(输入矩阵队列) + //pG = new ListDG(); + // 采用已有的"图" + pG = new ListDG(Arrays.asList(vexs), Arrays.asList(edges)); + + pG.print(); // 打印图 + //pG.DFS(); // 深度优先遍历 + //pG.BFS(); // 广度优先遍历 + pG.topologicalSort(); // 拓扑排序 + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/druid/parser/mysql/keywords b/src/main/resources/META-INF/druid/parser/mysql/keywords index 18da15607a..47da8234b5 100644 --- a/src/main/resources/META-INF/druid/parser/mysql/keywords +++ b/src/main/resources/META-INF/druid/parser/mysql/keywords @@ -412,6 +412,7 @@ sounds source spatial specific +sql sqlexception sqlstate sqlwarning diff --git a/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest.java b/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest.java index 92afeeba87..074c272762 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest.java @@ -62,21 +62,24 @@ public class CreateCompareTest extends TestCase { "\tint bigint\n" + ");"; - List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); - - List createStmtList = new ArrayList(); - for (SQLStatement item : stmtList) { - createStmtList.add((SQLCreateTableStatement) item); - } - - SQLCreateTableStatement.sort(createStmtList); - - assertEquals("t9", createStmtList.get(9).getName().getSimpleName()); - assertEquals("t8", createStmtList.get(8).getName().getSimpleName()); - assertEquals("t7", createStmtList.get(7).getName().getSimpleName()); - assertEquals("t6", createStmtList.get(6).getName().getSimpleName()); - assertEquals("t5", createStmtList.get(5).getName().getSimpleName()); + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + SQLCreateTableStatement.sort(stmtList); + + assertEquals("t9", ((SQLCreateTableStatement)stmtList.get(9)).getName().getSimpleName()); + assertEquals("t3", ((SQLCreateTableStatement)stmtList.get(8)).getName().getSimpleName()); + assertEquals("t0", ((SQLCreateTableStatement)stmtList.get(7)).getName().getSimpleName()); + assertEquals("t1", ((SQLCreateTableStatement)stmtList.get(6)).getName().getSimpleName()); + assertEquals("t8", ((SQLCreateTableStatement)stmtList.get(5)).getName().getSimpleName()); + assertEquals("t7", ((SQLCreateTableStatement)stmtList.get(4)).getName().getSimpleName()); + assertEquals("t6", ((SQLCreateTableStatement)stmtList.get(3)).getName().getSimpleName()); + assertEquals("t5", ((SQLCreateTableStatement)stmtList.get(2)).getName().getSimpleName()); + assertEquals("t4", ((SQLCreateTableStatement)stmtList.get(1)).getName().getSimpleName()); + assertEquals("t2", ((SQLCreateTableStatement)stmtList.get(0)).getName().getSimpleName()); + + + String sortedSql = SQLUtils.toSQLString(stmtList, JdbcConstants.ORACLE); + System.out.println(sortedSql); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest_1.java b/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest_1.java new file mode 100644 index 0000000000..edd08d0da0 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest_1.java @@ -0,0 +1,105 @@ +package com.alibaba.druid.bvt.sql; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +/** + * Created by wenshao on 18/07/2017. + */ +public class CreateCompareTest_1 extends TestCase { + public void test_0() throws Exception { + String sql = "CREATE TABLE XT_DJ_XT (\n" + + "\tXTBH varchar(20) NOT NULL,\n" + + "\tXTDM varchar(20) NOT NULL,\n" + + "\tXTMC varchar(200) NOT NULL,\n" + + "\tXTBB varchar(20),\n" + + "\tKQSJ datetime NOT NULL,\n" + + "\tYXSJQ datetime NOT NULL,\n" + + "\tYXSJZ datetime,\n" + + "\tYXBZ char(1),\n" + + "\tXTMS varchar(200),\n" + + "\tCONSTRAINT PK_XT_DJ_XT PRIMARY KEY (XTBH)\n" + + ");\n" + + "\n" + + "CREATE TABLE XT_DM_GN (\n" + + "\tGNDM varchar(20) NOT NULL,\n" + + "\tGNQQH varchar(20) NOT NULL,\n" + + "\tGNMC varchar(200) NOT NULL,\n" + + "\tSJGNDM varchar(20),\n" + + "\tCDBZ char(1),\n" + + "\tPLXH bigint,\n" + + "\tLJDZ varchar(200),\n" + + "\tYXBZ char(1),\n" + + "\tGNMS varchar(200),\n" + + "\tDYZB varchar(20),\n" + + "\tCDTB varchar(100),\n" + + "\tDXBZ char(1),\n" + + "\tCONSTRAINT PK_XT_DM_GN PRIMARY KEY (GNDM)\n" + + ");\n" + + "\n" + + "CREATE TABLE XT_DJ_YHCD (\n" + + "\tCDBH varchar(20) NOT NULL,\n" + + "\tYHBH varchar(20),\n" + + "\tGNBH varchar(20),\n" + + "\tPLXH bigint,\n" + + "\tXTBH varchar(20),\n" + + "\tCONSTRAINT PK_XT_DJ_YHCD PRIMARY KEY (CDBH),\n" + + "\tFOREIGN KEY (GNBH) REFERENCES XT_DJ_GN (GNBH),\n" + + "\tFOREIGN KEY (YHBH) REFERENCES XT_DJ_YH (YHBH)\n" + + ");\n" + + "\n" + + "CREATE TABLE XT_DJ_YH (\n" + + "\tYHBH varchar(20) NOT NULL,\n" + + "\tXTBH varchar(20) NOT NULL,\n" + + "\tYHDM varchar(20) NOT NULL,\n" + + "\tDLMM varchar(20) NOT NULL,\n" + + "\tYHMC varchar(200) NOT NULL,\n" + + "\tCJYH varchar(20),\n" + + "\tCJSJ datetime,\n" + + "\tYHBZ char(1) DEFAULT '1',\n" + + "\tYXBZ char(1),\n" + + "\tYHMS varchar(200),\n" + + "\tTSBZ char(1),\n" + + "\tCONSTRAINT PK_XT_DJ_YH PRIMARY KEY (YHBH),\n" + + "\tFOREIGN KEY (XTBH) REFERENCES XT_DJ_XT (XTBH)\n" + + ");\n" + + "\n" + + "CREATE TABLE XT_DJ_GN (\n" + + "\tGNBH varchar(20) NOT NULL,\n" + + "\tXTBH varchar(20),\n" + + "\tGNDM varchar(20) NOT NULL,\n" + + "\tGNMC varchar(200) NOT NULL,\n" + + "\tSJGNBH varchar(20),\n" + + "\tCDBZ char(1),\n" + + "\tPLXH bigint,\n" + + "\tFWKZBZ char(1),\n" + + "\tYXBZ char(1),\n" + + "\tLJDZ varchar(200),\n" + + "\tCONSTRAINT PK_XT_DJ_GN PRIMARY KEY (GNBH),\n" + + "\tFOREIGN KEY (XTBH) REFERENCES XT_DJ_XT (XTBH),\n" + + "\tFOREIGN KEY (GNDM) REFERENCES XT_DM_GN (GNDM)\n" + + ");\n" + + "\n" + + "\n" + + "\n" + + "\n"; + + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + + + SQLCreateTableStatement.sort(stmtList); + + assertEquals("XT_DJ_XT", ((SQLCreateTableStatement)stmtList.get(0)).getName().getSimpleName()); + assertEquals("XT_DM_GN", ((SQLCreateTableStatement)stmtList.get(1)).getName().getSimpleName()); + assertEquals("XT_DJ_YH", ((SQLCreateTableStatement)stmtList.get(2)).getName().getSimpleName()); + assertEquals("XT_DJ_GN", ((SQLCreateTableStatement)stmtList.get(3)).getName().getSimpleName()); + assertEquals("XT_DJ_YHCD", ((SQLCreateTableStatement)stmtList.get(4)).getName().getSimpleName()); + + String sortedSql = SQLUtils.toSQLString(stmtList, JdbcConstants.ORACLE); + System.out.println(sortedSql); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest69.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest69.java new file mode 100644 index 0000000000..fd69e400fa --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest69.java @@ -0,0 +1,289 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.oracle.select; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import org.junit.Assert; + +import java.util.List; + +public class OracleSelectTest69 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "CREATE TABLE \"SC01\".\"TB01\" \n" + + " (\t\"KPPZXH\" VARCHAR2(80) NOT NULL ENABLE, \n" + + "\t\"NSRDZDAH\" VARCHAR2(80) NOT NULL ENABLE, \n" + + "\t\"NSRSBH\" VARCHAR2(80) DEFAULT '', \n" + + "\t\"NSRMC\" VARCHAR2(160) DEFAULT '', \n" + + "\t\"KPFDZJDH\" VARCHAR2(400) DEFAULT '', \n" + + "\t\"KPFYHJZH\" VARCHAR2(400) DEFAULT '', \n" + + "\t\"FPZLDM\" VARCHAR2(20) NOT NULL ENABLE, \n" + + "\t\"DZFPHM\" VARCHAR2(40), \n" + + "\t\"KPRQ\" DATE NOT NULL ENABLE, \n" + + "\t\"HYFL\" VARCHAR2(40) NOT NULL ENABLE, \n" + + "\t\"SPFNSRMC\" VARCHAR2(400) DEFAULT '', \n" + + "\t\"SPFYHJZH\" VARCHAR2(400) DEFAULT '', \n" + + "\t\"HJ\" NUMBER(20,2) DEFAULT 0, \n" + + "\t\"SL\" NUMBER(20,2) DEFAULT 0, \n" + + "\t\"SE\" NUMBER(20,2) DEFAULT 0, \n" + + "\t\"KPR\" VARCHAR2(40) DEFAULT '', \n" + + "\t\"SKR\" VARCHAR2(40) DEFAULT '', \n" + + "\t\"LRRQ\" DATE, \n" + + "\t\"ZFBZ\" CHAR(1) DEFAULT 'N' NOT NULL ENABLE, \n" + + "\t\"YJBZ\" CHAR(1) DEFAULT 'N' NOT NULL ENABLE, \n" + + "\t\"GHFQYLX\" VARCHAR2(20), \n" + + "\t\"SPFDZJDH\" VARCHAR2(400), \n" + + "\t\"SPFNSRSBH\" VARCHAR2(60), \n" + + "\t\"FPCJBZ\" CHAR(1), \n" + + "\t\"FPBZ\" CHAR(1) DEFAULT '0', \n" + + "\t\"JSJE\" NUMBER(20,2), \n" + + "\t\"ZJLX\" VARCHAR2(20), \n" + + "\t\"KJFSBH\" VARCHAR2(40), \n" + + "\t\"SQBHM\" VARCHAR2(160), \n" + + "\t\"WSPZHM\" VARCHAR2(80), \n" + + "\t\"LZFPHM\" VARCHAR2(40), \n" + + "\t\"HCJE\" NUMBER(20,2) DEFAULT 0, \n" + + "\t\"XHFQYLX_DM\" VARCHAR2(20), \n" + + "\t\"YNSE\" NUMBER(20,2), \n" + + "\t\"BZ\" VARCHAR2(600), \n" + + "\t\"ZFYY\" VARCHAR2(20), \n" + + "\t\"HCYY\" VARCHAR2(20), \n" + + "\t\"ZFRQ\" DATE, \n" + + "\t\"FPZL\" VARCHAR2(20), \n" + + "\t\"SWJG_DM\" VARCHAR2(40), \n" + + "\t\"HTHM\" VARCHAR2(160), \n" + + "\t\"XYZHS\" VARCHAR2(160), \n" + + "\t\"JGRQ\" DATE, \n" + + "\t\"SHBZ\" VARCHAR2(40), \n" + + "\t\"BIZHONG\" VARCHAR2(40), \n" + + "\t\"DKJE\" NUMBER(20,2), \n" + + "\t\"DSWSPZHM\" VARCHAR2(80), \n" + + "\t\"DKYF\" DATE, \n" + + "\t\"JGTK\" VARCHAR2(200), \n" + + "\t\"HXDH\" VARCHAR2(80), \n" + + "\t\"HL\" NUMBER(20,6), \n" + + "\t\"LAJE\" NUMBER(20,2), \n" + + "\t\"HC_LCBZ\" CHAR(1), \n" + + "\t\"SPR_BHYY\" VARCHAR2(400), \n" + + "\t\"CONTENT\" BLOB, \n" + + "\t\"ZF_LCBZ\" CHAR(1), \n" + + "\t\"FPDM\" VARCHAR2(40), \n" + + "\t\"FPHM\" VARCHAR2(40), \n" + + "\t\"GHFSJH\" VARCHAR2(30), \n" + + "\t\"GHFDZYX\" VARCHAR2(100), \n" + + "\t\"GHFZH\" VARCHAR2(100), \n" + + "\t\"KPLX\" VARCHAR2(2), \n" + + "\t\"JSHJ\" NUMBER(18,2), \n" + + "\t\"HJJE\" NUMBER(18,2), \n" + + "\t\"HJSE\" NUMBER(18,2), \n" + + "\t\"YFPDM\" VARCHAR2(24), \n" + + "\t\"YFPHM\" VARCHAR2(16), \n" + + "\t\"FHR\" VARCHAR2(16), \n" + + "\t\"EWM\" VARCHAR2(4000), \n" + + "\t\"FPMW\" VARCHAR2(224), \n" + + "\t\"JYM\" VARCHAR2(40), \n" + + "\t\"JQBH\" VARCHAR2(24), \n" + + "\t\"ERPTID\" VARCHAR2(80), \n" + + "\t\"DSPTDM\" VARCHAR2(40), \n" + + "\t CONSTRAINT \"PK_FP_TY_KP_MFP1\" PRIMARY KEY (\"KPPZXH\")\n" + + " USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS NOLOGGING \n" + + " STORAGE(INITIAL 40960 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1\n" + + " BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)\n" + + " TABLESPACE \"DZFP_HWXS1_IDX\" ENABLE\n" + + " ) SEGMENT CREATION IMMEDIATE \n" + + " PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " NOCOMPRESS LOGGING\n" + + " STORAGE(INITIAL 40960 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1\n" + + " BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)\n" + + " TABLESPACE \"DZFP_HWXS1_IDX\" \n" + + " LOB (\"CONTENT\") STORE AS BASICFILE \"DZFP_HWXS1_IDX\"(\n" + + " TABLESPACE \"DZFP_HWXS1_IDX\" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10\n" + + " NOCACHE LOGGING \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1\n" + + " BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)) "; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(1, visitor.getTables().size()); + + assertEquals(74, visitor.getColumns().size()); + + { + String text = SQLUtils.toOracleString(stmt); + + assertEquals("CREATE TABLE \"SC01\".\"TB01\" (\n" + + "\t\"KPPZXH\" VARCHAR2(80) NOT NULL ENABLE,\n" + + "\t\"NSRDZDAH\" VARCHAR2(80) NOT NULL ENABLE,\n" + + "\t\"NSRSBH\" VARCHAR2(80) DEFAULT NULL,\n" + + "\t\"NSRMC\" VARCHAR2(160) DEFAULT NULL,\n" + + "\t\"KPFDZJDH\" VARCHAR2(400) DEFAULT NULL,\n" + + "\t\"KPFYHJZH\" VARCHAR2(400) DEFAULT NULL,\n" + + "\t\"FPZLDM\" VARCHAR2(20) NOT NULL ENABLE,\n" + + "\t\"DZFPHM\" VARCHAR2(40),\n" + + "\t\"KPRQ\" DATE NOT NULL ENABLE,\n" + + "\t\"HYFL\" VARCHAR2(40) NOT NULL ENABLE,\n" + + "\t\"SPFNSRMC\" VARCHAR2(400) DEFAULT NULL,\n" + + "\t\"SPFYHJZH\" VARCHAR2(400) DEFAULT NULL,\n" + + "\t\"HJ\" NUMBER(20, 2) DEFAULT 0,\n" + + "\t\"SL\" NUMBER(20, 2) DEFAULT 0,\n" + + "\t\"SE\" NUMBER(20, 2) DEFAULT 0,\n" + + "\t\"KPR\" VARCHAR2(40) DEFAULT NULL,\n" + + "\t\"SKR\" VARCHAR2(40) DEFAULT NULL,\n" + + "\t\"LRRQ\" DATE,\n" + + "\t\"ZFBZ\" CHAR(1) DEFAULT 'N' NOT NULL ENABLE,\n" + + "\t\"YJBZ\" CHAR(1) DEFAULT 'N' NOT NULL ENABLE,\n" + + "\t\"GHFQYLX\" VARCHAR2(20),\n" + + "\t\"SPFDZJDH\" VARCHAR2(400),\n" + + "\t\"SPFNSRSBH\" VARCHAR2(60),\n" + + "\t\"FPCJBZ\" CHAR(1),\n" + + "\t\"FPBZ\" CHAR(1) DEFAULT '0',\n" + + "\t\"JSJE\" NUMBER(20, 2),\n" + + "\t\"ZJLX\" VARCHAR2(20),\n" + + "\t\"KJFSBH\" VARCHAR2(40),\n" + + "\t\"SQBHM\" VARCHAR2(160),\n" + + "\t\"WSPZHM\" VARCHAR2(80),\n" + + "\t\"LZFPHM\" VARCHAR2(40),\n" + + "\t\"HCJE\" NUMBER(20, 2) DEFAULT 0,\n" + + "\t\"XHFQYLX_DM\" VARCHAR2(20),\n" + + "\t\"YNSE\" NUMBER(20, 2),\n" + + "\t\"BZ\" VARCHAR2(600),\n" + + "\t\"ZFYY\" VARCHAR2(20),\n" + + "\t\"HCYY\" VARCHAR2(20),\n" + + "\t\"ZFRQ\" DATE,\n" + + "\t\"FPZL\" VARCHAR2(20),\n" + + "\t\"SWJG_DM\" VARCHAR2(40),\n" + + "\t\"HTHM\" VARCHAR2(160),\n" + + "\t\"XYZHS\" VARCHAR2(160),\n" + + "\t\"JGRQ\" DATE,\n" + + "\t\"SHBZ\" VARCHAR2(40),\n" + + "\t\"BIZHONG\" VARCHAR2(40),\n" + + "\t\"DKJE\" NUMBER(20, 2),\n" + + "\t\"DSWSPZHM\" VARCHAR2(80),\n" + + "\t\"DKYF\" DATE,\n" + + "\t\"JGTK\" VARCHAR2(200),\n" + + "\t\"HXDH\" VARCHAR2(80),\n" + + "\t\"HL\" NUMBER(20, 6),\n" + + "\t\"LAJE\" NUMBER(20, 2),\n" + + "\t\"HC_LCBZ\" CHAR(1),\n" + + "\t\"SPR_BHYY\" VARCHAR2(400),\n" + + "\t\"CONTENT\" BLOB,\n" + + "\t\"ZF_LCBZ\" CHAR(1),\n" + + "\t\"FPDM\" VARCHAR2(40),\n" + + "\t\"FPHM\" VARCHAR2(40),\n" + + "\t\"GHFSJH\" VARCHAR2(30),\n" + + "\t\"GHFDZYX\" VARCHAR2(100),\n" + + "\t\"GHFZH\" VARCHAR2(100),\n" + + "\t\"KPLX\" VARCHAR2(2),\n" + + "\t\"JSHJ\" NUMBER(18, 2),\n" + + "\t\"HJJE\" NUMBER(18, 2),\n" + + "\t\"HJSE\" NUMBER(18, 2),\n" + + "\t\"YFPDM\" VARCHAR2(24),\n" + + "\t\"YFPHM\" VARCHAR2(16),\n" + + "\t\"FHR\" VARCHAR2(16),\n" + + "\t\"EWM\" VARCHAR2(4000),\n" + + "\t\"FPMW\" VARCHAR2(224),\n" + + "\t\"JYM\" VARCHAR2(40),\n" + + "\t\"JQBH\" VARCHAR2(24),\n" + + "\t\"ERPTID\" VARCHAR2(80),\n" + + "\t\"DSPTDM\" VARCHAR2(40),\n" + + "\tCONSTRAINT \"PK_FP_TY_KP_MFP1\" PRIMARY KEY (\"KPPZXH\")\n" + + "\t\tUSING INDEX\n" + + "\t\tPCTFREE 10\n" + + "\t\tINITRANS 2\n" + + "\t\tMAXTRANS 255\n" + + "\t\tNOLOGGING\n" + + "\t\tTABLESPACE \"DZFP_HWXS1_IDX\"\n" + + "\t\tSTORAGE (\n" + + "\t\t\tINITIAL 40960\n" + + "\t\t\tNEXT 1048576\n" + + "\t\t\tMINEXTENTS 1\n" + + "\t\t\tMAXEXTENTS 2147483645\n" + + "\t\t\tPCTINCREASE 0\n" + + "\t\t\tFREELISTS 1\n" + + "\t\t\tFREELIST GROUPS 1\n" + + "\t\t\tBUFFER_POOL DEFAULT\n" + + "\t\t\tFLASH_CACHE DEFAULT\n" + + "\t\t\tCELL_FLASH_CACHE DEFAULT\n" + + "\t\t)\n" + + "\t\tCOMPUTE STATISTICS\n" + + "\t\tENABLE\n" + + ")\n" + + "PCTFREE 10\n" + + "PCTUSED 40\n" + + "INITRANS 1\n" + + "MAXTRANS 255\n" + + "NOCOMPRESS\n" + + "LOGGING\n" + + "TABLESPACE \"DZFP_HWXS1_IDX\"\n" + + "STORAGE (\n" + + "\tINITIAL 40960\n" + + "\tNEXT 1048576\n" + + "\tMINEXTENTS 1\n" + + "\tMAXEXTENTS 2147483645\n" + + "\tPCTINCREASE 0\n" + + "\tFREELISTS 1\n" + + "\tFREELIST GROUPS 1\n" + + "\tBUFFER_POOL DEFAULT\n" + + "\tFLASH_CACHE DEFAULT\n" + + "\tCELL_FLASH_CACHE DEFAULT\n" + + ")\n" + + "LOB (\"CONTENT\") STORE AS BASICFILE \"DZFP_HWXS1_IDX\" (\n" + + "\tLOGGING\n" + + "\tTABLESPACE \"DZFP_HWXS1_IDX\"\n" + + "\tSTORAGE (\n" + + "\t\tINITIAL 1048576\n" + + "\t\tNEXT 1048576\n" + + "\t\tMINEXTENTS 1\n" + + "\t\tMAXEXTENTS 2147483645\n" + + "\t\tPCTINCREASE 0\n" + + "\t\tFREELISTS 1\n" + + "\t\tFREELIST GROUPS 1\n" + + "\t\tBUFFER_POOL DEFAULT\n" + + "\t\tFLASH_CACHE DEFAULT\n" + + "\t\tCELL_FLASH_CACHE DEFAULT\n" + + "\t)\n" + + "\tENABLE STORAGE IN ROW\n" + + "\tCHUNK 8192\n" + + "\tNOCACHE\n" + + ")", text); + } + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh"))); + + // Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +}