tursodatabase/turso · error
ranked row count mismatch
Error message
ranked row count mismatch
What it means
validate_result compares the rows returned by the benchmark query against a count recomputed from the seeded data predicate. For QueryCase::Ranked, expected rows are capped by the LIMIT 10 of the ranked query and multiplied by the number of query executions; ensure! at perf/fts/src/main.rs:333 fails when the observed row count differs, meaning the engine returned a different result set than the model predicts.
Solutions
- Re-run with a single query (--queries 1) to isolate whether the mismatch is per-query or aggregate
- Diff the actual returned rows against ids.filter(predicate).take(10) to see what is missing/extra
- Check for concurrent writers or MVCC snapshot differences between seeding and validation
- Update validate_result if the query's LIMIT or predicate legitimately changed
Example fix
// before (assumes no cap) assert_eq!(rows, expected_rows * queries); // after (ranked queries are LIMIT 10) assert_eq!(rows, expected_rows.min(10) * queries);
Defensive patterns
Strategy: try-catch
Validate before calling
// compute expectation locally before validating let expected: usize = (0..n).filter(|&id| id % 2 == 0 || id % 3 == 0).count().min(10) * queries;
Try / catch
match validate_result(...) {
Err(e) if e.to_string().contains("ranked row count mismatch") => {
// dump actual vs expected rows for diagnosis
eprintln!("ranked mismatch: got {rows}, want {expected}");
}
other => other?,
} Prevention
- Ensure seeding completes and is visible before validation queries run
- Keep validate_result's predicate in sync with the emitted query LIMIT
- Avoid concurrent writers during validation runs
- Reproduce mismatches with --queries 1 first
When it happens
Trigger: Calling validate_result with case == Ranked where rows != expected_rows.min(10) * queries — i.e. the FTS engine returned more or fewer matching rows than the capped expectation, typically indicating a query engine, ranking/LIMIT, or MVCC visibility discrepancy.
Common situations: Running the validation under WAL/MVCC where visibility differs; a Turso FTS bug returning duplicate or missing rows; changing the LIMIT or query text without updating validate_result; concurrency races writing rows between seed and validation.
Related errors
- row count mismatch for
- connections must be positive
- documents must be positive
- ID sum mismatch for
- index contains segment bytes, below requested minimum …
AI-assisted analysis of tursodatabase/turso@8d4a589f8d (2026-09-20).
Data as JSON: /api/errors/3eec1581705b010d.
Report an issue: GitHub.
Appendix: source
Thrown at perf/fts/src/main.rs:333
}
fn validate_result(
case: QueryCase,
documents: usize,
queries: usize,
rows: usize,
sum: i64,
) -> Result<()> {
let ids = (0..documents).filter(|id| match case {
QueryCase::Rare => id % 100 == 0,
QueryCase::Common => true,
QueryCase::And => id % 6 == 0,
QueryCase::Or | QueryCase::Ranked => id % 2 == 0 || id % 3 == 0,
QueryCase::Phrase => id % 200 == 0,
});
let expected_rows = ids.clone().count();
if matches!(case, QueryCase::Ranked) {
ensure!(
rows == expected_rows.min(10) * queries,
"ranked row count mismatch"
);
} else {
ensure!(
rows == expected_rows * queries,
"row count mismatch for {case:?}"
);
ensure!(
sum == ids.map(|id| id as i64).sum::<i64>() * queries as i64,
"ID sum mismatch for {case:?}"
);
}
Ok(())
}
#[cfg(test)]
mod tests {View on GitHub (pinned to 8d4a589f8d)