2
0

atomic_storage_test.go 1.0 KB

123456789101112131415161718192021222324252627282930313233
  1. package executor
  2. import (
  3. "errors"
  4. "testing"
  5. "github.com/danfragoso/pizzasql-next/pkg/storage"
  6. )
  7. func TestStorageScanUpdateCommitConflictHasNoPartialEffects(t *testing.T) {
  8. _, schema, table := newTestDB(t)
  9. e := newExec(schema, table)
  10. other := newExec(schema, table)
  11. execMust(t, e, "CREATE TABLE t (id INTEGER PRIMARY KEY, v TEXT)")
  12. execMust(t, e, "INSERT INTO t VALUES (1,'old'),(2,'old')")
  13. raced := false
  14. count, err := table.UpdateFunc("t", func(storage.Row) (storage.Row, error) {
  15. if !raced {
  16. raced = true
  17. execMust(t, other, "UPDATE t SET v='external' WHERE id=2")
  18. }
  19. return storage.Row{"v": "staged"}, nil
  20. }, nil)
  21. if !errors.Is(err, storage.ErrSerialization) || count != 0 {
  22. t.Fatalf("update returned count=%d err=%v", count, err)
  23. }
  24. if got := execMust(t, e, "SELECT v FROM t WHERE id=1").Rows[0][0]; got != "old" {
  25. t.Fatalf("conflicted batch published earlier row: %v", got)
  26. }
  27. if got := execMust(t, e, "SELECT v FROM t WHERE id=2").Rows[0][0]; got != "external" {
  28. t.Fatalf("conflicted batch overwrote concurrent writer: %v", got)
  29. }
  30. }