diff --git a/pkg/migrations/errors.go b/pkg/migrations/errors.go index db22f82..2945bfa 100644 --- a/pkg/migrations/errors.go +++ b/pkg/migrations/errors.go @@ -36,6 +36,15 @@ func (e ColumnDoesNotExistError) Error() string { return fmt.Sprintf("column %q does not exist on table %q", e.Name, e.Table) } +type ColumnIsNotNullableError struct { + Table string + Name string +} + +func (e ColumnIsNotNullableError) Error() string { + return fmt.Sprintf("column %q on table %q is NOT NULL", e.Name, e.Table) +} + type IndexAlreadyExistsError struct { Name string } diff --git a/pkg/migrations/op_set_notnull.go b/pkg/migrations/op_set_notnull.go index 2a07421..eb47a3d 100644 --- a/pkg/migrations/op_set_notnull.go +++ b/pkg/migrations/op_set_notnull.go @@ -171,10 +171,15 @@ func (o *OpSetNotNull) Validate(ctx context.Context, s *schema.Schema) error { return TableDoesNotExistError{Name: o.Table} } - if table.GetColumn(o.Column) == nil { + column := table.GetColumn(o.Column) + if column == nil { return ColumnDoesNotExistError{Table: o.Table, Name: o.Column} } + if !column.Nullable { + return ColumnIsNotNullableError{Table: o.Table, Name: o.Column} + } + if o.Up == nil { return FieldRequiredError{Name: "up"} } diff --git a/pkg/migrations/op_set_notnull_test.go b/pkg/migrations/op_set_notnull_test.go index d143f00..42499b4 100644 --- a/pkg/migrations/op_set_notnull_test.go +++ b/pkg/migrations/op_set_notnull_test.go @@ -239,5 +239,51 @@ func TestSetNotNullValidation(t *testing.T) { }, wantStartErr: migrations.ColumnDoesNotExistError{Table: "reviews", Name: "doesntexist"}, }, + { + name: "column is nullable", + migrations: []migrations.Migration{ + { + Name: "01_add_table", + Operations: migrations.Operations{ + &migrations.OpCreateTable{ + Name: "reviews", + Columns: []migrations.Column{ + { + Name: "id", + Type: "serial", + PrimaryKey: true, + }, + { + Name: "username", + Type: "text", + Nullable: false, + }, + { + Name: "product", + Type: "text", + Nullable: false, + }, + { + Name: "review", + Type: "text", + Nullable: false, + }, + }, + }, + }, + }, + { + Name: "02_set_not_null", + Operations: migrations.Operations{ + &migrations.OpSetNotNull{ + Table: "reviews", + Column: "review", + Up: ptr("product || ' is good'"), + }, + }, + }, + }, + wantStartErr: migrations.ColumnIsNotNullableError{Table: "reviews", Name: "review"}, + }, }) }