Skip to content

Preserve user-supplied grouping parentheses in boolean expressions #2

Description

@coderabbitai

Summary

When formatting SQL, libpgfmt currently drops user-supplied grouping parentheses in WHERE clauses and other boolean expressions. For example, an expression like:

WHERE (sp.cancelled_at IS NULL OR sp.cancelled_at > CURRENT_TIMESTAMP) AND f.feature_name = 'notifications'

is formatted as:

WHERE sp.cancelled_at IS NULL OR sp.cancelled_at > CURRENT_TIMESTAMP AND f.feature_name = 'notifications'

This matches the reference behavior of the Python pgfmt project (which uses pgparse/libpg_query and normalizes away such parentheses at the AST level). However, since libpgfmt uses tree-sitter-postgres (a concrete syntax tree), it is technically feasible to detect and preserve these user-supplied grouping parentheses.

Background

Discussed in PR #1 (#1) at comment #1 (comment).

Raised by @gmr — dropping parentheses is current intentional behavior to match Python pgfmt, with preservation as a planned future improvement.

Goal

Update the expression formatter so that when an OR node (or any lower-precedence boolean operator) is nested inside a higher-precedence boolean context (e.g., AND), the parentheses originally present in the source are emitted in the formatted output to preserve the intended evaluation order and semantics.

Notes

  • The tree-sitter-postgres CST retains the parenthesized grouping nodes, making this feasible without external heuristics.
  • Care should be taken to only restore parentheses that were present in the original source, not to add new ones based on operator precedence alone.
  • Requested by @gmr in PR Add SQL and PL/pgSQL formatting library #1.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions