Skip to content

Commit 364167f

Browse files
committed
fix: find tables in SET values instead of throwing
TablesNamesFinder threw UnsupportedOperationException for every SET statement except SQL Server ON/OFF options. A MySQL trigger whose body is or contains SET, such as FOR EACH ROW SET NEW.a = ..., failed the same way, although its table is known. The finder now visits the value expressions of each assignment, so a subquery in a SET value reports its tables and other SET statements report none. Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent c84ad0e commit 364167f

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,8 +1949,13 @@ public void visit(Execute execute) {
19491949

19501950
@Override
19511951
public <S> Void visit(SetStatement setStatement, S context) {
1952-
if (setStatement.getOnOffOptions() == null) {
1953-
throwUnsupported(setStatement);
1952+
for (int i = 0; i < setStatement.getCount(); i++) {
1953+
List<Expression> expressions = setStatement.getExpressions(i);
1954+
if (expressions != null) {
1955+
for (Expression expression : expressions) {
1956+
expression.accept(this, context);
1957+
}
1958+
}
19541959
}
19551960
return null;
19561961
}

‎src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,27 @@ public void testAlterSequenceHasNoTableReferences() throws JSQLParserException {
392392
assertThat(tablesNamesFinder.getTables(stmt)).isEmpty();
393393
}
394394

395+
@Test
396+
public void testSetStatementFindsTablesInValues() throws JSQLParserException {
397+
assertThat(TablesNamesFinder
398+
.findTables("SET @a = (SELECT MAX(id) FROM MY_TABLE1), @b = 2"))
399+
.containsExactlyInAnyOrder("MY_TABLE1");
400+
assertThat(TablesNamesFinder.findTables("SET search_path TO s1")).isEmpty();
401+
}
402+
403+
@Test
404+
public void testMySqlTriggerWithSetBody() throws JSQLParserException {
405+
String sqlStr = "CREATE TRIGGER trg BEFORE INSERT ON MY_TABLE1 FOR EACH ROW "
406+
+ "SET NEW.a = (SELECT MAX(id) FROM MY_TABLE2)";
407+
assertThat(TablesNamesFinder.findTables(sqlStr)).containsExactlyInAnyOrder("MY_TABLE1",
408+
"MY_TABLE2");
409+
410+
sqlStr = "CREATE TRIGGER trg BEFORE UPDATE ON MY_TABLE1 FOR EACH ROW "
411+
+ "BEGIN SET NEW.updated_at = NOW(); INSERT INTO MY_TABLE2 VALUES (NEW.id); END";
412+
assertThat(TablesNamesFinder.findTables(sqlStr)).containsExactlyInAnyOrder("MY_TABLE1",
413+
"MY_TABLE2");
414+
}
415+
395416
@Test
396417
public void testCreateSynonym_throwsException() throws JSQLParserException {
397418
String sql = "CREATE SYNONYM foo FOR bar";

0 commit comments

Comments
 (0)