Skip to content

Fix dropped DML/DDL clauses in statement formatting#39

Merged
gmr merged 1 commit into
mainfrom
fix/stmt-dropped-clauses
Jul 6, 2026
Merged

Fix dropped DML/DDL clauses in statement formatting#39
gmr merged 1 commit into
mainfrom
fix/stmt-dropped-clauses

Conversation

@gmr

@gmr gmr commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes eight bugs in src/formatter/stmt.rs where DML/DDL clauses were silently dropped during formatting, producing incomplete or invalid SQL.

Problem

Several statement clauses have CST nodes that the formatters never read, so they were discarded on output:

Solution

Read the previously-ignored CST nodes and emit each clause, keeping both river and left-aligned rendering consistent with the surrounding clauses:

  • Added format_relation_list_river / _left_aligned helpers to render an UPDATE FROM list and a DELETE USING list.
  • Added format_on_conflict (handles DO NOTHING, DO UPDATE SET ..., conflict target, optional WHERE) and a returning_text helper shared by all three DML statements.
  • River clause keywords now include FROM/USING/RETURNING in the river-width computation so alignment stays correct.
  • CREATE TABLE now emits IF NOT EXISTS in the header and INHERITS / PARTITION BY / TABLESPACE after the column list; CREATE VIEW builds its prefix from the actual OR REPLACE and OptTemp nodes.

Added a river regression fixture pair for each case under tests/fixtures/river/. All new outputs were verified to be valid, idempotent PostgreSQL. cargo fmt, cargo clippy -- -D warnings, and cargo test all pass.

Fixes #27
Fixes #28
Fixes #29
Fixes #30
Fixes #31
Fixes #33
Fixes #34
Fixes #35

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Expanded SQL formatting support for more statement variants, including INSERT, UPDATE, DELETE, CREATE TABLE, and CREATE VIEW.
    • Added handling for RETURNING, conflict actions, USING/FROM clauses, table inheritance, partitioning, tablespaces, and view variations like temporary and replaceable views.
  • Bug Fixes

    • Improved alignment and line wrapping for river-style and left-aligned output, making formatted SQL more consistent and readable.

Several INSERT/UPDATE/DELETE and CREATE TABLE/VIEW clauses were silently
dropped because their CST nodes were never read in stmt.rs. Read and emit
them, keeping river and left-aligned rendering consistent with existing
clauses.

- #27: emit UPDATE ... FROM (reuses river/left-aligned relation list)
- #28: emit INSERT ... ON CONFLICT ... DO UPDATE/DO NOTHING
- #29: emit INSERT INTO t DEFAULT VALUES (was invalid INSERT INTO t)
- #30: emit RETURNING for INSERT, UPDATE and DELETE
- #31: emit DELETE ... USING
- #33: emit CREATE TABLE IF NOT EXISTS, INHERITS, PARTITION BY, TABLESPACE
- #34: emit CREATE [OR REPLACE] [TEMP] VIEW modifiers (was hardcoded)
- #35: emit INSERT ... OVERRIDING {SYSTEM|USER} VALUE

Adds river regression fixtures for each case; all outputs verified as valid,
idempotent PostgreSQL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 372f49e5-e8a9-4f91-a543-1a7591aab93d

📥 Commits

Reviewing files that changed from the base of the PR and between c949e2b and 31324b7.

📒 Files selected for processing (31)
  • src/formatter/stmt.rs
  • tests/fixtures/river/create_table_if_not_exists.expected
  • tests/fixtures/river/create_table_if_not_exists.sql
  • tests/fixtures/river/create_table_inherits.expected
  • tests/fixtures/river/create_table_inherits.sql
  • tests/fixtures/river/create_table_partition_by.expected
  • tests/fixtures/river/create_table_partition_by.sql
  • tests/fixtures/river/create_table_tablespace.expected
  • tests/fixtures/river/create_table_tablespace.sql
  • tests/fixtures/river/create_view_or_replace.expected
  • tests/fixtures/river/create_view_or_replace.sql
  • tests/fixtures/river/create_view_temp.expected
  • tests/fixtures/river/create_view_temp.sql
  • tests/fixtures/river/delete_returning.expected
  • tests/fixtures/river/delete_returning.sql
  • tests/fixtures/river/delete_using.expected
  • tests/fixtures/river/delete_using.sql
  • tests/fixtures/river/insert_default_values.expected
  • tests/fixtures/river/insert_default_values.sql
  • tests/fixtures/river/insert_on_conflict_do_nothing.expected
  • tests/fixtures/river/insert_on_conflict_do_nothing.sql
  • tests/fixtures/river/insert_on_conflict_do_update.expected
  • tests/fixtures/river/insert_on_conflict_do_update.sql
  • tests/fixtures/river/insert_overriding_system.expected
  • tests/fixtures/river/insert_overriding_system.sql
  • tests/fixtures/river/insert_returning.expected
  • tests/fixtures/river/insert_returning.sql
  • tests/fixtures/river/update_from.expected
  • tests/fixtures/river/update_from.sql
  • tests/fixtures/river/update_returning.expected
  • tests/fixtures/river/update_returning.sql

📝 Walkthrough

Walkthrough

This PR fixes the SQL formatter so previously dropped clauses are now emitted correctly for INSERT (OVERRIDING VALUE, ON CONFLICT, RETURNING, DEFAULT VALUES), UPDATE (FROM, RETURNING), DELETE (USING, RETURNING), CREATE TABLE (IF NOT EXISTS, INHERITS, PARTITION BY, TABLESPACE), and CREATE VIEW (OR REPLACE, TEMP). New fixtures validate each clause.

Changes

Statement formatter clause fixes

Layer / File(s) Summary
INSERT: OVERRIDING, ON CONFLICT, RETURNING, DEFAULT VALUES
src/formatter/stmt.rs, tests/fixtures/river/insert_*
Adds OVERRIDING VALUE header injection, ON CONFLICT and RETURNING clause emission with new helper functions, and fixtures for override/on-conflict/returning/default-values cases.
Shared relation list rendering helpers
src/formatter/stmt.rs
Adds format_relation_list_river and format_relation_list_left_aligned helpers shared by UPDATE FROM and DELETE USING rendering.
UPDATE: FROM and RETURNING support
src/formatter/stmt.rs, tests/fixtures/river/update_from.*, tests/fixtures/river/update_returning.*
Widens river alignment calculation for FROM/WHERE/RETURNING and emits FROM relation list and RETURNING output in both river and non-river paths.
DELETE: USING and RETURNING support
src/formatter/stmt.rs, tests/fixtures/river/delete_using.*, tests/fixtures/river/delete_returning.*
Widens river alignment for USING/RETURNING and emits USING relation list and RETURNING clause in both formatting paths.
CREATE TABLE: IF NOT EXISTS, INHERITS, PARTITION BY, TABLESPACE
src/formatter/stmt.rs, tests/fixtures/river/create_table_*
Conditionally emits IF NOT EXISTS header token and adds INHERITS, PARTITION BY, and TABLESPACE clause rendering.
CREATE VIEW: OR REPLACE and TEMP modifiers
src/formatter/stmt.rs, tests/fixtures/river/create_view_*
Rebuilds the CREATE VIEW header token list to include OR REPLACE and TEMP/TEMPORARY modifiers.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

  • gmr/libpgfmt#1: Introduces the original INSERT/UPDATE/DELETE/CREATE/VIEW formatting logic in stmt.rs that this PR extends.
  • gmr/libpgfmt#4: Also modifies the CREATE VIEW header rendering logic in stmt.rs.

Poem

Clauses lost, now found again,
RETURNING, FROM, and USING too,
PARTITION BY and TABLESPACE plain,
OR REPLACE the view anew.
This rabbit hops with fixtures neat — 🐇
No dropped clause left to fret! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main formatting fix.
Linked Issues check ✅ Passed The PR preserves the clauses required by linked issues #27-35 and adds fixtures for each case.
Out of Scope Changes check ✅ Passed The code and fixture changes stay focused on the stated DML/DDL clause-preservation bugs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@gmr gmr merged commit e50de3a into main Jul 6, 2026
3 checks passed
@gmr gmr deleted the fix/stmt-dropped-clauses branch July 6, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment