diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java index 5931c2fa6..a78847037 100644 --- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java +++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java @@ -1393,11 +1393,7 @@ public Void visit(Update update, S context) { visit(update.getTable(), context); } - if (update.getStartJoins() != null) { - for (Join join : update.getStartJoins()) { - join.getRightItem().accept(this, context); - } - } + visitJoins(update.getStartJoins(), context); if (update.getUpdateSets() != null) { for (UpdateSet updateSet : update.getUpdateSets()) { @@ -1410,14 +1406,7 @@ public Void visit(Update update, S context) { update.getFromItem().accept(this, context); } - if (update.getJoins() != null) { - for (Join join : update.getJoins()) { - join.getRightItem().accept(this, context); - for (Expression expression : join.getOnExpressions()) { - expression.accept(this, context); - } - } - } + visitJoins(update.getJoins(), context); if (update.getWhere() != null) { update.getWhere().accept(this, context); diff --git a/src/test/java/net/sf/jsqlparser/util/UpdateJoinTablesTest.java b/src/test/java/net/sf/jsqlparser/util/UpdateJoinTablesTest.java new file mode 100644 index 000000000..f2d505574 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/util/UpdateJoinTablesTest.java @@ -0,0 +1,54 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import java.util.Set; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.update.Update; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class UpdateJoinTablesTest { + @ParameterizedTest + @ValueSource(strings = { + "UPDATE target t JOIN source s ON s.id IN (SELECT id FROM hidden) SET t.a = 1", + "UPDATE target t LEFT JOIN source s ON EXISTS (SELECT 1 FROM hidden h WHERE h.id = s.id) SET t.a = 1", + "UPDATE target SET a = 1 FROM source s JOIN target t ON s.id IN (SELECT id FROM hidden)", + "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"}) + void includesTablesInsideJoinConditions(String sql) throws Exception { + assertEquals(Set.of("target", "source", "hidden"), TablesNamesFinder.findTables(sql)); + } + + @Test + void preservesContextAndVisitsEachSourceOnce() throws Exception { + Update update = (Update) CCJSqlParserUtil.parse( + "UPDATE target t JOIN source s ON s.id IN (SELECT id FROM hidden) SET t.a = 1"); + Object context = new Object(); + java.util.List seen = new java.util.ArrayList<>(); + TablesNamesFinder finder = new TablesNamesFinder() { + { + init(false); + } + + @Override + public Void visit(Table table, S actual) { + assertSame(context, actual); + seen.add(table.getName()); + return null; + } + }; + update.accept(finder, context); + assertEquals(java.util.List.of("target", "source", "hidden"), seen); + } +}