org.nlpcn.es4sql.parse.ElasticSqlExprParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch-sql Show documentation
Show all versions of elasticsearch-sql Show documentation
Query elasticsearch using SQL
The newest version!
package org.nlpcn.es4sql.parse;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
import com.alibaba.druid.sql.ast.SQLPartition;
import com.alibaba.druid.sql.ast.SQLPartitionValue;
import com.alibaba.druid.sql.ast.SQLSubPartition;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLExistsExpr;
import com.alibaba.druid.sql.ast.expr.SQLHexExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntervalExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntervalUnit;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLNotExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
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.MySqlCharExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlUserName;
import com.alibaba.druid.sql.parser.Lexer;
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;
import com.alibaba.druid.util.FnvHash;
import com.alibaba.druid.util.JdbcConstants;
import java.util.Arrays;
import java.util.List;
/**
* Created by Eliran on 18/8/2015.
*/
public class ElasticSqlExprParser extends SQLExprParser {
public final static String[] AGGREGATE_FUNCTIONS;
public final static long[] AGGREGATE_FUNCTIONS_CODES;
static {
String[] strings = { "AVG", "COUNT", "GROUP_CONCAT", "MAX", "MIN", "STDDEV", "SUM" };
AGGREGATE_FUNCTIONS_CODES = FnvHash.fnv1a_64_lower(strings, true);
AGGREGATE_FUNCTIONS = new String[AGGREGATE_FUNCTIONS_CODES.length];
for (String str : strings) {
long hash = FnvHash.fnv1a_64_lower(str);
int index = Arrays.binarySearch(AGGREGATE_FUNCTIONS_CODES, hash);
AGGREGATE_FUNCTIONS[index] = str;
}
}
public ElasticSqlExprParser(Lexer lexer){
super(lexer, JdbcConstants.MYSQL);
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
this.aggregateFunctionHashCodes = AGGREGATE_FUNCTIONS_CODES;
}
public ElasticSqlExprParser(String sql){
this(new ElasticLexer(sql));
this.lexer.nextToken();
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void parseHints(List hints) {
while (lexer.token() == Token.HINT) {
SQLCommentHint hint = new SQLCommentHint(lexer.stringVal());
if (lexer.getCommentCount() > 0) {
hint.addBeforeComment(lexer.readAndResetComments());
}
hints.add(hint);
lexer.nextToken();
}
}
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(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 SQLExpr primary2() {
final Token tok = lexer.token();
if (lexer.identifierEquals(FnvHash.Constants.OUTFILE)) {
lexer.nextToken();
SQLExpr file = primary();
SQLExpr expr = new MySqlOutFileExpr(file);
return primaryRest(expr);
}
switch (tok) {
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. " + lexer.info());
}
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);
}
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 (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
lexer.nextToken();
String collate = lexer.stringVal();
mysqlCharExpr.setCollate(collate);
accept(Token.IDENTIFIER);
}
expr = mysqlCharExpr;
return primaryRest(expr);
}
} else if (expr instanceof SQLCharExpr) {
String text2 = ((SQLCharExpr) expr).getText();
do {
String chars = lexer.stringVal();
text2 += chars;
lexer.nextToken();
} while (lexer.token() == Token.LITERAL_CHARS || lexer.token() == Token.LITERAL_ALIAS);
expr = new SQLCharExpr(text2);
} else if (expr instanceof SQLVariantRefExpr) {
SQLMethodInvokeExpr concat = new SQLMethodInvokeExpr("CONCAT");
concat.addArgument(expr);
concat.addArgument(this.primary());
expr = concat;
return primaryRest(expr);
}
} 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. " + lexer.info());
}
String charSet = lexer.stringVal();
lexer.nextToken();
expr.getAttributes().put("USING", charSet);
return primaryRest(expr);
}
} else if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
if (lexer.token() != Token.IDENTIFIER
&& lexer.token() != Token.LITERAL_CHARS) {
throw new ParserException("syntax error. " + lexer.info());
}
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 (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
lexer.nextToken();
if (lexer.token() != Token.IDENTIFIER
&& lexer.token() != Token.LITERAL_CHARS) {
throw new ParserException("syntax error. " + lexer.info());
}
String collate = lexer.stringVal();
lexer.nextToken();
expr.putAttribute("COLLATE", collate);
return primaryRest(expr);
}
}
}
// if (lexer.token() == Token.LPAREN && expr instanceof SQLIdentifierExpr) {
// SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr;
// String ident = identExpr.getName();
//
// if ("POSITION".equalsIgnoreCase(ident)) {
// return parsePosition();
// }
// }
if (lexer.token() == Token.VARIANT && "@".equals(lexer.stringVal())) {
return userNameRest(expr);
}
//
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. " + lexer.info());
}
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 SQLName userName() {
SQLName name = this.name();
if (lexer.token() == Token.LPAREN && name.hashCode64() == FnvHash.Constants.CURRENT_USER) {
lexer.nextToken();
accept(Token.RPAREN);
return name;
}
return (SQLName) userNameRest(name);
}
private SQLExpr userNameRest(SQLExpr expr) {
if (lexer.token() != Token.VARIANT || !lexer.stringVal().startsWith("@")) {
return expr;
}
MySqlUserName userName = new MySqlUserName();
if (expr instanceof SQLCharExpr) {
userName.setUserName(((SQLCharExpr) expr).toString());
} else {
userName.setUserName(((SQLIdentifierExpr) expr).getName());
}
String strVal = lexer.stringVal();
lexer.nextToken();
if (strVal.length() > 1) {
userName.setHost(strVal.substring(1));
return userName;
}
if (lexer.token() == Token.LITERAL_CHARS) {
userName.setHost("'" + lexer.stringVal() + "'");
} else {
userName.setHost(lexer.stringVal());
}
lexer.nextToken();
if (lexer.token() == Token.IDENTIFIED) {
Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.token() == Token.BY) {
lexer.nextToken();
if (lexer.identifierEquals(FnvHash.Constants.PASSWORD)) {
lexer.reset(mark);
} else {
userName.setIdentifiedBy(lexer.stringVal());
lexer.nextToken();
}
} else {
lexer.reset(mark);
}
}
return userName;
}
protected SQLExpr parsePosition() {
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);
return primaryRest(locate);
}
protected SQLExpr parseExtract() {
SQLExpr expr;
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("syntax error. " + lexer.info());
}
String unitVal = lexer.stringVal();
SQLIntervalUnit unit = SQLIntervalUnit.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);
}
protected SQLExpr parseMatch() {
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 (lexer.identifierEquals(FnvHash.Constants.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 (lexer.identifierEquals(FnvHash.Constants.BOOLEAN)) {
lexer.nextToken();
acceptIdentifier("MODE");
matchAgainstExpr.setSearchModifier(MySqlMatchAgainstExpr.SearchModifier.IN_BOOLEAN_MODE);
} else {
throw new ParserException("syntax error. " + lexer.info());
}
} else if (lexer.token() == Token.WITH) {
throw new ParserException("TODO. " + lexer.info());
}
accept(Token.RPAREN);
return primaryRest(matchAgainstExpr);
}
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);
//
if (methodInvokeExpr.getParameters().size() == 1 //
&& lexer.token() == Token.IDENTIFIER) {
SQLExpr value = methodInvokeExpr.getParameters().get(0);
String unit = lexer.stringVal();
lexer.nextToken();
SQLIntervalExpr intervalExpr = new SQLIntervalExpr();
intervalExpr.setValue(value);
intervalExpr.setUnit(SQLIntervalUnit.valueOf(unit.toUpperCase()));
return intervalExpr;
} else {
return primaryRest(methodInvokeExpr);
}
} else {
SQLExpr value = expr();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("Syntax error. " + lexer.info());
}
String unit = lexer.stringVal();
lexer.nextToken();
SQLIntervalExpr intervalExpr = new SQLIntervalExpr();
intervalExpr.setValue(value);
intervalExpr.setUnit(SQLIntervalUnit.valueOf(unit.toUpperCase()));
return intervalExpr;
}
}
public SQLColumnDefinition parseColumn() {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
column.setName(name());
column.setDataType(parseDataType());
if (lexer.identifierEquals(FnvHash.Constants.GENERATED)) {
lexer.nextToken();
acceptIdentifier("ALWAYS");
accept(Token.AS);
accept(Token.LPAREN);
SQLExpr expr = this.expr();
accept(Token.RPAREN);
column.setGeneratedAlawsAs(expr);
}
return parseColumnRest(column);
}
public SQLColumnDefinition parseColumnRest(SQLColumnDefinition column) {
if (lexer.token() == Token.ON) {
lexer.nextToken();
accept(Token.UPDATE);
SQLExpr expr = this.expr();
column.setOnUpdate(expr);
}
if (lexer.identifierEquals(FnvHash.Constants.CHARACTER)) {
lexer.nextToken();
accept(Token.SET);
MySqlCharExpr charSetCollateExpr=new MySqlCharExpr();
charSetCollateExpr.setCharset(lexer.stringVal());
lexer.nextToken();
if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
lexer.nextToken();
charSetCollateExpr.setCollate(lexer.stringVal());
lexer.nextToken();
}
column.setCharsetExpr(charSetCollateExpr);
return parseColumnRest(column);
}
if (lexer.identifierEquals(FnvHash.Constants.CHARSET)) {
lexer.nextToken();
MySqlCharExpr charSetCollateExpr=new MySqlCharExpr();
charSetCollateExpr.setCharset(lexer.stringVal());
lexer.nextToken();
if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
lexer.nextToken();
charSetCollateExpr.setCollate(lexer.stringVal());
lexer.nextToken();
}
column.setCharsetExpr(charSetCollateExpr);
return parseColumnRest(column);
}
if (lexer.identifierEquals(FnvHash.Constants.AUTO_INCREMENT)) {
lexer.nextToken();
column.setAutoIncrement(true);
return parseColumnRest(column);
}
if (lexer.identifierEquals(FnvHash.Constants.PRECISION)
&& column.getDataType().nameHashCode64() ==FnvHash.Constants.DOUBLE) {
lexer.nextToken();
}
if (lexer.token() == Token.PARTITION) {
throw new ParserException("syntax error " + lexer.info());
}
if (lexer.identifierEquals(FnvHash.Constants.STORAGE)) {
lexer.nextToken();
SQLExpr expr = expr();
column.setStorage(expr);
}
if (lexer.token() == Token.AS) {
lexer.nextToken();
accept(Token.LPAREN);
SQLExpr expr = expr();
column.setAsExpr(expr);
accept(Token.RPAREN);
}
if (lexer.identifierEquals(FnvHash.Constants.STORED)) {
lexer.nextToken();
column.setStored(true);
}
if (lexer.identifierEquals(FnvHash.Constants.VIRTUAL)) {
lexer.nextToken();
column.setVirtual(true);
}
super.parseColumnRest(column);
return column;
}
protected SQLDataType parseDataTypeRest(SQLDataType dataType) {
super.parseDataTypeRest(dataType);
for (;;) {
if (lexer.identifierEquals(FnvHash.Constants.UNSIGNED)) {
lexer.nextToken();
((SQLDataTypeImpl) dataType).setUnsigned(true);
} else if (lexer.identifierEquals(FnvHash.Constants.ZEROFILL)) {
lexer.nextToken();
((SQLDataTypeImpl) dataType).setZerofill(true);
} else {
break;
}
}
return dataType;
}
public SQLAssignItem parseAssignItem() {
SQLAssignItem item = new SQLAssignItem();
SQLExpr var = primary();
String ident = null;
long identHash = 0;
if (var instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) var;
ident = identExpr.getName();
identHash = identExpr.hashCode64();
if (identHash == FnvHash.Constants.GLOBAL) {
ident = lexer.stringVal();
lexer.nextToken();
var = new SQLVariantRefExpr(ident, true);
} else if (identHash == FnvHash.Constants.SESSION) {
ident = lexer.stringVal();
lexer.nextToken();
var = new SQLVariantRefExpr(ident, false, true);
} else {
var = new SQLVariantRefExpr(ident);
}
}
if (identHash == FnvHash.Constants.NAMES) {
String charset = lexer.stringVal();
SQLExpr varExpr = null;
boolean chars = false;
final Token token = lexer.token();
if (token == Token.IDENTIFIER) {
lexer.nextToken();
} else if (token == Token.DEFAULT) {
charset = "DEFAULT";
lexer.nextToken();
} else if (token == Token.QUES) {
varExpr = new SQLVariantRefExpr("?");
lexer.nextToken();
} else {
chars = true;
accept(Token.LITERAL_CHARS);
}
if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
MySqlCharExpr charsetExpr = new MySqlCharExpr(charset);
lexer.nextToken();
String collate = lexer.stringVal();
lexer.nextToken();
charsetExpr.setCollate(collate);
item.setValue(charsetExpr);
} else {
if (varExpr != null) {
item.setValue(varExpr);
} else {
item.setValue(chars
? new SQLCharExpr(charset)
: new SQLIdentifierExpr(charset)
);
}
}
item.setTarget(var);
return item;
} else if (identHash == FnvHash.Constants.CHARACTER) {
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);
}
}
if (lexer.token() == Token.ON) {
lexer.nextToken();
item.setValue(new SQLIdentifierExpr("ON"));
} else {
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();
if (lexer.token() == Token.IDENTIFIED) {
lexer.nextToken();
accept(Token.BY);
userName.setIdentifiedBy(lexer.stringVal());
lexer.nextToken();
}
return userName;
}
return super.nameRest(name);
}
@Override
public MySqlPrimaryKey parsePrimaryKey() {
accept(Token.PRIMARY);
accept(Token.KEY);
MySqlPrimaryKey primaryKey = new MySqlPrimaryKey();
if (lexer.identifierEquals(FnvHash.Constants.USING)) {
lexer.nextToken();
primaryKey.setIndexType(lexer.stringVal());
lexer.nextToken();
}
if (lexer.token() != Token.LPAREN) {
SQLName name = this.name();
primaryKey.setName(name);
}
accept(Token.LPAREN);
for (;;) {
SQLExpr expr;
if (lexer.token() == Token.LITERAL_ALIAS) {
expr = this.name();
} else {
expr = this.expr();
}
primaryKey.addColumn(expr);
if (!(lexer.token() == (Token.COMMA))) {
break;
} else {
lexer.nextToken();
}
}
accept(Token.RPAREN);
if (lexer.identifierEquals(FnvHash.Constants.USING)) {
lexer.nextToken();
primaryKey.setIndexType(lexer.stringVal());
lexer.nextToken();
}
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.setName(indexName);
}
//5.5语法 USING BTREE 放在index 名字后
if (lexer.identifierEquals(FnvHash.Constants.USING)) {
lexer.nextToken();
unique.setIndexType(lexer.stringVal());
lexer.nextToken();
}
accept(Token.LPAREN);
for (;;) {
SQLExpr column = this.expr();
if (lexer.token() == Token.ASC) {
column = new MySqlOrderingExpr(column, SQLOrderingSpecification.ASC);
lexer.nextToken();
} else if (lexer.token() == Token.DESC) {
column = new MySqlOrderingExpr(column, SQLOrderingSpecification.DESC);
lexer.nextToken();
}
unique.addColumn(column);
if (!(lexer.token() == (Token.COMMA))) {
break;
} else {
lexer.nextToken();
}
}
accept(Token.RPAREN);
if (lexer.identifierEquals(FnvHash.Constants.USING)) {
lexer.nextToken();
unique.setIndexType(lexer.stringVal());
lexer.nextToken();
}
if (lexer.identifierEquals(FnvHash.Constants.KEY_BLOCK_SIZE)) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
SQLExpr value = this.primary();
unique.setKeyBlockSize(value);
}
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(), fk);
accept(Token.RPAREN);
accept(Token.REFERENCES);
fk.setReferencedTableName(this.name());
accept(Token.LPAREN);
this.names(fk.getReferencedColumns());
accept(Token.RPAREN);
if (lexer.identifierEquals(FnvHash.Constants.MATCH)) {
lexer.nextToken();
if (lexer.identifierEquals("FULL") || lexer.token() == Token.FULL) {
fk.setReferenceMatch(SQLForeignKeyImpl.Match.FULL);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.PARTIAL)) {
fk.setReferenceMatch(SQLForeignKeyImpl.Match.PARTIAL);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.SIMPLE)) {
fk.setReferenceMatch(SQLForeignKeyImpl.Match.SIMPLE);
lexer.nextToken();
} else {
throw new ParserException("TODO : " + lexer.info());
}
}
while (lexer.token() == Token.ON) {
lexer.nextToken();
if (lexer.token() == Token.DELETE) {
lexer.nextToken();
SQLForeignKeyImpl.Option option = parseReferenceOption();
fk.setOnDelete(option);
} else if (lexer.token() == Token.UPDATE) {
lexer.nextToken();
SQLForeignKeyImpl.Option option = parseReferenceOption();
fk.setOnUpdate(option);
} else {
throw new ParserException("syntax error, expect DELETE or UPDATE, actual " + lexer.token() + " "
+ lexer.info());
}
}
return fk;
}
protected SQLAggregateExpr parseAggregateExprRest(SQLAggregateExpr aggregateExpr) {
if (lexer.token() == Token.ORDER) {
SQLOrderBy orderBy = this.parseOrderBy();
aggregateExpr.putAttribute("ORDER BY", orderBy);
}
if (lexer.identifierEquals(FnvHash.Constants.SEPARATOR)) {
lexer.nextToken();
SQLExpr seperator = this.primary();
seperator.setParent(aggregateExpr);
aggregateExpr.putAttribute("SEPARATOR", seperator);
}
return aggregateExpr;
}
public MySqlOrderingExpr parseSelectGroupByItem() {
MySqlOrderingExpr item = new MySqlOrderingExpr();
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;
}
public SQLPartition parsePartition() {
accept(Token.PARTITION);
SQLPartition partitionDef = new SQLPartition();
partitionDef.setName(this.name());
SQLPartitionValue values = this.parsePartitionValues();
if (values != null) {
partitionDef.setValues(values);
}
for (;;) {
boolean storage = false;
if (lexer.identifierEquals(FnvHash.Constants.DATA)) {
lexer.nextToken();
acceptIdentifier("DIRECTORY");
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
partitionDef.setDataDirectory(this.expr());
} else if (lexer.token() == Token.TABLESPACE) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
SQLName tableSpace = this.name();
partitionDef.setTablespace(tableSpace);
} else if (lexer.token() == Token.INDEX) {
lexer.nextToken();
acceptIdentifier("DIRECTORY");
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
partitionDef.setIndexDirectory(this.expr());
} else if (lexer.identifierEquals(FnvHash.Constants.MAX_ROWS)) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
SQLExpr maxRows = this.primary();
partitionDef.setMaxRows(maxRows);
} else if (lexer.identifierEquals(FnvHash.Constants.MIN_ROWS)) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
SQLExpr minRows = this.primary();
partitionDef.setMaxRows(minRows);
} else if (lexer.identifierEquals(FnvHash.Constants.ENGINE) || //
(storage = (lexer.token() == Token.STORAGE || lexer.identifierEquals(FnvHash.Constants.STORAGE)))) {
if (storage) {
lexer.nextToken();
}
acceptIdentifier("ENGINE");
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
SQLName engine = this.name();
partitionDef.setEngine(engine);
} else if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
SQLExpr comment = this.primary();
partitionDef.setComment(comment);
} else {
break;
}
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
for (;;) {
acceptIdentifier("SUBPARTITION");
SQLName subPartitionName = this.name();
SQLSubPartition subPartition = new SQLSubPartition();
subPartition.setName(subPartitionName);
partitionDef.addSubPartition(subPartition);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
accept(Token.RPAREN);
}
return partitionDef;
}
protected SQLExpr parseAliasExpr(String alias) {
String chars = alias.substring(1, alias.length() - 1);
return new SQLCharExpr(chars);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy