ddl_defaults_test.go 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package executor
  2. import (
  3. "errors"
  4. "testing"
  5. "github.com/danfragoso/pizzasql-next/pkg/pgerror"
  6. )
  7. // Non-constant defaults cannot be stored in the schema catalog without freezing
  8. // their value at DDL time, so they must be rejected instead of silently
  9. // producing a constant.
  10. func TestCreateTableRejectsNonConstantDefaults(t *testing.T) {
  11. _, schema, table := newTestDB(t)
  12. e := newExec(schema, table)
  13. for _, sql := range []string{
  14. "CREATE TABLE t1 (id INTEGER PRIMARY KEY, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)",
  15. "CREATE TABLE t2 (id INTEGER PRIMARY KEY, created_at TIMESTAMP DEFAULT datetime('now'))",
  16. "CREATE TABLE t3 (id INTEGER PRIMARY KEY, token TEXT DEFAULT lower('X'))",
  17. } {
  18. if _, err := execSQL(e, sql); !errors.Is(err, pgerror.ErrFeatureNotSupported) {
  19. t.Fatalf("%s: error = %v, want ErrFeatureNotSupported", sql, err)
  20. }
  21. }
  22. }
  23. func TestAlterTableRejectsNonConstantDefault(t *testing.T) {
  24. _, schema, table := newTestDB(t)
  25. e := newExec(schema, table)
  26. execMust(t, e, "CREATE TABLE t (id INTEGER PRIMARY KEY)")
  27. if _, err := execSQL(e, "ALTER TABLE t ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP"); !errors.Is(err, pgerror.ErrFeatureNotSupported) {
  28. t.Fatalf("ALTER error = %v, want ErrFeatureNotSupported", err)
  29. }
  30. }
  31. func TestConstantDefaultsStillApplyOnInsert(t *testing.T) {
  32. _, schema, table := newTestDB(t)
  33. e := newExec(schema, table)
  34. execMust(t, e, "CREATE TABLE t (id INTEGER PRIMARY KEY, label TEXT DEFAULT 'new', score INTEGER DEFAULT -1, flag BOOLEAN DEFAULT false, note TEXT DEFAULT NULL)")
  35. execMust(t, e, "INSERT INTO t (id) VALUES (1)")
  36. res := execMust(t, e, "SELECT label, score, flag, note FROM t WHERE id = 1")
  37. if res.RowCount != 1 {
  38. t.Fatalf("row count = %d, want 1", res.RowCount)
  39. }
  40. if got := res.Rows[0][0]; got != "new" {
  41. t.Fatalf("label = %v, want new", got)
  42. }
  43. if got := res.Rows[0][1]; got != int64(-1) {
  44. t.Fatalf("score = %v (%T), want int64(-1)", got, got)
  45. }
  46. if got := res.Rows[0][2]; got != false {
  47. t.Fatalf("flag = %v, want false", got)
  48. }
  49. if got := res.Rows[0][3]; got != nil {
  50. t.Fatalf("note = %v, want NULL", got)
  51. }
  52. }
  53. func TestAlterTableAddColumnDoesNotBackfill(t *testing.T) {
  54. _, schema, table := newTestDB(t)
  55. e := newExec(schema, table)
  56. execMust(t, e, "CREATE TABLE t (id INTEGER PRIMARY KEY)")
  57. execMust(t, e, "INSERT INTO t (id) VALUES (1)")
  58. execMust(t, e, "ALTER TABLE t ADD COLUMN status TEXT DEFAULT 'pending'")
  59. res := execMust(t, e, "SELECT id, status FROM t WHERE id = 1")
  60. if res.RowCount != 1 {
  61. t.Fatalf("row count = %d, want 1", res.RowCount)
  62. }
  63. if got := res.Rows[0][1]; got != nil {
  64. t.Fatalf("existing row status = %v, want NULL (ADD COLUMN does not backfill)", got)
  65. }
  66. execMust(t, e, "INSERT INTO t (id) VALUES (2)")
  67. res = execMust(t, e, "SELECT status FROM t WHERE id = 2")
  68. if got := res.Rows[0][0]; got != "pending" {
  69. t.Fatalf("new row status = %v, want pending", got)
  70. }
  71. }