atomic_mutation_test.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package executor
  2. import (
  3. "reflect"
  4. "testing"
  5. )
  6. func checkAtomicMutations(t *testing.T, e *Executor) {
  7. t.Helper()
  8. execMust(t, e, "CREATE TABLE t (id INTEGER PRIMARY KEY, v TEXT, j TEXT)")
  9. execMust(t, e, `INSERT INTO t VALUES (1,'old','{"x":"new"}'),(2,'old','invalid')`)
  10. want := [][]interface{}{{int64(1), "old"}, {int64(2), "old"}}
  11. for _, sql := range []string{
  12. "UPDATE t SET v=json_extract(j,'$.x')",
  13. "UPDATE t SET v='new' WHERE json_extract(j,'$.x')='new'",
  14. "DELETE FROM t WHERE json_extract(j,'$.x')='new'",
  15. "UPDATE t SET v='new' RETURNING json_extract(j,'$.x')",
  16. "DELETE FROM t RETURNING json_extract(j,'$.x')",
  17. "UPDATE t SET id=CASE WHEN id=1 THEN 3 ELSE 3 END",
  18. } {
  19. if _, err := execSQL(e, sql); err == nil {
  20. t.Fatalf("%s: expected failure", sql)
  21. }
  22. if got := execMust(t, e, "SELECT id,v FROM t ORDER BY id").Rows; !reflect.DeepEqual(got, want) {
  23. t.Fatalf("%s left partial effects: %v", sql, got)
  24. }
  25. }
  26. execMust(t, e, "BEGIN")
  27. execMust(t, e, "INSERT INTO t VALUES (4,'before','{}')")
  28. if _, err := execSQL(e, "UPDATE t SET v=json_extract(j,'$.x') WHERE id<4"); err == nil {
  29. t.Fatal("expected failed in-transaction update")
  30. }
  31. execMust(t, e, "COMMIT")
  32. if got := execMust(t, e, "SELECT id,v FROM t WHERE id<4 ORDER BY id").Rows; !reflect.DeepEqual(got, want) {
  33. t.Fatalf("failed statement committed partial overlay: %v", got)
  34. }
  35. if got := execMust(t, e, "SELECT id FROM t WHERE id=4").RowCount; got != 1 {
  36. t.Fatal("earlier transaction work was lost")
  37. }
  38. }
  39. func TestAtomicMutationEvaluationAndReturning(t *testing.T) {
  40. _, schema, table := newTestDB(t)
  41. checkAtomicMutations(t, newExec(schema, table))
  42. }
  43. func TestAtomicMutationRealKV(t *testing.T) {
  44. e := newOptExec(t, "atomic_mutation_regressions")
  45. execSQL(e, "DROP TABLE IF EXISTS t")
  46. t.Cleanup(func() { execSQL(e, "DROP TABLE IF EXISTS t") })
  47. checkAtomicMutations(t, e)
  48. }