Skip to content

simplify: collapsing a CASE under an arithmetic operator drops the grouping of the branch #8380

Closed

Description

@Rodrigo-Palma

When simplify resolves a CASE to one of its branches, the branch replaces the CASE without parentheses. If the CASE is an operand of an arithmetic operator and the branch is itself a binary expression, the result changes meaning.

Fully reproducible code snippet

Checked on main (19077cc):

from sqlglot import parse_one
from sqlglot.optimizer.simplify import simplify

for sql in [
    "SELECT x * CASE WHEN FALSE THEN NULL ELSE a - b END FROM t",
    "SELECT x * (CASE WHEN 1 IS NULL THEN NULL ELSE 1 - b END) FROM t",
    "SELECT x - CASE WHEN TRUE THEN a + b ELSE c END FROM t",
]:
    print(simplify(parse_one(sql, read="duckdb")).sql(dialect="duckdb"))

Output:

SELECT x * a - b FROM t
SELECT x * 1 - b FROM t
SELECT x - a + b FROM t

Expected:

SELECT x * (a - b) FROM t
SELECT x * (1 - b) FROM t
SELECT x - (a + b) FROM t

With values, DuckDB gives SELECT 2 * CASE WHEN FALSE THEN NULL ELSE 10 - 5 END = 10, while the simplified SELECT 2 * 10 - 5 = 15.

The second case shows that parentheses written around the CASE don't help: they are removed while the node is still a CASE, and the CASE is collapsed afterwards.

Context

Found through SQLMesh's @SAFE_SUB macro, which builds CASE WHEN ... IS NULL THEN NULL ELSE a - b END. When an argument is a literal, the rendered model computes the wrong value (SQLMesh/sqlmesh#5649). SQLMesh can work around it by emitting an explicit paren around the branch (SQLMesh/sqlmesh#6074), but hand written CASE expressions hit the same thing.

Official Documentation

Operator precedence (PostgreSQL, same rules in DuckDB): https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-PRECEDENCE

Activity

  1. self-assigned this
    on Sep 17, 2026
  2. Kunal8954 commented on Sep 17, 2026

    @Kunal8954
    Contributor

    Hey,can i take this i would love to solve and raise PR.

  3. treysp commented on Sep 17, 2026

    @treysp
    Collaborator

    go for it!

  4. removed their assignment
    on Sep 17, 2026
  5. Kunal8954 commented on Sep 17, 2026

    @Kunal8954
    Contributor

    @treysp done

  6. self-assigned this
    on Sep 17, 2026
  7. Kunal8954 commented on Sep 19, 2026

    @Kunal8954
    Contributor

    Hey @georgesittas
    I just wanted to understand why my PRs are being closed every time. I understand that the code was written with the help of an LLM, and I’ve been transparent about that. However, I’m also explaining the exact procedure and reasoning behind the solution, and I genuinely understand the changes being proposed.
    As per my understanding, and after discussing/reviewing the approach with an LLM, I raise the PR only after understanding the solution and making sure it fits the issue.
    If the concern is specifically about AI-assisted contributions, could you please let me know what you expect from me? Do you want me to write every fix completely manually, or is AI-assisted code acceptable as long as I fully understand, verify, test, and explain the changes myself?
    I’d really appreciate some clarity so I can follow the project’s expectations correctly and contribute in the right way

  8. georgesittas commented on Sep 19, 2026

    @georgesittas
    Collaborator

    Hi @Kunal8954,

    The team's bandwidth is limited, which means we can't spend too much time reviewing AI-generated PRs that may not align with the codebase's conventions, look low-effort, or where the solution is more complicated than we'd like.

    Our contribution guideline is also clear: we expect the time we invest in reviewing to help people learn the right patterns and understand the codebase over time. Having agents solve issues does not help with this, even if you understand their output. We also use AI and can have it solve issues, so why not just do that and spend time iterating on misaligned PRs?

    Using AI is not a problem on its own. The issue is that we're flooded with countless such PRs every day, many of which are one-off by people that aren't an active part of the community, and this creates a DDoS effect on the core team.

    Finally, contributing in an open-source project requires effort and there are various ways to do it: discuss issues on the community Slack, pick up simpler issues and create bite-sized PRs, communicate the intent to pick something up, spend time to properly understand the codebase, put effort into cleaning up slop and producing elegant/clean solutions to problems, etc.

  9. Kunal8954 commented on Sep 19, 2026

    @Kunal8954
    Contributor

    Thanks for the feedback. I understand the concern and I’ll keep that in mind going forward.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions