You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Validation.validate throws ClassCastException on a data-modifying CTE (WithItem.getSelect on ParenthesedDelete) #2574
Validation.validate(..) throws a ClassCastException on a data-modifying CTE instead of reporting a validation error, so a caller using FeaturesAllowed.SELECT to keep writes out gets an exception rather than a verdict.
Version:com.manticore-projects.jsqlformatter:jsqlparser:5.4.351-SNAPSHOT (build 5.4.351-20260910.100601-1), master at b2115ac8.
Reproduce
Validation.validate(List.of(FeaturesAllowed.SELECT),
"WITH x AS (DELETE FROM foo RETURNING id) SELECT * FROM x");
java.lang.ClassCastException: class net.sf.jsqlparser.statement.delete.ParenthesedDelete cannot be cast to class net.sf.jsqlparser.statement.select.ParenthesedSelect
at net.sf.jsqlparser.statement.select.WithItem.getSelect(WithItem.java:229)
at net.sf.jsqlparser.util.validation.validator.SelectValidator.visit(SelectValidator.java:393)
at net.sf.jsqlparser.util.validation.validator.SelectValidator.visit(SelectValidator.java:57)
Same for WITH x AS (UPDATE foo SET id = 1 RETURNING id) SELECT * FROM x and the INSERT .. RETURNING form. Statement.getFeatures() handles all three (MODIFIES_DATA is certain), because StatementFeatureVisitor overrides visit(WithItem) to look at getParenthesedStatement(); the validator still calls withItem.getSelect().
Cause
SelectValidator.visit(WithItem) (SelectValidator.java:393): withItem.getSelect().accept(..); WithItem.getSelect() (WithItem.java:229) casts the body to ParenthesedSelect, and the body is a ParenthesedDelete.
Suggestion
Dispatch on getParenthesedStatement() as StatementFeatureVisitor does: a ParenthesedSelect continues into the select validator, a ParenthesedInsert/Update/Delete into the matching statement validator (so Feature.delete etc. are reported as not allowed), anything else as an unsupported feature. A ValidationTest case with FeaturesAllowed.SELECT and a DML CTE, expecting Feature.delete not allowed, would pin it.
Activity