diff --git a/go/libraries/doltcore/migrate/integration_test.go b/go/libraries/doltcore/migrate/integration_test.go index 31bc3a361f..35138c913b 100644 --- a/go/libraries/doltcore/migrate/integration_test.go +++ b/go/libraries/doltcore/migrate/integration_test.go @@ -28,6 +28,8 @@ import ( "github.com/dolthub/dolt/go/libraries/doltcore/env" "github.com/dolthub/dolt/go/libraries/doltcore/migrate" "github.com/dolthub/dolt/go/libraries/doltcore/ref" + "github.com/dolthub/dolt/go/libraries/doltcore/schema" + "github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo" "github.com/dolthub/dolt/go/libraries/doltcore/sqle" "github.com/dolthub/dolt/go/store/chunks" "github.com/dolthub/dolt/go/store/datas" @@ -37,11 +39,16 @@ import ( type migrationTest struct { name string + hook setupHook setup []string asserts []assertion err string } +// a setupHook performs special setup operations that cannot +// be performed via SQL statements (eg TEXT type PRIMARY KEY) +type setupHook func(context.Context, *env.DoltEnv) (*env.DoltEnv, error) + type assertion struct { query string expected []sql.Row @@ -68,13 +75,42 @@ func TestMigration(t *testing.T) { }, }, }, + { + name: "TEXT primary key, BLOB secondary key", + hook: SetupHookRefKeys, + setup: []string{ + // from setup hook: + // CREATE TABLE test ( + // pk TEXT PRIMARY KEY, + // c0 int, + // c1 BLOB, + // INDEX blob_idx(c1), + // ); + "INSERT INTO test VALUES ('a', 2, 'a')", + "CALL dolt_add('.')", + "CALL dolt_commit('-am', 'new table')", + }, + asserts: []assertion{ + { + query: "SELECT * FROM test", + expected: []sql.Row{{"a", int32(2), []byte("a")}}, + }, + { + query: "DESCRIBE test", + expected: []sql.Row{ + {"pk", "varchar(16383)", "NO", "PRI", "NULL", ""}, + {"c0", "int", "YES", "", "NULL", ""}, + {"c1", "varbinary(16383)", "YES", "", "NULL", ""}, + }, + }, + }, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { ctx := context.Background() - preEnv := runSetupSql(t, ctx, test.setup) - + preEnv := setupMigrationTest(t, ctx, test) postEnv := runMigration(t, ctx, preEnv) ddb := postEnv.DoltDB @@ -89,16 +125,52 @@ func TestMigration(t *testing.T) { } } -func runSetupSql(t *testing.T, ctx context.Context, setup []string) *env.DoltEnv { +func setupMigrationTest(t *testing.T, ctx context.Context, test migrationTest) *env.DoltEnv { dEnv := dtestutils.CreateTestEnv() + + // run setup hook before other setup queries + if test.hook != nil { + var err error + dEnv, err = test.hook(ctx, dEnv) + require.NoError(t, err) + } + cmd := commands.SqlCmd{} - for _, query := range setup { + for _, query := range test.setup { code := cmd.Exec(ctx, cmd.Name(), []string{"-q", query}, dEnv) require.Equal(t, 0, code) } return dEnv } +func SetupHookRefKeys(ctx context.Context, dEnv *env.DoltEnv) (*env.DoltEnv, error) { + pk, _ := schema.NewColumnWithTypeInfo("pk", 1, typeinfo.TextType, true, "", false, "", schema.NotNullConstraint{}) + c0, _ := schema.NewColumnWithTypeInfo("c0", 2, typeinfo.Int32Type, false, "", false, "") + c1, _ := schema.NewColumnWithTypeInfo("c1", 3, typeinfo.BlobType, false, "", false, "") + + sch, err := schema.SchemaFromCols(schema.NewColCollection(pk, c0, c1)) + if err != nil { + return nil, err + } + _, err = sch.Indexes().AddIndexByColNames("blob_idx", []string{"c1"}, schema.IndexProperties{IsUserDefined: true}) + if err != nil { + return nil, err + } + + ws, err := dEnv.WorkingSet(ctx) + if err != nil { + return nil, err + } + root, err := ws.WorkingRoot().CreateEmptyTable(ctx, "test", sch) + if err != nil { + return nil, err + } + if err = dEnv.UpdateWorkingSet(ctx, ws.WithWorkingRoot(root)); err != nil { + return nil, err + } + return dEnv, nil +} + func runMigration(t *testing.T, ctx context.Context, preEnv *env.DoltEnv) (postEnv *env.DoltEnv) { ddb, err := initTestMigrationDB(ctx) require.NoError(t, err) diff --git a/go/libraries/doltcore/migrate/validation.go b/go/libraries/doltcore/migrate/validation.go index 3a7c53fe89..d367a2dc60 100644 --- a/go/libraries/doltcore/migrate/validation.go +++ b/go/libraries/doltcore/migrate/validation.go @@ -112,10 +112,6 @@ func validateTableDataPartition(ctx context.Context, name string, old, new *dolt if err != nil { return err } - // todo: validate schema equality - //if !doltdb.HasDoltPrefix(name) && !oldSch.Equals(newSch) { - // return fmt.Errorf("differing schemas for table %s", name) - //} var o, n sql.Row for { diff --git a/go/libraries/doltcore/schema/typeinfo/blobstring.go b/go/libraries/doltcore/schema/typeinfo/blobstring.go index 7f2b661a90..7a3d99ecc9 100644 --- a/go/libraries/doltcore/schema/typeinfo/blobstring.go +++ b/go/libraries/doltcore/schema/typeinfo/blobstring.go @@ -43,6 +43,13 @@ type blobStringType struct { var _ TypeInfo = (*blobStringType)(nil) +var ( + TinyTextType TypeInfo = &blobStringType{sqlStringType: sql.TinyText} + TextType TypeInfo = &blobStringType{sqlStringType: sql.Text} + MediumTextType TypeInfo = &blobStringType{sqlStringType: sql.MediumText} + LongTextType TypeInfo = &blobStringType{sqlStringType: sql.LongText} +) + func CreateBlobStringTypeFromParams(params map[string]string) (TypeInfo, error) { var length int64 var collation sql.CollationID diff --git a/go/libraries/doltcore/schema/typeinfo/varbinary.go b/go/libraries/doltcore/schema/typeinfo/varbinary.go index 32303eeb0a..67470d9d5d 100644 --- a/go/libraries/doltcore/schema/typeinfo/varbinary.go +++ b/go/libraries/doltcore/schema/typeinfo/varbinary.go @@ -45,6 +45,13 @@ type varBinaryType struct { var _ TypeInfo = (*varBinaryType)(nil) +var ( + TinyBlobType TypeInfo = &varBinaryType{sqlBinaryType: sql.TinyBlob} + BlobType TypeInfo = &varBinaryType{sqlBinaryType: sql.Blob} + MediumBlobType TypeInfo = &varBinaryType{sqlBinaryType: sql.MediumBlob} + LongBlobType TypeInfo = &varBinaryType{sqlBinaryType: sql.LongBlob} +) + func CreateVarBinaryTypeFromParams(params map[string]string) (TypeInfo, error) { var length int64 var err error