mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-29 10:41:05 -06:00
Merge pull request #1278 from dolthub/andy/auto-inc-fix
Andy/auto inc fix
This commit is contained in:
@@ -293,4 +293,29 @@ SQL
|
||||
[[ "$output" =~ "20,20" ]] || false
|
||||
[[ "$output" =~ "30,30" ]] || false
|
||||
[[ "$output" =~ "31,31" ]] || false
|
||||
}
|
||||
|
||||
@test "adding index to AUTO_INCREMENT doesn't reset sequence" {
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE index_test (
|
||||
pk int PRIMARY KEY AUTO_INCREMENT,
|
||||
c0 int
|
||||
);
|
||||
|
||||
INSERT INTO index_test (c0) VALUES (1),(2),(3);
|
||||
|
||||
ALTER TABLE index_test ADD INDEX (c0);
|
||||
|
||||
INSERT INTO index_test (c0) VALUES (4),(5),(6);
|
||||
SQL
|
||||
|
||||
run dolt sql -q "select * from index_test" -r csv
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "${lines[0]}" =~ "pk,c0" ]] || false
|
||||
[[ "${lines[1]}" =~ "1,1" ]] || false
|
||||
[[ "${lines[2]}" =~ "2,2" ]] || false
|
||||
[[ "${lines[3]}" =~ "3,3" ]] || false
|
||||
[[ "${lines[4]}" =~ "4,4" ]] || false
|
||||
[[ "${lines[5]}" =~ "5,5" ]] || false
|
||||
[[ "${lines[6]}" =~ "6,6" ]] || false
|
||||
}
|
||||
@@ -317,7 +317,7 @@ func importSchema(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPars
|
||||
}
|
||||
}
|
||||
|
||||
tbl, err = doltdb.NewTable(ctx, root.VRW(), schVal, empty, indexData)
|
||||
tbl, err = doltdb.NewTable(ctx, root.VRW(), schVal, empty, indexData, nil)
|
||||
|
||||
if err != nil {
|
||||
return errhand.BuildDError("error: failed to create table.").AddCause(err).Build()
|
||||
|
||||
@@ -124,7 +124,7 @@ func CreateTestTable(vrw types.ValueReadWriter, tSchema schema.Schema, rowData t
|
||||
}
|
||||
|
||||
empty, _ := types.NewMap(context.Background(), vrw)
|
||||
tbl, err := doltdb.NewTable(context.Background(), vrw, schemaVal, rowData, empty)
|
||||
tbl, err := doltdb.NewTable(context.Background(), vrw, schemaVal, rowData, empty, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -77,7 +77,7 @@ func CreateTestTable(vrw types.ValueReadWriter, tSchema schema.Schema, rowData t
|
||||
}
|
||||
|
||||
empty, _ := types.NewMap(context.Background(), vrw)
|
||||
tbl, err := NewTable(context.Background(), vrw, schemaVal, rowData, empty)
|
||||
tbl, err := NewTable(context.Background(), vrw, schemaVal, rowData, empty, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -725,7 +725,7 @@ func (root *RootValue) CreateEmptyTable(ctx context.Context, tName string, sch s
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tbl, err := NewTable(ctx, root.VRW(), schVal, empty, indexes)
|
||||
tbl, err := NewTable(ctx, root.VRW(), schVal, empty, indexes, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ type Table struct {
|
||||
}
|
||||
|
||||
// NewTable creates a noms Struct which stores row data, index data, and schema.
|
||||
func NewTable(ctx context.Context, vrw types.ValueReadWriter, schemaVal types.Value, rowData types.Map, indexData types.Map) (*Table, error) {
|
||||
func NewTable(ctx context.Context, vrw types.ValueReadWriter, schemaVal types.Value, rowData types.Map, indexData types.Map, autoIncVal types.Value) (*Table, error) {
|
||||
schemaRef, err := WriteValAndGetRef(ctx, vrw, schemaVal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -77,6 +77,10 @@ func NewTable(ctx context.Context, vrw types.ValueReadWriter, schemaVal types.Va
|
||||
indexesKey: indexesRef,
|
||||
}
|
||||
|
||||
if autoIncVal != nil {
|
||||
sd[autoIncrementKey] = autoIncVal
|
||||
}
|
||||
|
||||
tableStruct, err := types.NewStruct(vrw.Format(), tableStructName, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -293,19 +297,18 @@ func (t *Table) UpdateSchema(ctx context.Context, sch schema.Schema) (*Table, er
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rowData, err := t.GetRowData(ctx)
|
||||
|
||||
schRef, err := WriteValAndGetRef(ctx, t.vrw, newSchemaVal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
indexData, err := t.GetIndexData(ctx)
|
||||
|
||||
newTableStruct, err := t.tableStruct.Set(schemaRefKey, schRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newTable, err := NewTable(ctx, t.vrw, newSchemaVal, rowData, indexData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newTable, nil
|
||||
|
||||
return &Table{t.vrw, newTableStruct}, nil
|
||||
}
|
||||
|
||||
// HasTheSameSchema tests the schema within 2 tables for equality
|
||||
|
||||
@@ -124,7 +124,7 @@ func createDocsTable(ctx context.Context, vrw types.ValueReadWriter, docs Docs)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newDocsTbl, err := doltdb.NewTable(ctx, vrw, schVal, wr.GetMap(), empty)
|
||||
newDocsTbl, err := doltdb.NewTable(ctx, vrw, schVal, wr.GetMap(), empty, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ func CreateTestTable(vrw types.ValueReadWriter, tSchema schema.Schema, rowData t
|
||||
}
|
||||
|
||||
empty, _ := types.NewMap(context.Background(), vrw)
|
||||
tbl, err := doltdb.NewTable(context.Background(), vrw, schemaVal, rowData, empty)
|
||||
tbl, err := doltdb.NewTable(context.Background(), vrw, schemaVal, rowData, empty, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -83,7 +83,7 @@ func CreateEnvWithSeedData(t *testing.T) *env.DoltEnv {
|
||||
require.NoError(t, err)
|
||||
empty, err := types.NewMap(ctx, vrw)
|
||||
require.NoError(t, err)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, wr.GetMap(), empty)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, wr.GetMap(), empty, nil)
|
||||
require.NoError(t, err)
|
||||
tbl, err = editor.RebuildAllIndexes(ctx, tbl)
|
||||
require.NoError(t, err)
|
||||
@@ -94,7 +94,7 @@ func CreateEnvWithSeedData(t *testing.T) *env.DoltEnv {
|
||||
require.NoError(t, err)
|
||||
indexes, err := tbl.GetIndexData(ctx)
|
||||
require.NoError(t, err)
|
||||
err = dEnv.PutTableToWorking(ctx, sch, rows, indexes, TableName)
|
||||
err = dEnv.PutTableToWorking(ctx, sch, rows, indexes, TableName, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
return dEnv
|
||||
|
||||
@@ -114,7 +114,7 @@ func CreateTestTable(t *testing.T, dEnv *env.DoltEnv, tableName string, sch sche
|
||||
require.NoError(t, err)
|
||||
empty, err := types.NewMap(ctx, vrw)
|
||||
require.NoError(t, err)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, wr.GetMap(), empty)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, wr.GetMap(), empty, nil)
|
||||
require.NoError(t, err)
|
||||
tbl, err = editor.RebuildAllIndexes(ctx, tbl)
|
||||
require.NoError(t, err)
|
||||
@@ -125,7 +125,7 @@ func CreateTestTable(t *testing.T, dEnv *env.DoltEnv, tableName string, sch sche
|
||||
require.NoError(t, err)
|
||||
indexes, err := tbl.GetIndexData(ctx)
|
||||
require.NoError(t, err)
|
||||
err = dEnv.PutTableToWorking(ctx, sch, rows, indexes, tableName)
|
||||
err = dEnv.PutTableToWorking(ctx, sch, rows, indexes, tableName, nil)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
||||
4
go/libraries/doltcore/env/environment.go
vendored
4
go/libraries/doltcore/env/environment.go
vendored
@@ -497,7 +497,7 @@ func (dEnv *DoltEnv) UpdateStagedRoot(ctx context.Context, newRoot *doltdb.RootV
|
||||
}
|
||||
|
||||
// todo: move this out of env to actions
|
||||
func (dEnv *DoltEnv) PutTableToWorking(ctx context.Context, sch schema.Schema, rows types.Map, indexData types.Map, tableName string) error {
|
||||
func (dEnv *DoltEnv) PutTableToWorking(ctx context.Context, sch schema.Schema, rows types.Map, indexData types.Map, tableName string, autoVal types.Value) error {
|
||||
root, err := dEnv.WorkingRoot(ctx)
|
||||
|
||||
if err != nil {
|
||||
@@ -511,7 +511,7 @@ func (dEnv *DoltEnv) PutTableToWorking(ctx context.Context, sch schema.Schema, r
|
||||
return ErrMarshallingSchema
|
||||
}
|
||||
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, rows, indexData)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, rows, indexData, autoVal)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -149,7 +149,7 @@ func UpdateTables(t *testing.T, ctx context.Context, root *doltdb.RootValue, tbl
|
||||
indexData, err = tbl.GetIndexData(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
tbl, err = doltdb.NewTable(ctx, root.VRW(), schVal, rowData, indexData)
|
||||
tbl, err = doltdb.NewTable(ctx, root.VRW(), schVal, rowData, indexData, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
root, err = root.PutTable(ctx, tblName, tbl)
|
||||
|
||||
@@ -350,17 +350,17 @@ func setupMergeTest(t *testing.T) (types.ValueReadWriter, *doltdb.Commit, *doltd
|
||||
emptyMap, err := types.NewMap(context.Background(), vrw)
|
||||
require.NoError(t, err)
|
||||
|
||||
tbl, err := doltdb.NewTable(context.Background(), vrw, schVal, initialRows, emptyMap)
|
||||
tbl, err := doltdb.NewTable(context.Background(), vrw, schVal, initialRows, emptyMap, nil)
|
||||
require.NoError(t, err)
|
||||
tbl, err = editor.RebuildAllIndexes(context.Background(), tbl)
|
||||
require.NoError(t, err)
|
||||
|
||||
updatedTbl, err := doltdb.NewTable(context.Background(), vrw, schVal, updatedRows, emptyMap)
|
||||
updatedTbl, err := doltdb.NewTable(context.Background(), vrw, schVal, updatedRows, emptyMap, nil)
|
||||
require.NoError(t, err)
|
||||
updatedTbl, err = editor.RebuildAllIndexes(context.Background(), updatedTbl)
|
||||
require.NoError(t, err)
|
||||
|
||||
mergeTbl, err := doltdb.NewTable(context.Background(), vrw, schVal, mergeRows, emptyMap)
|
||||
mergeTbl, err := doltdb.NewTable(context.Background(), vrw, schVal, mergeRows, emptyMap, nil)
|
||||
require.NoError(t, err)
|
||||
mergeTbl, err = editor.RebuildAllIndexes(context.Background(), mergeTbl)
|
||||
require.NoError(t, err)
|
||||
@@ -438,7 +438,7 @@ func TestMergeCommits(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
emptyMap, err := types.NewMap(context.Background(), vrw)
|
||||
assert.NoError(t, err)
|
||||
expected, err := doltdb.NewTable(context.Background(), vrw, targVal, expectedRows, emptyMap)
|
||||
expected, err := doltdb.NewTable(context.Background(), vrw, targVal, expectedRows, emptyMap, nil)
|
||||
assert.NoError(t, err)
|
||||
expected, err = editor.RebuildAllIndexes(context.Background(), expected)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -362,7 +362,11 @@ func replayCommitWithNewTag(ctx context.Context, root, parentRoot, rebasedParent
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rebasedTable, err := doltdb.NewTable(ctx, rebasedParentRoot.VRW(), rebasedSchVal, rebasedRows, emptyMap)
|
||||
// migration predates AUTO_INCREMENT support
|
||||
// so we don't need to copy the value here
|
||||
var autoVal types.Value = nil
|
||||
|
||||
rebasedTable, err := doltdb.NewTable(ctx, rebasedParentRoot.VRW(), rebasedSchVal, rebasedRows, emptyMap, autoVal)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/row"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
@@ -71,67 +70,20 @@ func AddColumnToTable(ctx context.Context, root *doltdb.RootValue, tbl *doltdb.T
|
||||
// updateTableWithNewSchema updates the existing table with a new schema and new values for the new column as necessary,
|
||||
// and returns the new table.
|
||||
func updateTableWithNewSchema(ctx context.Context, tblName string, tbl *doltdb.Table, tag uint64, newSchema schema.Schema, defaultVal string) (*doltdb.Table, error) {
|
||||
vrw := tbl.ValueReadWriter()
|
||||
newSchemaVal, err := encoding.MarshalSchemaAsNomsValue(ctx, vrw, newSchema)
|
||||
var err error
|
||||
tbl, err = tbl.UpdateSchema(ctx, newSchema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rowData, err := tbl.GetRowData(ctx)
|
||||
if defaultVal != "" {
|
||||
tbl, err = applyDefaultValue(ctx, tblName, tbl, tag, newSchema)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
indexData, err := tbl.GetIndexData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if defaultVal == "" {
|
||||
return doltdb.NewTable(ctx, vrw, newSchemaVal, rowData, indexData)
|
||||
}
|
||||
|
||||
me := rowData.Edit()
|
||||
|
||||
newSqlSchema, err := sqlutil.FromDoltSchema(tblName, newSchema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
columnIndex := -1
|
||||
for i, colTag := range newSchema.GetAllCols().Tags {
|
||||
if colTag == tag {
|
||||
columnIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if columnIndex == -1 {
|
||||
return nil, fmt.Errorf("could not find tag `%d` in new schema", tag)
|
||||
}
|
||||
|
||||
err = rowData.Iter(ctx, func(k, v types.Value) (stop bool, err error) {
|
||||
oldRow, err := row.FromNoms(newSchema, k.(types.Tuple), v.(types.Tuple))
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
newRow, err := sqlutil.ApplyDefaults(ctx, vrw, newSchema, newSqlSchema, []int{columnIndex}, oldRow)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
me.Set(newRow.NomsMapKey(newSchema), newRow.NomsMapValue(newSchema))
|
||||
return false, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m, err := me.Map(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return doltdb.NewTable(ctx, vrw, newSchemaVal, m, indexData)
|
||||
return tbl, nil
|
||||
}
|
||||
|
||||
// addColumnToSchema creates a new schema with a column as specified by the params.
|
||||
@@ -217,3 +169,51 @@ func validateNewColumn(ctx context.Context, root *doltdb.RootValue, tbl *doltdb.
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyDefaultValue(ctx context.Context, tblName string, tbl *doltdb.Table, tag uint64, newSchema schema.Schema) (*doltdb.Table, error) {
|
||||
rowData, err := tbl.GetRowData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
me := rowData.Edit()
|
||||
|
||||
newSqlSchema, err := sqlutil.FromDoltSchema(tblName, newSchema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
columnIndex := -1
|
||||
for i, colTag := range newSchema.GetAllCols().Tags {
|
||||
if colTag == tag {
|
||||
columnIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if columnIndex == -1 {
|
||||
return nil, fmt.Errorf("could not find tag `%d` in new schema", tag)
|
||||
}
|
||||
|
||||
err = rowData.Iter(ctx, func(k, v types.Value) (stop bool, err error) {
|
||||
oldRow, err := row.FromNoms(newSchema, k.(types.Tuple), v.(types.Tuple))
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
newRow, err := sqlutil.ApplyDefaults(ctx, tbl.ValueReadWriter(), newSchema, newSqlSchema, []int{columnIndex}, oldRow)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
me.Set(newRow.NomsMapKey(newSchema), newRow.NomsMapValue(newSchema))
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newRowData, err := me.Map(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tbl.UpdateRows(ctx, newRowData)
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
|
||||
)
|
||||
|
||||
var ErrKeylessAltTbl = errors.New("schema alterations not supported for keyless tables")
|
||||
@@ -32,19 +31,17 @@ func DropColumn(ctx context.Context, tbl *doltdb.Table, colName string, foreignK
|
||||
panic("invalid parameters")
|
||||
}
|
||||
|
||||
tblSch, err := tbl.GetSchema(ctx)
|
||||
sch, err := tbl.GetSchema(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if schema.IsKeyless(tblSch) {
|
||||
if schema.IsKeyless(sch) {
|
||||
return nil, ErrKeylessAltTbl
|
||||
}
|
||||
|
||||
allCols := tblSch.GetAllCols()
|
||||
|
||||
var dropTag uint64
|
||||
if col, ok := allCols.GetByName(colName); !ok {
|
||||
if col, ok := sch.GetAllCols().GetByName(colName); !ok {
|
||||
return nil, schema.ErrColNotFound
|
||||
} else if col.IsPartOfPK {
|
||||
return nil, errors.New("Cannot drop column in primary key")
|
||||
@@ -65,8 +62,8 @@ func DropColumn(ctx context.Context, tbl *doltdb.Table, colName string, foreignK
|
||||
}
|
||||
}
|
||||
|
||||
for _, index := range tblSch.Indexes().IndexesWithColumn(colName) {
|
||||
_, err = tblSch.Indexes().RemoveIndex(index.Name())
|
||||
for _, index := range sch.Indexes().IndexesWithColumn(colName) {
|
||||
_, err = sch.Indexes().RemoveIndex(index.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -77,7 +74,7 @@ func DropColumn(ctx context.Context, tbl *doltdb.Table, colName string, foreignK
|
||||
}
|
||||
|
||||
cols := make([]schema.Column, 0)
|
||||
err = allCols.Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
|
||||
err = sch.GetAllCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
|
||||
if col.Name != colName {
|
||||
cols = append(cols, col)
|
||||
}
|
||||
@@ -93,26 +90,7 @@ func DropColumn(ctx context.Context, tbl *doltdb.Table, colName string, foreignK
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newSch.Indexes().AddIndex(tblSch.Indexes().AllIndexes()...)
|
||||
newSch.Indexes().AddIndex(sch.Indexes().AllIndexes()...)
|
||||
|
||||
vrw := tbl.ValueReadWriter()
|
||||
schemaVal, err := encoding.MarshalSchemaAsNomsValue(ctx, vrw, newSch)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rd, err := tbl.GetRowData(ctx)
|
||||
|
||||
indexData, err := tbl.GetIndexData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newTable, err := doltdb.NewTable(ctx, vrw, schemaVal, rd, indexData)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newTable, nil
|
||||
return tbl.UpdateSchema(ctx, newSch)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/row"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
@@ -58,23 +57,14 @@ func ModifyColumn(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updatedTable, err := updateTableWithModifiedColumn(ctx, tbl, newSchema, newCol)
|
||||
updatedTable, err := tbl.UpdateSchema(ctx, newSchema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !newCol.TypeInfo.Equals(existingCol.TypeInfo) ||
|
||||
newCol.IsNullable() != existingCol.IsNullable() {
|
||||
for _, index := range sch.Indexes().IndexesWithTag(existingCol.Tag) {
|
||||
rebuiltIndexData, err := editor.RebuildIndex(ctx, updatedTable, index.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
updatedTable, err = updatedTable.SetIndexRowData(ctx, index.Name(), rebuiltIndexData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
updatedTable, err = handleNotNullConstraint(ctx, updatedTable, newSchema, existingCol, newCol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updatedTable, nil
|
||||
@@ -109,46 +99,47 @@ func validateModifyColumn(ctx context.Context, tbl *doltdb.Table, existingCol sc
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateTableWithModifiedColumn updates the existing table with the new schema. No data is changed.
|
||||
// TODO: type changes
|
||||
func updateTableWithModifiedColumn(ctx context.Context, tbl *doltdb.Table, newSchema schema.Schema, modifiedCol schema.Column) (*doltdb.Table, error) {
|
||||
vrw := tbl.ValueReadWriter()
|
||||
newSchemaVal, err := encoding.MarshalSchemaAsNomsValue(ctx, vrw, newSchema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// handleNotNullConstraint validates that rows do not violate a NOT NULL constraint, if one exists, and
|
||||
// rebuild indexes on the modified column if necessary
|
||||
func handleNotNullConstraint(ctx context.Context, tbl *doltdb.Table, newSchema schema.Schema, oldCol, newCol schema.Column) (*doltdb.Table, error) {
|
||||
rowData, err := tbl.GetRowData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Iterate over the rows in the table, checking for nils (illegal if the column is declared not null)
|
||||
if !modifiedCol.IsNullable() {
|
||||
if !newCol.IsNullable() {
|
||||
err = rowData.Iter(ctx, func(key, value types.Value) (stop bool, err error) {
|
||||
row, err := row.FromNoms(newSchema, key.(types.Tuple), value.(types.Tuple))
|
||||
r, err := row.FromNoms(newSchema, key.(types.Tuple), value.(types.Tuple))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
val, ok := row.GetColVal(modifiedCol.Tag)
|
||||
if (!ok || val == nil) && !modifiedCol.IsNullable() {
|
||||
val, ok := r.GetColVal(newCol.Tag)
|
||||
if (!ok || val == nil) && !newCol.IsNullable() {
|
||||
return true, fmt.Errorf("cannot change column to NOT NULL when one or more values is NULL")
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if !newCol.TypeInfo.Equals(oldCol.TypeInfo) ||
|
||||
newCol.IsNullable() != oldCol.IsNullable() {
|
||||
|
||||
for _, index := range newSchema.Indexes().IndexesWithTag(oldCol.Tag) {
|
||||
rebuiltIndexData, err := editor.RebuildIndex(ctx, tbl, index.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tbl, err = tbl.SetIndexRowData(ctx, index.Name(), rebuiltIndexData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
indexData, err := tbl.GetIndexData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return doltdb.NewTable(ctx, vrw, newSchemaVal, rowData, indexData)
|
||||
return tbl, err
|
||||
}
|
||||
|
||||
// replaceColumnInSchema replaces the column with the name given with its new definition, optionally reordering it.
|
||||
|
||||
@@ -59,6 +59,17 @@ func IsKeyless(sch Schema) bool {
|
||||
sch.GetAllCols().Size() != 0
|
||||
}
|
||||
|
||||
func HasAutoIncrement(sch Schema) (ok bool) {
|
||||
_ = sch.GetAllCols().Iter(func(tag uint64, col Column) (stop bool, err error) {
|
||||
if col.AutoIncrement {
|
||||
ok = true
|
||||
stop = true
|
||||
}
|
||||
return
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: this function never returns an error
|
||||
// SchemasAreEqual tests equality of two schemas.
|
||||
func SchemasAreEqual(sch1, sch2 Schema) (bool, error) {
|
||||
|
||||
@@ -384,7 +384,8 @@ func (t *WritableDoltTable) Truncate(ctx *sql.Context) (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
newTable, err := doltdb.NewTable(ctx, t.table.ValueReadWriter(), schVal, empty, empty)
|
||||
// truncate table resets auto-increment value
|
||||
newTable, err := doltdb.NewTable(ctx, t.table.ValueReadWriter(), schVal, empty, empty, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -1208,19 +1209,7 @@ func createIndexForTable(
|
||||
}
|
||||
|
||||
// update the table schema with the new index
|
||||
newSchemaVal, err := encoding.MarshalSchemaAsNomsValue(ctx, table.ValueReadWriter(), sch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tableRowData, err := table.GetRowData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
indexData, err := table.GetIndexData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newTable, err := doltdb.NewTable(ctx, table.ValueReadWriter(), newSchemaVal, tableRowData, indexData)
|
||||
newTable, err := table.UpdateSchema(ctx, sch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -843,7 +843,7 @@ func createTestSchema(t *testing.T) schema.Schema {
|
||||
|
||||
func createTableWithoutIndexRebuilding(ctx context.Context, vrw types.ValueReadWriter, schemaVal types.Value, rowData types.Map) (*doltdb.Table, error) {
|
||||
empty, _ := types.NewMap(ctx, vrw)
|
||||
return doltdb.NewTable(ctx, vrw, schemaVal, rowData, empty)
|
||||
return doltdb.NewTable(ctx, vrw, schemaVal, rowData, empty, nil)
|
||||
}
|
||||
|
||||
func rowsToIndexRows(t *testing.T, rows []row.Row, indexName schema.Index, indexAge schema.Index) (indexNameExpectedRows []row.Row, indexAgeExpectedRows []row.Row) {
|
||||
|
||||
@@ -55,7 +55,7 @@ func TestTableEditorConcurrency(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := types.NewMap(context.Background(), db)
|
||||
require.NoError(t, err)
|
||||
table, err := doltdb.NewTable(context.Background(), db, tableSchVal, emptyMap, emptyMap)
|
||||
table, err := doltdb.NewTable(context.Background(), db, tableSchVal, emptyMap, emptyMap, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
for i := 0; i < tableEditorConcurrencyIterations; i++ {
|
||||
@@ -151,7 +151,7 @@ func TestTableEditorConcurrencyPostInsert(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := types.NewMap(context.Background(), db)
|
||||
require.NoError(t, err)
|
||||
table, err := doltdb.NewTable(context.Background(), db, tableSchVal, emptyMap, emptyMap)
|
||||
table, err := doltdb.NewTable(context.Background(), db, tableSchVal, emptyMap, emptyMap, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
tableEditor, err := newPkTableEditor(context.Background(), table, tableSch, tableName)
|
||||
@@ -245,7 +245,7 @@ func TestTableEditorWriteAfterFlush(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := types.NewMap(context.Background(), db)
|
||||
require.NoError(t, err)
|
||||
table, err := doltdb.NewTable(context.Background(), db, tableSchVal, emptyMap, emptyMap)
|
||||
table, err := doltdb.NewTable(context.Background(), db, tableSchVal, emptyMap, emptyMap, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
tableEditor, err := newPkTableEditor(context.Background(), table, tableSch, tableName)
|
||||
@@ -316,7 +316,7 @@ func TestTableEditorDuplicateKeyHandling(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := types.NewMap(context.Background(), db)
|
||||
require.NoError(t, err)
|
||||
table, err := doltdb.NewTable(context.Background(), db, tableSchVal, emptyMap, emptyMap)
|
||||
table, err := doltdb.NewTable(context.Background(), db, tableSchVal, emptyMap, emptyMap, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
tableEditor, err := newPkTableEditor(context.Background(), table, tableSch, tableName)
|
||||
|
||||
@@ -134,7 +134,7 @@ func TestKeylessTableReader(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
rowMap := makeBag(vrw, sch, test.rows...)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, rowMap, empty)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, rowMap, empty, nil)
|
||||
require.NoError(t, err)
|
||||
rdr, err := table.NewTableReader(ctx, tbl)
|
||||
require.NoError(t, err)
|
||||
@@ -142,7 +142,7 @@ func TestKeylessTableReader(t *testing.T) {
|
||||
})
|
||||
t.Run(test.name+"_buffered", func(t *testing.T) {
|
||||
rowMap := makeBag(vrw, sch, test.rows...)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, rowMap, empty)
|
||||
tbl, err := doltdb.NewTable(ctx, vrw, schVal, rowMap, empty, nil)
|
||||
require.NoError(t, err)
|
||||
rdr, err := table.NewBufferedTableReader(ctx, tbl)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -88,7 +88,7 @@ func TestEndToEnd(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
idxMap, err := types.NewMap(ctx, root.VRW(), types.String(dtestutils.IndexName), idxRef)
|
||||
require.NoError(t, err)
|
||||
tbl, err := doltdb.NewTable(ctx, root.VRW(), schVal, empty, idxMap)
|
||||
tbl, err := doltdb.NewTable(ctx, root.VRW(), schVal, empty, idxMap, nil)
|
||||
require.NoError(t, err)
|
||||
root, err = root.PutTable(ctx, tableName, tbl)
|
||||
require.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user