Skip to content

Fix dropped PL/pgSQL EXCEPTION handlers and RAISE USING options#36

Merged
gmr merged 2 commits into
mainfrom
fix/plpgsql-dropped-clauses
Jul 6, 2026
Merged

Fix dropped PL/pgSQL EXCEPTION handlers and RAISE USING options#36
gmr merged 2 commits into
mainfrom
fix/plpgsql-dropped-clauses

Conversation

@gmr

@gmr gmr commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes two PL/pgSQL formatting bugs where constructs were silently dropped from the output.

Problem

Solution

  • format_exception_sect now iterates into each proc_exception node and renders its proc_conditions and proc_sect.
  • format_stmt_raise now handles kw_using and each raise_option (keyword = expression), supporting multiple comma-separated options.
  • Added inline regression tests to tests/plpgsql_test.rs for both cases.

just check (fmt, clippy -D warnings, tests) passes.

Fixes #26
Fixes #32

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved formatting of PL/pgSQL RAISE statements so USING options are preserved and displayed consistently.
    • Fixed formatting of EXCEPTION handlers to keep the handler body intact and correctly place WHEN ... THEN blocks.
  • Tests
    • Added regression coverage for exception handler formatting and RAISE ... USING option preservation.

- Iterate each proc_exception node in format_exception_sect so the WHEN
  conditions and handler body are rendered instead of a bare EXCEPTION
  keyword. The grammar wraps each handler in proc_exception, so scanning
  exception_sect's direct children for proc_conditions/proc_sect never
  matched (#26).
- Preserve RAISE ... USING options in format_stmt_raise by handling the
  kw_using keyword and each raise_option (ERRCODE, MESSAGE, ...), which
  were previously discarded. Supports multiple comma-separated options
  (#32).
- Add inline regression tests to tests/plpgsql_test.rs for both.

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

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: da8b90f5-cf41-479d-a00e-746e52adb4cc

📥 Commits

Reviewing files that changed from the base of the PR and between f151ce7 and d4745f3.

📒 Files selected for processing (2)
  • src/formatter/plpgsql.rs
  • tests/plpgsql_test.rs
📝 Walkthrough

Walkthrough

Two PL/pgSQL formatting bugs are fixed in src/formatter/plpgsql.rs: RAISE ... USING option clauses are now preserved instead of dropped, and EXCEPTION handler bodies are now correctly emitted instead of being discarded. Two regression tests are added to tests/plpgsql_test.rs.

Changes

PL/pgSQL formatter fixes

Layer / File(s) Summary
RAISE USING option preservation
src/formatter/plpgsql.rs, tests/plpgsql_test.rs
format_stmt_raise now handles kw_using and raise_option nodes, building KEY = expression fragments appended to the RAISE statement; a new test verifies ERRCODE/MESSAGE options survive formatting.
EXCEPTION handler body preservation
src/formatter/plpgsql.rs, tests/plpgsql_test.rs
format_exception_sect now iterates proc_exception nodes to emit WHEN <cond> THEN followed by the proc_sect handler body, instead of matching sibling nodes directly; a new test verifies the handler body (e.g. RAISE;) is retained.

Estimated code review effort: 2 (Simple) | ~12 minutes

Sequence Diagram(s)

Not applicable — changes are localized formatter logic fixes without multi-component interaction flows.

Poem

Two bugs I chased through leaves of code,
where RAISE and EXCEPTION lost their load.
Now USING clauses stay in place,
and handler bodies keep their space.
Hop hop hooray, the tests all pass — 🐇
this bunny's formatting job, at last!

🚥 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 accurately summarizes the main fix: preserving dropped PL/pgSQL EXCEPTION handlers and RAISE USING options.
Linked Issues check ✅ Passed The changes address #26 and #32 by preserving EXCEPTION handler bodies and RAISE USING options, with regression tests added.
Out of Scope Changes check ✅ Passed The diff stays focused on the two PL/pgSQL formatting bugs and their tests, with no unrelated changes evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/plpgsql_test.rs (1)

93-104: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding coverage for := and other raise_option keywords.

This test only exercises = with ERRCODE/MESSAGE. Given the grammar also allows := and other options (DETAIL, HINT, COLUMN, CONSTRAINT, etc.), an additional case would help catch the operator-normalization concern raised in src/formatter/plpgsql.rs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/plpgsql_test.rs` around lines 93 - 104, The current
`raise_using_options_preserved` test only covers `RAISE ... USING` with `=` for
`ERRCODE` and `MESSAGE`; add an additional assertion in `tests/plpgsql_test.rs`
that exercises `:=` and other `raise_option` keywords such as `DETAIL`, `HINT`,
`COLUMN`, or `CONSTRAINT` so the `format_plpgsql` path continues preserving all
supported option forms and operator normalization in `src/formatter/plpgsql.rs`
is covered.
src/formatter/plpgsql.rs (1)

390-402: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider extracting raise_option formatting into a helper.

The nested loop building opt_kw/opt_expr inline adds noticeable branching to an already large match in format_stmt_raise. A small helper (e.g., fn format_raise_option(&self, node: Node<'a>) -> String) would keep the match arm terse and make the option-formatting logic independently testable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/formatter/plpgsql.rs` around lines 390 - 402, The raise_option formatting
logic inside format_stmt_raise is too much inline branching for the match arm.
Extract that block into a dedicated helper such as format_raise_option that
takes the child node, walks named children, builds the keyword/expression pair,
and returns the formatted string; then call that helper from the raise_option
match branch to keep the match terse and make the logic easier to test and
maintain.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/formatter/plpgsql.rs`:
- Around line 390-402: The raise_option formatting logic inside
format_stmt_raise is too much inline branching for the match arm. Extract that
block into a dedicated helper such as format_raise_option that takes the child
node, walks named children, builds the keyword/expression pair, and returns the
formatted string; then call that helper from the raise_option match branch to
keep the match terse and make the logic easier to test and maintain.

In `@tests/plpgsql_test.rs`:
- Around line 93-104: The current `raise_using_options_preserved` test only
covers `RAISE ... USING` with `=` for `ERRCODE` and `MESSAGE`; add an additional
assertion in `tests/plpgsql_test.rs` that exercises `:=` and other
`raise_option` keywords such as `DETAIL`, `HINT`, `COLUMN`, or `CONSTRAINT` so
the `format_plpgsql` path continues preserving all supported option forms and
operator normalization in `src/formatter/plpgsql.rs` is covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 50b64be8-f7a7-4df1-8d48-3b42d602eacc

📥 Commits

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

📒 Files selected for processing (2)
  • src/formatter/plpgsql.rs
  • tests/plpgsql_test.rs

- Extract raise_option formatting into a format_raise_option helper to
  keep the format_stmt_raise match arm terse.
- Add regression test covering DETAIL/HINT USING options alongside
  ERRCODE. (Skipped the suggested `:=` case: it is not valid PostgreSQL
  RAISE USING syntax and the grammar does not parse it.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@gmr gmr merged commit 16623bf into main Jul 6, 2026
3 checks passed
@gmr gmr deleted the fix/plpgsql-dropped-clauses branch July 6, 2026 18:00
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.

RAISE ... USING options are dropped in PL/pgSQL formatting PL/pgSQL EXCEPTION handler body is dropped, leaving a bare EXCEPTION keyword

1 participant