Skip to content

Commit 0b5646d

Browse files
authored
Validate check name is unique (#429)
Validate that check name is unique before starting the migration.
1 parent 9922e5f commit 0b5646d

File tree

3 files changed

+79
-5
lines changed

3 files changed

+79
-5
lines changed

pkg/migrations/op_set_check.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99

1010
"github.com/lib/pq"
11+
1112
"github.com/xataio/pgroll/pkg/db"
1213
"github.com/xataio/pgroll/pkg/schema"
1314
)
@@ -58,6 +59,18 @@ func (o *OpSetCheckConstraint) Validate(ctx context.Context, s *schema.Schema) e
5859
}
5960
}
6061

62+
table := s.GetTable(o.Table)
63+
if table == nil {
64+
return TableDoesNotExistError{Name: o.Table}
65+
}
66+
67+
if table.ConstraintExists(o.Check.Name) {
68+
return ConstraintAlreadyExistsError{
69+
Table: table.Name,
70+
Constraint: o.Check.Name,
71+
}
72+
}
73+
6174
if o.Up == "" {
6275
return FieldRequiredError{Name: "up"}
6376
}

pkg/migrations/op_set_check_test.go

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import (
66
"database/sql"
77
"testing"
88

9-
"github.com/xataio/pgroll/internal/testutils"
10-
119
"github.com/stretchr/testify/assert"
10+
11+
"github.com/xataio/pgroll/internal/testutils"
1212
"github.com/xataio/pgroll/pkg/migrations"
1313
)
1414

@@ -543,6 +543,67 @@ func TestSetCheckConstraint(t *testing.T) {
543543
ColumnMustHaveComment(t, db, schema, "posts", "title", "the title of the post")
544544
},
545545
},
546+
{
547+
name: "validate that check constraint name is unique",
548+
migrations: []migrations.Migration{
549+
{
550+
Name: "01_add_table",
551+
Operations: migrations.Operations{
552+
&migrations.OpCreateTable{
553+
Name: "posts",
554+
Columns: []migrations.Column{
555+
{
556+
Name: "id",
557+
Type: "serial",
558+
Pk: ptr(true),
559+
},
560+
{
561+
Name: "title",
562+
Type: "text",
563+
},
564+
},
565+
},
566+
},
567+
},
568+
{
569+
Name: "02_add_check_constraint",
570+
Operations: migrations.Operations{
571+
&migrations.OpAlterColumn{
572+
Table: "posts",
573+
Column: "title",
574+
Check: &migrations.CheckConstraint{
575+
Name: "check_title_length",
576+
Constraint: "length(title) > 3",
577+
},
578+
Up: "(SELECT CASE WHEN length(title) <= 3 THEN LPAD(title, 4, '-') ELSE title END)",
579+
Down: "title",
580+
},
581+
},
582+
},
583+
{
584+
Name: "03_add_check_constraint_again",
585+
Operations: migrations.Operations{
586+
&migrations.OpAlterColumn{
587+
Table: "posts",
588+
Column: "title",
589+
Check: &migrations.CheckConstraint{
590+
Name: "check_title_length",
591+
Constraint: "length(title) > 3",
592+
},
593+
Up: "(SELECT CASE WHEN length(title) <= 3 THEN LPAD(title, 4, '-') ELSE title END)",
594+
Down: "title",
595+
},
596+
},
597+
},
598+
},
599+
wantStartErr: migrations.ConstraintAlreadyExistsError{
600+
Table: "posts",
601+
Constraint: "check_title_length",
602+
},
603+
afterStart: func(t *testing.T, db *sql.DB, schema string) {},
604+
afterRollback: func(t *testing.T, db *sql.DB, schema string) {},
605+
afterComplete: func(t *testing.T, db *sql.DB, schema string) {},
606+
},
546607
})
547608
}
548609

pkg/state/state.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,13 +542,13 @@ func (s *State) Start(ctx context.Context, schemaname string, migration *migrati
542542
return nil, err
543543
}
544544

545-
var schema schema.Schema
546-
err = json.Unmarshal([]byte(rawSchema), &schema)
545+
var unmarshalledSchema schema.Schema
546+
err = json.Unmarshal([]byte(rawSchema), &unmarshalledSchema)
547547
if err != nil {
548548
return nil, fmt.Errorf("unable to unmarshal schema: %w", err)
549549
}
550550

551-
return &schema, nil
551+
return &unmarshalledSchema, nil
552552
}
553553

554554
// Complete marks a migration as completed

0 commit comments

Comments
 (0)