Skip to content

Fix bug where some oracles were not reporting their findings - #1364

Merged
mrigger merged 6 commits into
mainfrom
fix/reproducer
Sep 14, 2026
Merged

mrigger merged 6 commits into
mainfrom
fix/reproducer

Conversation

@tlmorgan24

@tlmorgan24 tlmorgan24 commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator

This PR solves a bug where any oracle supplying a reproducer would only report its findings when --use-reducer was enabled. This bug has been present since 2022 (commit 625204e), and I noticed it as I have been extending reproducer support to more oracles.

This meant the CI was not running correctly for some oracles (because the CI runs without --use-reducer). By solving this, the CI now runs correctly, which has surfaced some previously hidden defects. With the help of Claude, I then went on to fix those newly surfaced bugs for the affected DBMSs so the CI passes again:

  • HSQLDBExpressionGenerator.generateUnoptimizedQueryString cleared the WHERE clause and projected COUNT(*) without re-projecting the predicate, making the unoptimised side count every row of the table. It now projects the predicate per row.
  • CockroachDBExpressionGenerator.generateOptimizedQueryString projected a COUNT(*) column without using a GROUP BY, which returns a single row with the count. countRows was then called on this, which counts the number of rows, and therefore always counted one row instead of the actual underlying rows. CockroachDBExpressionGenerator.generateOptimizedQueryString now projects * instead of COUNT(*), so countRows counts the actual rows.
  • YSQLExpressionGenerator.generateOptimizedQueryString set the WHERE clause only in its non-aggregate branch, so the aggregate branch counted every row while the unoptimized side applied the predicate; the WHERE clause is now set for both. Finally, YSQLErrors was missing "character number must be positive" as an expected error (which is already listed for Postgres).

tlmorgan24 and others added 6 commits September 13, 2026 16:47
generateUnoptimizedQueryString projected COUNT(*) and cleared the WHERE
clause without re-projecting the predicate, so the unoptimized side
counted every row of the table regardless of the condition. Every run
whose predicate filtered anything therefore reported a mismatch.

Project the predicate per row instead, as the other NoREC generators do.
A CASE expression is used rather than a cast because HSQLDB does not
allow casting a BOOLEAN to an integer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G1XqNaswnH8mWTXFkkGa1X
generateOptimizedQueryString projected a literal COUNT(*) column in its
non-aggregate branch as well as in its aggregate one. NoRECOracle counts
the rows that branch returns, and an aggregate always returns exactly
one, so the optimized count was 1 whatever the predicate matched.

Project * in the non-aggregate branch, as PostgresExpressionGenerator
does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G1XqNaswnH8mWTXFkkGa1X
generateOptimizedQueryString set the WHERE clause only in its
non-aggregate branch, so the aggregate branch counted every row of the
table while the unoptimized side applied the predicate.

Set the WHERE clause for both branches.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G1XqNaswnH8mWTXFkkGa1X
The expression generator can produce chr() with a negative argument, on
which YSQL raises "character number must be positive". That error was
missing from YSQLErrors, so the oracle reported it as an unexpected
error rather than ignoring the statement.

PostgresCommon already lists it (PostgresCommon.java:87); YSQLErrors
otherwise mirrors that list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G1XqNaswnH8mWTXFkkGa1X
@tlmorgan24
tlmorgan24 requested a review from mrigger September 14, 2026 09:54

@mrigger mrigger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM! Sounds like quite a serious bug. Great that you have found and fixed it!

@mrigger
mrigger merged commit 4630c61 into main Sep 14, 2026
45 of 50 checks passed
@mrigger
mrigger deleted the fix/reproducer branch September 14, 2026 15:31
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.

2 participants