Add support for Teradata 'MOD' and 'QUALIFY' keyword

This commit is contained in:
Louis Xu
2016-04-21 17:20:53 +08:00
parent a347bdc435
commit 5e1f16592d
5 changed files with 68 additions and 0 deletions
@@ -28,6 +28,7 @@ public enum SQLBinaryOperator {
Multiply("*", 60),
Divide("/", 60),
Modulus("%", 60),
Mod("MOD", 60),
Add("+", 70),
Subtract("-", 70),
@@ -1,6 +1,7 @@
package com.alibaba.druid.sql.dialect.teradata.ast.stmt;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.teradata.visitor.TeradataASTVisitor;
@@ -8,6 +9,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class TeradataSelectQueryBlock extends SQLSelectQueryBlock {
private SQLOrderBy orderBy;
private SQLExpr qualifyClause;
public TeradataSelectQueryBlock() {
@@ -30,6 +32,7 @@ public class TeradataSelectQueryBlock extends SQLSelectQueryBlock {
acceptChild(visitor, this.from);
acceptChild(visitor, this.where);
acceptChild(visitor, this.groupBy);
acceptChild(visitor, this.qualifyClause);
acceptChild(visitor, this.orderBy);
}
visitor.endVisit(this);
@@ -43,6 +46,17 @@ public class TeradataSelectQueryBlock extends SQLSelectQueryBlock {
this.orderBy = orderBy;
}
public SQLExpr getQualifyClause() {
return qualifyClause;
}
public void setQualifyClause(SQLExpr qualify) {
if (qualify != null) {
qualify.setParent(this);
}
this.qualifyClause = qualify;
}
public String toString() {
return SQLUtils.toTeradataString(this);
}
@@ -45,6 +45,10 @@ public class TeradataLexer extends Lexer {
map.put("FORMAT", Token.FORMAT);
map.put("QUALIFY", Token.QUALIFY);
map.put("MOD", Token.MOD);
DEFAULT_TD_KEYWORDS = new Keywords(map);
}
@@ -1,9 +1,17 @@
package com.alibaba.druid.sql.dialect.teradata.parser;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLDefaultExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.teradata.ast.stmt.TeradataSelectQueryBlock;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.Token;
@@ -54,9 +62,49 @@ public class TeradataSelectParser extends SQLSelectParser{
parseGroupBy(queryBlock);
parserQualify(queryBlock);
queryBlock.setOrderBy(this.exprParser.parseOrderBy());
return queryRest(queryBlock);
}
private void parserQualify(TeradataSelectQueryBlock queryBlock) {
if (lexer.token() != Token.QUALIFY) {
return;
}
lexer.nextToken();
if (lexer.token() == Token.LITERAL_INT) {
lexer.nextToken();
// possibly =, >=, <=
// ignore this for now
lexer.nextToken();
if (lexer.token() == Token.IDENTIFIER) {
SQLExpr expr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
if (lexer.token() != Token.COMMA) {
expr = this.exprParser.primaryRest(expr);
}
// TODO: add qualify clause into queryBlock
queryBlock.setQualifyClause(expr);
} else {
throw new ParserException("not support token:" + lexer.token());
}
} else if (lexer.token() == Token.IDENTIFIER) {
SQLExpr expr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
if (lexer.token() != Token.COMMA) {
expr = this.exprParser.primaryRest(expr);
}
lexer.nextToken();
lexer.nextToken();
// TODO: add qualify clause into queryBlock
queryBlock.setQualifyClause(expr);
} else {
throw new ParserException("not support token:" + lexer.token());
}
}
}
@@ -272,6 +272,7 @@ public enum Token {
RANGE_N("RANGE_N"),
FORMAT("FORMAT"),
QUALIFY("QUALIFY"),
MOD("MOD"),
LPAREN("("),
RPAREN(")"),