bug fixed for oracle sql parser

This commit is contained in:
温少
2012-02-28 04:51:12 +08:00
parent 431c684425
commit 81a70bed08
34 changed files with 962 additions and 140 deletions
@@ -18,7 +18,7 @@ package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLExprTableSource extends SQLTableSource {
public class SQLExprTableSource extends SQLTableSourceImpl {
private static final long serialVersionUID = 1L;
@@ -18,7 +18,7 @@ package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLJoinTableSource extends SQLTableSource {
public class SQLJoinTableSource extends SQLTableSourceImpl {
private static final long serialVersionUID = 1L;
@@ -31,6 +31,10 @@ public class SQLSetStatement extends SQLStatementImpl {
public SQLSetStatement(){
}
public SQLSetStatement(SQLExpr target, SQLExpr value) {
this.items.add(new Item(target, value));
}
public List<Item> getItems() {
return items;
@@ -17,7 +17,7 @@ package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLSubqueryTableSource extends SQLTableSource {
public class SQLSubqueryTableSource extends SQLTableSourceImpl {
private static final long serialVersionUID = 1L;
@@ -1,42 +1,10 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLObject;
public abstract class SQLTableSource extends SQLObjectImpl {
public interface SQLTableSource extends SQLObject {
private static final long serialVersionUID = 1L;
String getAlias();
protected String alias;
public SQLTableSource(){
}
public SQLTableSource(String alias){
this.alias = alias;
}
public String getAlias() {
return this.alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
void setAlias(String alias);
}
@@ -0,0 +1,42 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
public abstract class SQLTableSourceImpl extends SQLObjectImpl implements SQLTableSource {
private static final long serialVersionUID = 1L;
protected String alias;
public SQLTableSourceImpl(){
}
public SQLTableSourceImpl(String alias){
this.alias = alias;
}
public String getAlias() {
return this.alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
}
@@ -54,8 +54,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
public boolean visit(MySqlDeleteStatement x) {
aliasLocal.set(new HashMap<String, String>());
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Delete);
setMode(x, Mode.Delete);
aliasLocal.set(new HashMap<String, String>());
@@ -89,14 +88,12 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
@Override
public void endVisit(MySqlInsertStatement x) {
Mode originalMode = (Mode) x.getAttribute("_original_use_mode");
modeLocal.set(originalMode);
setModeOrigin(x);
}
@Override
public boolean visit(MySqlInsertStatement x) {
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Insert);
setMode(x, Mode.Insert);
aliasLocal.set(new HashMap<String, String>());
@@ -0,0 +1,31 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleBlockStatement extends OracleStatementImpl {
private static final long serialVersionUID = 1L;
private List<SQLStatement> statementList = new ArrayList<SQLStatement>();
public List<SQLStatement> getStatementList() {
return statementList;
}
public void setStatementList(List<SQLStatement> statementList) {
this.statementList = statementList;
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, statementList);
}
visitor.endVisit(this);
}
}
@@ -1,6 +1,10 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
@@ -10,8 +14,17 @@ public class OracleInsertStatement extends SQLInsertStatement implements OracleS
private static final long serialVersionUID = 1L;
private OracleReturningClause returning;
private OracleReturningClause returning;
private OracleErrorLoggingClause errorLogging;
private List<OracleHint> hints = new ArrayList<OracleHint>();
public List<OracleHint> getHints() {
return hints;
}
public void setHints(List<OracleHint> hints) {
this.hints = hints;
}
public OracleReturningClause getReturning() {
return returning;
@@ -0,0 +1,60 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleLockTableStatement extends OracleStatementImpl {
private static final long serialVersionUID = 1L;
private SQLName table;
private LockMode lockMode;
private boolean noWait = false;
private SQLExpr wait;
public boolean isNoWait() {
return noWait;
}
public void setNoWait(boolean noWait) {
this.noWait = noWait;
}
public SQLExpr getWait() {
return wait;
}
public void setWait(SQLExpr wait) {
this.wait = wait;
}
public SQLName getTable() {
return table;
}
public void setTable(SQLName table) {
this.table = table;
}
public LockMode getLockMode() {
return lockMode;
}
public void setLockMode(LockMode lockMode) {
this.lockMode = lockMode;
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, table);
acceptChild(visitor, wait);
}
visitor.endVisit(this);
}
public static enum LockMode {
EXCLUSIVE, SHARE
}
}
@@ -20,6 +20,7 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -29,6 +30,7 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
private final List<SQLExpr> using = new ArrayList<SQLExpr>();
protected OracleSelectPivotBase pivot;
protected FlashbackQueryClause flashback;
public OracleSelectJoin(String alias){
super(alias);
@@ -38,6 +40,14 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
}
public FlashbackQueryClause getFlashback() {
return flashback;
}
public void setFlashback(FlashbackQueryClause flashback) {
this.flashback = flashback;
}
public OracleSelectPivotBase getPivot() {
return pivot;
}
@@ -57,6 +67,7 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
acceptChild(visitor, this.right);
acceptChild(visitor, this.condition);
acceptChild(visitor, this.using);
acceptChild(visitor, this.flashback);
}
visitor.endVisit(this);
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -26,10 +27,20 @@ public class OracleSelectSubqueryTableSource extends SQLSubqueryTableSource impl
protected OracleSelectPivotBase pivot;
protected FlashbackQueryClause flashback;
public OracleSelectSubqueryTableSource(){
}
public FlashbackQueryClause getFlashback() {
return flashback;
}
public void setFlashback(FlashbackQueryClause flashback) {
this.flashback = flashback;
}
public OracleSelectSubqueryTableSource(String alias){
super(alias);
}
@@ -58,13 +69,9 @@ public class OracleSelectSubqueryTableSource extends SQLSubqueryTableSource impl
protected void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.select);
acceptChild(visitor, this.flashback);
}
visitor.endVisit(this);
}
public void output(StringBuffer buf) {
buf.append("(");
this.select.output(buf);
buf.append(")");
}
}
@@ -15,14 +15,16 @@
*/
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
public interface OracleSelectTableSource {
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause;
String getAlias();
void setAlias(String alias);
public interface OracleSelectTableSource extends SQLTableSource {
OracleSelectPivotBase getPivot();
void setPivot(OracleSelectPivotBase pivot);
FlashbackQueryClause getFlashback();
void setFlashback(FlashbackQueryClause flashback);
}
@@ -26,11 +26,14 @@ public class OracleDeleteParser extends SQLStatementParser {
public OracleDeleteParser(String sql){
super(sql);
this.exprParser = new OracleExprParser(lexer);
}
public OracleDeleteParser(Lexer lexer){
super(lexer);
this.exprParser = new OracleExprParser(lexer);
}
public OracleDeleteStatement parseDelete() throws ParserException {
accept(Token.DELETE);
@@ -19,6 +19,7 @@ import java.math.BigInteger;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
@@ -599,4 +600,22 @@ public class OracleExprParser extends SQLExprParser {
lexer.nextToken();
}
}
public SQLName name() throws ParserException {
SQLName name = super.name();
if (lexer.token() == Token.MONKEYS_AT) {
lexer.nextToken();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("syntax error, expect identifier, but " + lexer.token());
}
OracleDbLinkExpr dbLink = new OracleDbLinkExpr();
dbLink.setExpr(name);
dbLink.setDbLink(lexer.stringVal());
lexer.nextToken();
return dbLink;
}
return name;
}
}
@@ -113,6 +113,13 @@ public class OracleLexer extends Lexer {
map.put("UNLIMITED", Token.UNLIMITED);
map.put("RETURNING", Token.RETURNING);
map.put("LIMIT", Token.LIMIT);
map.put("OF", Token.OF);
map.put("BEGIN", Token.BEGIN);
map.put("SHARE", Token.SHARE);
map.put("EXCLUSIVE", Token.EXCLUSIVE);
map.put("MODE", Token.MODE);
map.put("WAIT", Token.WAIT);
map.put("NOWAIT", Token.NOWAIT);
DEFAULT_ORACLE_KEYWORDS = new Keywords(map);
}
@@ -164,7 +171,7 @@ public class OracleLexer extends Lexer {
if (tok != null) {
token = tok;
} else {
token = Token.IDENTIFIER;
token = Token.VARIANT;
}
}
@@ -323,4 +330,5 @@ public class OracleLexer extends Lexer {
token = Token.LITERAL_INT;
}
}
}
@@ -28,6 +28,7 @@ import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUnionOperator;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.GroupingSetExpr;
@@ -246,6 +247,8 @@ public class OracleSelectParser extends SQLSelectParser {
lexer.nextToken();
}
this.createExprParser().parseHints(queryBlock.getHints());
parseSelectList(queryBlock);
parseFrom(queryBlock);
@@ -666,6 +669,10 @@ public class OracleSelectParser extends SQLSelectParser {
private void parseTableSourceQueryTableExpr(OracleSelectTableReference tableReference) {
tableReference.setExpr(this.createExprParser().expr());
{
FlashbackQueryClause clause = flashback();
tableReference.setFlashback(clause);
}
if (identifierEquals("SAMPLE")) {
lexer.nextToken();
@@ -733,27 +740,7 @@ public class OracleSelectParser extends SQLSelectParser {
tableReference.setPartition(partition);
}
if (lexer.token() == Token.AS) {
lexer.nextToken();
if (identifierEquals("OF")) {
lexer.nextToken();
AsOfFlashbackQueryClause clause = new AsOfFlashbackQueryClause();
if (identifierEquals("SCN")) {
clause.setType(AsOfFlashbackQueryClause.Type.SCN);
lexer.nextToken();
} else {
accept(Token.TIMESTAMP);
clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP);
}
clause.setExpr(createExprParser().primary());
tableReference.setFlashback(clause);
} else {
throw new SQLParseException("TODO");
}
} else if (identifierEquals("VERSIONS")) {
if (identifierEquals("VERSIONS")) {
lexer.nextToken();
if (lexer.token() == Token.BETWEEN) {
@@ -784,8 +771,40 @@ public class OracleSelectParser extends SQLSelectParser {
}
protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) {
if ((tableSource.getAlias() == null) || (tableSource.getAlias().length() == 0)) {
private FlashbackQueryClause flashback() {
if (lexer.token() == Token.AS) {
lexer.nextToken();
}
if (lexer.token() == Token.OF) {
lexer.nextToken();
AsOfFlashbackQueryClause clause = new AsOfFlashbackQueryClause();
if (identifierEquals("SCN")) {
clause.setType(AsOfFlashbackQueryClause.Type.SCN);
lexer.nextToken();
} else {
accept(Token.TIMESTAMP);
clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP);
}
clause.setExpr(createExprParser().primary());
return clause;
}
return null;
}
protected SQLTableSource parseTableSourceRest(OracleSelectTableSource tableSource) {
if (lexer.token() == Token.AS) {
lexer.nextToken();
if (lexer.token() == Token.OF) {
tableSource.setFlashback(flashback());
}
tableSource.setAlias(as());
} else if ((tableSource.getAlias() == null) || (tableSource.getAlias().length() == 0)) {
if (lexer.token() != Token.LEFT && lexer.token() != Token.RIGHT && lexer.token() != Token.FULL) {
tableSource.setAlias(as());
}
@@ -15,21 +15,30 @@
*/
package com.alibaba.druid.sql.dialect.oracle.parser;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement.LockMode;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLStatementParser;
@@ -40,22 +49,37 @@ public class OracleStatementParser extends SQLStatementParser {
public OracleStatementParser(String sql){
super(new OracleLexer(sql));
this.lexer.nextToken();
this.exprParser = createExprParser();
}
public OracleStatementParser(Lexer lexer){
super(lexer);
this.exprParser = createExprParser();
}
protected OracleExprParser createExprParser() {
return new OracleExprParser(lexer);
}
protected void parseInsert0_hinits(SQLInsertInto insertStatement) {
if (insertStatement instanceof OracleInsertStatement) {
OracleInsertStatement stmt = (OracleInsertStatement) insertStatement;
this.createExprParser().parseHints(stmt.getHints());
} else {
List<OracleHint> hints = new ArrayList<OracleHint>();
this.createExprParser().parseHints(hints);
}
}
@Override
public void parseStatementList(List<SQLStatement> statementList) throws ParserException {
for (;;) {
if (lexer.token() == Token.EOF) {
return;
}
if (lexer.token() == Token.END) {
return;
}
if (lexer.token() == (Token.SEMI)) {
lexer.nextToken();
@@ -75,18 +99,6 @@ public class OracleStatementParser extends SQLStatementParser {
if (lexer.token() == (Token.CREATE)) {
lexer.nextToken();
// if ((this.tokenList.lookup(1).equals(Token.ViewToken)) ||
// (this.tokenList.lookup(3).equals(Token.ViewToken))
// || (this.tokenList.lookup(4).equals(Token.ViewToken)) ||
// (this.tokenList.lookup(5).equals(Token.ViewToken))) {
// statementList.add(parseCreateView());
// }
//
// if ((this.tokenList.lookup(1).equals(Token.TableToken)) ||
// (this.tokenList.lookup(3).equals(Token.TableToken))) {
// statementList.add(parseOracleCreateTable());
// }
throw new ParserException("TODO");
}
@@ -125,10 +137,75 @@ public class OracleStatementParser extends SQLStatementParser {
continue;
}
if (lexer.token() == Token.BEGIN) {
statementList.add(this.parseBegin());
continue;
}
if (lexer.token() == Token.LOCK) {
statementList.add(this.parseLock());
continue;
}
if (lexer.token() == Token.VARIANT) {
SQLExpr variant = this.exprParser.primary();
if (variant instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) variant;
if (binaryOpExpr.getOperator() == SQLBinaryOperator.Assignment) {
SQLSetStatement stmt = new SQLSetStatement(binaryOpExpr.getLeft(), binaryOpExpr.getRight());
statementList.add(stmt);
continue;
}
}
accept(Token.COLONEQ);
SQLExpr value = this.exprParser.expr();
SQLSetStatement stmt = new SQLSetStatement(variant, value);
statementList.add(stmt);
continue;
}
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
}
public OracleLockTableStatement parseLock() {
accept(Token.LOCK);
accept(Token.TABLE);
OracleLockTableStatement stmt = new OracleLockTableStatement();
stmt.setTable(this.exprParser.name());
accept(Token.IN);
if (lexer.token() == Token.SHARE) {
stmt.setLockMode(LockMode.SHARE);
lexer.nextToken();
} else if (lexer.token() == Token.EXCLUSIVE) {
stmt.setLockMode(LockMode.EXCLUSIVE);
lexer.nextToken();
}
accept(Token.MODE);
if (lexer.token() == Token.NOWAIT) {
lexer.nextToken();
} else if (lexer.token() == Token.WAIT) {
lexer.nextToken();
stmt.setWait(exprParser.expr());
}
return stmt;
}
public OracleStatement parseBegin() {
accept(Token.BEGIN);
OracleBlockStatement block = new OracleBlockStatement();
parseStatementList(block.getStatementList());
accept(Token.END);
return block;
}
public OracleMergeStatement parseMerge() throws ParserException {
accept(Token.MERGE);
@@ -285,13 +362,13 @@ public class OracleStatementParser extends SQLStatementParser {
OracleMultiInsertStatement.InsertIntoClause insertInto = new OracleMultiInsertStatement.InsertIntoClause();
parseInsert0(insertInto);
item.setThen(insertInto);
clause.getItems().add(item);
}
if (lexer.token() == Token.ELSE) {
lexer.nextToken();
OracleMultiInsertStatement.InsertIntoClause insertInto = new OracleMultiInsertStatement.InsertIntoClause();
parseInsert0(insertInto, false);
clause.setElseItem(insertInto);
@@ -36,9 +36,11 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeInsertClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause;
@@ -768,5 +770,25 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora
public void endVisit(OracleSelectQueryBlock x) {
}
@Override
public boolean visit(OracleBlockStatement x) {
return true;
}
@Override
public void endVisit(OracleBlockStatement x) {
}
@Override
public boolean visit(OracleLockTableStatement x) {
return true;
}
@Override
public void endVisit(OracleLockTableStatement x) {
}
}
@@ -42,9 +42,11 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClause;
@@ -335,4 +337,12 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(OracleSelectQueryBlock x);
void endVisit(OracleSelectQueryBlock x);
boolean visit(OracleBlockStatement x);
void endVisit(OracleBlockStatement x);
boolean visit(OracleLockTableStatement x);
void endVisit(OracleLockTableStatement x);
}
@@ -68,9 +68,11 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeInsertClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause;
@@ -107,13 +109,17 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
super(appender);
}
public void postVisit(SQLObject astNode) {
if (astNode instanceof SQLStatement) {
if (astNode instanceof OraclePLSQLCommitStatement) {
public void postVisit(SQLObject x) {
if (x instanceof SQLStatement) {
if (x instanceof OraclePLSQLCommitStatement) {
return;
}
println(";");
if (x.getParent() instanceof SQLStatement) {
print(";");
} else {
println(";");
}
}
}
@@ -376,6 +382,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
printAndAccept(x.getUsing(), ", ");
print(")");
}
if (x.getFlashback() != null) {
println();
x.getFlashback().accept(this);
}
return false;
}
@@ -513,7 +525,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
println();
decrementIndent();
print(")");
if (x.getPivot() != null) {
incrementIndent();
@@ -522,6 +534,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
decrementIndent();
}
if (x.getFlashback() != null) {
println();
x.getFlashback().accept(this);
}
if ((x.getAlias() != null) && (x.getAlias().length() != 0)) {
print(" ");
@@ -1607,4 +1624,49 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public void endVisit(OracleSelectQueryBlock x) {
}
@Override
public boolean visit(OracleBlockStatement x) {
print("BEGIN");
incrementIndent();
println();
for (int i = 0, size = x.getStatementList().size(); i < size; ++i) {
if (i != 0) {
println();
}
SQLStatement stmt = x.getStatementList().get(i);
stmt.setParent(x);
stmt.accept(this);
}
decrementIndent();
println();
print("END");
return false;
}
@Override
public void endVisit(OracleBlockStatement x) {
}
@Override
public boolean visit(OracleLockTableStatement x) {
print("LOCK TABLE ");
x.getTable().accept(this);
print(" IN ");
print(x.getLockMode().name());
print(" MODE ");
if (x.isNoWait()) {
print("NOWAIT");
} else if (x.getWait() != null){
print("WAIT ");
x.getWait().accept(this);
}
return false;
}
@Override
public void endVisit(OracleLockTableStatement x) {
}
}
@@ -51,9 +51,11 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeInsertClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause;
@@ -138,7 +140,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
x.putAttribute(ATTR_TABLE, ident);
}
Mode mode = modeLocal.get();
Mode mode = getMode();
switch (mode) {
case Delete:
stat.incrementDeleteCount();
@@ -895,8 +897,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public boolean visit(OracleMergeStatement x) {
aliasLocal.set(new HashMap<String, String>());
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Merge);
setMode(x, Mode.Merge);
String originalTable = currentTableLocal.get();
@@ -1029,8 +1030,8 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
@Override
public boolean visit(OracleMultiInsertStatement x) {
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Insert);
x.putAttribute("_original_use_mode", getMode());
setMode(x, Mode.Insert);
aliasLocal.set(new HashMap<String, String>());
@@ -1090,5 +1091,27 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public void endVisit(ConditionalInsertClauseItem x) {
}
@Override
public boolean visit(OracleBlockStatement x) {
return true;
}
@Override
public void endVisit(OracleBlockStatement x) {
}
@Override
public boolean visit(OracleLockTableStatement x) {
String tableName = x.getTable().toString();
TableStat stat = new TableStat();
this.tableStats.put(new TableStat.Name(tableName), stat);
return false;
}
@Override
public void endVisit(OracleLockTableStatement x) {
}
}
@@ -147,8 +147,8 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit
}
}
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Delete);
x.putAttribute("_original_use_mode", getMode());
setMode(x, Mode.Delete);
String ident = ((SQLIdentifierExpr) x.getTableName()).getName();
currentTableLocal.set(ident);
@@ -191,8 +191,8 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit
x.getWith().accept(this);
}
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Insert);
x.putAttribute("_original_use_mode", getMode());
setMode(x, Mode.Insert);
String originalTable = currentTableLocal.get();
@@ -70,6 +70,7 @@ public class CharTypes {
// identifierFlags['`'] = true;
identifierFlags['_'] = true;
identifierFlags['$'] = true;
identifierFlags['#'] = true;
}
public static boolean isIdentifierChar(char c) {
@@ -252,7 +252,13 @@ public class Lexer {
scanChar();
token = COLONEQ;
} else {
token = COLON;
if (isDigit(ch)) {
unscan();
scanVariable();
} else {
unscan();
scanVariable();
}
}
return;
case '.':
@@ -552,7 +552,7 @@ public class SQLExprParser extends SQLParser {
}
}
public final SQLName name() throws ParserException {
public SQLName name() throws ParserException {
String identName;
if (lexer.token() == Token.LITERAL_ALIAS) {
identName = '"' + lexer.stringVal() + '"';
@@ -570,8 +570,8 @@ public class SQLExprParser extends SQLParser {
if (lexer.token() == Token.DOT) {
lexer.nextToken();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("error");
if (lexer.token() != Token.LITERAL_ALIAS && lexer.token() != Token.IDENTIFIER) {
throw new ParserException("error, " + lexer.token());
}
name = new SQLPropertyExpr(name, lexer.stringVal());
@@ -114,7 +114,7 @@ public class SQLParser {
lexer.nextToken();
} else {
setErrorEndPos(lexer.pos());
throw new SQLParseException("syntax error, expect " + token + ", actual " + lexer.token());
throw new SQLParseException("syntax error, expect " + token + ", actual " + lexer.token() + " " + lexer.stringVal());
}
}
@@ -37,7 +37,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
public class SQLStatementParser extends SQLParser {
protected final SQLExprParser exprParser;
protected SQLExprParser exprParser;
public SQLStatementParser(String sql){
super(sql);
@@ -173,12 +173,18 @@ public class SQLStatementParser extends SQLParser {
parseInsert0(insertStatement, true);
}
protected void parseInsert0_hinits(SQLInsertInto insertStatement) {
}
protected void parseInsert0(SQLInsertInto insertStatement, boolean acceptSubQuery) {
accept(Token.INTO);
SQLName tableName = this.exprParser.name();
insertStatement.setTableName(tableName);
parseInsert0_hinits(insertStatement);
if (lexer.token() == Token.IDENTIFIER) {
insertStatement.setAlias(lexer.stringVal());
lexer.nextToken();
@@ -151,6 +151,10 @@ public enum Token {
ERRORS("ERRORS"),
REJECT("REJECT"),
UNLIMITED("UNLIMITED"),
BEGIN("BEGIN"),
EXCLUSIVE("EXCLUSIVE"),
MODE("MODE"),
WAIT("WAIT"),
// transact-sql
TOP("TOP"),
@@ -52,14 +52,31 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
protected final Set<Column> orderByColumns = new LinkedHashSet<Column>();
protected final Set<Column> groupByColumns = new LinkedHashSet<Column>();
protected final Map<String, SQLObject> subQueryMap = new LinkedHashMap<String, SQLObject>();
protected final Map<String, SQLObject> subQueryMap = new LinkedHashMap<String, SQLObject>();
protected final static ThreadLocal<Map<String, String>> aliasLocal = new ThreadLocal<Map<String, String>>();
protected final static ThreadLocal<String> currentTableLocal = new ThreadLocal<String>();
protected final static ThreadLocal<Mode> modeLocal = new ThreadLocal<Mode>();
public final static String ATTR_TABLE = "_table_";
public final static String ATTR_COLUMN = "_column_";
private Mode mode;
protected Mode getMode() {
return mode;
}
protected void setModeOrigin(SQLObject x) {
Mode originalMode = (Mode) x.getAttribute("_original_use_mode");
mode = originalMode;
}
protected Mode setMode(SQLObject x, Mode mode) {
Mode oldMode = this.mode;
x.putAttribute("_original_use_mode", oldMode);
this.mode = mode;
return oldMode;
}
public class OrderByStatVisitor extends SQLASTVisitorAdapter {
private final SQLOrderBy orderBy;
@@ -94,7 +111,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
if (subQueryMap.containsKey(owner)) {
return false;
}
owner = aliasWrap(owner);
if (owner != null) {
@@ -258,8 +275,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
@Override
public boolean visit(SQLTruncateStatement x) {
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Insert);
setMode(x, Mode.Insert);
aliasLocal.set(new HashMap<String, String>());
@@ -288,8 +304,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
@Override
public boolean visit(SQLDropTableStatement x) {
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Insert);
setMode(x, Mode.Insert);
aliasLocal.set(new HashMap<String, String>());
@@ -318,8 +333,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
@Override
public boolean visit(SQLInsertStatement x) {
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Insert);
setMode(x, Mode.Insert);
aliasLocal.set(new HashMap<String, String>());
@@ -365,15 +379,13 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
public boolean visit(SQLSelectQueryBlock x) {
setMode(x, Mode.Select);
if (x.getFrom() instanceof SQLSubqueryTableSource) {
x.getFrom().accept(this);
return false;
}
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Select);
String originalTable = currentTableLocal.get();
if (x.getFrom() instanceof SQLExprTableSource) {
@@ -404,8 +416,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
x.putAttribute("table", currentTableLocal.get());
currentTableLocal.set(originalTable);
Mode originalMode = (Mode) x.getAttribute("_original_use_mode");
modeLocal.set(originalMode);
setModeOrigin(x);
}
public boolean visit(SQLJoinTableSource x) {
@@ -415,13 +426,13 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLPropertyExpr x) {
if (x.getOwner() instanceof SQLIdentifierExpr) {
String owner = ((SQLIdentifierExpr) x.getOwner()).getName();
if (subQueryMap.containsKey(owner)) {
return false;
}
owner = aliasWrap(owner);
if (owner != null) {
Column column = new Column(owner, x.getName());
columns.add(column);
@@ -430,13 +441,13 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
return false;
}
protected String aliasWrap(String name) {
Map<String, String> aliasMap = aliasLocal.get();
if (aliasMap.containsKey(name)) {
return aliasMap.get(name);
}
return name;
}
@@ -503,7 +514,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLAllColumnExpr x) {
String currentTable = currentTableLocal.get();
if (subQueryMap.containsKey(currentTable)) {
return false;
}
@@ -557,7 +568,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLExprTableSource x) {
if (isSimpleExprTableSource(x)) {
String ident = x.getExpr().toString();
if (subQueryMap.containsKey(ident)) {
return false;
}
@@ -571,7 +582,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
x.putAttribute(ATTR_TABLE, ident);
}
Mode mode = modeLocal.get();
Mode mode = getMode();
switch (mode) {
case Delete:
stat.incrementDeleteCount();
@@ -664,8 +675,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLDeleteStatement x) {
aliasLocal.set(new HashMap<String, String>());
x.putAttribute("_original_use_mode", modeLocal.get());
modeLocal.set(Mode.Delete);
setMode(x, Mode.Delete);
String ident = ((SQLIdentifierExpr) x.getTableName()).getName();
currentTableLocal.set(ident);
@@ -0,0 +1,41 @@
package com.alibaba.druid.bvt.sql.oracle;
import java.util.List;
import junit.framework.Assert;
import com.alibaba.druid.sql.OracleTest;
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 com.alibaba.druid.stat.TableStat;
public class OracleLockTableTest1 extends OracleTest {
public void test_0() throws Exception {
String sql = "LOCK TABLE employees IN EXCLUSIVE MODE NOWAIT; ";
OracleStatementParser parser = new OracleStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
System.out.println(output(statementList));
Assert.assertEquals(1, statementList.size());
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
statemen.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());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees")));
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(0, visitor.getColumns().size());
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id")));
}
}
@@ -0,0 +1,41 @@
package com.alibaba.druid.bvt.sql.oracle;
import java.util.List;
import junit.framework.Assert;
import com.alibaba.druid.sql.OracleTest;
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 com.alibaba.druid.stat.TableStat;
public class OracleLockTableTest2 extends OracleTest {
public void test_0() throws Exception {
String sql = "LOCK TABLE employees@remote IN SHARE MODE";
OracleStatementParser parser = new OracleStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
System.out.println(output(statementList));
Assert.assertEquals(1, statementList.size());
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
statemen.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());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees@remote")));
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(0, visitor.getColumns().size());
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id")));
}
}
@@ -0,0 +1,63 @@
package com.alibaba.druid.bvt.sql.oracle;
import java.util.List;
import junit.framework.Assert;
import com.alibaba.druid.sql.OracleTest;
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 com.alibaba.druid.stat.TableStat;
public class OracleSelectTest11 extends OracleTest {
public void test_0() throws Exception {
String sql = "SELECT ID, GMT_CREATE, GMT_MODIFIED, COMPANY_ID, MEMBER_ID" + //
" , MEMBER_SEQ, FILE_NAME, DISPLAY_NAME, DISPLAY_NAME_UTF8, FILE_SIZE" + //
" , STATUS, WIDTH, HEIGHT, REFERENCE_COUNT, HASH_CODE" + //
" , GROUP_ID" + //
" FROM (SELECT *" + //
" FROM (SELECT row_.*, rownum AS rownum_" + //
" FROM (SELECT rowid AS rid" + //
" FROM IMAGE_REPOSITORY" + //
" WHERE COMPANY_ID = :1 AND STATUS = 'enable' " + //
" AND MEMBER_SEQ = :2 AND GMT_MODIFIED >= to_date(:3, 'yyyy-mm-dd hh24:mi:ss') " + //
" AND GMT_MODIFIED < to_date(:4, 'yyyy-mm-dd hh24:mi:ss')" + //
" ORDER BY \"FILE_SIZE\" DESC, \"ID\" DESC" + // //
" ) row_" + //
" WHERE rownum <= :5" + //
" )" + //
" WHERE rownum_ >= :6" + //
" ) a, IMAGE_REPOSITORY b " + //
" WHERE a.rid = b.rowid;"; //
// sql = "select ID, GMT_CREATE, GMT_MODIFIED, COMPANY_ID, MEMBER_ID, MEMBER_SEQ, FILE_NAME, DISPLAY_NAME, DISPLAY_NAME_UTF8, FILE_SIZE, STATUS, WIDTH, HEIGHT, REFERENCE_COUNT, HASH_CODE, GROUP_ID from ( select * from (select row_.*, rownum rownum_ from ( select rowid rid from IMAGE_REPOSITORY where COMPANY_ID = :1 and STATUS = 'enable' and MEMBER_SEQ = :2 and GMT_MODIFIED >= to_date(:3 , 'yyyy-mm-dd hh24:mi:ss') and GMT_MODIFIED < to_date(:4 , 'yyyy-mm-dd hh24:mi:ss') order by \"FILE_SIZE\" desc , \"ID\" desc )row_ where rownum <= :5 ) where rownum_ >= :6 ) a , IMAGE_REPOSITORY b where a.rid = b.rowid ";
OracleStatementParser parser = new OracleStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
System.out.println(output(statementList));
Assert.assertEquals(1, statementList.size());
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
statemen.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());
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("pivot_table")));
Assert.assertEquals(3, visitor.getColumns().size());
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode")));
}
}
@@ -0,0 +1,272 @@
package com.alibaba.druid.sql;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;
import junit.framework.Assert;
import com.alibaba.druid.pool.DruidDataSource;
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 com.alibaba.fastjson.JSON;
public class TestTransform extends OracleTest {
private String jdbcUrl;
private String user;
private String password;
private DruidDataSource dataSource;
public void setUp() throws Exception {
jdbcUrl = "jdbc:oracle:thin:@10.20.149.18:1521:emdb";
user = "wardon";
password = "wardon";
dataSource = new DruidDataSource();
dataSource.setInitialSize(1);
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(user);
dataSource.setPassword(password);
}
public void test_transform() throws Exception {
String sql = "SELECT SNAP_DATE, DBNAME, SQL_ID, PIECE, SQL_TEXT" + //
" , COMMAND_TYPE, LAST_SNAP_DATE, DB_PK, SQL_PARSE_RESULT " + //
" FROM db_day_sql_fulltext " + //
" ORDER BY sql_id, piece";
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
Record r = null;
while (rs.next()) {
r = new Record();
Date d1 = rs.getDate(1);
String s2 = rs.getString(2);
String sqlId = rs.getString(3);
r.setSnapshotDate(d1);
r.setDbName(s2);
r.setSqlId(sqlId);
r.setPiece(rs.getInt(4));
r.setSqlText(rs.getString(5));
r.setCommandType(rs.getInt(6));
r.setLastSnapshotDate(rs.getDate(7));
r.setDbPk(rs.getLong(8));
System.out.println(r.getSqlText());
schemaStat(r);
}
rs.close();
stmt.close();
conn.close();
}
public void schemaStat(Record r) {
String sql = r.getSqlText();
if (sql.startsWith("/* MV_REFRESH (INS) */")) {
return;
}
if (sql.startsWith("/* MV_REFRESH (DEL) */")) {
return;
}
OracleStatementParser parser = new OracleStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
Assert.assertEquals(1, statementList.size());
System.out.println(output(statementList));
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
statemen.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();
System.out.println();
System.out.println();
}
public void clearResult() throws Exception {
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
stmt.execute("DELETE FROM db_day_sql_fulltext");
stmt.close();
conn.close();
}
public void f_test_migrate() throws Exception {
clearResult();
String sql = "SELECT SNAP_DATE, DBNAME, SQL_ID, PIECE, SQL_TEXT" + //
" , COMMAND_TYPE, LAST_SNAP_DATE, DB_PK, SQL_PARSE_RESULT " + //
" FROM db_day_sqltext " + //
" WHERE db_pk = 40 and snap_date = trunc(sysdate) " + //
" ORDER BY sql_id, piece";
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
Record r = null;
String lastSqlId = null;
while (rs.next()) {
Date d1 = rs.getDate(1);
String s2 = rs.getString(2);
String sqlId = rs.getString(3);
if (lastSqlId == null || !lastSqlId.equals(sqlId)) {
if (r != null) {
System.out.println(r.getSqlText());
System.out.println();
insert(r);
}
r = new Record();
r.setSnapshotDate(d1);
r.setDbName(s2);
r.setSqlId(sqlId);
r.setPiece(rs.getInt(4));
r.setSqlText(rs.getString(5));
r.setCommandType(rs.getInt(6));
r.setLastSnapshotDate(rs.getDate(7));
r.setDbPk(rs.getLong(8));
} else {
String part = rs.getString(5);
if (part != null) {
r.setSqlText(r.getSqlText() + part);
}
}
lastSqlId = sqlId;
}
rs.close();
stmt.close();
conn.close();
}
public void insert(Record r) throws Exception {
String sql = "INSERT INTO db_day_sql_fulltext " + //
"(SNAP_DATE, DBNAME, SQL_ID, PIECE, SQL_TEXT" + //
", COMMAND_TYPE, LAST_SNAP_DATE, DB_PK, SQL_PARSE_RESULT)" + //
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setDate(1, r.getSnapshotDate());
stmt.setString(2, r.getDbName());
stmt.setString(3, r.getSqlId());
stmt.setInt(4, r.getPiece());
stmt.setString(5, r.getSqlText());
stmt.setInt(6, r.getCommandType());
stmt.setDate(7, r.getLastSnapshotDate());
stmt.setLong(8, r.getDbPk());
stmt.setString(9, r.getSqlText());
stmt.execute();
stmt.close();
conn.close();
}
public static class Record {
private Date snapshotDate;
private String dbName;
private String sqlId;
private String sqlText;
private Integer piece;
private Integer commandType;
private Date lastSnapshotDate;
private Long dbPk;
public Date getSnapshotDate() {
return snapshotDate;
}
public void setSnapshotDate(Date snapshotDate) {
this.snapshotDate = snapshotDate;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getSqlId() {
return sqlId;
}
public void setSqlId(String sqlId) {
this.sqlId = sqlId;
}
public String getSqlText() {
return sqlText;
}
public void setSqlText(String sqlText) {
this.sqlText = sqlText;
}
public Integer getPiece() {
return piece;
}
public void setPiece(Integer piece) {
this.piece = piece;
}
public Integer getCommandType() {
return commandType;
}
public void setCommandType(Integer commandType) {
this.commandType = commandType;
}
public Date getLastSnapshotDate() {
return lastSnapshotDate;
}
public void setLastSnapshotDate(Date lastSnapshotDate) {
this.lastSnapshotDate = lastSnapshotDate;
}
public Long getDbPk() {
return dbPk;
}
public void setDbPk(Long dbPk) {
this.dbPk = dbPk;
}
public String toString() {
return JSON.toJSONString(this);
}
}
}