Skip to content

fix: walk WITH items of TableStatement in adapter and validator - #2928

Open
tanjiroK-coder wants to merge 1 commit into
JSQLParser:masterfrom
tanjiroK-coder:table-statement-with-items
Open

tanjiroK-coder wants to merge 1 commit into
JSQLParser:masterfrom
tanjiroK-coder:table-statement-with-items

Conversation

@tanjiroK-coder

Copy link
Copy Markdown
Contributor

SelectVisitorAdapter.visit(TableStatement) returns without visiting anything, and SelectValidator.visit(TableStatement) only reports Feature.tableStatement, so the WITH list in front of a PostgreSQL TABLE statement never reaches StatementFeatureVisitor or any ValidationCapability. WITH d AS (DELETE FROM t RETURNING a) TABLE d therefore comes back as certain=[READS_DATA, RETURNS_RESULT_SET] with mayModifyData() == false and passes the read-only guard in usage.rst, and Validation with FeaturesAllowed.SELECT reports no error, while the same CTE in front of SELECT a FROM d reports MODIFIES_DATA and a delete not allowed error. PostgreSQL 18.6 runs the DELETE for the TABLE form, also when the TABLE names another table (WITH d AS (...) TABLE other), and TABLE t ORDER BY nextval('s') advances the sequence, which the empty adapter visit missed too. I ran into it while sending write-capable statements through getFeatures() and listing the ones that came back with mayModifyData() == false. The adapter now walks the WITH items, ORDER BY and LIMIT / OFFSET / FETCH of TABLE the way its visit(Values) already does, and SelectValidator validates the WITH list of TABLE and VALUES like it does for PlainSelect, SetOperationList and ParenthesedSelect (for VALUES this only mattered where Feature.values is allowed, since FeaturesAllowed.SELECT rejects VALUES itself). Pipe queries (FROM ... |>) are skipped by both visits too, but I left them alone since no server that accepts pipe syntax allows a data-modifying CTE. The new StatementFeatureVisitorTest, TableStatementValidatorTest and ValuesStatementValidatorTest cases fail before and pass after, PostgreSQL validation still accepts the statement, and ./gradlew check (15829 tests) and mvn verify (15811 tests) pass.

SelectVisitorAdapter.visit(TableStatement) visited nothing and
SelectValidator only reported tableStatement, so a data-modifying CTE in
front of TABLE was invisible to StatementFeatures and to Validation:
WITH d AS (DELETE FROM t RETURNING a) TABLE d gave mayModifyData() ==
false and passed FeaturesAllowed.SELECT. The adapter now walks the WITH
items, ORDER BY and LIMIT/OFFSET/FETCH of TABLE like its VALUES visit,
and SelectValidator validates the WITH list of TABLE and VALUES.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant