Skip to content

Commit a31333a

Browse files
Issue 195:
Add support for ORDER BY and LIMIT in UPDATE and DELETE statements (as supported by MySQL). LimitDeparser and OrderByDeParser have been pulled out into separate classes to avoid code duplication from SelectDeParser.
1 parent 975cddf commit a31333a

File tree

10 files changed

+302
-79
lines changed

10 files changed

+302
-79
lines changed

src/main/java/net/sf/jsqlparser/statement/delete/Delete.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,26 @@
2525
import net.sf.jsqlparser.schema.Table;
2626
import net.sf.jsqlparser.statement.Statement;
2727
import net.sf.jsqlparser.statement.StatementVisitor;
28+
import net.sf.jsqlparser.statement.select.Limit;
29+
import net.sf.jsqlparser.statement.select.OrderByElement;
30+
import net.sf.jsqlparser.statement.select.PlainSelect;
31+
32+
import java.util.List;
2833

2934
public class Delete implements Statement {
3035

3136
private Table table;
3237
private Expression where;
38+
private Limit limit;
39+
private List<OrderByElement> orderByElements;
40+
41+
public List<OrderByElement> getOrderByElements() {
42+
return orderByElements;
43+
}
44+
45+
public void setOrderByElements(List<OrderByElement> orderByElements) {
46+
this.orderByElements = orderByElements;
47+
}
3348

3449
@Override
3550
public void accept(StatementVisitor statementVisitor) {
@@ -52,8 +67,19 @@ public void setWhere(Expression expression) {
5267
where = expression;
5368
}
5469

70+
public Limit getLimit() {
71+
return limit;
72+
}
73+
74+
public void setLimit(Limit limit) {
75+
this.limit = limit;
76+
}
77+
5578
@Override
5679
public String toString() {
57-
return "DELETE FROM " + table + ((where != null) ? " WHERE " + where : "");
80+
return "DELETE FROM " + table +
81+
((where != null) ? " WHERE " + where : "") +
82+
(orderByElements!=null? PlainSelect.orderByToString(orderByElements):"") +
83+
(limit != null ? limit : "");
5884
}
5985
}

src/main/java/net/sf/jsqlparser/statement/update/Update.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import net.sf.jsqlparser.statement.select.Join;
3333
import net.sf.jsqlparser.statement.select.PlainSelect;
3434
import net.sf.jsqlparser.statement.select.Select;
35+
import net.sf.jsqlparser.statement.select.OrderByElement;
36+
import net.sf.jsqlparser.statement.select.Limit;
3537

3638
/**
3739
* The update statement.
@@ -47,6 +49,8 @@ public class Update implements Statement {
4749
private Select select;
4850
private boolean useColumnsBrackets = true;
4951
private boolean useSelect = false;
52+
private List<OrderByElement> orderByElements;
53+
private Limit limit;
5054

5155
@Override
5256
public void accept(StatementVisitor statementVisitor) {
@@ -137,6 +141,22 @@ public void setUseSelect(boolean useSelect) {
137141
this.useSelect = useSelect;
138142
}
139143

144+
public void setOrderByElements(List<OrderByElement> orderByElements) {
145+
this.orderByElements = orderByElements;
146+
}
147+
148+
public void setLimit(Limit limit) {
149+
this.limit = limit;
150+
}
151+
152+
public List<OrderByElement> getOrderByElements() {
153+
return orderByElements;
154+
}
155+
156+
public Limit getLimit() {
157+
return limit;
158+
}
159+
140160
@Override
141161
public String toString() {
142162
StringBuilder b = new StringBuilder("UPDATE ");
@@ -184,6 +204,12 @@ public String toString() {
184204
b.append(" WHERE ");
185205
b.append(where);
186206
}
207+
if (orderByElements!=null) {
208+
b.append(PlainSelect.orderByToString(orderByElements));
209+
}
210+
if (limit != null) {
211+
b.append(limit);
212+
}
187213
return b.toString();
188214
}
189215
}

src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ public void deParse(Delete delete) {
5959
delete.getWhere().accept(expressionVisitor);
6060
}
6161

62+
if(delete.getOrderByElements()!=null){
63+
new OrderByDeParser(expressionVisitor, buffer).deParse(delete.getOrderByElements());
64+
}
65+
if (delete.getLimit() != null) {
66+
new LimitDeparser(buffer).deParse(delete.getLimit());
67+
}
68+
6269
}
6370

6471
public ExpressionVisitor getExpressionVisitor() {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2015 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
package net.sf.jsqlparser.util.deparser;
23+
24+
import net.sf.jsqlparser.statement.select.Limit;
25+
26+
public class LimitDeparser {
27+
28+
private StringBuilder buffer;
29+
30+
public LimitDeparser(StringBuilder buffer) {
31+
this.buffer = buffer;
32+
}
33+
34+
public void deParse(Limit limit) {
35+
if (limit.isRowCountJdbcParameter()) {
36+
buffer.append(" LIMIT ");
37+
buffer.append("?");
38+
} else if (limit.getRowCount() >= 0) {
39+
buffer.append(" LIMIT ");
40+
buffer.append(limit.getRowCount());
41+
} else if (limit.isLimitNull()) {
42+
buffer.append(" LIMIT NULL");
43+
}
44+
45+
if (limit.isOffsetJdbcParameter()) {
46+
buffer.append(" OFFSET ?");
47+
} else if (limit.getOffset() != 0) {
48+
buffer.append(" OFFSET ").append(limit.getOffset());
49+
}
50+
}
51+
52+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2015 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
package net.sf.jsqlparser.util.deparser;
23+
24+
25+
import net.sf.jsqlparser.expression.ExpressionVisitor;
26+
import net.sf.jsqlparser.statement.select.OrderByElement;
27+
28+
import java.util.Iterator;
29+
import java.util.List;
30+
31+
public class OrderByDeParser {
32+
33+
private StringBuilder buffer;
34+
private ExpressionVisitor expressionVisitor;
35+
36+
public OrderByDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer) {
37+
this.expressionVisitor= expressionVisitor;
38+
this.buffer = buffer;
39+
}
40+
41+
public void deParse( List<OrderByElement> orderByElementList) {
42+
deParse(false, orderByElementList);
43+
}
44+
45+
46+
public void deParse(boolean oracleSiblings, List<OrderByElement> orderByElementList){
47+
if (oracleSiblings) {
48+
buffer.append(" ORDER SIBLINGS BY ");
49+
} else {
50+
buffer.append(" ORDER BY ");
51+
}
52+
53+
for (Iterator<OrderByElement> iter = orderByElementList.iterator(); iter.hasNext();) {
54+
OrderByElement orderByElement = iter.next();
55+
deParseElement(orderByElement);
56+
if (iter.hasNext()) {
57+
buffer.append(", ");
58+
}
59+
}
60+
}
61+
62+
public void deParseElement(OrderByElement orderBy){
63+
orderBy.getExpression().accept(expressionVisitor);
64+
if (!orderBy.isAsc()) {
65+
buffer.append(" DESC");
66+
} else if (orderBy.isAscDescPresent()) {
67+
buffer.append(" ASC");
68+
}
69+
if (orderBy.getNullOrdering() != null) {
70+
buffer.append(' ');
71+
buffer.append(orderBy.getNullOrdering() == OrderByElement.NullOrdering.NULLS_FIRST ? "NULLS FIRST" : "NULLS LAST");
72+
}
73+
}
74+
}

src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java

Lines changed: 5 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* A class to de-parse (that is, tranform from JSqlParser hierarchy into a
3232
* string) a {@link net.sf.jsqlparser.statement.select.Select}
3333
*/
34-
public class SelectDeParser implements SelectVisitor, OrderByVisitor, SelectItemVisitor, FromItemVisitor, PivotVisitor {
34+
public class SelectDeParser implements SelectVisitor, SelectItemVisitor, FromItemVisitor, PivotVisitor {
3535

3636
private StringBuilder buffer;
3737
private ExpressionVisitor expressionVisitor;
@@ -147,11 +147,11 @@ public void visit(PlainSelect plainSelect) {
147147
}
148148

149149
if (plainSelect.getOrderByElements() != null) {
150-
deparseOrderBy(plainSelect.isOracleSiblings(), plainSelect.getOrderByElements());
150+
new OrderByDeParser(expressionVisitor, buffer).deParse(plainSelect.isOracleSiblings(), plainSelect.getOrderByElements());
151151
}
152152

153153
if (plainSelect.getLimit() != null) {
154-
deparseLimit(plainSelect.getLimit());
154+
new LimitDeparser(buffer).deParse(plainSelect.getLimit());
155155
}
156156
if (plainSelect.getOffset() != null) {
157157
deparseOffset(plainSelect.getOffset());
@@ -170,20 +170,6 @@ public void visit(PlainSelect plainSelect) {
170170
}
171171
}
172172

173-
@Override
174-
public void visit(OrderByElement orderBy) {
175-
orderBy.getExpression().accept(expressionVisitor);
176-
if (!orderBy.isAsc()) {
177-
buffer.append(" DESC");
178-
} else if (orderBy.isAscDescPresent()) {
179-
buffer.append(" ASC");
180-
}
181-
if (orderBy.getNullOrdering() != null) {
182-
buffer.append(' ');
183-
buffer.append(orderBy.getNullOrdering() == OrderByElement.NullOrdering.NULLS_FIRST ? "NULLS FIRST" : "NULLS LAST");
184-
}
185-
}
186-
187173
public void visit(Column column) {
188174
buffer.append(column.getFullyQualifiedName());
189175
}
@@ -271,44 +257,7 @@ public void visit(PivotXml pivot) {
271257
buffer.append("))");
272258
}
273259

274-
public void deparseOrderBy(List<OrderByElement> orderByElements) {
275-
deparseOrderBy(false, orderByElements);
276-
}
277260

278-
public void deparseOrderBy(boolean oracleSiblings, List<OrderByElement> orderByElements) {
279-
if (oracleSiblings) {
280-
buffer.append(" ORDER SIBLINGS BY ");
281-
} else {
282-
buffer.append(" ORDER BY ");
283-
}
284-
for (Iterator<OrderByElement> iter = orderByElements.iterator(); iter.hasNext();) {
285-
OrderByElement orderByElement = iter.next();
286-
orderByElement.accept(this);
287-
if (iter.hasNext()) {
288-
buffer.append(", ");
289-
}
290-
}
291-
}
292-
293-
public void deparseLimit(Limit limit) {
294-
// LIMIT n OFFSET skip
295-
if (limit.isRowCountJdbcParameter()) {
296-
buffer.append(" LIMIT ");
297-
buffer.append("?");
298-
} else if (limit.getRowCount() >= 0) {
299-
buffer.append(" LIMIT ");
300-
buffer.append(limit.getRowCount());
301-
} else if (limit.isLimitNull()) {
302-
buffer.append(" LIMIT NULL");
303-
}
304-
305-
if (limit.isOffsetJdbcParameter()) {
306-
buffer.append(" OFFSET ?");
307-
} else if (limit.getOffset() != 0) {
308-
buffer.append(" OFFSET ").append(limit.getOffset());
309-
}
310-
311-
}
312261

313262
public void deparseOffset(Offset offset) {
314263
// OFFSET offset
@@ -429,11 +378,11 @@ public void visit(SetOperationList list) {
429378
buffer.append(")");
430379
}
431380
if (list.getOrderByElements() != null) {
432-
deparseOrderBy(list.getOrderByElements());
381+
new OrderByDeParser(expressionVisitor,buffer).deParse(list.getOrderByElements());
433382
}
434383

435384
if (list.getLimit() != null) {
436-
deparseLimit(list.getLimit());
385+
new LimitDeparser(buffer).deParse(list.getLimit());
437386
}
438387
if (list.getOffset() != null) {
439388
deparseOffset(list.getOffset());

src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@
2929
import net.sf.jsqlparser.statement.update.Update;
3030
import net.sf.jsqlparser.statement.select.Select;
3131
import net.sf.jsqlparser.statement.select.SelectVisitor;
32+
import net.sf.jsqlparser.statement.select.OrderByVisitor;
33+
import net.sf.jsqlparser.statement.select.OrderByElement;
3234

3335
/**
3436
* A class to de-parse (that is, tranform from JSqlParser hierarchy into a
3537
* string) an {@link net.sf.jsqlparser.statement.update.Update}
3638
*/
37-
public class UpdateDeParser {
39+
public class UpdateDeParser implements OrderByVisitor {
3840

3941
private StringBuilder buffer;
4042
private ExpressionVisitor expressionVisitor;
@@ -116,6 +118,12 @@ public void deParse(Update update) {
116118
buffer.append(" WHERE ");
117119
update.getWhere().accept(expressionVisitor);
118120
}
121+
if (update.getOrderByElements()!=null) {
122+
new OrderByDeParser(expressionVisitor, buffer).deParse(update.getOrderByElements());
123+
}
124+
if (update.getLimit() != null) {
125+
new LimitDeparser(buffer).deParse(update.getLimit());
126+
}
119127

120128
}
121129

@@ -126,4 +134,18 @@ public ExpressionVisitor getExpressionVisitor() {
126134
public void setExpressionVisitor(ExpressionVisitor visitor) {
127135
expressionVisitor = visitor;
128136
}
137+
138+
@Override
139+
public void visit(OrderByElement orderBy) {
140+
orderBy.getExpression().accept(expressionVisitor);
141+
if (!orderBy.isAsc()) {
142+
buffer.append(" DESC");
143+
} else if (orderBy.isAscDescPresent()) {
144+
buffer.append(" ASC");
145+
}
146+
if (orderBy.getNullOrdering() != null) {
147+
buffer.append(' ');
148+
buffer.append(orderBy.getNullOrdering() == OrderByElement.NullOrdering.NULLS_FIRST ? "NULLS FIRST" : "NULLS LAST");
149+
}
150+
}
129151
}

0 commit comments

Comments
 (0)