package sqlite import ( "strconv" "strings" "testing" "github.com/sqlc-dev/sqlc/internal/sql/ast" "github.com/sqlc-dev/sqlc/internal/sql/catalog" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" ) func TestUpdate(t *testing.T) { p := NewParser() for i, tc := range []struct { stmt string s *catalog.Schema }{ { ` CREATE TABLE foo (bar text); `, &catalog.Schema{ Name: "main", Tables: []*catalog.Table{ { Rel: &ast.TableName{Name: "foo"}, Columns: []*catalog.Column{ { Name: "bar", Type: ast.TypeName{Name: "text"}, }, }, }, }, }, }, { ` CREATE TABLE foo (bar text); ALTER TABLE foo RENAME TO baz; `, &catalog.Schema{ Name: "main", Tables: []*catalog.Table{ { Rel: &ast.TableName{Name: "baz"}, Columns: []*catalog.Column{ { Name: "bar", Type: ast.TypeName{Name: "text"}, }, }, }, }, }, }, { ` CREATE TABLE foo (bar text); ALTER TABLE foo ADD COLUMN baz bool; `, &catalog.Schema{ Name: "main", Tables: []*catalog.Table{ { Rel: &ast.TableName{Name: "foo"}, Columns: []*catalog.Column{ { Name: "bar", Type: ast.TypeName{Name: "text"}, }, { Name: "baz", Type: ast.TypeName{Name: "bool"}, }, }, }, }, }, }, { ` CREATE TABLE foo (bar text); ALTER TABLE foo RENAME COLUMN bar TO baz; `, &catalog.Schema{ Name: "main", Tables: []*catalog.Table{ { Rel: &ast.TableName{Name: "foo"}, Columns: []*catalog.Column{ { Name: "baz", Type: ast.TypeName{Name: "text"}, }, }, }, }, }, }, { ` CREATE TABLE foo (bar text); ALTER TABLE foo RENAME bar TO baz; `, &catalog.Schema{ Name: "main", Tables: []*catalog.Table{ { Rel: &ast.TableName{Name: "foo"}, Columns: []*catalog.Column{ { Name: "baz", Type: ast.TypeName{Name: "text"}, }, }, }, }, }, }, { ` ATTACH ':memory:' as ns; CREATE TABLE ns.foo (bar text); `, &catalog.Schema{ Name: "ns", Tables: []*catalog.Table{ { Rel: &ast.TableName{Schema: "ns", Name: "foo"}, Columns: []*catalog.Column{ { Name: "bar", Type: ast.TypeName{Name: "text"}, }, }, }, }, }, }, { ` ATTACH ':memory:' as ns; CREATE TABLE ns.foo (bar text); ALTER TABLE ns.foo RENAME TO baz; `, &catalog.Schema{ Name: "ns", Tables: []*catalog.Table{ { Rel: &ast.TableName{Schema: "ns", Name: "baz"}, Columns: []*catalog.Column{ { Name: "bar", Type: ast.TypeName{Name: "text"}, }, }, }, }, }, }, { ` ATTACH ':memory:' as ns; CREATE TABLE ns.foo (bar text); ALTER TABLE ns.foo ADD COLUMN baz bool; `, &catalog.Schema{ Name: "ns", Tables: []*catalog.Table{ { Rel: &ast.TableName{Schema: "ns", Name: "foo"}, Columns: []*catalog.Column{ { Name: "bar", Type: ast.TypeName{Name: "text"}, }, { Name: "baz", Type: ast.TypeName{Name: "bool"}, }, }, }, }, }, }, { ` ATTACH ':memory:' as ns; CREATE TABLE ns.foo (bar text); ALTER TABLE ns.foo RENAME COLUMN bar TO baz; `, &catalog.Schema{ Name: "ns", Tables: []*catalog.Table{ { Rel: &ast.TableName{Schema: "ns", Name: "foo"}, Columns: []*catalog.Column{ { Name: "baz", Type: ast.TypeName{Name: "text"}, }, }, }, }, }, }, { ` ATTACH ':memory:' as ns; CREATE TABLE ns.foo (bar text); ALTER TABLE ns.foo RENAME bar TO baz; `, &catalog.Schema{ Name: "ns", Tables: []*catalog.Table{ { Rel: &ast.TableName{Schema: "ns", Name: "foo"}, Columns: []*catalog.Column{ { Name: "baz", Type: ast.TypeName{Name: "text"}, }, }, }, }, }, }, } { test := tc t.Run(strconv.Itoa(i), func(t *testing.T) { stmts, err := p.Parse(strings.NewReader(test.stmt)) if err != nil { t.Log(test.stmt) t.Fatal(err) } c := newTestCatalog() if err := c.Build(stmts); err != nil { t.Log(test.stmt) t.Fatal(err) } e := newTestCatalog() if test.s != nil { var replaced bool for i := range e.Schemas { if e.Schemas[i].Name == test.s.Name { e.Schemas[i] = test.s replaced = true break } } if !replaced { e.Schemas = append(e.Schemas, test.s) } } if diff := cmp.Diff(e, c, cmpopts.EquateEmpty(), cmpopts.IgnoreUnexported(catalog.Column{})); diff != "" { t.Log(test.stmt) t.Errorf("catalog mismatch:\n%s", diff) } }) } }