Skip to content

Preimage rewrite evaluates a volatile argument two times: floor(random() * 10) = 3 returns wrong results #26910

Open

Description

@adriangb

Describe the bug

The preimage rewrite in the expression simplifier copies the argument of the function. When the argument is volatile, the copy makes the query evaluate it two times per row, and the query returns wrong results.

floor(random() * 10) = 3 becomes random() * 10 >= 3 AND random() * 10 < 4. Each random() draws a new value, so about 28% of rows pass (0.7 × 0.4), not 10%.

To Reproduce

In datafusion-cli:

SELECT count(*) FROM generate_series(1, 1000000) WHERE floor(random() * 10) = 3;
-- 279881  (expected about 100000)

EXPLAIN SELECT count(*) FROM generate_series(1, 1000000) WHERE floor(random() * 10) = 3;
-- FilterExec predicate: random() * 10 >= 3 AND random() * 10 < 4

For comparison, a filter the rewrite does not touch gives the expected count:

SELECT count(*) FROM (SELECT floor(random() * 10) AS f FROM generate_series(1, 1000000)) WHERE f + 0 = 3;
-- 99997

Expected behavior

The rewrite does not apply when an argument is volatile. get_preimage in expr_simplifier.rs already checks that the function is immutable. It must also check args.iter().any(Expr::is_volatile).

Additional context

Found while working on #25459. The same fix is in the combined draft #26873, with sqllogictest cases in floor_preimage.slt. Related: #25457 (the same kind of copy in BETWEEN).

Activity

  1. ninglinLiu commented on Oct 29, 2026

    @ninglinLiu
    Contributor

    take

  2. vikrantmehta123 commented on Nov 1, 2026

    @vikrantmehta123
    Contributor

    Hi @adriangb , The issue still seems to be open and the fix is removed from the draft PR. Is it still open? Would it be alright be I attempted it as a first issue?

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions