Skip to content

fix: collect tables from all SELECT and DML trailing clauses in TablesNamesFinder - #2517

Merged
manticore-projects merged 1 commit into
JSQLParser:masterfrom
fudianchn:fix/tables-names-finder-select-clauses
Aug 31, 2026
Merged

fix: collect tables from all SELECT and DML trailing clauses in TablesNamesFinder#2517
manticore-projects merged 1 commit into
JSQLParser:masterfrom
fudianchn:fix/tables-names-finder-select-clauses

Conversation

@fudianchn

@fudianchn fudianchn commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

AI disclosure: this change was prepared with AI coding agents, reviewed and revised line by line by me.

What

TablesNamesFinder now traverses all Expression- and Table-bearing clauses of the SELECT family and the DML trailing clauses it previously skipped, so tables located in those clauses are collected instead of silently dropped.

Why

TablesNamesFinder is the public helper for table extraction (SQL analysis, auditing, firewalls); a silently incomplete result is the worst failure mode for those consumers. All shapes in #2516 parse fine today and return incomplete table sets. This continues the family fixed by #2478 / #2479 (piped queries, DML side clauses, analytic clauses).

How

  • PlainSelect: DISTINCT ON items, INTO tables, LATERAL VIEW generator functions, PREFERRING, GROUP BY (incl. GROUPING SETS), QUALIFY, WINDOW definitions, PIVOT / UNPIVOT, ORDER BY, LIMIT / LIMIT BY, OFFSET, FETCH, SETTINGS, INTO TEMP target.
  • ParenthesedSelect, SetOperationList, Values: the ORDER BY / LIMIT / OFFSET / FETCH clauses they carry themselves.
  • Delete, Update: their ORDER BY and LIMIT clauses (MySQL single-table DML).
  • Attached PIVOT / UNPIVOT / PIVOT XML (incl. the PIVOT XML ... IN (SELECT ...) subquery) is reached via the newly implemented PivotVisitor, the same mechanism as MergeOperationVisitor / PipeOperationVisitor in fix: complete TablesNamesFinder traversal for piped queries, DML side clauses and analytic functions (#2478) #2479.

All traversals reuse the ExpressionVisitor / FromItemVisitor default helpers (visitOrderBy, visitLimit, visit(GroupByElement), visitUpdateSets, visitPreferringClause, visitTables, visitFromItem) already used by SelectVisitorAdapter and StatementVisitorAdapter. Two SelectVisitorAdapter @todos (windowDefinitions, lateralViews) are covered too, because both can carry subqueries.

Root cause

The finder's visit methods traversed only a subset of the Expression- and Table-bearing children; the adapters already covered most of these clauses, the finder did not.

Testing

Verification of the original issue

TablesNamesFinder.findTables("SELECT a FROM t GROUP BY a, (SELECT b FROM u)");
// before: [t]    after: [t, u]

With this change every shape in the #2516 matrix returns the complete table set.

Fixes #2516

@manticore-projects

Copy link
Copy Markdown
Contributor

Awesome job!

@fudianchn
fudianchn marked this pull request as draft August 31, 2026 12:42
@fudianchn
fudianchn force-pushed the fix/tables-names-finder-select-clauses branch from 71d254b to afbc87c Compare August 31, 2026 12:44
@fudianchn fudianchn changed the title fix: collect tables from all SELECT clauses in TablesNamesFinder fix: collect tables from all SELECT and DML trailing clauses in TablesNamesFinder Aug 31, 2026
@fudianchn
fudianchn marked this pull request as ready for review August 31, 2026 12:45
…sNamesFinder

TablesNamesFinder visited only a subset of the Expression/Table-bearing
children of PlainSelect, ParenthesedSelect, SetOperationList, Values,
Delete, Update and FromItem-attached pivots, silently dropping tables
located in INTO and INTO TEMP targets, DISTINCT ON, LATERAL VIEW
generator functions, PREFERRING, GROUP BY (incl. GROUPING SETS),
QUALIFY, WINDOW definitions, SETTINGS, PIVOT/UNPIVOT/PIVOT XML and the
ORDER BY / LIMIT / LIMIT BY / OFFSET / FETCH clauses shared by every
Select subclass (and by the MySQL single-table DELETE / UPDATE).

Complete the traversal reusing the same ExpressionVisitor and
FromItemVisitor default helpers used by SelectVisitorAdapter and
StatementVisitorAdapter, and implement PivotVisitor so pivot contents
(incl. the PivotXml IN subquery) are reached through dispatch.

Signed-off-by: fudianchn <fudianchn@gmail.com>
@fudianchn
fudianchn force-pushed the fix/tables-names-finder-select-clauses branch from afbc87c to 002ebc6 Compare August 31, 2026 12:48
@fudianchn

Copy link
Copy Markdown
Contributor Author

After your comment I pushed two more updates to the branch:

  1. Self-review found the same gap in the DELETE / UPDATE ORDER BY + LIMIT clauses (StatementVisitorAdapter already traverses them), now covered with 2 more tests; [BUG] JSQLParser 5.4-SNAPSHOT : all RDBMS : TablesNamesFinder silently misses tables in many SELECT and DML clauses (INTO, GROUP BY, QUALIFY, WINDOW, ORDER BY, LIMIT, DISTINCT ON, LATERAL VIEW, PIVOT XML, SETTINGS) #2516 updated accordingly.
  2. Fixed the commit author email: the earlier pushes were attributed to an unrelated GitHub account by mistake, the current head 002ebc6 is correct.

Full suite: 4971 tests, 0 failures.

@manticore-projects
manticore-projects merged commit 864181b into JSQLParser:master Aug 31, 2026
7 checks passed
@manticore-projects

Copy link
Copy Markdown
Contributor

Thank you for fixing this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants