Skip to content

Commit

Permalink
Support DELETE FROM T1 USING T2 WHERE ...
Browse files Browse the repository at this point in the history
  • Loading branch information
fanchuo committed Jun 14, 2021
1 parent aec76ea commit 9b81814
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 1 deletion.
34 changes: 34 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/delete/Delete.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

import static java.util.stream.Collectors.joining;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.OracleHint;
Expand All @@ -33,6 +34,7 @@ public class Delete implements Statement {
private Table table;
private OracleHint oracleHint = null;
private List<Table> tables;
private List<Table> usingList;
private List<Join> joins;
private Expression where;
private Limit limit;
Expand Down Expand Up @@ -116,6 +118,14 @@ public void setTables(List<Table> tables) {
this.tables = tables;
}

public List<Table> getUsingList() {
return usingList;
}

public void setUsingList(List<Table> usingList) {
this.usingList = usingList;
}

public List<Join> getJoins() {
return joins;
}
Expand Down Expand Up @@ -162,6 +172,13 @@ public String toString() {
}
b.append(" ").append(table);

if (usingList != null && usingList.size()>0) {
b.append(" USING ");
b.append(usingList.stream()
.map(Table::toString)
.collect(joining(", ")));
}

if (joins != null) {
for (Join join : joins) {
if (join.isSimple()) {
Expand Down Expand Up @@ -191,6 +208,11 @@ public Delete withTables(List<Table> tables) {
return this;
}

public Delete withUsingList(List<Table> usingList) {
this.setUsingList(usingList);
return this;
}

public Delete withJoins(List<Join> joins) {
this.setJoins(joins);
return this;
Expand Down Expand Up @@ -233,6 +255,18 @@ public Delete addTables(Collection<? extends Table> tables) {
return this.withTables(collection);
}

public Delete addUsingList(Table... usingList) {
List<Table> collection = Optional.ofNullable(getUsingList()).orElseGet(ArrayList::new);
Collections.addAll(collection, usingList);
return this.withUsingList(collection);
}

public Delete addUsingList(Collection<? extends Table> usingList) {
List<Table> collection = Optional.ofNullable(getUsingList()).orElseGet(ArrayList::new);
collection.addAll(usingList);
return this.withUsingList(collection);
}

public Delete addJoins(Join... joins) {
List<Join> collection = Optional.ofNullable(getJoins()).orElseGet(ArrayList::new);
Collections.addAll(collection, joins);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,12 @@ public void visit(ValueListExpression valueList) {
public void visit(Delete delete) {
visit(delete.getTable());

if (delete.getUsingList() != null) {
for (Table using : delete.getUsingList()) {
visit(using);
}
}

if (delete.getJoins() != null) {
for (Join join : delete.getJoins()) {
join.getRightItem().accept(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public void deParse(Delete delete) {
}
buffer.append(" ").append(delete.getTable().toString());

if (delete.getUsingList() != null && !delete.getUsingList().isEmpty()) {
buffer.append(" USING").append(
delete.getUsingList().stream().map(Table::toString).collect(joining(", ", " ", "")));
}
if (delete.getJoins() != null) {
for (Join join : delete.getJoins()) {
if (join.isSimple()) {
Expand Down
6 changes: 5 additions & 1 deletion src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,8 @@ Delete Delete( List<WithItem> with ):
Delete delete = new Delete();
Table table = null;
List<Table> tables = new ArrayList<Table>();
Table usingTable = null;
List<Table> usingList = new ArrayList<Table>();
List<Join> joins = null;
Expression where = null;
Limit limit = null;
Expand All @@ -1214,6 +1216,8 @@ Delete Delete( List<WithItem> with ):
<K_FROM> | <K_FROM>) { hasFrom = true; }]

[ LOOKAHEAD(3) table=TableWithAlias() joins=JoinsList() ]
[ <K_USING> usingTable=TableWithAlias() { usingList.add(usingTable); }
("," usingTable=TableWithAlias() { usingList.add(usingTable); } )*]
[where=WhereClause() { delete.setWhere(where); } ]
[orderByElements = OrderByElements() { delete.setOrderByElements(orderByElements); } ]
[limit=PlainLimit() {delete.setLimit(limit); } ]
Expand All @@ -1222,7 +1226,7 @@ Delete Delete( List<WithItem> with ):
delete.setJoins(joins);
}
return delete.withWithItemsList(with)
.withTables(tables).withTable(table).withHasFrom(hasFrom);
.withTables(tables).withTable(table).withHasFrom(hasFrom).withUsingList(usingList);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,10 @@ public void testNoFromWithSchema() throws JSQLParserException {
String statement = "DELETE A.B WHERE Z = 1";
assertSqlCanBeParsedAndDeparsed(statement);
}

@Test
public void testUsing() throws JSQLParserException {
String statement = "DELETE A USING B.C D WHERE D.Z = 1";
assertSqlCanBeParsedAndDeparsed(statement);
}
}
14 changes: 14 additions & 0 deletions src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.io.StringReader;
import java.util.Iterator;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -664,4 +665,17 @@ public void testAtTimeZoneExpression() throws JSQLParserException {
assertEquals(1, tableList.size());
assertTrue(tableList.contains("mytbl"));
}


@Test
public void testUsing() throws JSQLParserException {
String sql = "DELETE A USING B.C D WHERE D.Z = 1";
Statement stmt = CCJSqlParserUtil.parse(sql);
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> tableList = tablesNamesFinder.getTableList(stmt);
assertEquals(2, tableList.size());
assertTrue(tableList.contains("A"));
assertTrue(tableList.contains("B.C"));
}

}

0 comments on commit 9b81814

Please sign in to comment.