From 364167f54e4998edb9faf35d1271b4d1d5de19bd Mon Sep 17 00:00:00 2001 From: minleejae Date: Thu, 29 Oct 2026 10:45:39 +0900 Subject: [PATCH] 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 --- .../sf/jsqlparser/util/TablesNamesFinder.java | 9 ++++++-- .../util/TablesNamesFinderTest.java | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java index 4f9b44f912..c15690b856 100644 --- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java +++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java @@ -1949,8 +1949,13 @@ public void visit(Execute execute) { @Override public Void visit(SetStatement setStatement, S context) { - if (setStatement.getOnOffOptions() == null) { - throwUnsupported(setStatement); + for (int i = 0; i < setStatement.getCount(); i++) { + List expressions = setStatement.getExpressions(i); + if (expressions != null) { + for (Expression expression : expressions) { + expression.accept(this, context); + } + } } return null; } diff --git a/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java b/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java index 721a2d849e..aeac099060 100644 --- a/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java +++ b/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java @@ -392,6 +392,27 @@ public void testAlterSequenceHasNoTableReferences() throws JSQLParserException { assertThat(tablesNamesFinder.getTables(stmt)).isEmpty(); } + @Test + public void testSetStatementFindsTablesInValues() throws JSQLParserException { + assertThat(TablesNamesFinder + .findTables("SET @a = (SELECT MAX(id) FROM MY_TABLE1), @b = 2")) + .containsExactlyInAnyOrder("MY_TABLE1"); + assertThat(TablesNamesFinder.findTables("SET search_path TO s1")).isEmpty(); + } + + @Test + public void testMySqlTriggerWithSetBody() throws JSQLParserException { + String sqlStr = "CREATE TRIGGER trg BEFORE INSERT ON MY_TABLE1 FOR EACH ROW " + + "SET NEW.a = (SELECT MAX(id) FROM MY_TABLE2)"; + assertThat(TablesNamesFinder.findTables(sqlStr)).containsExactlyInAnyOrder("MY_TABLE1", + "MY_TABLE2"); + + sqlStr = "CREATE TRIGGER trg BEFORE UPDATE ON MY_TABLE1 FOR EACH ROW " + + "BEGIN SET NEW.updated_at = NOW(); INSERT INTO MY_TABLE2 VALUES (NEW.id); END"; + assertThat(TablesNamesFinder.findTables(sqlStr)).containsExactlyInAnyOrder("MY_TABLE1", + "MY_TABLE2"); + } + @Test public void testCreateSynonym_throwsException() throws JSQLParserException { String sql = "CREATE SYNONYM foo FOR bar";