mirror of
https://github.com/Gnucash/gnucash.git
synced 2026-10-25 07:37:39 -05:00
When an already-committed split is moved to another transaction with xaccSplitSetParent(), the split was marked dirty *after* the old transaction was committed. trans_cleanup_commit() only drops a moved-out split from the old transaction's split list when the split is dirty at that commit, so the still-clean split was left dangling in the old transaction's split list. On the SQL/DBI backends, destroying the now-vacated old transaction then deleted the moved split's KVP slots (online_id, cap-gains links, ...) by the split's own GUID, even though the split now belongs to another transaction. The split's native columns survive -- they are rewritten under the new tx_guid -- but its slots are lost; in some sequences the save fails outright with "UNIQUE constraint failed: transactions.guid". The XML backend is unaffected because it re-serializes the whole book. Mark the split dirty before committing the old transaction so trans_cleanup_commit() removes it from the old transaction's split list, as that code already intends. This is a no-op for split creation (the overwhelmingly common caller), where the prior parent is NULL. Add a DBI round-trip regression test (sqlite3, and mysql/pgsql when the TEST_*_URL variables are set): seed a split carrying an online_id, save and reload, reparent it onto another transaction, destroy the old transaction, then save and reload again and assert the online_id survived.