Skip to content

fix: fail with QueryBuilderError instead of throwing on unusable values - #42

Merged
Makisuo merged 2 commits into
fix/arith-argument-parensfrom
fix/typed-errors-not-throws
Oct 23, 2026
Merged

Makisuo merged 2 commits into
fix/arith-argument-parensfrom
fix/typed-errors-not-throws

Conversation

@Makisuo

@Makisuo Makisuo commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

The hostile-value fuzzer found compile paths that threw a raw TypeError/RangeError instead of failing:

Input Was
bigint compared with a String column describe() → JSON.stringify throws
non-string like/notLike/ilike pattern pattern.toFragment is not a function
lit({}), lit(Symbol()) wrote [object Object]; lit(0n) threw on Math.abs
non-numeric arithmetic operand Cannot read properties of undefined (reading 'schema')
invalid Date operand IllegalArgumentError: Invalid date
unparseable string / invalid Date for a Postgres timestamp RangeError: Invalid time value from toISOString
non-expression in a select record selectExprs[alias].toFragment is not a function

Values a request can supply now fail as QueryBuilderError InvalidLiteral. A select record's shape is written in source, so it is a QueryBuilderDefect naming the alias — the rule in errors.ts, like a malformed orderBy.

Verification: failure.test.ts cases for each; hostile fuzz (now also at lit and arithmetic sites) at 200× with no known issues — 100k values per dialect; full suite.


Stack (merge bottom-up):

  1. test(fuzz): property-based fuzzer for the query builder #39 test(fuzz): property-based fuzzer for the query builder
  2. fix(clickhouse): write number literals that read back exactly #40 fix(clickhouse): write number literals that read back exactly
  3. fix: parenthesise an arithmetic expression passed as an argument #41 fix: parenthesise an arithmetic expression passed as an argument
  4. fix: fail with QueryBuilderError instead of throwing on unusable values #42 fix: fail with QueryBuilderError instead of throwing on unusable values
  5. fix: bare select() over a subquery or union selects every alias #43 fix: bare select() over a subquery or union selects every alias
  6. fix(clickhouse): cast array and map comparison literals to the column type #44 fix(clickhouse): cast array and map comparison literals to the column type
  7. fix(postgres): type the two placeholders Postgres would mistype #45 fix(postgres): type the two placeholders Postgres would mistype

🤖 Generated with Claude Code

The hostile-value fuzzer found compile paths that threw a raw TypeError or
RangeError instead of recording a failure:

- describe() formatted a bigint with JSON.stringify, which throws;
- like/notLike/ilike called .toFragment() on any non-string pattern;
- lit() wrote String(value) for a non-number, and Math.abs threw on a bigint;
- arithmetic read .schema off a non-numeric operand;
- an invalid Date reached DateTime.makeUnsafe;
- the Postgres timestamp codec checked strings on the encoded side only, so
  an unparseable string or invalid Date reached toISOString;
- a non-expression in a select record had .toFragment() called on it.

Values a request can supply now fail as QueryBuilderError InvalidLiteral;
a select record's shape is source, so it is a QueryBuilderDefect, as
errors.ts and the orderBy precedent say. The fuzzer gains `lit` and
arithmetic sites and accepts a defect only at source-shaped sites.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 3 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fb377e66-0c26-4a90-939a-e450f755d2d0
📥 Commits

Reviewing files that changed from the base of the PR and between 73dfb51 and 1ac7d0a.

📒 Files selected for processing: 9
  • .changeset/typed-errors-not-throws.md
  • src/ch/compile.ts
  • src/ch/expr.ts
  • src/ch/failure.test.ts
  • src/ch/literal.ts
  • src/pg/types.ts
  • tests/fuzz/compile.fuzz.test.ts
  • tests/fuzz/known-issues.ts
  • tests/fuzz/regressions.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Makisuo
Makisuo added this pull request to stack #46 October 23, 2026 00:18
@Makisuo Makisuo changed the title fix: fail with QueryBuilderError instead of throwing on unusable values fix: parenthesise an arithmetic expression passed as an argument Oct 23, 2026
@Makisuo Makisuo changed the title fix: parenthesise an arithmetic expression passed as an argument fix: fail with QueryBuilderError instead of throwing on unusable values Oct 23, 2026
@Makisuo
Makisuo merged commit ed8f7b4 into main Oct 23, 2026
5 checks passed
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.

1 participant