diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 0cdac6bfa2..1683e0f71f 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -737,6 +737,11 @@ func (db Database) DropTable(ctx *sql.Context, tableName string) error { return ErrSystemTableAlter.New(tableName) } + return db.dropTable(ctx, tableName) +} + +// dropTable drops the table with the name given, without any business logic checks +func (db Database) dropTable(ctx *sql.Context, tableName string) error { ds := dsess.DSessFromSess(ctx.Session) if _, ok := ds.GetTemporaryTable(ctx, db.Name(), tableName); ok { ds.DropTemporaryTable(ctx, db.Name(), tableName) diff --git a/go/libraries/doltcore/sqle/schema_table.go b/go/libraries/doltcore/sqle/schema_table.go index e98a2719e6..4e96a0323e 100644 --- a/go/libraries/doltcore/sqle/schema_table.go +++ b/go/libraries/doltcore/sqle/schema_table.go @@ -76,11 +76,7 @@ func getOrCreateDoltSchemasTable(ctx *sql.Context, db Database) (retTbl *Writabl schemasTable := tbl.(*WritableDoltTable) // Old schemas table contains the `id` column or is missing an `extra` column. if tbl.Schema().Contains(doltdb.SchemasTablesIdCol, doltdb.SchemasTableName) || !tbl.Schema().Contains(doltdb.SchemasTablesExtraCol, doltdb.SchemasTableName) { - root, err := db.GetRoot(ctx) - if err != nil { - return nil, err - } - return migrateOldSchemasTableToNew(ctx, db, root, schemasTable) + return migrateOldSchemasTableToNew(ctx, db, schemasTable) } else { return schemasTable, nil } @@ -110,7 +106,6 @@ func getOrCreateDoltSchemasTable(ctx *sql.Context, db Database) (retTbl *Writabl func migrateOldSchemasTableToNew( ctx *sql.Context, db Database, - root *doltdb.RootValue, schemasTable *WritableDoltTable, ) (newTable *WritableDoltTable, rerr error) { // Copy all of the old data over and add an index column and an extra column @@ -154,11 +149,16 @@ func migrateOldSchemasTableToNew( newRows = append(newRows, newRow) } - err = db.DropTable(ctx, doltdb.SchemasTableName) + err = db.dropTable(ctx, doltdb.SchemasTableName) if err != nil { return nil, err } + root, err := db.GetRoot(ctx) + if err != nil { + return nil, err + } + err = db.createDoltTable(ctx, doltdb.SchemasTableName, root, schemaTableSchema) if err != nil { return nil, err diff --git a/go/libraries/doltcore/sqle/schema_table_test.go b/go/libraries/doltcore/sqle/schema_table_test.go index 13c3e27675..b126813b09 100644 --- a/go/libraries/doltcore/sqle/schema_table_test.go +++ b/go/libraries/doltcore/sqle/schema_table_test.go @@ -16,6 +16,8 @@ package sqle import ( "context" + "encoding/json" + "io" "testing" "github.com/dolthub/go-mysql-server/sql" @@ -25,14 +27,11 @@ import ( "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils" - "github.com/dolthub/dolt/go/libraries/doltcore/row" "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" - "github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil" "github.com/dolthub/dolt/go/libraries/doltcore/table/editor" - "github.com/dolthub/dolt/go/store/types" ) -func TestSchemaTableRecreationOlder(t *testing.T) { +func TestSchemaTableMigrationOriginal(t *testing.T) { ctx := NewTestSQLCtx(context.Background()) dEnv := dtestutils.CreateTestEnv() tmpDir, err := dEnv.TempTableFilesDir() @@ -48,15 +47,17 @@ func TestSchemaTableRecreationOlder(t *testing.T) { require.NoError(t, err) ctx.SetCurrentDatabase(db.Name()) - err = db.createSqlTable(ctx, doltdb.SchemasTableName, sql.NewPrimaryKeySchema(sql.Schema{ // schema of dolt_schemas table before the change + err = db.createSqlTable(ctx, doltdb.SchemasTableName, sql.NewPrimaryKeySchema(sql.Schema{ // original schema of dolt_schemas table {Name: doltdb.SchemasTablesTypeCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: true}, {Name: doltdb.SchemasTablesNameCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: true}, {Name: doltdb.SchemasTablesFragmentCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: false}, }), sql.Collation_Default) require.NoError(t, err) + sqlTbl, found, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName) require.NoError(t, err) require.True(t, found) + inserter := sqlTbl.(*WritableDoltTable).Inserter(ctx) err = inserter.Insert(ctx, sql.Row{"view", "view1", "SELECT v1 FROM test;"}) require.NoError(t, err) @@ -65,56 +66,33 @@ func TestSchemaTableRecreationOlder(t *testing.T) { err = inserter.Close(ctx) require.NoError(t, err) - table, err := sqlTbl.(*WritableDoltTable).DoltTable.DoltTable(ctx) - require.NoError(t, err) - - rowData, err := table.GetNomsRowData(ctx) - require.NoError(t, err) - expectedVals := []sql.Row{ - {"view", "view1", "SELECT v1 FROM test;"}, - {"view", "view2", "SELECT v2 FROM test;"}, - } - index := 0 - _ = rowData.IterAll(ctx, func(keyTpl, valTpl types.Value) error { - dRow, err := row.FromNoms(sqlTbl.(*WritableDoltTable).sch, keyTpl.(types.Tuple), valTpl.(types.Tuple)) - require.NoError(t, err) - sqlRow, err := sqlutil.DoltRowToSqlRow(dRow, sqlTbl.(*WritableDoltTable).sch) - require.NoError(t, err) - assert.Equal(t, expectedVals[index], sqlRow) - index++ - return nil - }) - tbl, err := getOrCreateDoltSchemasTable(ctx, db) // removes the old table and recreates it with the new schema require.NoError(t, err) - table, err = tbl.DoltTable.DoltTable(ctx) + iter, err := SqlTableToRowIter(ctx, tbl.DoltTable, nil) require.NoError(t, err) - - rowData, err = table.GetNomsRowData(ctx) - require.NoError(t, err) - expectedVals = []sql.Row{ - {"view", "view1", "SELECT v1 FROM test;", int64(1), nil}, - {"view", "view2", "SELECT v2 FROM test;", int64(2), nil}, + + var rows []sql.Row + for { + row, err := iter.Next(ctx) + if err == io.EOF { + break + } + + require.NoError(t, err) + rows = append(rows, row) } - index = 0 - _ = rowData.IterAll(ctx, func(keyTpl, valTpl types.Value) error { - dRow, err := row.FromNoms(tbl.sch, keyTpl.(types.Tuple), valTpl.(types.Tuple)) - require.NoError(t, err) - sqlRow, err := sqlutil.DoltRowToSqlRow(dRow, tbl.sch) - require.NoError(t, err) - assert.Equal(t, expectedVals[index], sqlRow) - index++ - return nil - }) - - indexes := tbl.sch.Indexes().AllIndexes() - require.Len(t, indexes, 1) - assert.Equal(t, true, indexes[0].IsUnique()) - assert.Equal(t, doltdb.SchemasTablesIndexName, indexes[0].Name()) + + require.NoError(t, iter.Close(ctx)) + expectedRows := []sql.Row{ + {"view", "view1", "SELECT v1 FROM test;", nil}, + {"view", "view2", "SELECT v2 FROM test;", nil}, + } + + assert.Equal(t, expectedRows, rows) } -func TestSchemaTableRecreation(t *testing.T) { +func TestSchemaTableMigrationV1(t *testing.T) { ctx := NewTestSQLCtx(context.Background()) dEnv := dtestutils.CreateTestEnv() tmpDir, err := dEnv.TempTableFilesDir() @@ -130,70 +108,54 @@ func TestSchemaTableRecreation(t *testing.T) { require.NoError(t, err) ctx.SetCurrentDatabase(db.Name()) - // This is the schema of dolt_schemas table after the change adding the ID column, but before adding the extra column - err = db.createSqlTable(ctx, doltdb.SchemasTableName, sql.NewPrimaryKeySchema(sql.Schema{ // - {Name: doltdb.SchemasTablesTypeCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: true}, - {Name: doltdb.SchemasTablesNameCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: true}, + // original schema of dolt_schemas table with the ID column + err = db.createSqlTable(ctx, doltdb.SchemasTableName, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: doltdb.SchemasTablesTypeCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: false}, + {Name: doltdb.SchemasTablesNameCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: false}, {Name: doltdb.SchemasTablesFragmentCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: false}, - {Name: doltdb.SchemasTablesIdCol, Type: gmstypes.Int64, Source: doltdb.SchemasTableName, PrimaryKey: false}, + {Name: doltdb.SchemasTablesIdCol, Type: gmstypes.Int64, Source: doltdb.SchemasTableName, PrimaryKey: true}, + {Name: doltdb.SchemasTablesExtraCol, Type: gmstypes.JsonType{}, Source: doltdb.SchemasTableName, PrimaryKey: false, Nullable: true}, }), sql.Collation_Default) require.NoError(t, err) + sqlTbl, found, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName) require.NoError(t, err) require.True(t, found) + inserter := sqlTbl.(*WritableDoltTable).Inserter(ctx) - err = inserter.Insert(ctx, sql.Row{"view", "view1", "SELECT v1 FROM test;", int64(1)}) + err = inserter.Insert(ctx, sql.Row{"view", "view1", "SELECT v1 FROM test;", 1, `{"extra": "data"}`}) require.NoError(t, err) - err = inserter.Insert(ctx, sql.Row{"view", "view2", "SELECT v2 FROM test;", int64(2)}) + err = inserter.Insert(ctx, sql.Row{"view", "view2", "SELECT v2 FROM test;", 2, nil}) require.NoError(t, err) err = inserter.Close(ctx) require.NoError(t, err) - table, err := sqlTbl.(*WritableDoltTable).DoltTable.DoltTable(ctx) - require.NoError(t, err) - - rowData, err := table.GetNomsRowData(ctx) - require.NoError(t, err) - expectedVals := []sql.Row{ - {"view", "view1", "SELECT v1 FROM test;", int64(1)}, - {"view", "view2", "SELECT v2 FROM test;", int64(2)}, - } - index := 0 - _ = rowData.IterAll(ctx, func(keyTpl, valTpl types.Value) error { - dRow, err := row.FromNoms(sqlTbl.(*WritableDoltTable).sch, keyTpl.(types.Tuple), valTpl.(types.Tuple)) - require.NoError(t, err) - sqlRow, err := sqlutil.DoltRowToSqlRow(dRow, sqlTbl.(*WritableDoltTable).sch) - require.NoError(t, err) - assert.Equal(t, expectedVals[index], sqlRow) - index++ - return nil - }) - tbl, err := getOrCreateDoltSchemasTable(ctx, db) // removes the old table and recreates it with the new schema require.NoError(t, err) - table, err = tbl.DoltTable.DoltTable(ctx) + iter, err := SqlTableToRowIter(ctx, tbl.DoltTable, nil) require.NoError(t, err) - rowData, err = table.GetNomsRowData(ctx) - require.NoError(t, err) - expectedVals = []sql.Row{ - {"view", "view1", "SELECT v1 FROM test;", int64(1), nil}, - {"view", "view2", "SELECT v2 FROM test;", int64(2), nil}, + var rows []sql.Row + for { + row, err := iter.Next(ctx) + if err == io.EOF { + break + } + + require.NoError(t, err) + rows = append(rows, row) } - index = 0 - _ = rowData.IterAll(ctx, func(keyTpl, valTpl types.Value) error { - dRow, err := row.FromNoms(tbl.sch, keyTpl.(types.Tuple), valTpl.(types.Tuple)) - require.NoError(t, err) - sqlRow, err := sqlutil.DoltRowToSqlRow(dRow, tbl.sch) - require.NoError(t, err) - assert.Equal(t, expectedVals[index], sqlRow) - index++ - return nil - }) - indexes := tbl.sch.Indexes().AllIndexes() - require.Len(t, indexes, 1) - assert.Equal(t, true, indexes[0].IsUnique()) - assert.Equal(t, doltdb.SchemasTablesIndexName, indexes[0].Name()) + require.NoError(t, iter.Close(ctx)) + + var expectedJsonDoc any + require.NoError(t, json.Unmarshal([]byte(`{"extra": "data"}`), &expectedJsonDoc)) + + expectedRows := []sql.Row{ + {"view", "view1", "SELECT v1 FROM test;", gmstypes.JSONDocument{Val: expectedJsonDoc}}, + {"view", "view2", "SELECT v2 FROM test;", nil}, + } + + assert.Equal(t, expectedRows, rows) }