expr = mysqlCharExpr;
return primaryRest(expr);
}
} else if (expr instanceof SQLCharExpr) {
SQLMethodInvokeExpr concat = new SQLMethodInvokeExpr("CONCAT");
concat.getParameters().add(expr);
do {
String chars = lexer.stringVal();
concat.getParameters().add(new SQLCharExpr(chars));
lexer.nextToken();
} while (lexer.token() == Token.LITERAL_CHARS);
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.IDENTIFIER) {
throw new ParserException("syntax error");
}
String collate = lexer.stringVal();
lexer.nextToken();
SQLBinaryOpExpr binaryExpr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.COLLATE,
new SQLIdentifierExpr(collate));
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 MySqlBinaryExpr(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);
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.getParameters().add(param);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLExpr from = expr();
methodInvokeExpr.putAttribute("FROM", from);
if (lexer.token() == Token.FOR) {
lexer.nextToken();
SQLExpr _for = expr();
methodInvokeExpr.putAttribute("FOR", _for);
}
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.getParameters().add(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());
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 (identifierEquals("WITH")) {
lexer.nextToken();
acceptIdentifier("QUERY");
acceptIdentifier("EXPANSION");
matchAgainstExpr.setSearchModifier(SearchModifier.IN_NATURAL_LANGUAGE_MODE_WITH_QUERY_EXPANSION);
} else {
matchAgainstExpr.setSearchModifier(SearchModifier.IN_NATURAL_LANGUAGE_MODE);
}
} else {
throw new ParserException("TODO");
}
} else if (identifierEquals("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());
}
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;