mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve Oracle SQL Parser, support Timestamp & Interval
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleDataTypeIntervalDay extends SQLDataTypeImpl implements OracleSQLObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private boolean toSecond = false;
|
||||
|
||||
protected final List<SQLExpr> fractionalSeconds = new ArrayList<SQLExpr>();
|
||||
|
||||
public OracleDataTypeIntervalDay(){
|
||||
this.setName("INTERVAL DAY");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
this.accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, getArguments());
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public boolean isToSecond() {
|
||||
return toSecond;
|
||||
}
|
||||
|
||||
public void setToSecond(boolean toSecond) {
|
||||
this.toSecond = toSecond;
|
||||
}
|
||||
|
||||
public List<SQLExpr> getFractionalSeconds() {
|
||||
return fractionalSeconds;
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleDataTypeIntervalYear extends SQLDataTypeImpl implements OracleSQLObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OracleDataTypeIntervalYear(){
|
||||
this.setName("INTERVAL YEAR");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
this.accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, getArguments());
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleDataTypeTimestamp extends SQLDataTypeImpl implements OracleSQLObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private boolean withTimeZone = false;
|
||||
private boolean withLocalTimeZone = false;
|
||||
|
||||
public OracleDataTypeTimestamp() {
|
||||
this.setName("TIMESTAMP");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
this.accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, getArguments());
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public boolean isWithTimeZone() {
|
||||
return withTimeZone;
|
||||
}
|
||||
|
||||
public void setWithTimeZone(boolean withTimeZone) {
|
||||
this.withTimeZone = withTimeZone;
|
||||
}
|
||||
|
||||
public boolean isWithLocalTimeZone() {
|
||||
return withLocalTimeZone;
|
||||
}
|
||||
|
||||
public void setWithLocalTimeZone(boolean withLocalTimeZone) {
|
||||
this.withLocalTimeZone = withLocalTimeZone;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,6 +37,9 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCharactorDataType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
|
||||
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;
|
||||
@@ -75,6 +78,7 @@ public class OracleExprParser extends SQLExprParser {
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean allowStringAdditive = false;
|
||||
|
||||
/**
|
||||
@@ -117,9 +121,73 @@ public class OracleExprParser extends SQLExprParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.INTERVAL) {
|
||||
lexer.nextToken();
|
||||
if (identifierEquals("YEAR")) {
|
||||
lexer.nextToken();
|
||||
OracleDataTypeIntervalYear interval = new OracleDataTypeIntervalYear();
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
interval.getArguments().add(this.expr());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
accept(Token.TO);
|
||||
acceptIdentifier("MONTH");
|
||||
|
||||
return interval;
|
||||
} else {
|
||||
acceptIdentifier("DAY");
|
||||
OracleDataTypeIntervalDay interval = new OracleDataTypeIntervalDay();
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
interval.getArguments().add(this.expr());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
accept(Token.TO);
|
||||
acceptIdentifier("SECOND");
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
interval.getFractionalSeconds().add(this.expr());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
return interval;
|
||||
}
|
||||
}
|
||||
|
||||
SQLName typeExpr = name();
|
||||
String typeName = typeExpr.toString();
|
||||
|
||||
if ("TIMESTAMP".equalsIgnoreCase(typeName)) {
|
||||
OracleDataTypeTimestamp timestamp = new OracleDataTypeTimestamp();
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
timestamp.getArguments().add(this.expr());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.WITH) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (identifierEquals("LOCAL")) {
|
||||
lexer.nextToken();
|
||||
timestamp.setWithLocalTimeZone(true);
|
||||
} else {
|
||||
timestamp.setWithTimeZone(true);
|
||||
}
|
||||
|
||||
acceptIdentifier("TIME");
|
||||
acceptIdentifier("ZONE");
|
||||
}
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
if (isCharType(typeName)) {
|
||||
SQLCharactorDataType charType = new SQLCharactorDataType(typeName);
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
|
||||
@@ -611,4 +614,17 @@ public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(OracleDropDatabaseLinkStatement x);
|
||||
|
||||
void endVisit(OracleDropDatabaseLinkStatement x);
|
||||
|
||||
boolean visit(OracleDataTypeTimestamp x);
|
||||
|
||||
void endVisit(OracleDataTypeTimestamp x);
|
||||
|
||||
boolean visit(OracleDataTypeIntervalYear x);
|
||||
|
||||
void endVisit(OracleDataTypeIntervalYear x);
|
||||
|
||||
boolean visit(OracleDataTypeIntervalDay x);
|
||||
|
||||
void endVisit(OracleDataTypeIntervalDay x);
|
||||
|
||||
}
|
||||
|
||||
+33
@@ -16,6 +16,9 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
|
||||
@@ -1393,4 +1396,34 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeTimestamp x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeTimestamp x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeIntervalYear x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeIntervalYear x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeIntervalDay x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeIntervalDay x) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
|
||||
@@ -3107,4 +3110,72 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeTimestamp x) {
|
||||
print(x.getName());
|
||||
if (x.getArguments().size() > 0) {
|
||||
print("(");
|
||||
x.getArguments().get(0).accept(this);
|
||||
print(")");
|
||||
}
|
||||
|
||||
if (x.isWithTimeZone()) {
|
||||
print(" WITH TIME ZONE");
|
||||
} else if (x.isWithLocalTimeZone()) {
|
||||
print(" WITH LOCAL TIME ZONE");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeTimestamp x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeIntervalYear x) {
|
||||
print(x.getName());
|
||||
if (x.getArguments().size() > 0) {
|
||||
print("(");
|
||||
x.getArguments().get(0).accept(this);
|
||||
print(")");
|
||||
}
|
||||
|
||||
print(" TO MONTH");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeIntervalYear x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeIntervalDay x) {
|
||||
print(x.getName());
|
||||
if (x.getArguments().size() > 0) {
|
||||
print("(");
|
||||
x.getArguments().get(0).accept(this);
|
||||
print(")");
|
||||
}
|
||||
|
||||
print(" TO SECOND");
|
||||
|
||||
if (x.getFractionalSeconds().size() > 0) {
|
||||
print("(");
|
||||
x.getFractionalSeconds().get(0).accept(this);
|
||||
print(")");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeIntervalDay x) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+33
@@ -37,6 +37,9 @@ 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.ast.statement.SQLTruncateStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
|
||||
@@ -1822,4 +1825,34 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
public void endVisit(OracleDropDatabaseLinkStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeTimestamp x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeTimestamp x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeIntervalYear x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeIntervalYear x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleDataTypeIntervalDay x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleDataTypeIntervalDay x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user