Search in sources :

Example 11 with SQLLimit

use of com.alibaba.druid.sql.ast.SQLLimit in project druid by alibaba.

the class WallVisitorUtils method checkSqlExpr.

public static boolean checkSqlExpr(SQLExpr x) {
    // check groupby, orderby, limit
    if (x == null) {
        return false;
    }
    SQLObject obj = x;
    for (; ; ) {
        SQLObject parent = obj.getParent();
        if (parent == null) {
            return false;
        }
        if (parent instanceof SQLSelectGroupByClause) {
            return true;
        } else if (parent instanceof SQLOrderBy) {
            return true;
        } else if (parent instanceof SQLLimit) {
            return true;
        } else if (parent instanceof MySqlOrderingExpr) {
            return true;
        }
        obj = parent;
    }
}
Also used : SQLOrderBy(com.alibaba.druid.sql.ast.SQLOrderBy) MySqlOrderingExpr(com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr) SQLObject(com.alibaba.druid.sql.ast.SQLObject) SQLLimit(com.alibaba.druid.sql.ast.SQLLimit)

Example 12 with SQLLimit

use of com.alibaba.druid.sql.ast.SQLLimit in project druid by alibaba.

the class OracleRowNumToLimit method visit.

@Override
public boolean visit(SQLUnionQuery x) {
    if (x.getLeft() != null) {
        x.getLeft().accept(this);
    }
    if (x.getRight() != null) {
        x.getRight().accept(this);
    }
    if (x.getLeft() instanceof SQLSelectQueryBlock && x.getRight() instanceof SQLSelectQueryBlock) {
        if (x.getOperator() == SQLUnionOperator.MINUS) {
            boolean eqNonLimit;
            {
                SQLSelectQueryBlock left = (SQLSelectQueryBlock) x.getLeft().clone();
                SQLSelectQueryBlock right = (SQLSelectQueryBlock) x.getRight().clone();
                left.setLimit(null);
                right.setLimit(null);
                eqNonLimit = left.toString().equals(right.toString());
            }
            if (eqNonLimit) {
                SQLSelectQueryBlock merged = (SQLSelectQueryBlock) x.getLeft().clone();
                SQLSelectQueryBlock right = (SQLSelectQueryBlock) x.getRight();
                SQLLimit leftLimit = merged.getLimit();
                SQLLimit rightLimit = right.getLimit();
                if ((leftLimit == null && rightLimit == null) || (leftLimit != null && leftLimit.equals(rightLimit))) {
                    merged.setLimit(new SQLLimit(0));
                } else if (leftLimit == null) {
                    SQLExpr rightOffset = rightLimit.getOffset();
                    if (rightOffset != null && !SQLIntegerExpr.isZero(rightOffset)) {
                        // can not merge
                        return false;
                    }
                    SQLLimit limit = new SQLLimit();
                    limit.setOffset(rightLimit.getRowCount());
                    merged.setLimit(limit);
                } else {
                    SQLExpr rightOffset = rightLimit.getOffset();
                    if (rightOffset != null && !SQLIntegerExpr.isZero(rightOffset)) {
                        // can not merge
                        return false;
                    }
                    SQLExpr leftOffset = leftLimit.getOffset();
                    if (leftOffset != null && !SQLIntegerExpr.isZero(leftOffset)) {
                        // todo
                        return false;
                    }
                    SQLExpr rightRowCount = rightLimit.getRowCount();
                    SQLExpr leftRowCount = leftLimit.getRowCount();
                    SQLLimit limit = new SQLLimit();
                    limit.setOffset(rightRowCount);
                    limit.setRowCount(substract(leftRowCount, rightRowCount));
                    if (SQLIntegerExpr.isZero(limit.getRowCount())) {
                        limit.setRowCount(0);
                        limit.setOffset(null);
                        if (merged.getOrderBy() != null) {
                            merged.setOrderBy(null);
                        }
                    }
                    merged.setLimit(limit);
                }
                SQLObject parent = x.getParent();
                if (parent instanceof SQLSelect) {
                    SQLSelect select = (SQLSelect) parent;
                    select.setQuery(merged);
                } else if (parent instanceof SQLUnionQuery) {
                    SQLUnionQuery union = (SQLUnionQuery) parent;
                    if (union.getLeft() == x) {
                        union.setLeft(merged);
                    } else {
                        union.setRight(merged);
                    }
                }
            }
        } else if (x.getOperator() == SQLUnionOperator.INTERSECT) {
            boolean eqNonLimit;
            {
                SQLSelectQueryBlock left = (SQLSelectQueryBlock) x.getLeft().clone();
                SQLSelectQueryBlock right = (SQLSelectQueryBlock) x.getRight().clone();
                left.setLimit(null);
                right.setLimit(null);
                eqNonLimit = left.toString().equals(right.toString());
            }
            if (eqNonLimit) {
                SQLSelectQueryBlock merged = (SQLSelectQueryBlock) x.getLeft().clone();
                SQLSelectQueryBlock right = (SQLSelectQueryBlock) x.getRight();
                SQLLimit leftLimit = merged.getLimit();
                SQLLimit rightLimit = right.getLimit();
                if (rightLimit == null || (rightLimit.equals(leftLimit))) {
                // skip
                } else if (leftLimit == null) {
                    merged.setLimit(rightLimit.clone());
                } else {
                    SQLLimit limit = new SQLLimit();
                    SQLExpr rightOffset = rightLimit.getOffset();
                    SQLExpr leftOffset = leftLimit.getOffset();
                    if (leftOffset == null) {
                        limit.setOffset(rightOffset);
                    } else if (rightOffset == null) {
                        limit.setOffset(leftOffset);
                    } else if (rightOffset.equals(leftOffset)) {
                        limit.setOffset(leftOffset);
                    } else {
                        if ((!(leftOffset instanceof SQLIntegerExpr)) || !(rightOffset instanceof SQLIntegerExpr)) {
                            // can not merged
                            return false;
                        }
                        limit.setOffset(SQLIntegerExpr.greatst((SQLIntegerExpr) leftOffset, (SQLIntegerExpr) rightOffset));
                    }
                    SQLExpr rightRowCount = rightLimit.getRowCount();
                    SQLExpr leftRowCount = leftLimit.getRowCount();
                    SQLExpr leftEnd = leftOffset == null ? leftRowCount : substract(leftRowCount, leftOffset);
                    SQLExpr rightEnd = rightOffset == null ? rightRowCount : substract(rightRowCount, rightOffset);
                    if ((leftEnd != null && !(leftEnd instanceof SQLIntegerExpr)) || (rightEnd != null && !(rightEnd instanceof SQLIntegerExpr))) {
                        // can not merged
                        return false;
                    }
                    SQLIntegerExpr end = SQLIntegerExpr.least((SQLIntegerExpr) leftEnd, (SQLIntegerExpr) rightEnd);
                    if (limit.getOffset() == null) {
                        limit.setRowCount(end);
                    } else {
                        limit.setRowCount(substract(end, limit.getOffset()));
                    }
                    merged.setLimit(limit);
                }
                SQLObject parent = x.getParent();
                if (parent instanceof SQLSelect) {
                    SQLSelect select = (SQLSelect) parent;
                    select.setQuery(merged);
                } else if (parent instanceof SQLUnionQuery) {
                    SQLUnionQuery union = (SQLUnionQuery) parent;
                    if (union.getLeft() == x) {
                        union.setLeft(merged);
                    } else {
                        union.setRight(merged);
                    }
                }
            }
        }
    }
    return false;
}
Also used : SQLObject(com.alibaba.druid.sql.ast.SQLObject) SQLLimit(com.alibaba.druid.sql.ast.SQLLimit) SQLIntegerExpr(com.alibaba.druid.sql.ast.expr.SQLIntegerExpr) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr)

Example 13 with SQLLimit

use of com.alibaba.druid.sql.ast.SQLLimit in project druid by alibaba.

the class OracleRowNumToLimit method removeSelectListRowNum.

private void removeSelectListRowNum(SQLSelectQueryBlock x) {
    SQLTableSource from = x.getFrom();
    SQLLimit limit = x.getLimit();
    if (limit == null && from instanceof SQLSubqueryTableSource && ((SQLSubqueryTableSource) from).getSelect().getQuery() instanceof SQLSelectQueryBlock) {
        limit = ((SQLSubqueryTableSource) from).getSelect().getQueryBlock().getLimit();
    }
    if (!removeSelectListRownum) {
        return;
    }
    List<SQLSelectItem> selectList = x.getSelectList();
    for (int i = selectList.size() - 1; i >= 0; i--) {
        SQLSelectItem selectItem = selectList.get(i);
        SQLExpr expr = selectItem.getExpr();
        if (isRowNum(expr) && limit != null) {
            selectList.remove(i);
        }
    }
}
Also used : SQLLimit(com.alibaba.druid.sql.ast.SQLLimit) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr)

Example 14 with SQLLimit

use of com.alibaba.druid.sql.ast.SQLLimit in project druid by alibaba.

the class MySqlASTVisitorAdapterTest method test_adapter.

public void test_adapter() throws Exception {
    MySqlASTVisitorAdapter adapter = new MySqlASTVisitorAdapter();
    new SQLBooleanExpr().accept(adapter);
    new SQLLimit().accept(adapter);
    new MySqlTableIndex().accept(adapter);
    new MySqlKey().accept(adapter);
    new MySqlPrimaryKey().accept(adapter);
    new SQLIntervalExpr().accept(adapter);
    new SQLBinaryExpr().accept(adapter);
    new MySqlPrepareStatement().accept(adapter);
    new MySqlExecuteStatement().accept(adapter);
    new MysqlDeallocatePrepareStatement().accept(adapter);
    new MySqlDeleteStatement().accept(adapter);
    new MySqlInsertStatement().accept(adapter);
    new MySqlLoadXmlStatement().accept(adapter);
    new SQLReplaceStatement().accept(adapter);
    new SQLStartTransactionStatement().accept(adapter);
    new SQLShowColumnsStatement().accept(adapter);
    new SQLShowDatabasesStatement().accept(adapter);
    new MySqlShowWarningsStatement().accept(adapter);
    new MySqlShowStatusStatement().accept(adapter);
    new CobarShowStatus().accept(adapter);
    new MySqlKillStatement().accept(adapter);
    new MySqlBinlogStatement().accept(adapter);
    new MySqlResetStatement().accept(adapter);
    new UserSpecification().accept(adapter);
    new MySqlPartitionByKey().accept(adapter);
    new MySqlOutFileExpr().accept(adapter);
    new MySqlUpdateStatement().accept(adapter);
    new MySqlSetTransactionStatement().accept(adapter);
    new MySqlShowMasterLogsStatement().accept(adapter);
    new MySqlShowAuthorsStatement().accept(adapter);
    new MySqlShowCollationStatement().accept(adapter);
    new MySqlShowBinLogEventsStatement().accept(adapter);
    new MySqlShowCharacterSetStatement().accept(adapter);
    new MySqlShowContributorsStatement().accept(adapter);
    new MySqlShowCreateDatabaseStatement().accept(adapter);
    new MySqlShowCreateEventStatement().accept(adapter);
    new MySqlShowCreateFunctionStatement().accept(adapter);
    new MySqlShowCreateProcedureStatement().accept(adapter);
    new SQLShowCreateTableStatement().accept(adapter);
    new MySqlShowCreateTriggerStatement().accept(adapter);
    new SQLShowCreateViewStatement().accept(adapter);
    new MySqlShowEngineStatement().accept(adapter);
    new MySqlShowEnginesStatement().accept(adapter);
    new MySqlShowErrorsStatement().accept(adapter);
    new MySqlShowEventsStatement().accept(adapter);
    new MySqlShowFunctionCodeStatement().accept(adapter);
    new MySqlShowFunctionStatusStatement().accept(adapter);
    new MySqlShowGrantsStatement().accept(adapter);
    new MySqlUserName().accept(adapter);
    new SQLShowIndexesStatement().accept(adapter);
    new MySqlShowMasterStatusStatement().accept(adapter);
    new MySqlShowOpenTablesStatement().accept(adapter);
    new MySqlShowBinaryLogsStatement().accept(adapter);
    new MySqlShowPluginsStatement().accept(adapter);
    new MySqlShowPrivilegesStatement().accept(adapter);
    new MySqlShowProcedureCodeStatement().accept(adapter);
    new MySqlShowProcedureStatusStatement().accept(adapter);
    new MySqlShowProcessListStatement().accept(adapter);
    new MySqlShowProfileStatement().accept(adapter);
    new MySqlShowSlaveHostsStatement().accept(adapter);
    new MySqlShowRelayLogEventsStatement().accept(adapter);
    new MySqlShowSlaveStatusStatement().accept(adapter);
    new MySqlShowTableStatusStatement().accept(adapter);
    new MySqlShowTriggersStatement().accept(adapter);
    new MySqlRenameTableStatement().accept(adapter);
    new MySqlUseIndexHint().accept(adapter);
    new MySqlIgnoreIndexHint().accept(adapter);
    new MySqlLockTableStatement().accept(adapter);
    new MySqlUnlockTablesStatement().accept(adapter);
    new MySqlForceIndexHint().accept(adapter);
    new MySqlAlterTableChangeColumn().accept(adapter);
    new SQLAlterCharacter().accept(adapter);
    new MySqlAlterTableOption().accept(adapter);
    new MySqlCreateTableStatement().accept(adapter);
    new MySqlCharExpr().accept(adapter);
    new MySqlUnique().accept(adapter);
    new MySqlAlterTableModifyColumn().accept(adapter);
    new MySqlAlterTableDiscardTablespace().accept(adapter);
    new MySqlAlterTableImportTablespace().accept(adapter);
    new TableSpaceOption().accept(adapter);
}
Also used : MySqlASTVisitorAdapter(com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter) SQLBinaryExpr(com.alibaba.druid.sql.ast.expr.SQLBinaryExpr) UserSpecification(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification) TableSpaceOption(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement.TableSpaceOption) SQLBooleanExpr(com.alibaba.druid.sql.ast.expr.SQLBooleanExpr) MySqlUserName(com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlUserName) SQLIntervalExpr(com.alibaba.druid.sql.ast.expr.SQLIntervalExpr) SQLLimit(com.alibaba.druid.sql.ast.SQLLimit) MySqlCharExpr(com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr) MySqlOutFileExpr(com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr)

Example 15 with SQLLimit

use of com.alibaba.druid.sql.ast.SQLLimit in project druid by alibaba.

the class MySqlSelectTest_clearLimit method test_1.

public void test_1() throws Exception {
    String sql = "select a from t limit 1,2";
    SQLLimit limit = SQLUtils.getLimit(sql, DbType.mysql);
    assertEquals("LIMIT 1, 2", limit.toString());
}
Also used : SQLLimit(com.alibaba.druid.sql.ast.SQLLimit)

Aggregations

SQLLimit (com.alibaba.druid.sql.ast.SQLLimit)15 SQLExpr (com.alibaba.druid.sql.ast.SQLExpr)7 SQLIntegerExpr (com.alibaba.druid.sql.ast.expr.SQLIntegerExpr)4 SQLSelectQuery (com.alibaba.druid.sql.ast.statement.SQLSelectQuery)3 SQLSelectQueryBlock (com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock)3 OdpsSelectQueryBlock (com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock)3 SQLObject (com.alibaba.druid.sql.ast.SQLObject)2 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)2 SQLSelectStatement (com.alibaba.druid.sql.ast.statement.SQLSelectStatement)2 MySqlSelectQueryBlock (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock)2 PGSelectQueryBlock (com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock)2 SQLOrderBy (com.alibaba.druid.sql.ast.SQLOrderBy)1 SQLBinaryExpr (com.alibaba.druid.sql.ast.expr.SQLBinaryExpr)1 SQLBooleanExpr (com.alibaba.druid.sql.ast.expr.SQLBooleanExpr)1 SQLIdentifierExpr (com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr)1 SQLIntervalExpr (com.alibaba.druid.sql.ast.expr.SQLIntervalExpr)1 SQLNumberExpr (com.alibaba.druid.sql.ast.expr.SQLNumberExpr)1 SQLNumericLiteralExpr (com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr)1 SQLExprTableSource (com.alibaba.druid.sql.ast.statement.SQLExprTableSource)1 SQLSelectOrderByItem (com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem)1