org.nlpcn.es4sql.parse.ElasticSqlExprParser Maven / Gradle / Ivy
package org.nlpcn.es4sql.parse;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.*;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.*;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSQLColumnDefinition;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
import com.alibaba.druid.sql.parser.*;
import com.alibaba.druid.util.JdbcConstants;
import java.util.List;
/**
* Created by Eliran on 18/8/2015.
*/
public class ElasticSqlExprParser extends SQLExprParser {
public ElasticSqlExprParser(Lexer lexer) {
super(lexer);
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
}
public ElasticSqlExprParser(String sql) {
this(new ElasticLexer(sql));
this.lexer.nextToken();
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public void parseHints(List hints) {
while (lexer.token() == Token.HINT) {
hints.add(new SQLCommentHint(lexer.stringVal()));
lexer.nextToken();
}
}
@Override
protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) {
if (acceptLPAREN) {
accept(Token.LPAREN);
}
if (expr instanceof SQLName || expr instanceof SQLDefaultExpr) {
String methodName;
SQLMethodInvokeExpr methodInvokeExpr;
if (expr instanceof SQLPropertyExpr) {
methodName = ((SQLPropertyExpr) expr).getName();
methodInvokeExpr = new SQLMethodInvokeExpr(methodName);
methodInvokeExpr.setOwner(((SQLPropertyExpr) expr).getOwner());
} else {
methodName = expr.toString();
methodInvokeExpr = new SQLMethodInvokeExpr(methodName);
}
if (isAggreateFunction(methodName)) {
SQLAggregateExpr aggregateExpr = parseAggregateExpr(methodName);
return aggregateExpr;
}
if (lexer.token() != Token.RPAREN) {
exprList(methodInvokeExpr.getParameters(), methodInvokeExpr);
}
accept(Token.RPAREN);
return primaryRest(methodInvokeExpr);
}
throw new ParserException("not support token:" + lexer.token());
}
public SQLExpr primary() {
if (lexer.token() == Token.LBRACE) {
lexer.nextToken();
boolean foundRBrace = false;
if (lexer.stringVal().equals("ts")) {
String current = lexer.stringVal();
do {
if (current.equals(lexer.token().RBRACE.name())) {
foundRBrace = true;
break;
}
lexer.nextToken();
current = lexer.token().name();
} while (!foundRBrace && !current.trim().equals(""));
if (foundRBrace) {
SQLOdbcExpr sdle = new SQLOdbcExpr(lexer.stringVal());
accept(Token.RBRACE);
return sdle;
} else {
throw new ParserException("Error. Unable to find closing RBRACE");
}
} else {
throw new ParserException("Error. Unable to parse ODBC Literal Timestamp");
}
} else if (lexer.token() == Token.LBRACKET) {
StringBuilder identifier = new StringBuilder();
lexer.nextToken();
String prefix = "";
while (lexer.token() != Token.RBRACKET) {
if (lexer.token() != Token.IDENTIFIER && lexer.token() != Token.INDEX && lexer.token() != Token.LITERAL_CHARS) {
throw new ParserException("All items between Brackets should be identifiers , got:" + lexer.token());
}
identifier.append(prefix);
identifier.append(lexer.stringVal());
prefix = " ";
lexer.nextToken();
}
accept(Token.RBRACKET);
return new SQLIdentifierExpr(identifier.toString());
} else if (lexer.token() == Token.NOT) {
lexer.nextToken();
SQLExpr sqlExpr;
if (lexer.token() == Token.EXISTS) {
lexer.nextToken();
accept(Token.LPAREN);
sqlExpr = new SQLExistsExpr(createSelectParser().select(), true);
accept(Token.RPAREN);
} else if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLExpr notTarget = expr();
accept(Token.RPAREN);
sqlExpr = new SQLNotExpr(notTarget);
return primaryRest(sqlExpr);
} else {
SQLExpr restExpr = relational();
sqlExpr = new SQLNotExpr(restExpr);
}
return sqlExpr;
}
boolean parenWrapped = lexer.token() == Token.LPAREN;
SQLExpr expr = primary2();
// keep track of if the identifier is wrapped in parens
if (parenWrapped && expr instanceof SQLIdentifierExpr) {
expr = new SQLParensIdentifierExpr((SQLIdentifierExpr) expr);
}
return expr;
}
public static String[] AGGREGATE_FUNCTIONS = {"AVG", "COUNT", "GROUP_CONCAT", "MAX", "MIN", "STDDEV", "SUM"};
public SQLExpr relationalRest(SQLExpr expr) {
if (identifierEquals("REGEXP")) {
lexer.nextToken();
SQLExpr rightExp = equality();
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.RegExp, rightExp, JdbcConstants.MYSQL);
}
return super.relationalRest(expr);
}
public SQLExpr multiplicativeRest(SQLExpr expr) {
if (lexer.token() == Token.IDENTIFIER && "MOD".equalsIgnoreCase(lexer.stringVal())) {
lexer.nextToken();
SQLExpr rightExp = primary();
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.Modulus, rightExp, JdbcConstants.MYSQL);
}
return super.multiplicativeRest(expr);
}
public SQLExpr notRationalRest(SQLExpr expr) {
if (identifierEquals("REGEXP")) {
lexer.nextToken();
SQLExpr rightExp = primary();
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRegExp, rightExp, JdbcConstants.MYSQL);
}
return super.notRationalRest(expr);
}
public SQLExpr primary2() {
final Token tok = lexer.token();
if (identifierEquals("outfile")) {
lexer.nextToken();
SQLExpr file = primary();
SQLExpr expr = new MySqlOutFileExpr(file);
return primaryRest(expr);
}
switch (tok) {
case LITERAL_ALIAS:
String aliasValue = lexer.stringVal();
lexer.nextToken();
return primaryRest(new SQLCharExpr(aliasValue));
case VARIANT:
SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(lexer.stringVal());
lexer.nextToken();
if (varRefExpr.getName().equalsIgnoreCase("@@global")) {
accept(Token.DOT);
varRefExpr = new SQLVariantRefExpr(lexer.stringVal(), true);
lexer.nextToken();
} else if (varRefExpr.getName().equals("@") && lexer.token() == Token.LITERAL_CHARS) {
varRefExpr.setName("@'" + lexer.stringVal() + "'");
lexer.nextToken();
} else if (varRefExpr.getName().equals("@@") && lexer.token() == Token.LITERAL_CHARS) {
varRefExpr.setName("@@'" + lexer.stringVal() + "'");
lexer.nextToken();
}
return primaryRest(varRefExpr);
case VALUES:
lexer.nextToken();
if (lexer.token() != Token.LPAREN) {
throw new ParserException("syntax error, illegal values clause");
}
return this.methodRest(new SQLIdentifierExpr("VALUES"), true);
case BINARY:
lexer.nextToken();
if (lexer.token() == Token.COMMA || lexer.token() == Token.SEMI || lexer.token() == Token.EOF) {
return new SQLIdentifierExpr("BINARY");
} else {
SQLUnaryExpr binaryExpr = new SQLUnaryExpr(SQLUnaryOperator.BINARY, expr());
return primaryRest(binaryExpr);
}
case CACHE:
case GROUP:
lexer.nextToken();
return primaryRest(new SQLIdentifierExpr(lexer.stringVal()));
default:
return super.primary();
}
}
public final SQLExpr primaryRest(SQLExpr expr) {
if (expr == null) {
throw new IllegalArgumentException("expr");
}
if (lexer.token() == Token.LITERAL_CHARS) {
if (expr instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr;
String ident = identExpr.getName();
if (ident.equalsIgnoreCase("x")) {
String charValue = lexer.stringVal();
lexer.nextToken();
expr = new SQLHexExpr(charValue);
return primaryRest(expr);
} else if (ident.equalsIgnoreCase("b")) {
String charValue = lexer.stringVal();
lexer.nextToken();
expr = new SQLBinaryExpr(charValue);
return primaryRest(expr);
} else if (ident.startsWith("_")) {
String charValue = lexer.stringVal();
lexer.nextToken();
MySqlCharExpr mysqlCharExpr = new MySqlCharExpr(charValue);
mysqlCharExpr.setCharset(identExpr.getName());
if (identifierEquals("COLLATE")) {
lexer.nextToken();
String collate = lexer.stringVal();
mysqlCharExpr.setCollate(collate);
accept(Token.IDENTIFIER);
}
expr = mysqlCharExpr;
return primaryRest(expr);
}
} else if (expr instanceof SQLCharExpr) {
SQLMethodInvokeExpr concat = new SQLMethodInvokeExpr("CONCAT");
concat.addParameter(expr);
do {
String chars = lexer.stringVal();
concat.addParameter(new SQLCharExpr(chars));
lexer.nextToken();
} while (lexer.token() == Token.LITERAL_CHARS || lexer.token() == Token.LITERAL_ALIAS);
expr = concat;
}
} else if (lexer.token() == Token.IDENTIFIER) {
if (expr instanceof SQLHexExpr) {
if ("USING".equalsIgnoreCase(lexer.stringVal())) {
lexer.nextToken();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("syntax error, illegal hex");
}
String charSet = lexer.stringVal();
lexer.nextToken();
expr.getAttributes().put("USING", charSet);
return primaryRest(expr);
}
} else if ("COLLATE".equalsIgnoreCase(lexer.stringVal())) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("syntax error");
}
String collate = lexer.stringVal();
lexer.nextToken();
SQLBinaryOpExpr binaryExpr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.COLLATE,
new SQLIdentifierExpr(collate), JdbcConstants.MYSQL);
expr = binaryExpr;
return primaryRest(expr);
} else if (expr instanceof SQLVariantRefExpr) {
if ("COLLATE".equalsIgnoreCase(lexer.stringVal())) {
lexer.nextToken();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("syntax error");
}
String collate = lexer.stringVal();
lexer.nextToken();
expr.putAttribute("COLLATE", collate);
return primaryRest(expr);
}
} else if (expr instanceof SQLIntegerExpr) {
SQLIntegerExpr intExpr = (SQLIntegerExpr) expr;
String binaryString = lexer.stringVal();
if (intExpr.getNumber().intValue() == 0 && binaryString.startsWith("b")) {
lexer.nextToken();
expr = new SQLBinaryExpr(binaryString.substring(1));
return primaryRest(expr);
}
}
}
if (lexer.token() == Token.LPAREN && expr instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr;
String ident = identExpr.getName();
if ("EXTRACT".equalsIgnoreCase(ident)) {
lexer.nextToken();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("syntax error");
}
String unitVal = lexer.stringVal();
MySqlIntervalUnit unit = MySqlIntervalUnit.valueOf(unitVal.toUpperCase());
lexer.nextToken();
accept(Token.FROM);
SQLExpr value = expr();
MySqlExtractExpr extract = new MySqlExtractExpr();
extract.setValue(value);
extract.setUnit(unit);
accept(Token.RPAREN);
expr = extract;
return primaryRest(expr);
} else if ("SUBSTRING".equalsIgnoreCase(ident)) {
lexer.nextToken();
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(ident);
for (; ; ) {
SQLExpr param = expr();
methodInvokeExpr.addParameter(param);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLExpr from = expr();
methodInvokeExpr.addParameter(from);
if (lexer.token() == Token.FOR) {
lexer.nextToken();
SQLExpr forExpr = expr();
methodInvokeExpr.addParameter(forExpr);
}
break;
} else if (lexer.token() == Token.RPAREN) {
break;
} else {
throw new ParserException("syntax error");
}
}
accept(Token.RPAREN);
expr = methodInvokeExpr;
return primaryRest(expr);
} else if ("TRIM".equalsIgnoreCase(ident)) {
lexer.nextToken();
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(ident);
if (lexer.token() == Token.IDENTIFIER) {
String flagVal = lexer.stringVal();
if ("LEADING".equalsIgnoreCase(flagVal)) {
lexer.nextToken();
methodInvokeExpr.getAttributes().put("TRIM_TYPE", "LEADING");
} else if ("BOTH".equalsIgnoreCase(flagVal)) {
lexer.nextToken();
methodInvokeExpr.getAttributes().put("TRIM_TYPE", "BOTH");
} else if ("TRAILING".equalsIgnoreCase(flagVal)) {
lexer.nextToken();
methodInvokeExpr.putAttribute("TRIM_TYPE", "TRAILING");
}
}
SQLExpr param = expr();
methodInvokeExpr.addParameter(param);
if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLExpr from = expr();
methodInvokeExpr.putAttribute("FROM", from);
}
accept(Token.RPAREN);
expr = methodInvokeExpr;
return primaryRest(expr);
} else if ("MATCH".equalsIgnoreCase(ident)) {
lexer.nextToken();
MySqlMatchAgainstExpr matchAgainstExpr = new MySqlMatchAgainstExpr();
if (lexer.token() == Token.RPAREN) {
lexer.nextToken();
} else {
exprList(matchAgainstExpr.getColumns(), matchAgainstExpr);
accept(Token.RPAREN);
}
acceptIdentifier("AGAINST");
accept(Token.LPAREN);
SQLExpr against = primary();
matchAgainstExpr.setAgainst(against);
if (lexer.token() == Token.IN) {
lexer.nextToken();
if (identifierEquals("NATURAL")) {
lexer.nextToken();
acceptIdentifier("LANGUAGE");
acceptIdentifier("MODE");
if (lexer.token() == Token.WITH) {
lexer.nextToken();
acceptIdentifier("QUERY");
acceptIdentifier("EXPANSION");
matchAgainstExpr.setSearchModifier(MySqlMatchAgainstExpr.SearchModifier.IN_NATURAL_LANGUAGE_MODE_WITH_QUERY_EXPANSION);
} else {
matchAgainstExpr.setSearchModifier(MySqlMatchAgainstExpr.SearchModifier.IN_NATURAL_LANGUAGE_MODE);
}
} else if (identifierEquals("BOOLEAN")) {
lexer.nextToken();
acceptIdentifier("MODE");
matchAgainstExpr.setSearchModifier(MySqlMatchAgainstExpr.SearchModifier.IN_BOOLEAN_MODE);
} else {
throw new ParserException("TODO");
}
} else if (lexer.token() == Token.WITH) {
throw new ParserException("TODO");
}
accept(Token.RPAREN);
expr = matchAgainstExpr;
return primaryRest(expr);
} else if ("CONVERT".equalsIgnoreCase(ident)) {
lexer.nextToken();
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(ident);
if (lexer.token() != Token.RPAREN) {
exprList(methodInvokeExpr.getParameters(), methodInvokeExpr);
}
if (identifierEquals("USING")) {
lexer.nextToken();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("syntax error");
}
String charset = lexer.stringVal();
lexer.nextToken();
methodInvokeExpr.putAttribute("USING", charset);
}
accept(Token.RPAREN);
expr = methodInvokeExpr;
return primaryRest(expr);
} else if ("POSITION".equalsIgnoreCase(ident)) {
accept(Token.LPAREN);
SQLExpr subStr = this.primary();
accept(Token.IN);
SQLExpr str = this.expr();
accept(Token.RPAREN);
SQLMethodInvokeExpr locate = new SQLMethodInvokeExpr("LOCATE");
locate.addParameter(subStr);
locate.addParameter(str);
expr = locate;
return primaryRest(expr);
}
}
if (lexer.token() == Token.VARIANT && "@".equals(lexer.stringVal())) {
lexer.nextToken();
MySqlUserName userName = new MySqlUserName();
if (expr instanceof SQLCharExpr) {
userName.setUserName(((SQLCharExpr) expr).toString());
} else {
userName.setUserName(((SQLIdentifierExpr) expr).getName());
}
if (lexer.token() == Token.LITERAL_CHARS) {
userName.setHost("'" + lexer.stringVal() + "'");
} else {
userName.setHost(lexer.stringVal());
}
lexer.nextToken();
return userName;
}
//
if (expr instanceof SQLMethodInvokeExpr && lexer.token() == Token.LBRACKET) {
lexer.nextToken();
expr = bracketRest(expr);
return primaryRest(expr);
}
if (lexer.token() == Token.ERROR) {
throw new ParserException("syntax error, token: " + lexer.token() + " " + lexer.stringVal() + ", pos : "
+ lexer.pos());
}
return super.primaryRest(expr);
}
protected SQLExpr bracketRest(SQLExpr expr) {
Number index;
if (lexer.token() == Token.LITERAL_INT) {
index = lexer.integerValue();
lexer.nextToken();
} else {
throw new ParserException("error : " + lexer.stringVal());
}
if (expr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodInvokeExpr = (SQLMethodInvokeExpr) expr;
methodInvokeExpr.getParameters().add(new SQLIntegerExpr(index));
}
lexer.nextToken();
expr = primaryRest(expr);
return expr;
}
public SQLSelectParser createSelectParser() {
return new ElasticSqlSelectParser(this);
}
protected SQLExpr parseInterval() {
accept(Token.INTERVAL);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr("INTERVAL");
if (lexer.token() != Token.RPAREN) {
exprList(methodInvokeExpr.getParameters(), methodInvokeExpr);
}
accept(Token.RPAREN);
return primaryRest(methodInvokeExpr);
} else {
SQLExpr value = expr();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("Syntax error");
}
String unit = lexer.stringVal();
lexer.nextToken();
MySqlIntervalExpr intervalExpr = new MySqlIntervalExpr();
intervalExpr.setValue(value);
intervalExpr.setUnit(MySqlIntervalUnit.valueOf(unit.toUpperCase()));
return intervalExpr;
}
}
public SQLColumnDefinition parseColumn() {
MySqlSQLColumnDefinition column = new MySqlSQLColumnDefinition();
column.setName(name());
column.setDataType(parseDataType());
return parseColumnRest(column);
}
public SQLColumnDefinition parseColumnRest(SQLColumnDefinition column) {
if (lexer.token() == Token.ON) {
lexer.nextToken();
accept(Token.UPDATE);
SQLExpr expr = this.expr();
((MySqlSQLColumnDefinition) column).setOnUpdate(expr);
}
if (identifierEquals("AUTO_INCREMENT")) {
lexer.nextToken();
if (column instanceof MySqlSQLColumnDefinition) {
((MySqlSQLColumnDefinition) column).setAutoIncrement(true);
}
return parseColumnRest(column);
}
if (identifierEquals("precision") && column.getDataType().getName().equalsIgnoreCase("double")) {
lexer.nextToken();
}
if (identifierEquals("PARTITION")) {
throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal());
}
if (identifierEquals("STORAGE")) {
lexer.nextToken();
SQLExpr expr = expr();
if (column instanceof MySqlSQLColumnDefinition) {
((MySqlSQLColumnDefinition) column).setStorage(expr);
}
}
super.parseColumnRest(column);
return column;
}
protected SQLDataType parseDataTypeRest(SQLDataType dataType) {
super.parseDataTypeRest(dataType);
if (identifierEquals("UNSIGNED")) {
lexer.nextToken();
dataType.getAttributes().put("UNSIGNED", true);
}
if (identifierEquals("ZEROFILL")) {
lexer.nextToken();
dataType.getAttributes().put("ZEROFILL", true);
}
return dataType;
}
public SQLExpr orRest(SQLExpr expr) {
for (; ; ) {
if (lexer.token() == Token.OR || lexer.token() == Token.BARBAR) {
lexer.nextToken();
SQLExpr rightExp = and();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp, JdbcConstants.MYSQL);
} else if (lexer.token() == Token.XOR) {
lexer.nextToken();
SQLExpr rightExp = and();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp, JdbcConstants.MYSQL);
} else {
break;
}
}
return expr;
}
public SQLExpr additiveRest(SQLExpr expr) {
if (lexer.token() == Token.PLUS) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Add, rightExp, JdbcConstants.MYSQL);
expr = additiveRest(expr);
} else if (lexer.token() == Token.SUB) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Subtract, rightExp, JdbcConstants.MYSQL);
expr = additiveRest(expr);
}
return expr;
}
public SQLAssignItem parseAssignItem() {
SQLAssignItem item = new SQLAssignItem();
SQLExpr var = primary();
String ident = null;
if (var instanceof SQLIdentifierExpr) {
ident = ((SQLIdentifierExpr) var).getName();
if ("GLOBAL".equalsIgnoreCase(ident)) {
ident = lexer.stringVal();
lexer.nextToken();
var = new SQLVariantRefExpr(ident, true);
} else if ("SESSION".equalsIgnoreCase(ident)) {
ident = lexer.stringVal();
lexer.nextToken();
var = new SQLVariantRefExpr(ident, false);
} else {
var = new SQLVariantRefExpr(ident);
}
}
if ("NAMES".equalsIgnoreCase(ident)) {
// skip
} else if ("CHARACTER".equalsIgnoreCase(ident)) {
var = new SQLIdentifierExpr("CHARACTER SET");
accept(Token.SET);
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
} else {
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
} else {
accept(Token.EQ);
}
}
item.setValue(this.expr());
item.setTarget(var);
return item;
}
public SQLName nameRest(SQLName name) {
if (lexer.token() == Token.VARIANT && "@".equals(lexer.stringVal())) {
lexer.nextToken();
MySqlUserName userName = new MySqlUserName();
userName.setUserName(((SQLIdentifierExpr) name).getName());
if (lexer.token() == Token.LITERAL_CHARS) {
userName.setHost("'" + lexer.stringVal() + "'");
} else {
userName.setHost(lexer.stringVal());
}
lexer.nextToken();
return userName;
}
return super.nameRest(name);
}
public MySqlSelectQueryBlock.Limit parseLimit() {
if (lexer.token() == Token.LIMIT) {
lexer.nextToken();
MySqlSelectQueryBlock.Limit limit = new MySqlSelectQueryBlock.Limit();
SQLExpr temp = this.expr();
if (lexer.token() == (Token.COMMA)) {
limit.setOffset(temp);
lexer.nextToken();
limit.setRowCount(this.expr());
} else if (identifierEquals("OFFSET")) {
limit.setRowCount(temp);
lexer.nextToken();
limit.setOffset(this.expr());
} else {
limit.setRowCount(temp);
}
return limit;
}
return null;
}
@Override
public MySqlPrimaryKey parsePrimaryKey() {
accept(Token.PRIMARY);
accept(Token.KEY);
MySqlPrimaryKey primaryKey = new MySqlPrimaryKey();
if (identifierEquals("USING")) {
lexer.nextToken();
primaryKey.setIndexType(lexer.stringVal());
lexer.nextToken();
}
accept(Token.LPAREN);
for (; ; ) {
primaryKey.getColumns().add(this.expr());
if (!(lexer.token() == (Token.COMMA))) {
break;
} else {
lexer.nextToken();
}
}
accept(Token.RPAREN);
return primaryKey;
}
public MySqlUnique parseUnique() {
accept(Token.UNIQUE);
if (lexer.token() == Token.KEY) {
lexer.nextToken();
}
if (lexer.token() == Token.INDEX) {
lexer.nextToken();
}
MySqlUnique unique = new MySqlUnique();
if (lexer.token() != Token.LPAREN) {
SQLName indexName = name();
unique.setIndexName(indexName);
}
accept(Token.LPAREN);
for (; ; ) {
unique.getColumns().add(this.expr());
if (!(lexer.token() == (Token.COMMA))) {
break;
} else {
lexer.nextToken();
}
}
accept(Token.RPAREN);
if (identifierEquals("USING")) {
lexer.nextToken();
unique.setIndexType(lexer.stringVal());
lexer.nextToken();
}
return unique;
}
public MysqlForeignKey parseForeignKey() {
accept(Token.FOREIGN);
accept(Token.KEY);
MysqlForeignKey fk = new MysqlForeignKey();
if (lexer.token() != Token.LPAREN) {
SQLName indexName = name();
fk.setIndexName(indexName);
}
accept(Token.LPAREN);
this.names(fk.getReferencingColumns());
accept(Token.RPAREN);
accept(Token.REFERENCES);
fk.setReferencedTableName(this.name());
accept(Token.LPAREN);
this.names(fk.getReferencedColumns());
accept(Token.RPAREN);
if (identifierEquals("MATCH")) {
if (identifierEquals("FULL")) {
fk.setReferenceMatch(MysqlForeignKey.Match.FULL);
} else if (identifierEquals("PARTIAL")) {
fk.setReferenceMatch(MysqlForeignKey.Match.PARTIAL);
} else if (identifierEquals("SIMPLE")) {
fk.setReferenceMatch(MysqlForeignKey.Match.SIMPLE);
}
}
if (lexer.token() == Token.ON) {
lexer.nextToken();
if (lexer.token() == Token.DELETE) {
fk.setReferenceOn(MysqlForeignKey.On.DELETE);
} else if (lexer.token() == Token.UPDATE) {
fk.setReferenceOn(MysqlForeignKey.On.UPDATE);
} else {
throw new ParserException("syntax error, expect DELETE or UPDATE, actual " + lexer.token() + " "
+ lexer.stringVal());
}
lexer.nextToken();
if (lexer.token() == Token.RESTRICT) {
fk.setReferenceOption(MysqlForeignKey.Option.RESTRICT);
} else if (identifierEquals("CASCADE")) {
fk.setReferenceOption(MysqlForeignKey.Option.CASCADE);
} else if (lexer.token() == Token.SET) {
accept(Token.NULL);
fk.setReferenceOption(MysqlForeignKey.Option.SET_NULL);
} else if (identifierEquals("ON")) {
lexer.nextToken();
if (identifierEquals("ACTION")) {
fk.setReferenceOption(MysqlForeignKey.Option.NO_ACTION);
} else {
throw new ParserException("syntax error, expect ACTION, actual " + lexer.token() + " "
+ lexer.stringVal());
}
}
lexer.nextToken();
}
return fk;
}
protected SQLAggregateExpr parseAggregateExprRest(SQLAggregateExpr aggregateExpr) {
if (lexer.token() == Token.ORDER) {
SQLOrderBy orderBy = this.parseOrderBy();
aggregateExpr.putAttribute("ORDER BY", orderBy);
}
if (identifierEquals("SEPARATOR")) {
lexer.nextToken();
SQLExpr seperator = this.primary();
aggregateExpr.putAttribute("SEPARATOR", seperator);
}
return aggregateExpr;
}
public MySqlSelectGroupByExpr parseSelectGroupByItem() {
MySqlSelectGroupByExpr item = new MySqlSelectGroupByExpr();
item.setExpr(expr());
if (lexer.token() == Token.ASC) {
lexer.nextToken();
item.setType(SQLOrderingSpecification.ASC);
} else if (lexer.token() == Token.DESC) {
lexer.nextToken();
item.setType(SQLOrderingSpecification.DESC);
}
return item;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy