Add support for Teradata interval

This commit is contained in:
Louis Xu
2016-03-29 19:01:52 +08:00
parent ce91facc67
commit c21bcfc9e4
9 changed files with 240 additions and 5 deletions
@@ -0,0 +1,78 @@
package com.alibaba.druid.sql.dialect.teradata.ast.expr;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.dialect.teradata.visitor.TeradataASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class TeradataIntervalExpr extends SQLExprImpl implements TeradataExpr {
private SQLExpr value;
private TeradataIntervalUnit unit;
public TeradataIntervalExpr() {
}
public SQLExpr getValue() {
return this.value;
}
public void setValue(SQLExpr value) {
this.value = value;
}
public TeradataIntervalUnit getUnit() {
return unit;
}
public void setUnit(TeradataIntervalUnit unit) {
this.unit = unit;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
TeradataIntervalExpr other = (TeradataIntervalExpr) obj;
if (unit != other.unit) {
return false;
}
if (value == null) {
if (other.value != null) {
return false;
}
} else if (!value.equals(other.value)) {
return false;
}
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((unit == null)? 0 : unit.hashCode());
result = prime * result + ((value == null)? 0 : value.hashCode());
return result;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
TeradataASTVisitor tdVisitor = (TeradataASTVisitor) visitor;
if (tdVisitor.visit(this)) {
acceptChild(visitor, this.value);
}
tdVisitor.endVisit(this);
}
}
@@ -0,0 +1,14 @@
package com.alibaba.druid.sql.dialect.teradata.ast.expr;
public enum TeradataIntervalUnit {
YEAR, MONTH, DAY,
HOUR, MINUTE, SECOND;
public final String name_lcase;
private TeradataIntervalUnit() {
this.name_lcase = name().toLowerCase();
}
}
@@ -15,13 +15,10 @@
*/
package com.alibaba.druid.sql.dialect.teradata.parser;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLKeep;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.SQLKeep.DenseRank;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLAggregateOption;
import com.alibaba.druid.sql.ast.expr.SQLCastExpr;
@@ -29,6 +26,8 @@ import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalytic;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalyticWindowing;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataIntervalExpr;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataIntervalUnit;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLExprParser;
@@ -258,4 +257,27 @@ public class TeradataExprParser extends SQLExprParser {
return aggregateExpr;
}
protected SQLExpr parseInterval() {
accept(Token.INTERVAL);
if (lexer.token() == Token.LITERAL_CHARS) {
SQLExpr value = expr();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("Syntax error");
}
String unit = lexer.stringVal();
lexer.nextToken();
TeradataIntervalExpr intervalExpr = new TeradataIntervalExpr();
intervalExpr.setValue(value);
intervalExpr.setUnit(TeradataIntervalUnit.valueOf(unit.toUpperCase()));
return intervalExpr;
} else {
throw new ParserException("TODO with other interval");
}
}
}
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalytic;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalyticWindowing;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataIntervalExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public interface TeradataASTVisitor extends SQLASTVisitor {
@@ -32,4 +33,8 @@ public interface TeradataASTVisitor extends SQLASTVisitor {
boolean visit(SQLSelectQueryBlock x);
boolean visit(SQLSelect x);
boolean visit(TeradataIntervalExpr x);
void endVisit(TeradataIntervalExpr x);
}
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.dialect.teradata.visitor;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalytic;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalyticWindowing;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataIntervalExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
public class TeradataASTVisitorAdapter extends SQLASTVisitorAdapter implements TeradataASTVisitor {
@@ -39,4 +40,16 @@ public class TeradataASTVisitorAdapter extends SQLASTVisitorAdapter implements T
return false;
}
@Override
public boolean visit(TeradataIntervalExpr x) {
// TODO Auto-generated method stub
return true;
}
@Override
public void endVisit(TeradataIntervalExpr x) {
// TODO Auto-generated method stub
}
}
@@ -0,0 +1,73 @@
package com.alibaba.druid.sql.dialect.teradata.visitor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
import com.alibaba.druid.sql.visitor.functions.Function;
public class TeradataEvalVisitor extends TeradataASTVisitorAdapter implements SQLEvalVisitor {
private Map<String, Function> functions = new HashMap<String, Function>();
private List<Object> parameters = new ArrayList<Object>();
private int variantIndex = -1;
private boolean markVariantIndex = true;
public TeradataEvalVisitor() {
this(new ArrayList<Object>(1));
}
public TeradataEvalVisitor(List<Object> parameters) {
this.parameters = parameters;
}
@Override
public Function getFunction(String funcName) {
return functions.get(funcName);
}
@Override
public void registerFunction(String funcName, Function function) {
functions.put(funcName, function);
}
@Override
public void unregisterFunction(String funcName) {
functions.remove(funcName);
}
@Override
public List<Object> getParameters() {
return parameters;
}
@Override
public void setParameters(List<Object> parameters) {
this.parameters = parameters;
}
@Override
public int incrementAndGetVariantIndex() {
return ++variantIndex;
}
@Override
public boolean isMarkVariantIndex() {
return markVariantIndex;
}
@Override
public void setMarkVariantIndex(boolean markVariantIndex) {
this.markVariantIndex = markVariantIndex;
}
public boolean visit(SQLBinaryOpExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
}
@@ -23,6 +23,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalytic;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalyticWindowing;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataIntervalExpr;
import com.alibaba.druid.sql.dialect.teradata.ast.stmt.TeradataSelectQueryBlock;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
@@ -158,4 +159,18 @@ public class TeradataOutputVisitor extends SQLASTOutputVisitor implements Terada
}
}
}
@Override
public boolean visit(TeradataIntervalExpr x) {
print0(ucase ? "INTERVAL " : "interval ");
x.getValue().accept(this);
print(' ');
print0(ucase ? x.getUnit().name() : x.getUnit().name_lcase);
return false;
}
@Override
public void endVisit(TeradataIntervalExpr x) {
}
}
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.dialect.teradata.visitor;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalytic;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataAnalyticWindowing;
import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataIntervalExpr;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.util.JdbcUtils;
@@ -29,7 +30,6 @@ public class TeradataSchemaStatVisitor extends SchemaStatVisitor implements Tera
@Override
public boolean visit(TeradataAnalyticWindowing x) {
// TODO Auto-generated method stub
return true;
}
@@ -45,4 +45,14 @@ public class TeradataSchemaStatVisitor extends SchemaStatVisitor implements Tera
return false;
}
@Override
public boolean visit(TeradataIntervalExpr x) {
return true;
}
@Override
public void endVisit(TeradataIntervalExpr x) {
}
}
@@ -44,6 +44,7 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlEvalVisitorImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleEvalVisitor;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGEvalVisitor;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerEvalVisitor;
import com.alibaba.druid.sql.dialect.teradata.visitor.TeradataEvalVisitor;
import com.alibaba.druid.sql.visitor.functions.Ascii;
import com.alibaba.druid.sql.visitor.functions.Bin;
import com.alibaba.druid.sql.visitor.functions.BitLength;
@@ -178,6 +179,10 @@ public class SQLEvalVisitorUtils {
if (JdbcUtils.DB2.equals(dbType)) {
return new DB2EvalVisitor();
}
if (JdbcUtils.TERADATA.equals(dbType)) {
return new TeradataEvalVisitor();
}
return new SQLEvalVisitorImpl();
}