bug fixed for oracle sql parser

This commit is contained in:
温少
2012-02-29 17:31:36 +08:00
65 changed files with 2937 additions and 183 deletions
@@ -1,5 +1,8 @@
package com.alibaba.druid.sql.dialect.oracle.ast.clause;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
@@ -10,7 +13,7 @@ public class SampleClause extends OracleSQLObjectImpl {
private boolean block = false;
private int percent;
private List<SQLExpr> percent = new ArrayList<SQLExpr>();
private SQLExpr seedValue;
@@ -22,11 +25,11 @@ public class SampleClause extends OracleSQLObjectImpl {
this.block = block;
}
public int getPercent() {
public List<SQLExpr> getPercent() {
return percent;
}
public void setPercent(int percent) {
public void setPercent(List<SQLExpr> percent) {
this.percent = percent;
}
@@ -42,6 +45,7 @@ public class SampleClause extends OracleSQLObjectImpl {
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, seedValue);
acceptChild(visitor, percent);
}
visitor.endVisit(this);
}
@@ -25,10 +25,19 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleAggregateExpr extends SQLAggregateExpr implements Serializable, OracleExpr {
private boolean unique = false;
private static final long serialVersionUID = 1L;
private OracleAnalytic over;
private boolean ignoreNulls = false;
public boolean isUnique() {
return unique;
}
public void setUnique(boolean unique) {
this.unique = unique;
}
public boolean isIgnoreNulls() {
return this.ignoreNulls;
}
@@ -74,7 +83,16 @@ public class OracleAggregateExpr extends SQLAggregateExpr implements Serializabl
@Override
protected void accept0(SQLASTVisitor visitor) {
this.accept0((OracleASTVisitor) visitor);
if (visitor instanceof OracleASTVisitor) {
this.accept0((OracleASTVisitor) visitor);
} else {
if (visitor.visit(this)) {
acceptChild(visitor, this.methodName);
acceptChild(visitor, this.arguments);
acceptChild(visitor, this.over);
}
visitor.endVisit(this);
}
}
public void accept0(OracleASTVisitor visitor) {
@@ -0,0 +1,46 @@
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleArgumentExpr extends OracleSQLObjectImpl implements SQLExpr {
private static final long serialVersionUID = 1L;
private String argumentName;
private SQLExpr value;
public OracleArgumentExpr(){
}
public OracleArgumentExpr(String argumentName, SQLExpr value){
this.argumentName = argumentName;
this.value = value;
}
public String getArgumentName() {
return argumentName;
}
public void setArgumentName(String argumentName) {
this.argumentName = argumentName;
}
public SQLExpr getValue() {
return value;
}
public void setValue(SQLExpr value) {
this.value = value;
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, value);
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,48 @@
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleDatetimeExpr extends OracleSQLObjectImpl implements SQLExpr {
private static final long serialVersionUID = 1L;
private SQLExpr expr;
private SQLExpr timeZone;
public OracleDatetimeExpr(){
}
public OracleDatetimeExpr(SQLExpr expr, SQLExpr timeZone){
this.expr = expr;
this.timeZone = timeZone;
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, expr);
acceptChild(visitor, timeZone);
}
visitor.endVisit(this);
}
public SQLExpr getExpr() {
return expr;
}
public void setExpr(SQLExpr expr) {
this.expr = expr;
}
public SQLExpr getTimeZone() {
return timeZone;
}
public void setTimeZone(SQLExpr timeZone) {
this.timeZone = timeZone;
}
}
@@ -0,0 +1,26 @@
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleSysdateExpr extends OracleSQLObjectImpl implements SQLExpr {
private static final long serialVersionUID = 1L;
private String option;
public String getOption() {
return option;
}
public void setOption(String option) {
this.option = option;
}
@Override
public void accept0(OracleASTVisitor visitor) {
visitor.visit(this);
visitor.endVisit(this);
}
}
@@ -0,0 +1,64 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
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.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleExceptionStatement extends OracleSQLObjectImpl implements OracleStatement {
private static final long serialVersionUID = 1L;
private List<Item> items = new ArrayList<Item>();
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public static class Item extends OracleSQLObjectImpl {
private static final long serialVersionUID = 1L;
private SQLExpr when;
private SQLStatement statement;
public SQLExpr getWhen() {
return when;
}
public void setWhen(SQLExpr when) {
this.when = when;
}
public SQLStatement getStatement() {
return statement;
}
public void setStatement(SQLStatement statement) {
this.statement = statement;
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, when);
acceptChild(visitor, statement);
}
visitor.endVisit(this);
}
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, items);
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,42 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleGrantStatement extends OracleSQLObjectImpl implements OracleStatement {
private static final long serialVersionUID = 1L;
private List<String> privileges = new ArrayList<String>();
private SQLExpr on;
public SQLExpr getOn() {
return on;
}
public void setOn(SQLExpr on) {
this.on = on;
}
public List<String> getPrivileges() {
return privileges;
}
public void setPrivileges(List<String> privileges) {
this.privileges = privileges;
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, on);
}
visitor.endVisit(this);
}
}
@@ -29,13 +29,42 @@ public class OracleSelectForUpdate extends OracleSQLObjectImpl {
private final List<SQLExpr> of = new ArrayList<SQLExpr>();
private boolean notWait = false;
private SQLExpr wait;
private boolean skipLocked = false;
public OracleSelectForUpdate(){
}
public boolean isNotWait() {
return notWait;
}
public void setNotWait(boolean notWait) {
this.notWait = notWait;
}
public SQLExpr getWait() {
return wait;
}
public void setWait(SQLExpr wait) {
this.wait = wait;
}
public boolean isSkipLocked() {
return skipLocked;
}
public void setSkipLocked(boolean skipLocked) {
this.skipLocked = skipLocked;
}
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.of);
acceptChild(visitor, this.wait);
}
visitor.endVisit(this);
@@ -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.OracleHint;
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;
@@ -31,6 +32,7 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
private final List<SQLExpr> using = new ArrayList<SQLExpr>();
protected OracleSelectPivotBase pivot;
protected FlashbackQueryClause flashback;
private List<OracleHint> hints = new ArrayList<OracleHint>();
public OracleSelectJoin(String alias){
super(alias);
@@ -40,6 +42,14 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
}
public List<OracleHint> getHints() {
return hints;
}
public void setHints(List<OracleHint> hints) {
this.hints = hints;
}
public FlashbackQueryClause getFlashback() {
return flashback;
}
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
@@ -34,10 +35,20 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock {
private OracleSelectHierachicalQueryClause hierachicalQueryClause;
private ModelClause modelClause;
private SQLExpr into;
public OracleSelectQueryBlock(){
}
public SQLExpr getInto() {
return into;
}
public void setInto(SQLExpr into) {
this.into = into;
}
public ModelClause getModelClause() {
return modelClause;
@@ -68,6 +79,7 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock {
if (visitor.visit(this)) {
acceptChild(visitor, this.selectList);
acceptChild(visitor, this.into);
acceptChild(visitor, this.from);
acceptChild(visitor, this.where);
acceptChild(visitor, this.groupBy);
@@ -79,6 +91,7 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock {
if (visitor.visit(this)) {
acceptChild(visitor, this.hints);
acceptChild(visitor, this.selectList);
acceptChild(visitor, this.into);
acceptChild(visitor, this.from);
acceptChild(visitor, this.where);
acceptChild(visitor, this.hierachicalQueryClause);
@@ -15,8 +15,12 @@
*/
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
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,10 +33,20 @@ public class OracleSelectSubqueryTableSource extends SQLSubqueryTableSource impl
protected FlashbackQueryClause flashback;
private List<OracleHint> hints = new ArrayList<OracleHint>();
public OracleSelectSubqueryTableSource(){
}
public List<OracleHint> getHints() {
return hints;
}
public void setHints(List<OracleHint> hints) {
this.hints = hints;
}
public FlashbackQueryClause getFlashback() {
return flashback;
}
@@ -15,7 +15,11 @@
*/
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.PartitionExtensionClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause;
@@ -33,11 +37,20 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or
protected SampleClause sampleClause;
protected FlashbackQueryClause flashback;
private List<OracleHint> hints = new ArrayList<OracleHint>();
public OracleSelectTableReference(){
}
public List<OracleHint> getHints() {
return hints;
}
public void setHints(List<OracleHint> hints) {
this.hints = hints;
}
public FlashbackQueryClause getFlashback() {
return flashback;
}
@@ -15,7 +15,10 @@
*/
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import java.util.List;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause;
public interface OracleSelectTableSource extends SQLTableSource {
@@ -27,4 +30,6 @@ public interface OracleSelectTableSource extends SQLTableSource {
FlashbackQueryClause getFlashback();
void setFlashback(FlashbackQueryClause flashback);
List<OracleHint> getHints();
}
@@ -0,0 +1,29 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleSetTransactionStatement extends OracleSQLObjectImpl implements OracleStatement {
private static final long serialVersionUID = 1L;
private SQLExpr name;
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
}
visitor.endVisit(this);
}
public SQLExpr getName() {
return name;
}
public void setName(SQLExpr name) {
this.name = name;
}
}
@@ -19,18 +19,17 @@ import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleUpdateStatement extends SQLStatementImpl {
public class OracleUpdateStatement extends SQLUpdateStatement implements OracleStatement {
private static final long serialVersionUID = 1L;
private final List<OracleHint> hints = new ArrayList<OracleHint>(1);
private boolean only = false;
private SQLExpr table;
private String alias;
private OracleUpdateSetClause setClause;
private SQLExpr where;
@@ -49,12 +48,12 @@ public class OracleUpdateStatement extends SQLStatementImpl {
super.accept(visitor);
}
protected void accept0(OracleASTVisitor visitor) {
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.hints);
acceptChild(visitor, this.table);
acceptChild(visitor, this.setClause);
acceptChild(visitor, this.where);
acceptChild(visitor, tableSource);
acceptChild(visitor, items);
acceptChild(visitor, where);
}
visitor.endVisit(this);
@@ -95,12 +94,4 @@ public class OracleUpdateStatement extends SQLStatementImpl {
public List<OracleHint> getHints() {
return this.hints;
}
public SQLExpr getTable() {
return this.table;
}
public void setTable(SQLExpr table) {
this.table = table;
}
}
@@ -77,7 +77,11 @@ public class OracleDeleteParser extends SQLStatementParser {
return deleteStatement;
}
protected OracleExprParser createExprParser() {
return new OracleExprParser(lexer);
}
private void parseHints(OracleDeleteStatement parseInsert) throws ParserException {
if (lexer.token() == Token.HINT) throw new ParserException("TODO");
this.createExprParser().parseHints(parseInsert.getHints());
}
}
@@ -29,23 +29,28 @@ import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateTimeUnit;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalType;
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.OracleSysdateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
@@ -58,6 +63,7 @@ public class OracleExprParser extends SQLExprParser {
public boolean allowStringAdditive = false;
/**
@@ -90,6 +96,21 @@ public class OracleExprParser extends SQLExprParser {
SQLExpr sqlExpr = null;
switch (tok) {
case SYSDATE:
lexer.nextToken();
OracleSysdateExpr sysdate = new OracleSysdateExpr();
if (lexer.token() == Token.MONKEYS_AT) {
lexer.nextToken();
accept(Token.BANG);
sysdate.setOption("!");
}
sqlExpr = sysdate;
return primaryRest(sqlExpr);
case PRIOR:
lexer.nextToken();
sqlExpr = expr();
sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Prior, sqlExpr);
return primaryRest(sqlExpr);
case COLON:
lexer.nextToken();
if (lexer.token() == Token.LITERAL_INT) {
@@ -116,7 +137,7 @@ public class OracleExprParser extends SQLExprParser {
accept(Token.LPAREN);
extract.setUnit(OracleDateTimeUnit.valueOf(lexer.stringVal()));
extract.setUnit(OracleDateTimeUnit.valueOf(lexer.stringVal().toUpperCase()));
lexer.nextToken();
accept(Token.FROM);
@@ -204,8 +225,13 @@ public class OracleExprParser extends SQLExprParser {
sqlExpr = new OracleBinaryDoubleExpr(Double.parseDouble(lexer.numberString()) * -1);
lexer.nextToken();
break;
case VARIANT:
case IDENTIFIER:
sqlExpr = expr();
sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr);
break;
default:
throw new ParserException("TODO");
throw new ParserException("TODO " + lexer.token());
}
return primaryRest(sqlExpr);
@@ -286,6 +312,27 @@ public class OracleExprParser extends SQLExprParser {
expr = interval;
}
if (lexer.token() == Token.AT) {
char mark_ch = lexer.current();
int mark_bp = lexer.bp();
lexer.nextToken();
if (lexer.token() == Token.LOCAL) {
lexer.nextToken();
expr = new OracleDatetimeExpr(expr, new SQLIdentifierExpr("LOCAL"));
} else {
if (lexer.token() == Token.TIME) {
lexer.nextToken();
} else {
lexer.reset(mark_bp, mark_ch, Token.AT);
return expr;
}
accept(Token.ZONE);
SQLExpr timeZone = primary();
expr = new OracleDatetimeExpr(expr, timeZone);
}
}
SQLExpr restExpr = super.primaryRest(expr);
if (restExpr != expr && restExpr instanceof SQLMethodInvokeExpr) {
@@ -312,7 +359,11 @@ public class OracleExprParser extends SQLExprParser {
String name = '"' + lexer.stringVal() + '"';
lexer.nextToken();
expr = new SQLPropertyExpr(expr, name);
expr = primaryRest(expr);
if (lexer.token() == Token.DOT) {
lexer.nextToken();
expr = dotRest(expr);
}
return expr;
}
@@ -332,8 +383,12 @@ public class OracleExprParser extends SQLExprParser {
return timestamp;
}
public OracleTimestampExpr parseTimestamp() {
public SQLExpr parseTimestamp() {
accept(Token.TIMESTAMP);
if (lexer.token() != Token.LITERAL_ALIAS) {
return new SQLIdentifierExpr("TIMESTAMP");
}
OracleTimestampExpr timestamp = new OracleTimestampExpr();
@@ -382,6 +437,13 @@ public class OracleExprParser extends SQLExprParser {
}
protected OracleAggregateExpr parseAggregateExpr(String method_name) {
boolean unique = false;
if (lexer.token() == Token.UNIQUE) {
lexer.nextToken();
unique = true;
}
OracleAggregateExpr aggregateExpr;
if (lexer.token() == (Token.ALL)) {
aggregateExpr = new OracleAggregateExpr(method_name, 1);
@@ -392,6 +454,7 @@ public class OracleExprParser extends SQLExprParser {
} else {
aggregateExpr = new OracleAggregateExpr(method_name, 1);
}
aggregateExpr.setUnique(unique);
exprList(aggregateExpr.getArguments());
if (lexer.stringVal().equalsIgnoreCase("IGNORE")) {
@@ -517,10 +580,10 @@ public class OracleExprParser extends SQLExprParser {
protected SQLExpr parseInterval() {
accept(Token.INTERVAL);
OracleIntervalExpr interval = new OracleIntervalExpr();
if (lexer.token() != Token.LITERAL_CHARS) {
throw new ParserException("syntax error : " + lexer.token());
return new SQLIdentifierExpr("INTERVAL");
}
interval.setValue(new SQLCharExpr(lexer.stringVal()));
lexer.nextToken();
@@ -618,4 +681,33 @@ public class OracleExprParser extends SQLExprParser {
return name;
}
public SQLExpr equalityRest(SQLExpr expr) throws ParserException {
SQLExpr rightExp;
if (lexer.token() == Token.EQ) {
lexer.nextToken();
if (lexer.token() == Token.GT) {
lexer.nextToken();
rightExp = expr();
String argumentName = ((SQLIdentifierExpr) expr).getName();
return new OracleArgumentExpr(argumentName, rightExp);
}
rightExp = shift();
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp);
} else if (lexer.token() == Token.BANGEQ) {
lexer.nextToken();
rightExp = shift();
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp);
}
return expr;
}
}
@@ -94,6 +94,7 @@ public class OracleLexer extends Lexer {
map.put("EXTRACT", Token.EXTRACT);
map.put("DATE", Token.DATE);
map.put("TIMESTAMP", Token.TIMESTAMP);
map.put("COLUMN", Token.COLUMN);
map.put("CURSOR", Token.CURSOR);
@@ -121,6 +122,15 @@ public class OracleLexer extends Lexer {
map.put("WAIT", Token.WAIT);
map.put("NOWAIT", Token.NOWAIT);
map.put("SESSION", Token.SESSION);
map.put("AT", Token.AT);
map.put("LOCAL", Token.LOCAL);
map.put("TIME", Token.TIME);
map.put("ZONE", Token.ZONE);
map.put("SYSDATE", Token.SYSDATE);
map.put("DECLARE", Token.DECLARE);
map.put("EXCEPTION", Token.EXCEPTION);
map.put("GRANT", Token.GRANT);
map.put("COMMENT", Token.COMMENT);
DEFAULT_ORACLE_KEYWORDS = new Keywords(map);
}
@@ -177,7 +187,7 @@ public class OracleLexer extends Lexer {
}
public void scanComment() {
if (ch != '/') {
if (ch != '/' && ch != '-') {
throw new IllegalStateException();
}
@@ -227,7 +237,7 @@ public class OracleLexer extends Lexer {
return;
}
if (ch == '/') {
if (ch == '/' || ch == '-') {
scanChar();
sp++;
@@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
@@ -167,15 +168,21 @@ public class OracleSelectParser extends SQLSelectParser {
OracleSelectForUpdate forUpdate = new OracleSelectForUpdate();
if (identifierEquals("OF")) {
if (lexer.token() == Token.OF) {
lexer.nextToken();
this.createExprParser().exprList(forUpdate.getOf());
if (identifierEquals("WAIT")) throw new ParserException("TODO");
if (identifierEquals("NOWAIT")) throw new ParserException("TODO");
if (identifierEquals("SKIP")) {
throw new ParserException("TODO");
}
}
if (lexer.token() == Token.NOWAIT) {
lexer.nextToken();
forUpdate.setNotWait(true);
} else if (lexer.token() == Token.WAIT) {
lexer.nextToken();
forUpdate.setWait(this.createExprParser().primary());
} else if (identifierEquals("SKIP")) {
lexer.nextToken();
acceptIdentifier("LOCKED");
forUpdate.setSkipLocked(true);
}
select.setForUpdate(forUpdate);
@@ -250,6 +257,8 @@ public class OracleSelectParser extends SQLSelectParser {
this.createExprParser().parseHints(queryBlock.getHints());
parseSelectList(queryBlock);
parseInto(queryBlock);
parseFrom(queryBlock);
@@ -607,6 +616,14 @@ public class OracleSelectParser extends SQLSelectParser {
queryBlock.setGroupBy(groupBy);
}
}
protected String as() throws ParserException {
if (lexer.token() == Token.CONNECT) {
return null;
}
return super.as();
}
private void parseHierachical(OracleSelectQueryBlock queryBlock) {
OracleSelectHierachicalQueryClause hierachical = null;
@@ -695,12 +712,13 @@ public class OracleSelectParser extends SQLSelectParser {
parseTableSourceQueryTableExpr(tableReference);
parsePivot(tableReference);
}
return parseTableSourceRest(tableReference);
}
private void parseTableSourceQueryTableExpr(OracleSelectTableReference tableReference) {
tableReference.setExpr(this.createExprParser().expr());
{
FlashbackQueryClause clause = flashback();
tableReference.setFlashback(clause);
@@ -713,16 +731,11 @@ public class OracleSelectParser extends SQLSelectParser {
if (identifierEquals("BLOCK")) {
sample.setBlock(true);
lexer.nextToken();
}
accept(Token.LPAREN);
if (lexer.token() != Token.LITERAL_INT) {
throw new ParserException("syntax error : " + lexer.token());
}
sample.setPercent(lexer.integerValue().intValue());
lexer.nextToken();
this.createExprParser().exprList(sample.getPercent());
accept(Token.RPAREN);
if (identifierEquals("SEED")) {
@@ -819,7 +832,7 @@ public class OracleSelectParser extends SQLSelectParser {
accept(Token.TIMESTAMP);
clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP);
}
clause.setExpr(createExprParser().primary());
clause.setExpr(createExprParser().expr());
return clause;
}
@@ -841,12 +854,16 @@ public class OracleSelectParser extends SQLSelectParser {
tableSource.setAlias(as());
}
}
if (lexer.token() == Token.HINT) {
this.createExprParser().parseHints(tableSource.getHints());
}
OracleSelectJoin.JoinType joinType = null;
if (lexer.token() == Token.LEFT) {
lexer.nextToken();
if (identifierEquals("OUTER")) {
if (lexer.token() == Token.OUTER) {
lexer.nextToken();
}
accept(Token.JOIN);
@@ -855,16 +872,16 @@ public class OracleSelectParser extends SQLSelectParser {
if (lexer.token() == Token.RIGHT) {
lexer.nextToken();
if (identifierEquals("OUTER")) {
if (lexer.token() == Token.OUTER) {
lexer.nextToken();
}
accept(Token.JOIN);
joinType = OracleSelectJoin.JoinType.RIGHT_OUTER_JOIN;
}
if (identifierEquals("FULL")) {
if (lexer.token() == Token.FULL) {
lexer.nextToken();
if (identifierEquals("OUTER")) {
if (lexer.token() == Token.OUTER) {
lexer.nextToken();
}
accept(Token.JOIN);
@@ -1050,6 +1067,24 @@ public class OracleSelectParser extends SQLSelectParser {
tableSource.setPivot(unPivot);
}
}
protected void parseInto(OracleSelectQueryBlock x) {
if (lexer.token() == Token.INTO) {
lexer.nextToken();
SQLExpr expr = expr();
if (lexer.token() != Token.COMMA) {
x.setInto(expr);
return;
}
SQLListExpr list = new SQLListExpr();
list.getItems().add(expr);
while (lexer.token() == Token.COMMA) {
lexer.nextToken();
list.getItems().add(expr());
}
x.setInto(list);
}
}
private void parseHints(OracleSelectQueryBlock queryBlock) {
this.createExprParser().parseHints(queryBlock.getHints());
@@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
@@ -34,6 +35,8 @@ 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.OracleAlterSessionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement;
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.OracleLockTableStatement.LockMode;
@@ -41,6 +44,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMethodInvokeStatement;
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.OracleSetTransactionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleStatement;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
@@ -76,7 +80,17 @@ public class OracleStatementParser extends SQLStatementParser {
@Override
public void parseStatementList(List<SQLStatement> statementList) throws ParserException {
parseStatementList(statementList, -1);
}
public void parseStatementList(List<SQLStatement> statementList, int max) throws ParserException {
for (;;) {
if (max != -1) {
if (statementList.size() >= max) {
return;
}
}
if (lexer.token() == Token.EOF) {
return;
}
@@ -142,7 +156,12 @@ public class OracleStatementParser extends SQLStatementParser {
}
if (lexer.token() == Token.BEGIN) {
statementList.add(this.parseBegin());
statementList.add(this.parseBlock());
continue;
}
if (lexer.token() == Token.DECLARE) {
statementList.add(this.parseBlock());
continue;
}
@@ -150,7 +169,7 @@ public class OracleStatementParser extends SQLStatementParser {
statementList.add(this.parseLock());
continue;
}
if (lexer.token() == Token.TRUNCATE) {
statementList.add(this.parseTruncate());
continue;
@@ -173,22 +192,113 @@ public class OracleStatementParser extends SQLStatementParser {
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.EXCEPTION) {
statementList.add(this.parseException());
continue;
}
if (lexer.token() == Token.IDENTIFIER) {
SQLExpr expr = exprParser.expr();
if (expr instanceof SQLMethodInvokeExpr) {
OracleMethodInvokeStatement stmt = new OracleMethodInvokeStatement((SQLMethodInvokeExpr) expr);
statementList.add(stmt);
continue;
} else if (expr instanceof SQLName) {
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(((SQLName) expr).toString());
statementList.add(new OracleMethodInvokeStatement(methodInvokeExpr));
continue;
} else {
throw new ParserException("expr : " + expr);
}
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
parseStatementList(statementList, statementList.size() + 1);
accept(Token.RPAREN);
continue;
}
if (lexer.token() == Token.SET) {
statementList.add(this.parseSet());
continue;
}
if (lexer.token() == Token.GRANT) {
statementList.add(this.parseGrant());
continue;
}
if (lexer.token() == Token.COMMENT) {
statementList.add(this.parseComment());
continue;
}
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
}
public SQLStatement parseGrant() {
accept(Token.GRANT);
OracleGrantStatement stmt = new OracleGrantStatement();
for (;;) {
if (lexer.token() == Token.ALL) {
lexer.nextToken();
if (identifierEquals("PRIVILEGES")) {
lexer.nextToken();
}
stmt.getPrivileges().add("ALL");
} else if (lexer.token() == Token.SELECT) {
stmt.getPrivileges().add("SELECT");
lexer.nextToken();
} else if (lexer.token() == Token.UPDATE) {
stmt.getPrivileges().add("UPDATE");
lexer.nextToken();
} else if (lexer.token() == Token.DELETE) {
stmt.getPrivileges().add("DELETE");
lexer.nextToken();
} else if (lexer.token() == Token.INSERT) {
stmt.getPrivileges().add("INSERT");
lexer.nextToken();
} else if (lexer.token() == Token.CREATE) {
lexer.nextToken();
if (lexer.token() == Token.TABLE) {
stmt.getPrivileges().add("CREATE TABLE");
lexer.nextToken();
} else if (identifierEquals("SYNONYM")) {
stmt.getPrivileges().add("CREATE SYNONYM");
lexer.nextToken();
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
}
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
if (lexer.token() == Token.ON) {
lexer.nextToken();
stmt.setOn(this.exprParser.expr());
}
return stmt;
}
public SQLStatement parseSet() {
accept(Token.SET);
acceptIdentifier("TRANSACTION");
acceptIdentifier("NAME");
OracleSetTransactionStatement stmt = new OracleSetTransactionStatement();
stmt.setName(this.exprParser.expr());
return stmt;
}
public SQLStatement parseTruncate() {
return super.parseTruncate();
}
@@ -197,13 +307,13 @@ public class OracleStatementParser extends SQLStatementParser {
accept(Token.ALTER);
if (lexer.token() == Token.SESSION) {
lexer.nextToken();
OracleAlterSessionStatement stmt = new OracleAlterSessionStatement();
if (lexer.token() == Token.SET) {
lexer.nextToken();
parseAssignItems(stmt.getItems());
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
return stmt;
}
@@ -236,7 +346,11 @@ public class OracleStatementParser extends SQLStatementParser {
return stmt;
}
public OracleStatement parseBegin() {
public OracleStatement parseBlock() {
if (lexer.token() == Token.DECLARE) {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
accept(Token.BEGIN);
OracleBlockStatement block = new OracleBlockStatement();
@@ -329,9 +443,12 @@ public class OracleStatementParser extends SQLStatementParser {
accept(Token.MATCHED);
accept(Token.THEN);
accept(Token.INSERT);
accept(Token.LPAREN);
exprParser.exprList(insertClause.getColumns());
accept(Token.RPAREN);
if (lexer.token() == Token.LPAREN) {
accept(Token.LPAREN);
exprParser.exprList(insertClause.getColumns());
accept(Token.RPAREN);
}
accept(Token.VALUES);
accept(Token.LPAREN);
exprParser.exprList(insertClause.getValues());
@@ -355,13 +472,13 @@ public class OracleStatementParser extends SQLStatementParser {
accept(Token.INSERT);
List<OracleHint> hints = new ArrayList<OracleHint>();
this.createExprParser().parseHints(hints);
if (lexer.token() == Token.INTO) {
OracleInsertStatement stmt = new OracleInsertStatement();
stmt.setHints(hints);
parseInsert0(stmt);
stmt.setReturning(parseReturningClause());
@@ -430,6 +547,28 @@ public class OracleStatementParser extends SQLStatementParser {
return stmt;
}
private OracleExceptionStatement parseException() {
accept(Token.EXCEPTION);
OracleExceptionStatement stmt = new OracleExceptionStatement();
for (;;) {
accept(Token.WHEN);
OracleExceptionStatement.Item item = new OracleExceptionStatement.Item();
item.setWhen(this.exprParser.expr());
accept(Token.THEN);
List<SQLStatement> statements = new ArrayList<SQLStatement>();
parseStatementList(statements, 1);
item.setStatement(statements.get(0));
stmt.getItems().add(item);
if (lexer.token() != Token.WHEN) {
break;
}
}
return stmt;
}
private OracleErrorLoggingClause parseErrorLoggingClause() {
if (lexer.token() == Token.LOG) {
OracleErrorLoggingClause errorClause = new OracleErrorLoggingClause();
@@ -15,8 +15,9 @@
*/
package com.alibaba.druid.sql.dialect.oracle.parser;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListSingleColumnItem;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateStatement;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
@@ -44,7 +45,8 @@ public class OracleUpdateParser extends SQLStatementParser {
update.setOnly(true);
}
update.setTable(this.exprParser.expr());
SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource();
update.setTableSource(tableSource);
if ((update.getAlias() == null) || (update.getAlias().length() == 0)) {
update.setAlias(as());
@@ -87,27 +89,28 @@ public class OracleUpdateParser extends SQLStatementParser {
private void parseSet(OracleUpdateStatement update) throws ParserException {
accept(Token.SET);
if (identifierEquals("VALUE")) {
throw new ParserException("TODO");
}
OracleUpdateSetListClause setListClause = new OracleUpdateSetListClause();
while (true) {
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
if (lexer.token() == (Token.LPAREN)) {
throw new ParserException("TODO");
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
this.exprParser.exprList(list.getItems());
accept(Token.RPAREN);
item.setColumn(list);
} else {
item.setColumn(this.exprParser.primary());
}
OracleUpdateSetListSingleColumnItem item = new OracleUpdateSetListSingleColumnItem();
item.setColumn(this.exprParser.primary());
accept(Token.EQ);
item.setValue(this.exprParser.expr());
setListClause.getItems().add(item);
update.getItems().add(item);
if (!(lexer.token() == (Token.COMMA))) break;
if (lexer.token() != Token.COMMA) {
break;
}
lexer.nextToken();
}
update.setSetClause(setListClause);
}
protected SQLExprParser createExprParser() {
@@ -26,20 +26,25 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause.E
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr;
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.OracleSysdateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement;
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.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement;
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;
@@ -64,6 +69,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.Rea
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListMultiColumnItem;
@@ -813,4 +819,74 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora
}
@Override
public boolean visit(OracleDatetimeExpr x) {
return true;
}
@Override
public void endVisit(OracleDatetimeExpr x) {
}
@Override
public boolean visit(OracleSysdateExpr x) {
return true;
}
@Override
public void endVisit(OracleSysdateExpr x) {
}
@Override
public boolean visit(OracleExceptionStatement x) {
return true;
}
@Override
public void endVisit(OracleExceptionStatement x) {
}
@Override
public boolean visit(OracleExceptionStatement.Item x) {
return true;
}
@Override
public void endVisit(OracleExceptionStatement.Item x) {
}
@Override
public boolean visit(OracleArgumentExpr x) {
return true;
}
@Override
public void endVisit(OracleArgumentExpr x) {
}
@Override
public boolean visit(OracleSetTransactionStatement x) {
return true;
}
@Override
public void endVisit(OracleSetTransactionStatement x) {
}
@Override
public boolean visit(OracleGrantStatement x) {
return true;
}
@Override
public void endVisit(OracleGrantStatement x) {
}
}
@@ -32,20 +32,25 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr;
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.OracleSysdateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement;
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.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement;
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;
@@ -66,6 +71,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListMultiColumnItem;
@@ -355,4 +361,32 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(OracleMethodInvokeStatement x);
void endVisit(OracleMethodInvokeStatement x);
boolean visit(OracleDatetimeExpr x);
void endVisit(OracleDatetimeExpr x);
boolean visit(OracleSysdateExpr x);
void endVisit(OracleSysdateExpr x);
boolean visit(OracleExceptionStatement x);
void endVisit(OracleExceptionStatement x);
boolean visit(OracleExceptionStatement.Item x);
void endVisit(OracleExceptionStatement.Item x);
boolean visit(OracleArgumentExpr x);
void endVisit(OracleArgumentExpr x);
boolean visit(OracleSetTransactionStatement x);
void endVisit(OracleSetTransactionStatement x);
boolean visit(OracleGrantStatement x);
void endVisit(OracleGrantStatement x);
}
@@ -24,6 +24,7 @@ import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
@@ -58,20 +59,25 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr;
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.OracleSysdateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement;
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.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement;
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;
@@ -97,6 +103,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.Rea
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListMultiColumnItem;
@@ -126,12 +133,19 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
private void printHints(List<OracleHint> hints) {
if (hints.size() > 0) throw new UnsupportedOperationException();
if (hints.size() > 0) {
print("/*+ ");
printAndAccept(hints, ", ");
print(" */");
}
}
public boolean visit(OracleAggregateExpr expr) {
expr.getMethodName().accept(this);
print("(");
if (expr.isUnique()) {
print("UNIQUE ");
}
printAndAccept(expr.getArguments(), ", ");
print(")");
@@ -335,6 +349,15 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
printAndAccept(x.getOf(), ", ");
print(")");
}
if (x.isNotWait()) {
print(" NOWAIT");
} else if (x.isSkipLocked()) {
print(" SKIP LOCKED");
} else if (x.getWait() != null) {
print(" WAIT ");
x.getWait().accept(this);
}
return false;
}
@@ -473,6 +496,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
printSelectList(select.getSelectList());
if (select.getInto() != null) {
println();
print("INTO ");
select.getInto().accept(this);
}
println();
print("FROM ");
@@ -569,6 +598,10 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
x.getPartition().accept(this);
}
}
if (x.getHints().size() > 0) {
this.printHints(x.getHints());
}
if (x.getSampleClause() != null) {
println();
@@ -707,17 +740,23 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
if (x.isOnly()) {
print("ONLY (");
x.getTable().accept(this);
x.getTableSource().accept(this);
print(")");
} else {
x.getTable().accept(this);
x.getTableSource().accept(this);
}
printAlias(x.getAlias());
println();
x.getSetClause().accept(this);
print("SET ");
for (int i = 0, size = x.getItems().size(); i < size; ++i) {
if (i != 0) {
print(", ");
}
x.getItems().get(i).accept(this);
}
if (x.getWhere() != null) {
println();
@@ -904,7 +943,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
print("(");
print(x.getPercent());
printAndAccept(x.getPercent(), ", ");
print(")");
if (x.getSeedValue() != null) {
@@ -1416,8 +1455,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
@Override
public boolean visit(MergeInsertClause x) {
print("WHEN NOT MATCHED THEN INSERT ");
printAndAccept(x.getColumns(), ", ");
print("WHEN NOT MATCHED THEN INSERT");
if (x.getColumns().size() > 0) {
print(" ");
printAndAccept(x.getColumns(), ", ");
}
print(" VALUES (");
printAndAccept(x.getValues(), ", ");
print(")");
@@ -1694,4 +1736,122 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public void endVisit(OracleMethodInvokeStatement x) {
}
@Override
public boolean visit(OracleDatetimeExpr x) {
x.getExpr().accept(this);
SQLExpr timeZone = x.getTimeZone();
if (timeZone instanceof SQLIdentifierExpr) {
if (((SQLIdentifierExpr) timeZone).getName().equalsIgnoreCase("LOCAL")) {
print(" AT LOCAL");
return false;
}
}
print(" AT TIME ZONE ");
timeZone.accept(this);
return false;
}
@Override
public void endVisit(OracleDatetimeExpr x) {
}
@Override
public boolean visit(OracleSysdateExpr x) {
print("SYSDATE");
if (x.getOption() != null) {
print("@");
print(x.getOption());
}
return false;
}
@Override
public void endVisit(OracleSysdateExpr x) {
}
@Override
public void endVisit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) {
}
@Override
public boolean visit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) {
print("WHEN ");
x.getWhen().accept(this);
incrementIndent();
println();
x.getStatement().accept(this);
decrementIndent();
return false;
}
@Override
public boolean visit(OracleExceptionStatement x) {
print("EXCEPTION");
incrementIndent();
for (OracleExceptionStatement.Item item : x.getItems()) {
println();
item.accept(this);
}
decrementIndent();
return false;
}
@Override
public void endVisit(OracleExceptionStatement x) {
}
@Override
public boolean visit(OracleArgumentExpr x) {
print(x.getArgumentName());
print(" => ");
x.getValue().accept(this);
return false;
}
@Override
public void endVisit(OracleArgumentExpr x) {
}
@Override
public boolean visit(OracleSetTransactionStatement x) {
print("SET TRANSACTION NAME ");
x.getName().accept(this);
return false;
}
@Override
public void endVisit(OracleSetTransactionStatement x) {
}
@Override
public boolean visit(OracleGrantStatement x) {
print("GRANT ");
for (int i = 0, size = x.getPrivileges().size(); i < size; ++i) {
if (i != 0) {
print(", ");
}
print(x.getPrivileges().get(i));
}
if (x.getOn() != null) {
print(" ON ");
x.getOn().accept(this);
}
return false;
}
@Override
public void endVisit(OracleGrantStatement x) {
}
}
@@ -13,9 +13,11 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
@@ -41,20 +43,25 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause.E
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr;
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.OracleSysdateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement;
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.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement;
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;
@@ -79,6 +86,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.Rea
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListMultiColumnItem;
@@ -216,9 +224,17 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public boolean visit(OracleUpdateStatement x) {
aliasLocal.set(new HashMap<String, String>());
setMode(x, Mode.Update);
if (x.getTable() instanceof SQLIdentifierExpr) {
String ident = x.getTable().toString();
SQLTableSource tableSource = x.getTableSource();
SQLExpr tableExpr = null;
if (tableSource instanceof SQLExprTableSource) {
tableExpr = ((SQLExprTableSource) tableSource).getExpr();
}
if (tableExpr instanceof SQLIdentifierExpr) {
String ident = tableExpr.toString();
currentTableLocal.set(ident);
TableStat stat = tableStats.get(ident);
@@ -231,7 +247,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
Map<String, String> aliasMap = aliasLocal.get();
aliasMap.put(ident, ident);
} else {
accept(x.getTable());
tableSource.accept(this);
}
accept(x.getSetClause());
@@ -1136,4 +1152,74 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public void endVisit(OracleLockTableStatement x) {
}
@Override
public boolean visit(OracleDatetimeExpr x) {
return true;
}
@Override
public void endVisit(OracleDatetimeExpr x) {
}
@Override
public boolean visit(OracleSysdateExpr x) {
return false;
}
@Override
public void endVisit(OracleSysdateExpr x) {
}
@Override
public void endVisit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) {
}
@Override
public boolean visit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) {
return true;
}
@Override
public boolean visit(OracleExceptionStatement x) {
return true;
}
@Override
public void endVisit(OracleExceptionStatement x) {
}
@Override
public boolean visit(OracleArgumentExpr x) {
return true;
}
@Override
public void endVisit(OracleArgumentExpr x) {
}
@Override
public boolean visit(OracleSetTransactionStatement x) {
return false;
}
@Override
public void endVisit(OracleSetTransactionStatement x) {
}
@Override
public boolean visit(OracleGrantStatement x) {
return false;
}
@Override
public void endVisit(OracleGrantStatement x) {
}
}