use of com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr in project Mycat-Server by MyCATApache.
the class JoinParser method parserWhere.
private void parserWhere(SQLExpr aexpr, String Operator) {
if (aexpr == null) {
return;
}
if (aexpr instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr expr = (SQLBinaryOpExpr) aexpr;
SQLExpr exprL = expr.getLeft();
if (!(exprL instanceof SQLBinaryOpExpr)) {
opSQLExpr((SQLBinaryOpExpr) aexpr, Operator);
} else {
// if (expr.getOperator().getName().equals("AND")) {
if (expr.getOperator() == SQLBinaryOperator.BooleanAnd) {
//parserWhere(exprL);
//parserWhere(expr.getRight());
andorWhere(exprL, expr.getOperator().getName(), expr.getRight());
} else if (expr.getOperator() == SQLBinaryOperator.BooleanOr) {
//.getName().equals("OR")) {
andorWhere(exprL, expr.getOperator().getName(), expr.getRight());
} else {
throw new RuntimeException("Can't identify the operation of of where");
}
}
}
}
use of com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr in project Mycat-Server by MyCATApache.
the class DruidSelectOracleParser method parseThreeLevelPageSql.
private void parseThreeLevelPageSql(SQLStatement stmt, RouteResultset rrs, SchemaConfig schema, SQLSubqueryTableSource from, SQLBinaryOpExpr one, SQLBinaryOperator operator) {
SQLIntegerExpr right = (SQLIntegerExpr) one.getRight();
int firstrownum = right.getNumber().intValue();
if (operator == SQLBinaryOperator.GreaterThanOrEqual && firstrownum != 0) {
firstrownum = firstrownum - 1;
}
SQLSelectQuery subSelect = from.getSelect().getQuery();
if (subSelect instanceof OracleSelectQueryBlock) {
//第二层子查询
OracleSelectQueryBlock twoSubSelect = (OracleSelectQueryBlock) subSelect;
if (twoSubSelect.getWhere() instanceof SQLBinaryOpExpr && twoSubSelect.getFrom() instanceof SQLSubqueryTableSource) {
SQLBinaryOpExpr twoWhere = (SQLBinaryOpExpr) twoSubSelect.getWhere();
boolean isRowNum = "rownum".equalsIgnoreCase(twoWhere.getLeft().toString());
boolean isLess = twoWhere.getOperator() == SQLBinaryOperator.LessThanOrEqual || twoWhere.getOperator() == SQLBinaryOperator.LessThan;
if (isRowNum && twoWhere.getRight() instanceof SQLIntegerExpr && isLess) {
int lastrownum = ((SQLIntegerExpr) twoWhere.getRight()).getNumber().intValue();
if (operator == SQLBinaryOperator.LessThan && lastrownum != 0) {
lastrownum = lastrownum - 1;
}
SQLSelectQuery finalQuery = ((SQLSubqueryTableSource) twoSubSelect.getFrom()).getSelect().getQuery();
if (finalQuery instanceof OracleSelectQueryBlock) {
setLimitIFChange(stmt, rrs, schema, one, firstrownum, lastrownum);
parseOrderAggGroupOracle(stmt, rrs, (OracleSelectQueryBlock) finalQuery, schema);
isNeedParseOrderAgg = false;
}
}
}
}
}
use of com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr in project Mycat-Server by MyCATApache.
the class DruidUpdateParserTest method printWhereClauseAST.
/*
* 添加一个static方法用于打印一个SQL的where子句,比如这样的一条SQL:
* update mytab t set t.ptn_col = 'A', col1 = 3 where ptn_col = 'A' and (col1 = 4 or col2 > 5);
* where子句的语法树如下
* AND
* / \
* = OR
* / \ / \
* ptn_col 'A' = >
* / \ / \
* col1 4 col2 5
* 其输出如下,(按层输出,并且每层最后输出下一层的节点数目)
* BooleanAnd Num of nodes in next level: 2
* Equality BooleanOr Num of nodes in next level: 4
* ptn_col 'A' Equality Equality Num of nodes in next level: 4
* col1 4 col2 5 Num of nodes in next level: 0
*
* 因为大部分的update的where子句都比较简单,按层次打印应该足够清晰,未来可以完全按照逻辑打印类似上面的整棵树结构
*/
public static void printWhereClauseAST(SQLExpr sqlExpr) {
// where子句的AST sqlExpr可以通过 MySqlUpdateStatement.getWhere(); 获得
if (sqlExpr == null)
return;
ArrayList<SQLExpr> exprNode = new ArrayList<>();
int i = 0, curLevel = 1, nextLevel = 0;
SQLExpr iterExpr;
exprNode.add(sqlExpr);
while (true) {
iterExpr = exprNode.get(i++);
if (iterExpr == null)
break;
if (iterExpr instanceof SQLBinaryOpExpr) {
System.out.print(((SQLBinaryOpExpr) iterExpr).getOperator());
} else {
System.out.print(iterExpr.toString());
}
System.out.print("\t");
curLevel--;
if (iterExpr instanceof SQLBinaryOpExpr) {
if (((SQLBinaryOpExpr) iterExpr).getLeft() != null) {
exprNode.add(((SQLBinaryOpExpr) iterExpr).getLeft());
nextLevel++;
}
if (((SQLBinaryOpExpr) iterExpr).getRight() != null) {
exprNode.add(((SQLBinaryOpExpr) iterExpr).getRight());
nextLevel++;
}
}
if (curLevel == 0) {
System.out.println("\t\tNum of nodes in next level: " + nextLevel);
curLevel = nextLevel;
nextLevel = 0;
}
if (exprNode.size() == i)
break;
}
}
use of com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr in project druid by alibaba.
the class PagerUtils method limitDB2.
private static String limitDB2(SQLSelect select, String dbType, int offset, int count) {
SQLSelectQuery query = select.getQuery();
SQLBinaryOpExpr gt = new //
SQLBinaryOpExpr(//
new SQLIdentifierExpr("ROWNUM"), //
SQLBinaryOperator.GreaterThan, //
new SQLNumberExpr(offset), JdbcConstants.DB2);
SQLBinaryOpExpr lteq = new //
SQLBinaryOpExpr(//
new SQLIdentifierExpr("ROWNUM"), //
SQLBinaryOperator.LessThanOrEqual, //
new SQLNumberExpr(count + offset), JdbcConstants.DB2);
SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq, JdbcConstants.DB2);
if (query instanceof SQLSelectQueryBlock) {
DB2SelectQueryBlock queryBlock = (DB2SelectQueryBlock) query;
if (offset <= 0) {
queryBlock.setFirst(new SQLNumberExpr(count));
return SQLUtils.toSQLString(select, dbType);
}
SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER");
SQLOrderBy orderBy = select.getOrderBy();
if (orderBy == null && select.getQuery() instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock selectQueryBlcok = (SQLSelectQueryBlock) select.getQuery();
orderBy = selectQueryBlcok.getOrderBy();
selectQueryBlcok.setOrderBy(null);
} else {
select.setOrderBy(null);
}
aggregateExpr.setOver(new SQLOver(orderBy));
queryBlock.getSelectList().add(new SQLSelectItem(aggregateExpr, "ROWNUM"));
DB2SelectQueryBlock countQueryBlock = new DB2SelectQueryBlock();
countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr()));
countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX"));
countQueryBlock.setWhere(pageCondition);
return SQLUtils.toSQLString(countQueryBlock, dbType);
}
DB2SelectQueryBlock countQueryBlock = new DB2SelectQueryBlock();
countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLPropertyExpr(new SQLIdentifierExpr("XX"), "*")));
SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER");
SQLOrderBy orderBy = select.getOrderBy();
aggregateExpr.setOver(new SQLOver(orderBy));
select.setOrderBy(null);
countQueryBlock.getSelectList().add(new SQLSelectItem(aggregateExpr, "ROWNUM"));
countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX"));
if (offset <= 0) {
return SQLUtils.toSQLString(countQueryBlock, dbType);
}
DB2SelectQueryBlock offsetQueryBlock = new DB2SelectQueryBlock();
offsetQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr()));
offsetQueryBlock.setFrom(new SQLSubqueryTableSource(new SQLSelect(countQueryBlock), "XXX"));
offsetQueryBlock.setWhere(pageCondition);
return SQLUtils.toSQLString(offsetQueryBlock, dbType);
}
use of com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr in project druid by alibaba.
the class MySqlExprParser method primaryRest.
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(SearchModifier.IN_NATURAL_LANGUAGE_MODE_WITH_QUERY_EXPANSION);
} else {
matchAgainstExpr.setSearchModifier(SearchModifier.IN_NATURAL_LANGUAGE_MODE);
}
} else if (identifierEquals("BOOLEAN")) {
lexer.nextToken();
acceptIdentifier("MODE");
matchAgainstExpr.setSearchModifier(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)) || ("CHAR".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 (lexer.token() == Token.ERROR) {
throw new ParserException("syntax error, token: " + lexer.token() + " " + lexer.stringVal() + ", pos : " + lexer.pos());
}
return super.primaryRest(expr);
}
Aggregations