package net.sf.jsqlparser.util.deparser; import java.util.Iterator; import java.util.List; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.AllColumns; import net.sf.jsqlparser.statement.select.AllTableColumns; import net.sf.jsqlparser.statement.select.FromItem; import net.sf.jsqlparser.statement.select.FromItemVisitor; import net.sf.jsqlparser.statement.select.Join; import net.sf.jsqlparser.statement.select.Limit; import net.sf.jsqlparser.statement.select.OrderByElement; import net.sf.jsqlparser.statement.select.OrderByVisitor; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.SelectExpressionItem; import net.sf.jsqlparser.statement.select.SelectItem; import net.sf.jsqlparser.statement.select.SelectItemVisitor; import net.sf.jsqlparser.statement.select.SelectVisitor; import net.sf.jsqlparser.statement.select.SubJoin; import net.sf.jsqlparser.statement.select.SubSelect; import net.sf.jsqlparser.statement.select.Top; import net.sf.jsqlparser.statement.select.Union; /** * A class to de-parse (that is, tranform from JSqlParser hierarchy into a string) * a {@link net.sf.jsqlparser.statement.select.Select} */ public class SelectDeParser implements SelectVisitor, OrderByVisitor, SelectItemVisitor, FromItemVisitor { protected StringBuffer buffer; protected ExpressionVisitor expressionVisitor; public SelectDeParser() { } /** * @param expressionVisitor a {@link ExpressionVisitor} to de-parse expressions. It has to share the same<br> * StringBuffer (buffer parameter) as this object in order to work * @param buffer the buffer that will be filled with the select */ public SelectDeParser(ExpressionVisitor expressionVisitor, StringBuffer buffer) { this.buffer = buffer; this.expressionVisitor = expressionVisitor; } public void visit(PlainSelect plainSelect) { buffer.append("SELECT "); Top top = plainSelect.getTop(); if (top != null) top.toString(); if (plainSelect.getDistinct() != null) { buffer.append("DISTINCT "); if (plainSelect.getDistinct().getOnSelectItems() != null) { buffer.append("ON ("); for (Iterator iter = plainSelect.getDistinct().getOnSelectItems().iterator(); iter.hasNext();) { SelectItem selectItem = (SelectItem) iter.next(); selectItem.accept(this); if (iter.hasNext()) { buffer.append(", "); } } buffer.append(") "); } } for (Iterator iter = plainSelect.getSelectItems().iterator(); iter.hasNext();) { SelectItem selectItem = (SelectItem) iter.next(); selectItem.accept(this); if (iter.hasNext()) { buffer.append(", "); } } buffer.append(" "); if (plainSelect.getFromItem() != null) { buffer.append("FROM "); plainSelect.getFromItem().accept(this); } if (plainSelect.getJoins() != null) { for (Iterator iter = plainSelect.getJoins().iterator(); iter.hasNext();) { Join join = (Join) iter.next(); deparseJoin(join); } } if (plainSelect.getWhere() != null) { buffer.append(" WHERE "); plainSelect.getWhere().accept(expressionVisitor); } if (plainSelect.getGroupByColumnReferences() != null) { buffer.append(" GROUP BY "); for (Iterator iter = plainSelect.getGroupByColumnReferences().iterator(); iter.hasNext();) { Expression columnReference = (Expression) iter.next(); columnReference.accept(expressionVisitor); if (iter.hasNext()) { buffer.append(", "); } } } if (plainSelect.getHaving() != null) { buffer.append(" HAVING "); plainSelect.getHaving().accept(expressionVisitor); } if (plainSelect.getOrderByElements() != null) { deparseOrderBy(plainSelect.getOrderByElements()); } if (plainSelect.getLimit() != null) { deparseLimit(plainSelect.getLimit()); } } public void visit(Union union) { for (Iterator iter = union.getPlainSelects().iterator(); iter.hasNext();) { buffer.append("("); PlainSelect plainSelect = (PlainSelect) iter.next(); plainSelect.accept(this); buffer.append(")"); if (iter.hasNext()) { buffer.append(" UNION "); } } if (union.getOrderByElements() != null) { deparseOrderBy(union.getOrderByElements()); } if (union.getLimit() != null) { deparseLimit(union.getLimit()); } } public void visit(OrderByElement orderBy) { orderBy.getExpression().accept(expressionVisitor); if (orderBy.isAsc()) buffer.append(" ASC"); else buffer.append(" DESC"); } public void visit(Column column) { buffer.append(column.getWholeColumnName()); } public void visit(AllColumns allColumns) { buffer.append("*"); } public void visit(AllTableColumns allTableColumns) { buffer.append(allTableColumns.getTable().getWholeTableName() + ".*"); } public void visit(SelectExpressionItem selectExpressionItem) { selectExpressionItem.getExpression().accept(expressionVisitor); if (selectExpressionItem.getAlias() != null) { buffer.append(" AS " + selectExpressionItem.getAlias()); } } public void visit(SubSelect subSelect) { buffer.append("("); subSelect.getSelectBody().accept(this); buffer.append(")"); } public void visit(Table tableName) { buffer.append(tableName.getWholeTableName()); String alias = tableName.getAlias(); if (alias != null && !alias.equals("")) { buffer.append(" AS " + alias); } } public void deparseOrderBy(List orderByElements) { buffer.append(" ORDER BY "); for (Iterator iter = orderByElements.iterator(); iter.hasNext();) { OrderByElement orderByElement = (OrderByElement) iter.next(); orderByElement.accept(this); if (iter.hasNext()) { buffer.append(", "); } } } public void deparseLimit(Limit limit) { // LIMIT n OFFSET skip buffer.append(" LIMIT "); if (limit.isRowCountJdbcParameter()) { buffer.append("?"); } else if (limit.getRowCount() != 0) { buffer.append(limit.getRowCount()); } else { /* from mysql docs: For compatibility with PostgreSQL, MySQL also supports the LIMIT row_count OFFSET offset syntax. To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. */ buffer.append("18446744073709551615"); } if (limit.isOffsetJdbcParameter()) { buffer.append(" OFFSET ?"); } else if (limit.getOffset() != 0) { buffer.append(" OFFSET " + limit.getOffset()); } } public StringBuffer getBuffer() { return buffer; } public void setBuffer(StringBuffer buffer) { this.buffer = buffer; } public ExpressionVisitor getExpressionVisitor() { return expressionVisitor; } public void setExpressionVisitor(ExpressionVisitor visitor) { expressionVisitor = visitor; } public void visit(SubJoin subjoin) { buffer.append("("); subjoin.getLeft().accept(this); buffer.append(" "); deparseJoin(subjoin.getJoin()); buffer.append(")"); } public void deparseJoin(Join join) { if (join.isSimple()) buffer.append(", "); else { if (join.isRight()) buffer.append("RIGHT "); else if (join.isNatural()) buffer.append("NATURAL "); else if (join.isFull()) buffer.append("FULL "); else if (join.isLeft()) buffer.append("LEFT "); if (join.isOuter()) buffer.append("OUTER "); else if (join.isInner()) buffer.append("INNER "); buffer.append("JOIN "); } FromItem fromItem = join.getRightItem(); fromItem.accept(this); if (join.getOnExpression() != null) { buffer.append(" ON "); join.getOnExpression().accept(expressionVisitor); } if (join.getUsingColumns() != null) { buffer.append(" USING ( "); for (Iterator iterator = join.getUsingColumns().iterator(); iterator.hasNext();) { Column column = (Column) iterator.next(); buffer.append(column.getWholeColumnName()); if (iterator.hasNext()) { buffer.append(" ,"); } } buffer.append(")"); } } }