Summary
In dolt sql -q / dolt sql -f (CLI batch mode, no server), EXECUTE of a prepared write statement (UPDATE, INSERT) reports success but applies nothing. Prepared reads (SELECT) execute and return results, and the identical statements run directly apply fine — so scripts using SET @sql = ...; PREPARE stmt FROM @sql; EXECUTE stmt (the standard MySQL idiom for conditional migrations) silently lose their writes.
Steps to reproduce
dolt init --name t --email t@t
dolt sql -q "CREATE TABLE t2 (id VARCHAR(64) PRIMARY KEY, val INT); INSERT INTO t2 VALUES ('a',1);"
# Prepared UPDATE: no error, no effect
dolt sql -q "PREPARE s FROM 'UPDATE t2 SET val=9 WHERE id=''a'''; EXECUTE s; DEALLOCATE PREPARE s;"
dolt sql -q "SELECT val FROM t2 WHERE id='a'" -r csv # => 1 (expected 9)
# Same via a user variable (the conditional-migration idiom): same silent no-op
dolt sql -q "SET @sql='UPDATE t2 SET val=8 WHERE id=''a'''; PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;"
dolt sql -q "SELECT val FROM t2 WHERE id='a'" -r csv # => 1 (expected 8)
# Prepared INSERT: same
dolt sql -q "PREPARE s FROM 'INSERT INTO t2 VALUES (''b'',2)'; EXECUTE s;"
dolt sql -q "SELECT COUNT(*) FROM t2" -r csv # => 1 (expected 2)
# Controls: prepared SELECT works; direct UPDATE works
dolt sql -q "PREPARE s FROM 'SELECT COUNT(*) AS n FROM t2'; EXECUTE s;" # returns a result
dolt sql -q "UPDATE t2 SET val=5 WHERE id='a';"
dolt sql -q "SELECT val FROM t2 WHERE id='a'" -r csv # => 5
Expected
EXECUTE of a prepared DML statement applies the write (or errors); it must not report success while changing nothing.
Observed
No error, no warning, zero effect. Reproduced on dolt 2.2.0 and 2.2.2 (linux-amd64), fresh dolt init database, no sql-server involved.
Impact
We hit this via a schema-migration file using the SET @sql = IF(<condition>, '<UPDATE ...>', 'SELECT 1'); PREPARE/EXECUTE idiom, applied through dolt sql -f: the migration's direct statements applied and its prepared recompute silently didn't, leaving derived state (a blocked-flag column) zeroed. Because nothing errors, the corruption is invisible until downstream behavior breaks.
claude-fable-5-xhigh on behalf of maphew
Summary
In
dolt sql -q/dolt sql -f(CLI batch mode, no server),EXECUTEof a prepared write statement (UPDATE, INSERT) reports success but applies nothing. Prepared reads (SELECT) execute and return results, and the identical statements run directly apply fine — so scripts usingSET @sql = ...; PREPARE stmt FROM @sql; EXECUTE stmt(the standard MySQL idiom for conditional migrations) silently lose their writes.Steps to reproduce
Expected
EXECUTEof a prepared DML statement applies the write (or errors); it must not report success while changing nothing.Observed
No error, no warning, zero effect. Reproduced on dolt 2.2.0 and 2.2.2 (linux-amd64), fresh
dolt initdatabase, no sql-server involved.Impact
We hit this via a schema-migration file using the
SET @sql = IF(<condition>, '<UPDATE ...>', 'SELECT 1'); PREPARE/EXECUTEidiom, applied throughdolt sql -f: the migration's direct statements applied and its prepared recompute silently didn't, leaving derived state (a blocked-flag column) zeroed. Because nothing errors, the corruption is invisible until downstream behavior breaks.claude-fable-5-xhigh on behalf of maphew