Skip to content

Commit a2baa18

Browse files
authored
Reuse common JOIN traversal when discovering UPDATE tables (#2625)
1 parent 3822466 commit a2baa18

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
@@ -1398,11 +1398,7 @@ public <S> Void visit(Update update, S context) {
13981398
visit(update.getTable(), context);
13991399
}
14001400

1401-
if (update.getStartJoins() != null) {
1402-
for (Join join : update.getStartJoins()) {
1403-
join.getRightItem().accept(this, context);
1404-
}
1405-
}
1401+
visitJoins(update.getStartJoins(), context);
14061402

14071403
if (update.getUpdateSets() != null) {
14081404
for (UpdateSet updateSet : update.getUpdateSets()) {
@@ -1415,14 +1411,7 @@ public <S> Void visit(Update update, S context) {
14151411
update.getFromItem().accept(this, context);
14161412
}
14171413

1418-
if (update.getJoins() != null) {
1419-
for (Join join : update.getJoins()) {
1420-
join.getRightItem().accept(this, context);
1421-
for (Expression expression : join.getOnExpressions()) {
1422-
expression.accept(this, context);
1423-
}
1424-
}
1425-
}
1414+
visitJoins(update.getJoins(), context);
14261415

14271416
if (update.getForPortionClause() != null) {
14281417
update.getForPortionClause().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)