Skip to content

Commit be8be85

Browse files
committed
Reuse common JOIN traversal when discovering UPDATE tables
1 parent 0ecf096 commit be8be85

2 files changed

Lines changed: 56 additions & 13 deletions

File tree

src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,11 +1393,7 @@ public <S> Void visit(Update update, S context) {
13931393
visit(update.getTable(), context);
13941394
}
13951395

1396-
if (update.getStartJoins() != null) {
1397-
for (Join join : update.getStartJoins()) {
1398-
join.getRightItem().accept(this, context);
1399-
}
1400-
}
1396+
visitJoins(update.getStartJoins(), context);
14011397

14021398
if (update.getUpdateSets() != null) {
14031399
for (UpdateSet updateSet : update.getUpdateSets()) {
@@ -1410,14 +1406,7 @@ public <S> Void visit(Update update, S context) {
14101406
update.getFromItem().accept(this, context);
14111407
}
14121408

1413-
if (update.getJoins() != null) {
1414-
for (Join join : update.getJoins()) {
1415-
join.getRightItem().accept(this, context);
1416-
for (Expression expression : join.getOnExpressions()) {
1417-
expression.accept(this, context);
1418-
}
1419-
}
1420-
}
1409+
visitJoins(update.getJoins(), context);
14211410

14221411
if (update.getWhere() != null) {
14231412
update.getWhere().accept(this, context);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2019 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.util;
11+
12+
import static org.junit.jupiter.api.Assertions.assertEquals;
13+
import static org.junit.jupiter.api.Assertions.assertSame;
14+
import java.util.Set;
15+
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
16+
import net.sf.jsqlparser.schema.Table;
17+
import net.sf.jsqlparser.statement.update.Update;
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.params.ParameterizedTest;
20+
import org.junit.jupiter.params.provider.ValueSource;
21+
22+
class UpdateJoinTablesTest {
23+
@ParameterizedTest
24+
@ValueSource(strings = {
25+
"UPDATE target t JOIN source s ON s.id IN (SELECT id FROM hidden) SET t.a = 1",
26+
"UPDATE target t LEFT JOIN source s ON EXISTS (SELECT 1 FROM hidden h WHERE h.id = s.id) SET t.a = 1",
27+
"UPDATE target SET a = 1 FROM source s JOIN target t ON s.id IN (SELECT id FROM hidden)",
28+
"WITH h AS (SELECT id FROM hidden) UPDATE target t JOIN source s ON s.id IN (SELECT id FROM h) SET t.a = 1"})
29+
void includesTablesInsideJoinConditions(String sql) throws Exception {
30+
assertEquals(Set.of("target", "source", "hidden"), TablesNamesFinder.findTables(sql));
31+
}
32+
33+
@Test
34+
void preservesContextAndVisitsEachSourceOnce() throws Exception {
35+
Update update = (Update) CCJSqlParserUtil.parse(
36+
"UPDATE target t JOIN source s ON s.id IN (SELECT id FROM hidden) SET t.a = 1");
37+
Object context = new Object();
38+
java.util.List<String> seen = new java.util.ArrayList<>();
39+
TablesNamesFinder<Void> finder = new TablesNamesFinder<Void>() {
40+
{
41+
init(false);
42+
}
43+
44+
@Override
45+
public <S> Void visit(Table table, S actual) {
46+
assertSame(context, actual);
47+
seen.add(table.getName());
48+
return null;
49+
}
50+
};
51+
update.accept(finder, context);
52+
assertEquals(java.util.List.of("target", "source", "hidden"), seen);
53+
}
54+
}

0 commit comments

Comments
 (0)