23 conversions that passed review — and silently returned the wrong data
Every conversion below parses, runs, and looks correct — yet returns different result rows than the source query. Each was proven wrong by JarvisX’s credential-free execution oracle (the engine behind /prove) on a synthetic sample fixture. A syntax or compile check passes all of them. These are the defect classes real migrations ship — from hand-written SQL, a transpiler, or a raw LLM.
COUNT(DISTINCT) silently became COUNT() — a de-dup requirement was lost, inflating a reported total.
SELECT COUNT(DISTINCT cust_id) AS active_customers FROM orders
SELECT COUNT(cust_id) AS active_customers FROM orders
SELECT DISTINCT lost its DISTINCT — a dimension list now emits duplicates.
SELECT DISTINCT status FROM orders
SELECT status FROM orders
The HAVING clause was dropped in conversion — groups that should have been filtered now appear.
SELECT cust_id, COUNT(*) AS n FROM orders GROUP BY cust_id HAVING COUNT(*) > 1
SELECT cust_id, COUNT(*) AS n FROM orders GROUP BY cust_id
A LEFT JOIN became an INNER JOIN — unmatched driving-table rows silently disappear.
SELECT o.cust_id, o.amount FROM orders o LEFT JOIN refunds r ON o.cust_id = r.cust_id
SELECT o.cust_id, o.amount FROM orders o INNER JOIN refunds r ON o.cust_id = r.cust_id
Date-difference arguments were reversed in conversion — every duration comes out negated.
SELECT (ship_date - order_date) AS lead_days FROM orders
SELECT DATEDIFF('day', ship_date, order_date) AS lead_days FROM ordersORDER BY direction flipped on a top-1 query — it returns the smallest where the source returned the largest.
SELECT cust_id FROM orders ORDER BY amount DESC LIMIT 1
SELECT cust_id FROM orders ORDER BY amount ASC LIMIT 1
An IN-list lost members during conversion — rows that should qualify are excluded.
SELECT COUNT(*) AS n FROM orders WHERE cust_id IN (1, 2, 3, 4, 5)
SELECT COUNT(*) AS n FROM orders WHERE cust_id IN (1, 2, 3)
>= became > — records exactly on the threshold are silently excluded.
SELECT COUNT(*) AS n FROM orders WHERE cust_id >= 3
SELECT COUNT(*) AS n FROM orders WHERE cust_id > 3
SUM was pointed at the wrong column in conversion — the total is of price, not amount.
SELECT SUM(amount) AS revenue FROM orders
SELECT SUM(price) AS revenue FROM orders
BETWEEN (inclusive) became strict < / > — the endpoints are silently dropped.
SELECT COUNT(*) AS n FROM orders WHERE cust_id BETWEEN 2 AND 4
SELECT COUNT(*) AS n FROM orders WHERE cust_id > 2 AND cust_id < 4
A LIMIT (likely a leftover sampling clause) was introduced — the result set is cut short.
SELECT cust_id, amount FROM orders
SELECT cust_id, amount FROM orders LIMIT 5
An extra self-join inflates the row count through fan-out on a non-unique key.
SELECT COUNT(*) AS n FROM orders
SELECT COUNT(*) AS n FROM orders o1 JOIN orders o2 ON o1.cust_id = o2.cust_id
MAX was converted to MIN — the query now reports the opposite extreme.
SELECT MAX(amount) AS peak FROM orders
SELECT MIN(amount) AS peak FROM orders
A CASE threshold moved from >= to > — a whole boundary bucket is misclassified.
SELECT SUM(CASE WHEN cust_id >= 3 THEN 1 ELSE 0 END) AS flagged FROM orders
SELECT SUM(CASE WHEN cust_id > 3 THEN 1 ELSE 0 END) AS flagged FROM orders
Missing parentheses changed AND/OR precedence — the predicate now matches a different set.
SELECT COUNT(*) AS n FROM orders WHERE (cust_id = 1 OR cust_id = 2) AND amount > 0
SELECT COUNT(*) AS n FROM orders WHERE cust_id = 1 OR cust_id = 2 AND amount > 0
A <> filter was converted to = — the query returns the complement of what was intended.
SELECT COUNT(*) AS n FROM orders WHERE cust_id <> 3
SELECT COUNT(*) AS n FROM orders WHERE cust_id = 3
COUNT(DISTINCT region_id) lost DISTINCT — a cardinality metric is overstated.
SELECT COUNT(DISTINCT region_id) AS regions FROM orders
SELECT COUNT(region_id) AS regions FROM orders
> became >= — records on the boundary are now wrongly included.
SELECT COUNT(*) AS n FROM orders WHERE cust_id > 3
SELECT COUNT(*) AS n FROM orders WHERE cust_id >= 3
SUM(amount) was converted to COUNT(*) — a monetary total became a row count.
SELECT SUM(amount) AS total FROM orders
SELECT COUNT(*) AS total FROM orders
A < filter was converted to > — the query returns the opposite tail of the distribution.
SELECT COUNT(*) AS n FROM orders WHERE cust_id < 3
SELECT COUNT(*) AS n FROM orders WHERE cust_id > 3
A GROUP BY dimension was dropped — rows collapse to a coarser grain than intended.
SELECT region, status, COUNT(*) AS n FROM orders GROUP BY region, status
SELECT region, COUNT(*) AS n FROM orders GROUP BY region
COUNT(DISTINCT concat) collapsed to COUNT — a composite-cardinality metric is inflated.
SELECT COUNT(DISTINCT region_id) AS n FROM refunds
SELECT COUNT(region_id) AS n FROM refunds
An INNER JOIN became a LEFT JOIN — unmatched rows with NULLs are silently introduced.
SELECT COUNT(*) AS n FROM refunds r INNER JOIN orders o ON r.cust_id = o.cust_id
SELECT COUNT(*) AS n FROM refunds r LEFT JOIN orders o ON r.cust_id = o.cust_id
Prove your own — free
Paste a source query and its conversion from any tool. JarvisX independently proves whether they return the same rows — no signup, no production access, nothing leaves your boundary.
Prove a conversion — free →Reproducible: this corpus is generated by an open harness (benchmark/gtm_silent_bugs.py) that runs each conversion through the same execution oracle and keeps only the ones it can prove wrong on the fixture.
