Skip to content

Expression simplifier treats arithmetic negation as bitwise NOT #24665

Open

Description

@Amogh-2404

Describe the bug

Expr::Negative represents arithmetic negation, but the expression simplifier applies bitwise-NOT identities to it. This produces wrong results for expressions combining unary minus with bitwise AND, OR, or XOR.

The same path also distributes unary minus through bitwise expressions and removes nested negation without considering the expression type.

To Reproduce

SELECT i, (-i) & i, i | (-i), (-i) ^ i
FROM (VALUES (5), (6)) AS t(i);

Current result:

5  0  -1  -1
6  0  -1  -1

Expected result:

5  1  -1  -2
6  2  -2  -4

Generic double-negation removal can also hide overflow for checked types:

SELECT -(-arrow_cast(
  CAST(-9223372036854775808 AS BIGINT),
  'Timestamp(Nanosecond, None)'
));

The inner timestamp negation should report arithmetic overflow.

Expected behavior

Arithmetic negation should not use bitwise-complement identities.

Double negation may be cancelled only where negation is total and involutive: signed integers with wrapping semantics, floating-point values, valid decimals, and NULL. Timestamp and interval negation must remain explicit because it can overflow.

Additional context

Disabling the optimizer produces the correct bitwise results and preserves the timestamp overflow.

Signed integer scalar and array execution must use the same wrapping semantics. Pruning through signed negation must also account for the discontinuity at MIN.

Activity

  1. Amogh-2404 commented on Aug 25, 2026

    @Amogh-2404
    ContributorAuthor

    take

  2. added a commit that references this issue on Aug 27, 2026
    d2969bb
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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions