diff --git a/internal/integration/testdata/sqlite/column-user-defined.txt b/internal/integration/testdata/sqlite/column-user-defined.txt new file mode 100644 index 00000000000..fcf96fe9fb4 --- /dev/null +++ b/internal/integration/testdata/sqlite/column-user-defined.txt @@ -0,0 +1,54 @@ +# Initial changes. +atlas schema apply --url URL --dev-url DEV_URL --to file://schema.v1.hcl --auto-approve +atlas schema apply --url URL --dev-url DEV_URL --to file://schema.v1.hcl --auto-approve +stdout 'Schema is synced, no changes to be made' +atlas schema inspect --url URL > got +cmp schema.v1.hcl.inspected got + +# Changing user defined type. +atlas schema apply --url URL --dev-url DEV_URL --to file://schema.v2.hcl --auto-approve +atlas schema apply --url URL --dev-url DEV_URL --to file://schema.v2.hcl --auto-approve +stdout 'Schema is synced, no changes to be made' +atlas schema inspect --url URL > got +cmp schema.v2.hcl.inspected got + +-- schema.v1.hcl -- +table "t" { + schema = schema.main + column "c" { + null = true + type = sql("USER_DEFINED") + } +} +schema "main" { +} +-- schema.v1.hcl.inspected -- +table "t" { + schema = schema.main + column "c" { + null = true + type = sql("USER_DEFINED") + } +} +schema "main" { +} +-- schema.v2.hcl -- +table "t" { + schema = schema.main + column "c" { + null = true + type = sql("USER_TYPE") + } +} +schema "main" { +} +-- schema.v2.hcl.inspected -- +table "t" { + schema = schema.main + column "c" { + null = true + type = sql("USER_TYPE") + } +} +schema "main" { +} \ No newline at end of file diff --git a/sql/sqlite/convert.go b/sql/sqlite/convert.go index 55ef8cb005c..a6fa876cfcf 100644 --- a/sql/sqlite/convert.go +++ b/sql/sqlite/convert.go @@ -41,6 +41,8 @@ func FormatType(t schema.Type) (string, error) { f = strings.ToLower(t.T) case *schema.UUIDType: f = strings.ToLower(t.T) + case *UserDefinedType: + f = t.T case *schema.UnsupportedType: return "", fmt.Errorf("sqlite: unsupported type: %q", t.T) default: @@ -102,6 +104,6 @@ func ParseType(c string) (schema.Type, error) { case "uuid": return &schema.UUIDType{T: t}, nil default: - return &schema.UnsupportedType{T: t}, nil + return &UserDefinedType{T: c}, nil } } diff --git a/sql/sqlite/diff.go b/sql/sqlite/diff.go index 60628ca40ee..c728b4bbba9 100644 --- a/sql/sqlite/diff.go +++ b/sql/sqlite/diff.go @@ -91,6 +91,10 @@ func (d *diff) typeChanged(from, to *schema.Column) (bool, error) { if fromT == nil || toT == nil { return false, fmt.Errorf("sqlite: missing type information for column %q", from.Name) } + if u1, ok := fromT.(*UserDefinedType); ok { + u2, ok := toT.(*UserDefinedType) + return !ok || u1.T != u2.T, nil + } // Types are mismatched if they do not have the same "type affinity". return reflect.TypeOf(fromT) != reflect.TypeOf(toT), nil } diff --git a/sql/sqlite/inspect.go b/sql/sqlite/inspect.go index 4677d32f796..2b56d7bbb85 100644 --- a/sql/sqlite/inspect.go +++ b/sql/sqlite/inspect.go @@ -515,6 +515,12 @@ type ( // // Deprecated: Use schema.UUIDType instead. UUIDType = schema.UUIDType + + // UserDefinedType defines a user-defined type attribute. + UserDefinedType struct { + schema.Type + T string + } ) func columnParts(t string) []string { diff --git a/sql/sqlite/sqlspec_test.go b/sql/sqlite/sqlspec_test.go index 8f83dfb5052..5a97fc853b4 100644 --- a/sql/sqlite/sqlspec_test.go +++ b/sql/sqlite/sqlspec_test.go @@ -344,7 +344,7 @@ func TestTypes(t *testing.T) { }, { typeExpr: `sql("custom")`, - expected: &schema.UnsupportedType{T: "custom"}, + expected: &UserDefinedType{T: "custom"}, }, { typeExpr: "tinyint(10)",