use of com.alibaba.druid.sql.ast.statement.SQLSelectQuery in project Mycat-Server by MyCATApache.
the class DruidSelectDb2Parser method parseNativePageSql.
protected void parseNativePageSql(SQLStatement stmt, RouteResultset rrs, OracleSelectQueryBlock mysqlSelectQuery, SchemaConfig schema) {
//第一层子查询
SQLExpr where = mysqlSelectQuery.getWhere();
SQLTableSource from = mysqlSelectQuery.getFrom();
if (where instanceof SQLBinaryOpExpr && from instanceof SQLSubqueryTableSource) {
SQLBinaryOpExpr one = (SQLBinaryOpExpr) where;
SQLExpr left = one.getLeft();
SQLBinaryOperator operator = one.getOperator();
SQLSelectQuery subSelect = ((SQLSubqueryTableSource) from).getSelect().getQuery();
SQLOrderBy orderBy = null;
if (subSelect instanceof OracleSelectQueryBlock) {
boolean hasRowNumber = false;
OracleSelectQueryBlock subSelectOracle = (OracleSelectQueryBlock) subSelect;
List<SQLSelectItem> sqlSelectItems = subSelectOracle.getSelectList();
for (SQLSelectItem sqlSelectItem : sqlSelectItems) {
SQLExpr sqlExpr = sqlSelectItem.getExpr();
if (sqlExpr instanceof SQLAggregateExpr) {
SQLAggregateExpr agg = (SQLAggregateExpr) sqlExpr;
if ("row_number".equalsIgnoreCase(agg.getMethodName()) && agg.getOver() != null) {
hasRowNumber = true;
orderBy = agg.getOver().getOrderBy();
}
}
}
if (hasRowNumber) {
if ((operator == SQLBinaryOperator.LessThan || operator == SQLBinaryOperator.LessThanOrEqual) && one.getRight() instanceof SQLIntegerExpr) {
SQLIntegerExpr right = (SQLIntegerExpr) one.getRight();
int firstrownum = right.getNumber().intValue();
if (operator == SQLBinaryOperator.LessThan && firstrownum != 0) {
firstrownum = firstrownum - 1;
}
if (subSelect instanceof OracleSelectQueryBlock) {
rrs.setLimitStart(0);
rrs.setLimitSize(firstrownum);
//为了继续解出order by 等
mysqlSelectQuery = (OracleSelectQueryBlock) subSelect;
if (orderBy != null) {
OracleSelect oracleSelect = (OracleSelect) subSelect.getParent();
oracleSelect.setOrderBy(orderBy);
}
parseOrderAggGroupOracle(stmt, rrs, mysqlSelectQuery, schema);
isNeedParseOrderAgg = false;
}
} else if (operator == SQLBinaryOperator.BooleanAnd && left instanceof SQLBinaryOpExpr && one.getRight() instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr leftE = (SQLBinaryOpExpr) left;
SQLBinaryOpExpr rightE = (SQLBinaryOpExpr) one.getRight();
SQLBinaryOpExpr small = null;
SQLBinaryOpExpr larger = null;
int firstrownum = 0;
int lastrownum = 0;
if (leftE.getRight() instanceof SQLIntegerExpr && (leftE.getOperator() == SQLBinaryOperator.GreaterThan || leftE.getOperator() == SQLBinaryOperator.GreaterThanOrEqual)) {
small = leftE;
firstrownum = ((SQLIntegerExpr) leftE.getRight()).getNumber().intValue();
if (leftE.getOperator() == SQLBinaryOperator.GreaterThanOrEqual && firstrownum != 0) {
firstrownum = firstrownum - 1;
}
} else if (leftE.getRight() instanceof SQLIntegerExpr && (leftE.getOperator() == SQLBinaryOperator.LessThan || leftE.getOperator() == SQLBinaryOperator.LessThanOrEqual)) {
larger = leftE;
lastrownum = ((SQLIntegerExpr) leftE.getRight()).getNumber().intValue();
if (leftE.getOperator() == SQLBinaryOperator.LessThan && lastrownum != 0) {
lastrownum = lastrownum - 1;
}
}
if (rightE.getRight() instanceof SQLIntegerExpr && (rightE.getOperator() == SQLBinaryOperator.GreaterThan || rightE.getOperator() == SQLBinaryOperator.GreaterThanOrEqual)) {
small = rightE;
firstrownum = ((SQLIntegerExpr) rightE.getRight()).getNumber().intValue();
if (rightE.getOperator() == SQLBinaryOperator.GreaterThanOrEqual && firstrownum != 0) {
firstrownum = firstrownum - 1;
}
} else if (rightE.getRight() instanceof SQLIntegerExpr && (rightE.getOperator() == SQLBinaryOperator.LessThan || rightE.getOperator() == SQLBinaryOperator.LessThanOrEqual)) {
larger = rightE;
lastrownum = ((SQLIntegerExpr) rightE.getRight()).getNumber().intValue();
if (rightE.getOperator() == SQLBinaryOperator.LessThan && lastrownum != 0) {
lastrownum = lastrownum - 1;
}
}
if (small != null && larger != null) {
setLimitIFChange(stmt, rrs, schema, small, firstrownum, lastrownum);
if (orderBy != null) {
OracleSelect oracleSelect = (OracleSelect) subSelect.getParent();
oracleSelect.setOrderBy(orderBy);
}
parseOrderAggGroupOracle(stmt, rrs, (OracleSelectQueryBlock) subSelect, schema);
isNeedParseOrderAgg = false;
}
}
} else {
parseNativeSql(stmt, rrs, mysqlSelectQuery, schema);
}
}
} else {
parseNativeSql(stmt, rrs, mysqlSelectQuery, schema);
}
if (isNeedParseOrderAgg) {
parseOrderAggGroupOracle(stmt, rrs, mysqlSelectQuery, schema);
}
}
use of com.alibaba.druid.sql.ast.statement.SQLSelectQuery in project Mycat-Server by MyCATApache.
the class DruidSelectOracleParser method parseNativePageSql.
protected void parseNativePageSql(SQLStatement stmt, RouteResultset rrs, OracleSelectQueryBlock mysqlSelectQuery, SchemaConfig schema) {
//第一层子查询
SQLExpr where = mysqlSelectQuery.getWhere();
SQLTableSource from = mysqlSelectQuery.getFrom();
if (where instanceof SQLBinaryOpExpr && from instanceof SQLSubqueryTableSource) {
SQLBinaryOpExpr one = (SQLBinaryOpExpr) where;
SQLExpr left = one.getLeft();
SQLBinaryOperator operator = one.getOperator();
//解析只有一层rownum限制大小
if (one.getRight() instanceof SQLIntegerExpr && "rownum".equalsIgnoreCase(left.toString()) && (operator == SQLBinaryOperator.LessThanOrEqual || operator == SQLBinaryOperator.LessThan)) {
SQLIntegerExpr right = (SQLIntegerExpr) one.getRight();
int firstrownum = right.getNumber().intValue();
if (operator == SQLBinaryOperator.LessThan && firstrownum != 0) {
firstrownum = firstrownum - 1;
}
SQLSelectQuery subSelect = ((SQLSubqueryTableSource) from).getSelect().getQuery();
if (subSelect instanceof OracleSelectQueryBlock) {
rrs.setLimitStart(0);
rrs.setLimitSize(firstrownum);
//为了继续解出order by 等
mysqlSelectQuery = (OracleSelectQueryBlock) subSelect;
parseOrderAggGroupOracle(stmt, rrs, mysqlSelectQuery, schema);
isNeedParseOrderAgg = false;
}
} else //解析oracle三层嵌套分页
if (one.getRight() instanceof SQLIntegerExpr && !"rownum".equalsIgnoreCase(left.toString()) && (operator == SQLBinaryOperator.GreaterThan || operator == SQLBinaryOperator.GreaterThanOrEqual)) {
parseThreeLevelPageSql(stmt, rrs, schema, (SQLSubqueryTableSource) from, one, operator);
} else //解析oracle rownumber over分页
{
SQLSelectQuery subSelect = ((SQLSubqueryTableSource) from).getSelect().getQuery();
SQLOrderBy orderBy = null;
if (subSelect instanceof OracleSelectQueryBlock) {
boolean hasRowNumber = false;
OracleSelectQueryBlock subSelectOracle = (OracleSelectQueryBlock) subSelect;
List<SQLSelectItem> sqlSelectItems = subSelectOracle.getSelectList();
for (SQLSelectItem sqlSelectItem : sqlSelectItems) {
SQLExpr sqlExpr = sqlSelectItem.getExpr();
if (sqlExpr instanceof SQLAggregateExpr) {
SQLAggregateExpr agg = (SQLAggregateExpr) sqlExpr;
if ("row_number".equalsIgnoreCase(agg.getMethodName()) && agg.getOver() != null) {
hasRowNumber = true;
orderBy = agg.getOver().getOrderBy();
}
}
}
if (hasRowNumber) {
if ((operator == SQLBinaryOperator.LessThan || operator == SQLBinaryOperator.LessThanOrEqual) && one.getRight() instanceof SQLIntegerExpr) {
SQLIntegerExpr right = (SQLIntegerExpr) one.getRight();
int firstrownum = right.getNumber().intValue();
if (operator == SQLBinaryOperator.LessThan && firstrownum != 0) {
firstrownum = firstrownum - 1;
}
if (subSelect instanceof OracleSelectQueryBlock) {
rrs.setLimitStart(0);
rrs.setLimitSize(firstrownum);
mysqlSelectQuery = (OracleSelectQueryBlock) subSelect;
if (orderBy != null) {
OracleSelect oracleSelect = (OracleSelect) subSelect.getParent();
oracleSelect.setOrderBy(orderBy);
}
parseOrderAggGroupOracle(stmt, rrs, mysqlSelectQuery, schema);
isNeedParseOrderAgg = false;
}
} else if (operator == SQLBinaryOperator.BooleanAnd && left instanceof SQLBinaryOpExpr && one.getRight() instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr leftE = (SQLBinaryOpExpr) left;
SQLBinaryOpExpr rightE = (SQLBinaryOpExpr) one.getRight();
SQLBinaryOpExpr small = null;
SQLBinaryOpExpr larger = null;
int firstrownum = 0;
int lastrownum = 0;
if (leftE.getRight() instanceof SQLIntegerExpr && (leftE.getOperator() == SQLBinaryOperator.GreaterThan || leftE.getOperator() == SQLBinaryOperator.GreaterThanOrEqual)) {
small = leftE;
firstrownum = ((SQLIntegerExpr) leftE.getRight()).getNumber().intValue();
if (leftE.getOperator() == SQLBinaryOperator.GreaterThanOrEqual && firstrownum != 0) {
firstrownum = firstrownum - 1;
}
} else if (leftE.getRight() instanceof SQLIntegerExpr && (leftE.getOperator() == SQLBinaryOperator.LessThan || leftE.getOperator() == SQLBinaryOperator.LessThanOrEqual)) {
larger = leftE;
lastrownum = ((SQLIntegerExpr) leftE.getRight()).getNumber().intValue();
if (leftE.getOperator() == SQLBinaryOperator.LessThan && lastrownum != 0) {
lastrownum = lastrownum - 1;
}
}
if (rightE.getRight() instanceof SQLIntegerExpr && (rightE.getOperator() == SQLBinaryOperator.GreaterThan || rightE.getOperator() == SQLBinaryOperator.GreaterThanOrEqual)) {
small = rightE;
firstrownum = ((SQLIntegerExpr) rightE.getRight()).getNumber().intValue();
if (rightE.getOperator() == SQLBinaryOperator.GreaterThanOrEqual && firstrownum != 0) {
firstrownum = firstrownum - 1;
}
} else if (rightE.getRight() instanceof SQLIntegerExpr && (rightE.getOperator() == SQLBinaryOperator.LessThan || rightE.getOperator() == SQLBinaryOperator.LessThanOrEqual)) {
larger = rightE;
lastrownum = ((SQLIntegerExpr) rightE.getRight()).getNumber().intValue();
if (rightE.getOperator() == SQLBinaryOperator.LessThan && lastrownum != 0) {
lastrownum = lastrownum - 1;
}
}
if (small != null && larger != null) {
setLimitIFChange(stmt, rrs, schema, small, firstrownum, lastrownum);
if (orderBy != null) {
OracleSelect oracleSelect = (OracleSelect) subSelect.getParent();
oracleSelect.setOrderBy(orderBy);
}
parseOrderAggGroupOracle(stmt, rrs, (OracleSelectQueryBlock) subSelect, schema);
isNeedParseOrderAgg = false;
}
}
} else {
parseNativeSql(stmt, rrs, mysqlSelectQuery, schema);
}
}
}
} else {
parseNativeSql(stmt, rrs, mysqlSelectQuery, schema);
}
if (isNeedParseOrderAgg) {
parseOrderAggGroupOracle(stmt, rrs, mysqlSelectQuery, schema);
}
}
use of com.alibaba.druid.sql.ast.statement.SQLSelectQuery in project Mycat-Server by MyCATApache.
the class DruidSelectOracleParser method statementParse.
@Override
public void statementParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt) {
SQLSelectStatement selectStmt = (SQLSelectStatement) stmt;
SQLSelectQuery sqlSelectQuery = selectStmt.getSelect().getQuery();
//从mysql解析过来
if (sqlSelectQuery instanceof MySqlSelectQueryBlock) {
MySqlSelectQueryBlock mysqlSelectQuery = (MySqlSelectQueryBlock) selectStmt.getSelect().getQuery();
Limit limit = mysqlSelectQuery.getLimit();
if (limit == null) {
//使用oracle的解析,否则会有部分oracle语法识别错误
OracleStatementParser oracleParser = new OracleStatementParser(getCtx().getSql());
SQLSelectStatement oracleStmt = (SQLSelectStatement) oracleParser.parseStatement();
selectStmt = oracleStmt;
SQLSelectQuery oracleSqlSelectQuery = oracleStmt.getSelect().getQuery();
if (oracleSqlSelectQuery instanceof OracleSelectQueryBlock) {
parseNativePageSql(oracleStmt, rrs, (OracleSelectQueryBlock) oracleSqlSelectQuery, schema);
}
}
if (isNeedParseOrderAgg) {
parseOrderAggGroupMysql(schema, selectStmt, rrs, mysqlSelectQuery);
//更改canRunInReadDB属性
if ((mysqlSelectQuery.isForUpdate() || mysqlSelectQuery.isLockInShareMode()) && rrs.isAutocommit() == false) {
rrs.setCanRunInReadDB(false);
}
}
}
}
use of com.alibaba.druid.sql.ast.statement.SQLSelectQuery in project Mycat-Server by MyCATApache.
the class DruidSelectParser method changeSql.
/**
* 改写sql:需要加limit的加上
*/
@Override
public void changeSql(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt, LayerCachePool cachePool) throws SQLNonTransientException {
tryRoute(schema, rrs, cachePool);
rrs.copyLimitToNodes();
SQLSelectStatement selectStmt = (SQLSelectStatement) stmt;
SQLSelectQuery sqlSelectQuery = selectStmt.getSelect().getQuery();
if (sqlSelectQuery instanceof MySqlSelectQueryBlock) {
MySqlSelectQueryBlock mysqlSelectQuery = (MySqlSelectQueryBlock) selectStmt.getSelect().getQuery();
int limitStart = 0;
int limitSize = schema.getDefaultMaxLimit();
//clear group having
SQLSelectGroupByClause groupByClause = mysqlSelectQuery.getGroupBy();
// Modified by winbill, 20160614, do NOT include having clause when routing to multiple nodes
if (groupByClause != null && groupByClause.getHaving() != null && isRoutMultiNode(schema, rrs)) {
groupByClause.setHaving(null);
}
Map<String, Map<String, Set<ColumnRoutePair>>> allConditions = getAllConditions();
boolean isNeedAddLimit = isNeedAddLimit(schema, rrs, mysqlSelectQuery, allConditions);
if (isNeedAddLimit) {
Limit limit = new Limit();
limit.setRowCount(new SQLIntegerExpr(limitSize));
mysqlSelectQuery.setLimit(limit);
rrs.setLimitSize(limitSize);
String sql = getSql(rrs, stmt, isNeedAddLimit);
rrs.changeNodeSqlAfterAddLimit(schema, getCurentDbType(), sql, 0, limitSize, true);
}
Limit limit = mysqlSelectQuery.getLimit();
if (limit != null && !isNeedAddLimit) {
SQLIntegerExpr offset = (SQLIntegerExpr) limit.getOffset();
SQLIntegerExpr count = (SQLIntegerExpr) limit.getRowCount();
if (offset != null) {
limitStart = offset.getNumber().intValue();
rrs.setLimitStart(limitStart);
}
if (count != null) {
limitSize = count.getNumber().intValue();
rrs.setLimitSize(limitSize);
}
if (isNeedChangeLimit(rrs)) {
Limit changedLimit = new Limit();
changedLimit.setRowCount(new SQLIntegerExpr(limitStart + limitSize));
if (offset != null) {
if (limitStart < 0) {
String msg = "You have an error in your SQL syntax; check the manual that " + "corresponds to your MySQL server version for the right syntax to use near '" + limitStart + "'";
throw new SQLNonTransientException(ErrorCode.ER_PARSE_ERROR + " - " + msg);
} else {
changedLimit.setOffset(new SQLIntegerExpr(0));
}
}
mysqlSelectQuery.setLimit(changedLimit);
String sql = getSql(rrs, stmt, isNeedAddLimit);
rrs.changeNodeSqlAfterAddLimit(schema, getCurentDbType(), sql, 0, limitStart + limitSize, true);
//设置改写后的sql
ctx.setSql(sql);
} else {
rrs.changeNodeSqlAfterAddLimit(schema, getCurentDbType(), getCtx().getSql(), rrs.getLimitStart(), rrs.getLimitSize(), true);
// ctx.setSql(nativeSql);
}
}
if (rrs.isDistTable()) {
SQLTableSource from = mysqlSelectQuery.getFrom();
for (RouteResultsetNode node : rrs.getNodes()) {
SQLIdentifierExpr sqlIdentifierExpr = new SQLIdentifierExpr();
sqlIdentifierExpr.setParent(from);
sqlIdentifierExpr.setName(node.getSubTableName());
SQLExprTableSource from2 = new SQLExprTableSource(sqlIdentifierExpr);
mysqlSelectQuery.setFrom(from2);
node.setStatement(stmt.toString());
}
}
rrs.setCacheAble(isNeedCache(schema, rrs, mysqlSelectQuery, allConditions));
}
}
use of com.alibaba.druid.sql.ast.statement.SQLSelectQuery in project Mycat-Server by MyCATApache.
the class DruidSelectParser method statementParse.
@Override
public void statementParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt) {
SQLSelectStatement selectStmt = (SQLSelectStatement) stmt;
SQLSelectQuery sqlSelectQuery = selectStmt.getSelect().getQuery();
if (sqlSelectQuery instanceof MySqlSelectQueryBlock) {
MySqlSelectQueryBlock mysqlSelectQuery = (MySqlSelectQueryBlock) selectStmt.getSelect().getQuery();
parseOrderAggGroupMysql(schema, stmt, rrs, mysqlSelectQuery);
//更改canRunInReadDB属性
if ((mysqlSelectQuery.isForUpdate() || mysqlSelectQuery.isLockInShareMode()) && rrs.isAutocommit() == false) {
rrs.setCanRunInReadDB(false);
}
} else if (sqlSelectQuery instanceof MySqlUnionQuery) {
// MySqlUnionQuery unionQuery = (MySqlUnionQuery)sqlSelectQuery;
// MySqlSelectQueryBlock left = (MySqlSelectQueryBlock)unionQuery.getLeft();
// MySqlSelectQueryBlock right = (MySqlSelectQueryBlock)unionQuery.getLeft();
// System.out.println();
}
}
Aggregations