The shadow model was building WHERE predicates by manually nesting
Expr::Binary nodes, which caused AND/OR expressions to be evaluated
left-to-right instead of using SQLite’s precedence rules. Mixed
expressions like `a OR b AND c` were effectively generated as
`(a OR b) AND c`.
Update the predicate generator to use Predicate::and / Predicate::or
to combine context predicates, letting those helpers insert the
appropriate parentheses. This ensures that AND groups are formed
before OR and that the resulting Expr tree matches SQLite’s logical
evaluation order.
## Background
Simulator wants to create predicates that it knows will be Greater or
Less than some known value. It uses `LTValue` and `GTValue` for
generating these.
## Problem
Current implementation simply decrements or increments a random char by
1, and can thus generate strings with control characters like null
terminators that result in parse errors, as seen in e.g. this CI run htt
ps://github.com/tursodatabase/turso/actions/runs/18459131141/job/5258630
5749?pr=3702 of PR #3702
EDIT: I realized the _actual_ problem is in `GTValue` when it decides to
make the string longer, it uses a random char value from `0..255` which
can include null terminators etc. Fixed that too. I think in general
this PR's approach is a bit more predictable so let's keep it.
## Solution
Restrict string mutations to ascii string characters so that the
mutation always results in another ascii string character.
Closes#3708