github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/doltdb/durable/table.go (about)

     1  // Copyright 2021 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package durable
    16  
    17  import (
    18  	"bytes"
    19  	"context"
    20  	"errors"
    21  	"fmt"
    22  
    23  	flatbuffers "github.com/dolthub/flatbuffers/v23/go"
    24  
    25  	"github.com/dolthub/dolt/go/gen/fb/serial"
    26  	"github.com/dolthub/dolt/go/libraries/doltcore/conflict"
    27  	"github.com/dolthub/dolt/go/libraries/doltcore/schema"
    28  	"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
    29  	"github.com/dolthub/dolt/go/store/hash"
    30  	"github.com/dolthub/dolt/go/store/pool"
    31  	"github.com/dolthub/dolt/go/store/prolly"
    32  	"github.com/dolthub/dolt/go/store/prolly/shim"
    33  	"github.com/dolthub/dolt/go/store/prolly/tree"
    34  	"github.com/dolthub/dolt/go/store/types"
    35  )
    36  
    37  const (
    38  	tableStructName = "table"
    39  
    40  	schemaRefKey            = "schema_ref"
    41  	tableRowsKey            = "rows"
    42  	artifactsKey            = "artifacts"
    43  	conflictsKey            = "conflicts"
    44  	conflictSchemasKey      = "conflict_schemas"
    45  	constraintViolationsKey = "constraint_violations"
    46  	indexesKey              = "indexes"
    47  	autoIncrementKey        = "auto_increment"
    48  )
    49  
    50  var (
    51  	ErrUnknownAutoIncrementValue = fmt.Errorf("auto increment set for non-numeric column type")
    52  )
    53  
    54  var (
    55  	errNbfUnknown     = fmt.Errorf("unknown NomsBinFormat")
    56  	errNbfUnsupported = fmt.Errorf("operation unsupported for NomsBinFormat")
    57  )
    58  
    59  // Table is a Dolt table that can be persisted.
    60  type Table interface {
    61  	// HashOf returns the hash.Hash of this table.
    62  	HashOf() (hash.Hash, error)
    63  
    64  	// Format returns the types.NomsBinFormat for this table.
    65  	Format() *types.NomsBinFormat
    66  
    67  	// GetSchemaHash returns the hash.Hash of this table's schema.
    68  	GetSchemaHash(ctx context.Context) (hash.Hash, error)
    69  	// GetSchema returns this table's schema.
    70  	GetSchema(ctx context.Context) (schema.Schema, error)
    71  	// SetSchema sets this table's schema.
    72  	SetSchema(ctx context.Context, sch schema.Schema) (Table, error)
    73  
    74  	// GetTableRows returns this tables rows.
    75  	GetTableRows(ctx context.Context) (Index, error)
    76  	// SetTableRows sets this table's rows.
    77  	SetTableRows(ctx context.Context, rows Index) (Table, error)
    78  
    79  	// GetIndexes returns the secondary indexes for this table.
    80  	GetIndexes(ctx context.Context) (IndexSet, error)
    81  	// SetIndexes sets the secondary indexes for this table.
    82  	SetIndexes(ctx context.Context, indexes IndexSet) (Table, error)
    83  
    84  	// GetArtifacts returns the merge artifacts for this table.
    85  	GetArtifacts(ctx context.Context) (ArtifactIndex, error)
    86  	// SetArtifacts sets the merge artifacts for this table.
    87  	SetArtifacts(ctx context.Context, artifacts ArtifactIndex) (Table, error)
    88  
    89  	// GetConflicts returns the merge conflicts for this table.
    90  	GetConflicts(ctx context.Context) (conflict.ConflictSchema, ConflictIndex, error)
    91  	// HasConflicts returns true if this table has conflicts.
    92  	HasConflicts(ctx context.Context) (bool, error)
    93  	// SetConflicts sets the merge conflicts for this table.
    94  	SetConflicts(ctx context.Context, sch conflict.ConflictSchema, conflicts ConflictIndex) (Table, error)
    95  	// ClearConflicts removes all merge conflicts for this table.
    96  	ClearConflicts(ctx context.Context) (Table, error)
    97  
    98  	// GetConstraintViolations returns the constraint violations for this table.
    99  	GetConstraintViolations(ctx context.Context) (types.Map, error)
   100  	// SetConstraintViolations sets the constraint violations for this table.
   101  	SetConstraintViolations(ctx context.Context, violations types.Map) (Table, error)
   102  
   103  	// GetAutoIncrement returns the AUTO_INCREMENT sequence value for this table.
   104  	GetAutoIncrement(ctx context.Context) (uint64, error)
   105  	// SetAutoIncrement sets the AUTO_INCREMENT sequence value for this table.
   106  	SetAutoIncrement(ctx context.Context, val uint64) (Table, error)
   107  
   108  	// DebugString returns the table contents for debugging purposes
   109  	DebugString(ctx context.Context, ns tree.NodeStore) string
   110  }
   111  
   112  type nomsTable struct {
   113  	vrw         types.ValueReadWriter
   114  	ns          tree.NodeStore
   115  	tableStruct types.Struct
   116  }
   117  
   118  var _ Table = nomsTable{}
   119  
   120  var sharePool = pool.NewBuffPool()
   121  
   122  // NewNomsTable makes a new Table.
   123  func NewNomsTable(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema, rows types.Map, indexes IndexSet, autoIncVal types.Value) (Table, error) {
   124  	return NewTable(ctx, vrw, ns, sch, nomsIndex{index: rows, vrw: vrw}, indexes, autoIncVal)
   125  }
   126  
   127  // NewTable returns a new Table.
   128  func NewTable(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema, rows Index, indexes IndexSet, autoIncVal types.Value) (Table, error) {
   129  	if vrw.Format().UsesFlatbuffers() {
   130  		return newDoltDevTable(ctx, vrw, ns, sch, rows, indexes, autoIncVal)
   131  	}
   132  
   133  	schVal, err := encoding.MarshalSchema(ctx, vrw, sch)
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  
   138  	schemaRef, err := refFromNomsValue(ctx, vrw, schVal)
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  
   143  	rowsRef, err := RefFromIndex(ctx, vrw, rows)
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	if indexes == nil {
   149  		indexes, err = NewIndexSet(ctx, vrw, ns)
   150  		if err != nil {
   151  			return nil, err
   152  		}
   153  	}
   154  
   155  	indexesRef, err := refFromNomsValue(ctx, vrw, mapFromIndexSet(indexes))
   156  	if err != nil {
   157  		return nil, err
   158  	}
   159  
   160  	sd := types.StructData{
   161  		schemaRefKey: schemaRef,
   162  		tableRowsKey: rowsRef,
   163  		indexesKey:   indexesRef,
   164  	}
   165  
   166  	if schema.HasAutoIncrement(sch) && autoIncVal != nil {
   167  		sd[autoIncrementKey] = autoIncVal
   168  	}
   169  
   170  	tableStruct, err := types.NewStruct(vrw.Format(), tableStructName, sd)
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  
   175  	return nomsTable{vrw, ns, tableStruct}, nil
   176  }
   177  
   178  // TableFromAddr deserializes the table in the chunk at |addr|.
   179  func TableFromAddr(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, addr hash.Hash) (Table, error) {
   180  	val, err := vrw.ReadValue(ctx, addr)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  
   185  	if !vrw.Format().UsesFlatbuffers() {
   186  		st, ok := val.(types.Struct)
   187  		if !ok {
   188  			err = errors.New("table ref is unexpected noms value")
   189  			return nil, err
   190  		}
   191  
   192  		return nomsTable{vrw: vrw, tableStruct: st, ns: ns}, nil
   193  	} else {
   194  		sm, ok := val.(types.SerialMessage)
   195  		if !ok {
   196  			err = errors.New("table ref is unexpected noms value; not SerialMessage")
   197  			return nil, err
   198  		}
   199  		id := serial.GetFileID(sm)
   200  		if id != serial.TableFileID {
   201  			err = errors.New("table ref is unexpected noms value; GetFileID == " + id)
   202  			return nil, err
   203  		}
   204  		st, err := serial.TryGetRootAsTable([]byte(sm), serial.MessagePrefixSz)
   205  		if err != nil {
   206  			return nil, err
   207  		}
   208  		return doltDevTable{vrw, ns, st}, nil
   209  	}
   210  }
   211  
   212  // RefFromNomsTable serialized |table|, and returns its types.Ref.
   213  func RefFromNomsTable(ctx context.Context, table Table) (types.Ref, error) {
   214  	nt, ok := table.(nomsTable)
   215  	if ok {
   216  		return refFromNomsValue(ctx, nt.vrw, nt.tableStruct)
   217  	}
   218  	ddt := table.(doltDevTable)
   219  
   220  	return refFromNomsValue(ctx, ddt.vrw, ddt.nomsValue())
   221  }
   222  
   223  // VrwFromTable returns the types.ValueReadWriter used by |t|.
   224  // todo(andy): this is a temporary method that will be removed when there is a
   225  // general-purpose abstraction to replace types.ValueReadWriter.
   226  func VrwFromTable(t Table) types.ValueReadWriter {
   227  	if nt, ok := t.(nomsTable); ok {
   228  		return nt.vrw
   229  	} else {
   230  		ddt := t.(doltDevTable)
   231  		return ddt.vrw
   232  	}
   233  }
   234  
   235  func NodeStoreFromTable(t Table) tree.NodeStore {
   236  	if nt, ok := t.(nomsTable); ok {
   237  		return nt.ns
   238  	} else {
   239  		ddt := t.(doltDevTable)
   240  		return ddt.ns
   241  	}
   242  }
   243  
   244  // valueReadWriter returns the valueReadWriter for this table.
   245  func (t nomsTable) valueReadWriter() types.ValueReadWriter {
   246  	return t.vrw
   247  }
   248  
   249  // HashOf implements Table.
   250  func (t nomsTable) HashOf() (hash.Hash, error) {
   251  	return t.tableStruct.Hash(t.vrw.Format())
   252  }
   253  
   254  // Format returns the types.NomsBinFormat for this index.
   255  func (t nomsTable) Format() *types.NomsBinFormat {
   256  	return t.vrw.Format()
   257  }
   258  
   259  // GetSchema implements Table.
   260  func (t nomsTable) GetSchema(ctx context.Context) (schema.Schema, error) {
   261  	schemaRefVal, _, err := t.tableStruct.MaybeGet(schemaRefKey)
   262  
   263  	if err != nil {
   264  		return nil, err
   265  	}
   266  
   267  	schemaRef := schemaRefVal.(types.Ref)
   268  	return schemaFromRef(ctx, t.vrw, schemaRef)
   269  }
   270  
   271  // GetSchemaHash implements Table.
   272  func (t nomsTable) GetSchemaHash(ctx context.Context) (hash.Hash, error) {
   273  	r, _, err := t.tableStruct.MaybeGet(schemaRefKey)
   274  	if err != nil {
   275  		return hash.Hash{}, err
   276  	}
   277  	return r.(types.Ref).TargetHash(), nil
   278  }
   279  
   280  // SetSchema implements Table.
   281  func (t nomsTable) SetSchema(ctx context.Context, sch schema.Schema) (Table, error) {
   282  	newSchemaVal, err := encoding.MarshalSchema(ctx, t.vrw, sch)
   283  	if err != nil {
   284  		return nil, err
   285  	}
   286  
   287  	schRef, err := refFromNomsValue(ctx, t.vrw, newSchemaVal)
   288  	if err != nil {
   289  		return nil, err
   290  	}
   291  
   292  	newTableStruct, err := t.tableStruct.Set(schemaRefKey, schRef)
   293  	if err != nil {
   294  		return nil, err
   295  	}
   296  
   297  	return nomsTable{t.vrw, t.ns, newTableStruct}, nil
   298  }
   299  
   300  // SetTableRows implements Table.
   301  func (t nomsTable) SetTableRows(ctx context.Context, updatedRows Index) (Table, error) {
   302  	rowsRef, err := RefFromIndex(ctx, t.vrw, updatedRows)
   303  	if err != nil {
   304  		return nil, err
   305  	}
   306  
   307  	updatedSt, err := t.tableStruct.Set(tableRowsKey, rowsRef)
   308  	if err != nil {
   309  		return nil, err
   310  	}
   311  
   312  	return nomsTable{t.vrw, t.ns, updatedSt}, nil
   313  }
   314  
   315  // GetTableRows implements Table.
   316  func (t nomsTable) GetTableRows(ctx context.Context) (Index, error) {
   317  	val, _, err := t.tableStruct.MaybeGet(tableRowsKey)
   318  	if err != nil {
   319  		return nil, err
   320  	}
   321  
   322  	sch, err := t.GetSchema(ctx)
   323  	if err != nil {
   324  		return nil, err
   325  	}
   326  
   327  	return indexFromRef(ctx, t.vrw, t.ns, sch, val.(types.Ref))
   328  }
   329  
   330  // GetIndexes implements Table.
   331  func (t nomsTable) GetIndexes(ctx context.Context) (IndexSet, error) {
   332  	iv, ok, err := t.tableStruct.MaybeGet(indexesKey)
   333  	if err != nil {
   334  		return nil, err
   335  	}
   336  	if !ok {
   337  		return NewIndexSet(ctx, t.vrw, t.ns)
   338  	}
   339  
   340  	im, err := iv.(types.Ref).TargetValue(ctx, t.vrw)
   341  	if err != nil {
   342  		return nil, err
   343  	}
   344  
   345  	return nomsIndexSet{
   346  		indexes: im.(types.Map),
   347  		vrw:     t.vrw,
   348  		ns:      t.ns,
   349  	}, nil
   350  }
   351  
   352  // SetIndexes implements Table.
   353  func (t nomsTable) SetIndexes(ctx context.Context, indexes IndexSet) (Table, error) {
   354  	if indexes == nil {
   355  		var err error
   356  		indexes, err = NewIndexSet(ctx, t.vrw, t.ns)
   357  		if err != nil {
   358  			return nil, err
   359  		}
   360  	}
   361  
   362  	indexesRef, err := refFromNomsValue(ctx, t.vrw, mapFromIndexSet(indexes))
   363  	if err != nil {
   364  		return nil, err
   365  	}
   366  
   367  	newTableStruct, err := t.tableStruct.Set(indexesKey, indexesRef)
   368  	if err != nil {
   369  		return nil, err
   370  	}
   371  
   372  	return nomsTable{t.vrw, t.ns, newTableStruct}, nil
   373  }
   374  
   375  // GetArtifacts implements Table.
   376  func (t nomsTable) GetArtifacts(ctx context.Context) (ArtifactIndex, error) {
   377  	if t.Format() != types.Format_DOLT {
   378  		panic("artifacts not implemented for old storage format")
   379  	}
   380  
   381  	sch, err := t.GetSchema(ctx)
   382  	if err != nil {
   383  		return nil, err
   384  	}
   385  
   386  	val, ok, err := t.tableStruct.MaybeGet(artifactsKey)
   387  	if err != nil {
   388  		return nil, err
   389  	}
   390  	if !ok {
   391  		return NewEmptyArtifactIndex(ctx, t.vrw, t.ns, sch)
   392  	}
   393  
   394  	return artifactIndexFromRef(ctx, t.vrw, t.ns, sch, val.(types.Ref))
   395  }
   396  
   397  // SetArtifacts implements Table.
   398  func (t nomsTable) SetArtifacts(ctx context.Context, artifacts ArtifactIndex) (Table, error) {
   399  	if t.Format() != types.Format_DOLT {
   400  		panic("artifacts not implemented for old storage format")
   401  	}
   402  
   403  	ref, err := RefFromArtifactIndex(ctx, t.vrw, artifacts)
   404  	if err != nil {
   405  		return nil, err
   406  	}
   407  
   408  	updated, err := t.tableStruct.Set(artifactsKey, ref)
   409  	if err != nil {
   410  		return nil, err
   411  	}
   412  
   413  	return nomsTable{t.vrw, t.ns, updated}, nil
   414  }
   415  
   416  // HasConflicts implements Table.
   417  func (t nomsTable) HasConflicts(ctx context.Context) (bool, error) {
   418  	_, ok, err := t.tableStruct.MaybeGet(conflictSchemasKey)
   419  	return ok, err
   420  }
   421  
   422  // GetConflicts implements Table.
   423  func (t nomsTable) GetConflicts(ctx context.Context) (conflict.ConflictSchema, ConflictIndex, error) {
   424  	schemasVal, ok, err := t.tableStruct.MaybeGet(conflictSchemasKey)
   425  	if err != nil {
   426  		return conflict.ConflictSchema{}, nil, err
   427  	}
   428  	if !ok {
   429  		sch, err := t.GetSchema(ctx)
   430  		if err != nil {
   431  			return conflict.ConflictSchema{}, nil, err
   432  		}
   433  		empty, err := NewEmptyConflictIndex(ctx, t.vrw, t.ns, sch, sch, sch)
   434  		if err != nil {
   435  			return conflict.ConflictSchema{}, nil, err
   436  		}
   437  		return conflict.ConflictSchema{}, empty, nil
   438  	}
   439  
   440  	schemas, err := conflict.ConflictSchemaFromValue(ctx, t.vrw, schemasVal)
   441  	if err != nil {
   442  		return conflict.ConflictSchema{}, nil, err
   443  	}
   444  
   445  	conflictsVal, _, err := t.tableStruct.MaybeGet(conflictsKey)
   446  	if err != nil {
   447  		return conflict.ConflictSchema{}, nil, err
   448  	}
   449  
   450  	if conflictsVal == nil {
   451  		confIndex, err := NewEmptyConflictIndex(ctx, t.vrw, t.ns, schemas.Schema, schemas.MergeSchema, schemas.Base)
   452  		if err != nil {
   453  			return conflict.ConflictSchema{}, nil, err
   454  		}
   455  		return conflict.ConflictSchema{}, confIndex, nil
   456  	}
   457  
   458  	i, err := conflictIndexFromRef(ctx, t.vrw, t.ns, schemas.Schema, schemas.MergeSchema, schemas.Base, conflictsVal.(types.Ref))
   459  	if err != nil {
   460  		return conflict.ConflictSchema{}, nil, err
   461  	}
   462  
   463  	return schemas, i, nil
   464  }
   465  
   466  // SetConflicts implements Table.
   467  func (t nomsTable) SetConflicts(ctx context.Context, schemas conflict.ConflictSchema, conflictData ConflictIndex) (Table, error) {
   468  	if t.Format() == types.Format_DOLT {
   469  		panic("should use artifacts")
   470  	}
   471  
   472  	conflictsRef, err := RefFromConflictIndex(ctx, t.vrw, conflictData)
   473  	if err != nil {
   474  		return nil, err
   475  	}
   476  
   477  	tpl, err := conflict.ValueFromConflictSchema(ctx, t.vrw, schemas)
   478  	if err != nil {
   479  		return nil, err
   480  	}
   481  
   482  	updatedSt, err := t.tableStruct.Set(conflictSchemasKey, tpl)
   483  	if err != nil {
   484  		return nil, err
   485  	}
   486  
   487  	updatedSt, err = updatedSt.Set(conflictsKey, conflictsRef)
   488  	if err != nil {
   489  		return nil, err
   490  	}
   491  
   492  	return nomsTable{t.vrw, t.ns, updatedSt}, nil
   493  }
   494  
   495  // GetConflictSchemas implements Table.
   496  func (t nomsTable) GetConflictSchemas(ctx context.Context) (base, sch, mergeSch schema.Schema, err error) {
   497  	schemasVal, ok, err := t.tableStruct.MaybeGet(conflictSchemasKey)
   498  
   499  	if err != nil {
   500  		return nil, nil, nil, err
   501  	}
   502  
   503  	if ok {
   504  		schemas, err := conflict.ConflictFromTuple(schemasVal.(types.Tuple))
   505  
   506  		if err != nil {
   507  			return nil, nil, nil, err
   508  		}
   509  
   510  		baseRef := schemas.Base.(types.Ref)
   511  		valRef := schemas.Value.(types.Ref)
   512  		mergeRef := schemas.MergeValue.(types.Ref)
   513  
   514  		var baseSch, sch, mergeSch schema.Schema
   515  		if baseSch, err = schemaFromRef(ctx, t.vrw, baseRef); err == nil {
   516  			if sch, err = schemaFromRef(ctx, t.vrw, valRef); err == nil {
   517  				mergeSch, err = schemaFromRef(ctx, t.vrw, mergeRef)
   518  			}
   519  		}
   520  
   521  		return baseSch, sch, mergeSch, err
   522  	}
   523  	return nil, nil, nil, nil
   524  }
   525  
   526  // ClearConflicts implements Table.
   527  func (t nomsTable) ClearConflicts(ctx context.Context) (Table, error) {
   528  	if t.Format() == types.Format_DOLT {
   529  		panic("should use artifacts")
   530  	}
   531  
   532  	tSt, err := t.tableStruct.Delete(conflictSchemasKey)
   533  
   534  	if err != nil {
   535  		return nil, err
   536  	}
   537  
   538  	tSt, err = tSt.Delete(conflictsKey)
   539  
   540  	if err != nil {
   541  		return nil, err
   542  	}
   543  
   544  	return nomsTable{t.vrw, t.ns, tSt}, nil
   545  }
   546  
   547  // GetConstraintViolations implements Table.
   548  func (t nomsTable) GetConstraintViolations(ctx context.Context) (types.Map, error) {
   549  	constraintViolationsRefVal, ok, err := t.tableStruct.MaybeGet(constraintViolationsKey)
   550  	if err != nil {
   551  		return types.EmptyMap, err
   552  	}
   553  	if !ok {
   554  		emptyMap, err := types.NewMap(ctx, t.vrw)
   555  		return emptyMap, err
   556  	}
   557  	constraintViolationsVal, err := constraintViolationsRefVal.(types.Ref).TargetValue(ctx, t.vrw)
   558  	if err != nil {
   559  		return types.EmptyMap, err
   560  	}
   561  	return constraintViolationsVal.(types.Map), nil
   562  }
   563  
   564  // SetConstraintViolations implements Table.
   565  func (t nomsTable) SetConstraintViolations(ctx context.Context, violationsMap types.Map) (Table, error) {
   566  	// We can't just call violationsMap.Empty() as we can't guarantee that the caller passed in an instantiated map
   567  	if violationsMap == types.EmptyMap || violationsMap.Len() == 0 {
   568  		updatedStruct, err := t.tableStruct.Delete(constraintViolationsKey)
   569  		if err != nil {
   570  			return nil, err
   571  		}
   572  		return nomsTable{t.vrw, t.ns, updatedStruct}, nil
   573  	}
   574  	constraintViolationsRef, err := refFromNomsValue(ctx, t.vrw, violationsMap)
   575  	if err != nil {
   576  		return nil, err
   577  	}
   578  	updatedStruct, err := t.tableStruct.Set(constraintViolationsKey, constraintViolationsRef)
   579  	if err != nil {
   580  		return nil, err
   581  	}
   582  	return nomsTable{t.vrw, t.ns, updatedStruct}, nil
   583  }
   584  
   585  // GetAutoIncrement implements Table.
   586  func (t nomsTable) GetAutoIncrement(ctx context.Context) (uint64, error) {
   587  	val, ok, err := t.tableStruct.MaybeGet(autoIncrementKey)
   588  	if err != nil {
   589  		return 0, err
   590  	}
   591  	if !ok {
   592  		return 1, nil
   593  	}
   594  
   595  	// older versions might have serialized auto-increment
   596  	// value as types.Int or types.Float.
   597  	switch t := val.(type) {
   598  	case types.Int:
   599  		return uint64(t), nil
   600  	case types.Uint:
   601  		return uint64(t), nil
   602  	case types.Float:
   603  		return uint64(t), nil
   604  	default:
   605  		return 0, ErrUnknownAutoIncrementValue
   606  	}
   607  }
   608  
   609  // SetAutoIncrement implements Table.
   610  func (t nomsTable) SetAutoIncrement(ctx context.Context, val uint64) (Table, error) {
   611  	st, err := t.tableStruct.Set(autoIncrementKey, types.Uint(val))
   612  	if err != nil {
   613  		return nil, err
   614  	}
   615  	return nomsTable{t.vrw, t.ns, st}, nil
   616  }
   617  
   618  func (t nomsTable) DebugString(ctx context.Context, ns tree.NodeStore) string {
   619  	var buf bytes.Buffer
   620  	err := types.WriteEncodedValue(ctx, &buf, t.tableStruct)
   621  	if err != nil {
   622  		panic(err)
   623  	}
   624  
   625  	schemaRefVal, _, _ := t.tableStruct.MaybeGet(schemaRefKey)
   626  	schemaRef := schemaRefVal.(types.Ref)
   627  	schemaVal, err := schemaRef.TargetValue(ctx, t.vrw)
   628  	if err != nil {
   629  		panic(err)
   630  	}
   631  
   632  	buf.WriteString("\nschema: ")
   633  	err = types.WriteEncodedValue(ctx, &buf, schemaVal)
   634  	if err != nil {
   635  		panic(err)
   636  	}
   637  
   638  	iv, ok, err := t.tableStruct.MaybeGet(indexesKey)
   639  	if err != nil {
   640  		panic(err)
   641  	}
   642  
   643  	if ok {
   644  		buf.WriteString("\nindexes: ")
   645  		im, err := iv.(types.Ref).TargetValue(ctx, t.vrw)
   646  		if err != nil {
   647  			panic(err)
   648  		}
   649  
   650  		err = types.WriteEncodedValue(ctx, &buf, im)
   651  		if err != nil {
   652  			panic(err)
   653  		}
   654  	}
   655  
   656  	buf.WriteString("\ndata:\n")
   657  	data, err := t.GetTableRows(ctx)
   658  	if err != nil {
   659  		panic(err)
   660  	}
   661  
   662  	err = types.WriteEncodedValue(ctx, &buf, NomsMapFromIndex(data))
   663  	if err != nil {
   664  		panic(err)
   665  	}
   666  
   667  	return buf.String()
   668  }
   669  
   670  func refFromNomsValue(ctx context.Context, vrw types.ValueReadWriter, val types.Value) (types.Ref, error) {
   671  	return vrw.WriteValue(ctx, val)
   672  }
   673  
   674  func schemaFromRef(ctx context.Context, vrw types.ValueReadWriter, ref types.Ref) (schema.Schema, error) {
   675  	return schemaFromAddr(ctx, vrw, ref.TargetHash())
   676  }
   677  
   678  func schemaFromAddr(ctx context.Context, vrw types.ValueReadWriter, addr hash.Hash) (schema.Schema, error) {
   679  	return encoding.UnmarshalSchemaAtAddr(ctx, vrw, addr)
   680  }
   681  
   682  type doltDevTable struct {
   683  	vrw types.ValueReadWriter
   684  	ns  tree.NodeStore
   685  	msg *serial.Table
   686  }
   687  
   688  func (t doltDevTable) DebugString(ctx context.Context, ns tree.NodeStore) string {
   689  	rows, err := t.GetTableRows(ctx)
   690  	if err != nil {
   691  		panic(err)
   692  	}
   693  
   694  	schema, err := t.GetSchema(ctx)
   695  	if err != nil {
   696  		panic(err)
   697  	}
   698  
   699  	return rows.DebugString(ctx, ns, schema)
   700  }
   701  
   702  var _ Table = doltDevTable{}
   703  
   704  type serialTableFields struct {
   705  	schema            []byte
   706  	rows              []byte
   707  	indexes           prolly.AddressMap
   708  	conflictsdata     []byte
   709  	conflictsours     []byte
   710  	conflictstheirs   []byte
   711  	conflictsancestor []byte
   712  	violations        []byte
   713  	artifacts         []byte
   714  	autoincval        uint64
   715  }
   716  
   717  func (fields serialTableFields) write() (*serial.Table, error) {
   718  	// TODO: Chance for a pool.
   719  	builder := flatbuffers.NewBuilder(1024)
   720  
   721  	indexesam := fields.indexes
   722  	indexesbytes := []byte(tree.ValueFromNode(indexesam.Node()).(types.SerialMessage))
   723  
   724  	schemaoff := builder.CreateByteVector(fields.schema)
   725  	rowsoff := builder.CreateByteVector(fields.rows)
   726  	indexesoff := builder.CreateByteVector(indexesbytes)
   727  	conflictsdataoff := builder.CreateByteVector(fields.conflictsdata)
   728  	conflictsoursoff := builder.CreateByteVector(fields.conflictsours)
   729  	conflictstheirsoff := builder.CreateByteVector(fields.conflictstheirs)
   730  	conflictsbaseoff := builder.CreateByteVector(fields.conflictsancestor)
   731  	serial.ConflictsStart(builder)
   732  	serial.ConflictsAddData(builder, conflictsdataoff)
   733  	serial.ConflictsAddOurSchema(builder, conflictsoursoff)
   734  	serial.ConflictsAddTheirSchema(builder, conflictstheirsoff)
   735  	serial.ConflictsAddAncestorSchema(builder, conflictsbaseoff)
   736  	conflictsoff := serial.ConflictsEnd(builder)
   737  
   738  	violationsoff := builder.CreateByteVector(fields.violations)
   739  	artifactsoff := builder.CreateByteVector(fields.artifacts)
   740  
   741  	serial.TableStart(builder)
   742  	serial.TableAddSchema(builder, schemaoff)
   743  	serial.TableAddPrimaryIndex(builder, rowsoff)
   744  	serial.TableAddSecondaryIndexes(builder, indexesoff)
   745  	serial.TableAddAutoIncrementValue(builder, fields.autoincval)
   746  	serial.TableAddConflicts(builder, conflictsoff)
   747  	serial.TableAddViolations(builder, violationsoff)
   748  	serial.TableAddArtifacts(builder, artifactsoff)
   749  	bs := serial.FinishMessage(builder, serial.TableEnd(builder), []byte(serial.TableFileID))
   750  	return serial.TryGetRootAsTable(bs, serial.MessagePrefixSz)
   751  }
   752  
   753  func newDoltDevTable(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema, rows Index, indexes IndexSet, autoIncVal types.Value) (Table, error) {
   754  	schVal, err := encoding.MarshalSchema(ctx, vrw, sch)
   755  	if err != nil {
   756  		return nil, err
   757  	}
   758  
   759  	schemaRef, err := refFromNomsValue(ctx, vrw, schVal)
   760  	if err != nil {
   761  		return nil, err
   762  	}
   763  	schemaAddr := schemaRef.TargetHash()
   764  
   765  	rowsbytes, err := rows.bytes()
   766  	if err != nil {
   767  		return nil, err
   768  	}
   769  
   770  	if indexes == nil {
   771  		indexes, err = NewIndexSet(ctx, vrw, ns)
   772  		if err != nil {
   773  			return nil, err
   774  		}
   775  	}
   776  
   777  	var autoInc uint64
   778  	if autoIncVal != nil {
   779  		autoInc = uint64(autoIncVal.(types.Uint))
   780  	}
   781  
   782  	var emptyhash hash.Hash
   783  	msg, err := serialTableFields{
   784  		schema:            schemaAddr[:],
   785  		rows:              rowsbytes,
   786  		indexes:           indexes.(doltDevIndexSet).am,
   787  		conflictsdata:     emptyhash[:],
   788  		conflictsours:     emptyhash[:],
   789  		conflictstheirs:   emptyhash[:],
   790  		conflictsancestor: emptyhash[:],
   791  		violations:        emptyhash[:],
   792  		artifacts:         emptyhash[:],
   793  		autoincval:        autoInc,
   794  	}.write()
   795  	if err != nil {
   796  		return nil, err
   797  	}
   798  
   799  	return doltDevTable{vrw, ns, msg}, nil
   800  }
   801  
   802  func (t doltDevTable) nomsValue() types.Value {
   803  	return types.SerialMessage(t.msg.Table().Bytes)
   804  }
   805  
   806  func (t doltDevTable) HashOf() (hash.Hash, error) {
   807  	return t.nomsValue().Hash(t.Format())
   808  }
   809  
   810  func (t doltDevTable) Format() *types.NomsBinFormat {
   811  	return t.vrw.Format()
   812  }
   813  
   814  func (t doltDevTable) GetSchemaHash(ctx context.Context) (hash.Hash, error) {
   815  	return hash.New(t.msg.SchemaBytes()), nil
   816  }
   817  
   818  func (t doltDevTable) GetSchema(ctx context.Context) (schema.Schema, error) {
   819  	addr := hash.New(t.msg.SchemaBytes())
   820  	return schemaFromAddr(ctx, t.vrw, addr)
   821  }
   822  
   823  func (t doltDevTable) SetSchema(ctx context.Context, sch schema.Schema) (Table, error) {
   824  	newSchemaVal, err := encoding.MarshalSchema(ctx, t.vrw, sch)
   825  	if err != nil {
   826  		return nil, err
   827  	}
   828  
   829  	schRef, err := refFromNomsValue(ctx, t.vrw, newSchemaVal)
   830  	if err != nil {
   831  		return nil, err
   832  	}
   833  
   834  	addr := schRef.TargetHash()
   835  	msg := t.clone()
   836  	copy(msg.SchemaBytes(), addr[:])
   837  	return doltDevTable{t.vrw, t.ns, msg}, nil
   838  }
   839  
   840  func (t doltDevTable) GetTableRows(ctx context.Context) (Index, error) {
   841  	rowbytes := t.msg.PrimaryIndexBytes()
   842  	sch, err := t.GetSchema(ctx)
   843  	if err != nil {
   844  		return nil, err
   845  	}
   846  	m, err := shim.MapFromValue(types.SerialMessage(rowbytes), sch, t.ns)
   847  	if err != nil {
   848  		return nil, err
   849  	}
   850  	return IndexFromProllyMap(m), nil
   851  }
   852  
   853  func (t doltDevTable) SetTableRows(ctx context.Context, rows Index) (Table, error) {
   854  	rowsbytes, err := rows.bytes()
   855  	if err != nil {
   856  		return nil, err
   857  	}
   858  
   859  	fields, err := t.fields()
   860  	if err != nil {
   861  		return nil, err
   862  	}
   863  	fields.rows = rowsbytes
   864  	msg, err := fields.write()
   865  	if err != nil {
   866  		return nil, err
   867  	}
   868  
   869  	return doltDevTable{t.vrw, t.ns, msg}, nil
   870  }
   871  
   872  func (t doltDevTable) GetIndexes(ctx context.Context) (IndexSet, error) {
   873  	ambytes := t.msg.SecondaryIndexesBytes()
   874  	node, err := tree.NodeFromBytes(ambytes)
   875  	if err != nil {
   876  		return nil, err
   877  	}
   878  	ns := t.ns
   879  	am, err := prolly.NewAddressMap(node, ns)
   880  	if err != nil {
   881  		return nil, err
   882  	}
   883  	return doltDevIndexSet{t.vrw, t.ns, am}, nil
   884  }
   885  
   886  func (t doltDevTable) SetIndexes(ctx context.Context, indexes IndexSet) (Table, error) {
   887  	fields, err := t.fields()
   888  	if err != nil {
   889  		return nil, err
   890  	}
   891  	fields.indexes = indexes.(doltDevIndexSet).am
   892  	msg, err := fields.write()
   893  	if err != nil {
   894  		return nil, err
   895  	}
   896  	return doltDevTable{t.vrw, t.ns, msg}, nil
   897  }
   898  
   899  func (t doltDevTable) GetConflicts(ctx context.Context) (conflict.ConflictSchema, ConflictIndex, error) {
   900  	conflicts, err := t.msg.TryConflicts(nil)
   901  	if err != nil {
   902  		return conflict.ConflictSchema{}, nil, err
   903  	}
   904  
   905  	ouraddr := hash.New(conflicts.OurSchemaBytes())
   906  	theiraddr := hash.New(conflicts.TheirSchemaBytes())
   907  	baseaddr := hash.New(conflicts.AncestorSchemaBytes())
   908  
   909  	if ouraddr.IsEmpty() {
   910  		sch, err := t.GetSchema(ctx)
   911  		if err != nil {
   912  			return conflict.ConflictSchema{}, nil, err
   913  		}
   914  		empty, err := NewEmptyConflictIndex(ctx, t.vrw, t.ns, sch, sch, sch)
   915  		if err != nil {
   916  			return conflict.ConflictSchema{}, nil, err
   917  		}
   918  		return conflict.ConflictSchema{}, empty, nil
   919  	}
   920  
   921  	ourschema, err := getSchemaAtAddr(ctx, t.vrw, ouraddr)
   922  	if err != nil {
   923  		return conflict.ConflictSchema{}, nil, err
   924  	}
   925  	theirschema, err := getSchemaAtAddr(ctx, t.vrw, theiraddr)
   926  	if err != nil {
   927  		return conflict.ConflictSchema{}, nil, err
   928  	}
   929  	baseschema, err := getSchemaAtAddr(ctx, t.vrw, baseaddr)
   930  	if err != nil {
   931  		return conflict.ConflictSchema{}, nil, err
   932  	}
   933  
   934  	conflictschema := conflict.ConflictSchema{
   935  		Base:        baseschema,
   936  		Schema:      ourschema,
   937  		MergeSchema: theirschema,
   938  	}
   939  
   940  	mapaddr := hash.New(conflicts.DataBytes())
   941  	var conflictIdx ConflictIndex
   942  	if mapaddr.IsEmpty() {
   943  		conflictIdx, err = NewEmptyConflictIndex(ctx, t.vrw, t.ns, ourschema, theirschema, baseschema)
   944  		if err != nil {
   945  			return conflict.ConflictSchema{}, nil, err
   946  		}
   947  	} else {
   948  		conflictIdx, err = conflictIndexFromAddr(ctx, t.vrw, t.ns, ourschema, theirschema, baseschema, mapaddr)
   949  		if err != nil {
   950  			return conflict.ConflictSchema{}, nil, err
   951  		}
   952  	}
   953  
   954  	return conflictschema, conflictIdx, nil
   955  }
   956  
   957  // GetArtifacts implements Table.
   958  func (t doltDevTable) GetArtifacts(ctx context.Context) (ArtifactIndex, error) {
   959  	if t.Format() != types.Format_DOLT {
   960  		panic("artifacts only implemented for DOLT")
   961  	}
   962  
   963  	sch, err := t.GetSchema(ctx)
   964  	if err != nil {
   965  		return nil, err
   966  	}
   967  
   968  	addr := hash.New(t.msg.ArtifactsBytes())
   969  	if addr.IsEmpty() {
   970  		return NewEmptyArtifactIndex(ctx, t.vrw, t.ns, sch)
   971  	}
   972  
   973  	return artifactIndexFromAddr(ctx, t.vrw, t.ns, sch, addr)
   974  }
   975  
   976  // SetArtifacts implements Table.
   977  func (t doltDevTable) SetArtifacts(ctx context.Context, artifacts ArtifactIndex) (Table, error) {
   978  	if t.Format() != types.Format_DOLT {
   979  		panic("artifacts only implemented for DOLT")
   980  	}
   981  
   982  	var addr hash.Hash
   983  	if artifacts != nil {
   984  		c, err := artifacts.Count()
   985  		if err != nil {
   986  			return nil, err
   987  		}
   988  		if c != 0 {
   989  			ref, err := RefFromArtifactIndex(ctx, t.vrw, artifacts)
   990  			if err != nil {
   991  				return nil, err
   992  			}
   993  			addr = ref.TargetHash()
   994  		}
   995  	}
   996  	msg := t.clone()
   997  	copy(msg.ArtifactsBytes(), addr[:])
   998  	return doltDevTable{t.vrw, t.ns, msg}, nil
   999  }
  1000  
  1001  func (t doltDevTable) HasConflicts(ctx context.Context) (bool, error) {
  1002  
  1003  	conflicts, err := t.msg.TryConflicts(nil)
  1004  	if err != nil {
  1005  		return false, err
  1006  	}
  1007  	addr := hash.New(conflicts.OurSchemaBytes())
  1008  	return !addr.IsEmpty(), nil
  1009  }
  1010  
  1011  func (t doltDevTable) SetConflicts(ctx context.Context, sch conflict.ConflictSchema, conflicts ConflictIndex) (Table, error) {
  1012  	conflictsRef, err := RefFromConflictIndex(ctx, t.vrw, conflicts)
  1013  	if err != nil {
  1014  		return nil, err
  1015  	}
  1016  	conflictsAddr := conflictsRef.TargetHash()
  1017  
  1018  	baseaddr, err := getAddrForSchema(ctx, t.vrw, sch.Base)
  1019  	if err != nil {
  1020  		return nil, err
  1021  	}
  1022  	ouraddr, err := getAddrForSchema(ctx, t.vrw, sch.Schema)
  1023  	if err != nil {
  1024  		return nil, err
  1025  	}
  1026  	theiraddr, err := getAddrForSchema(ctx, t.vrw, sch.MergeSchema)
  1027  	if err != nil {
  1028  		return nil, err
  1029  	}
  1030  
  1031  	msg := t.clone()
  1032  	cmsg, err := msg.TryConflicts(nil)
  1033  	if err != nil {
  1034  		return nil, err
  1035  	}
  1036  	copy(cmsg.DataBytes(), conflictsAddr[:])
  1037  	copy(cmsg.OurSchemaBytes(), ouraddr[:])
  1038  	copy(cmsg.TheirSchemaBytes(), theiraddr[:])
  1039  	copy(cmsg.AncestorSchemaBytes(), baseaddr[:])
  1040  
  1041  	return doltDevTable{t.vrw, t.ns, msg}, nil
  1042  }
  1043  
  1044  func (t doltDevTable) ClearConflicts(ctx context.Context) (Table, error) {
  1045  	msg := t.clone()
  1046  	conflicts, err := msg.TryConflicts(nil)
  1047  	if err != nil {
  1048  		return nil, err
  1049  	}
  1050  	var emptyhash hash.Hash
  1051  	copy(conflicts.DataBytes(), emptyhash[:])
  1052  	copy(conflicts.OurSchemaBytes(), emptyhash[:])
  1053  	copy(conflicts.TheirSchemaBytes(), emptyhash[:])
  1054  	copy(conflicts.AncestorSchemaBytes(), emptyhash[:])
  1055  	return doltDevTable{t.vrw, t.ns, msg}, nil
  1056  }
  1057  
  1058  func (t doltDevTable) GetConstraintViolations(ctx context.Context) (types.Map, error) {
  1059  	addr := hash.New(t.msg.ViolationsBytes())
  1060  	if addr.IsEmpty() {
  1061  		return types.NewMap(ctx, t.vrw)
  1062  	}
  1063  	v, err := t.vrw.ReadValue(ctx, addr)
  1064  	if err != nil {
  1065  		return types.Map{}, err
  1066  	}
  1067  	return v.(types.Map), nil
  1068  }
  1069  
  1070  func (t doltDevTable) SetConstraintViolations(ctx context.Context, violations types.Map) (Table, error) {
  1071  	var addr hash.Hash
  1072  	if violations != types.EmptyMap && violations.Len() != 0 {
  1073  		ref, err := refFromNomsValue(ctx, t.vrw, violations)
  1074  		if err != nil {
  1075  			return nil, err
  1076  		}
  1077  		addr = ref.TargetHash()
  1078  	}
  1079  	msg := t.clone()
  1080  	copy(msg.ViolationsBytes(), addr[:])
  1081  	return doltDevTable{t.vrw, t.ns, msg}, nil
  1082  }
  1083  
  1084  func (t doltDevTable) GetAutoIncrement(ctx context.Context) (uint64, error) {
  1085  	res := t.msg.AutoIncrementValue()
  1086  	if res == 0 {
  1087  		return 1, nil
  1088  	}
  1089  	return res, nil
  1090  }
  1091  
  1092  func (t doltDevTable) SetAutoIncrement(ctx context.Context, val uint64) (Table, error) {
  1093  	// TODO: This clones before checking if the mutate will work.
  1094  	msg := t.clone()
  1095  	if !msg.MutateAutoIncrementValue(val) {
  1096  		fields, err := t.fields()
  1097  		if err != nil {
  1098  			return nil, err
  1099  		}
  1100  		fields.autoincval = val
  1101  		msg, err = fields.write()
  1102  		if err != nil {
  1103  			return nil, err
  1104  		}
  1105  	}
  1106  	return doltDevTable{t.vrw, t.ns, msg}, nil
  1107  }
  1108  
  1109  func (t doltDevTable) clone() *serial.Table {
  1110  	bs := make([]byte, len(t.msg.Table().Bytes))
  1111  	copy(bs, t.msg.Table().Bytes)
  1112  	var ret serial.Table
  1113  	ret.Init(bs, t.msg.Table().Pos)
  1114  	return &ret
  1115  }
  1116  
  1117  func (t doltDevTable) fields() (serialTableFields, error) {
  1118  	ambytes := t.msg.SecondaryIndexesBytes()
  1119  	node, err := tree.NodeFromBytes(ambytes)
  1120  	if err != nil {
  1121  		return serialTableFields{}, err
  1122  	}
  1123  	ns := t.ns
  1124  
  1125  	conflicts, err := t.msg.TryConflicts(nil)
  1126  	if err != nil {
  1127  		return serialTableFields{}, err
  1128  	}
  1129  	am, err := prolly.NewAddressMap(node, ns)
  1130  	if err != nil {
  1131  		return serialTableFields{}, err
  1132  	}
  1133  	return serialTableFields{
  1134  		schema:            t.msg.SchemaBytes(),
  1135  		rows:              t.msg.PrimaryIndexBytes(),
  1136  		indexes:           am,
  1137  		conflictsdata:     conflicts.DataBytes(),
  1138  		conflictsours:     conflicts.OurSchemaBytes(),
  1139  		conflictstheirs:   conflicts.TheirSchemaBytes(),
  1140  		conflictsancestor: conflicts.AncestorSchemaBytes(),
  1141  		violations:        t.msg.ViolationsBytes(),
  1142  		artifacts:         t.msg.ArtifactsBytes(),
  1143  		autoincval:        t.msg.AutoIncrementValue(),
  1144  	}, nil
  1145  }
  1146  
  1147  func getSchemaAtAddr(ctx context.Context, vrw types.ValueReadWriter, addr hash.Hash) (schema.Schema, error) {
  1148  	return encoding.UnmarshalSchemaAtAddr(ctx, vrw, addr)
  1149  }
  1150  
  1151  func getAddrForSchema(ctx context.Context, vrw types.ValueReadWriter, sch schema.Schema) (hash.Hash, error) {
  1152  	st, err := encoding.MarshalSchema(ctx, vrw, sch)
  1153  	if err != nil {
  1154  		return hash.Hash{}, err
  1155  	}
  1156  	ref, err := vrw.WriteValue(ctx, st)
  1157  	if err != nil {
  1158  		return hash.Hash{}, err
  1159  	}
  1160  	return ref.TargetHash(), nil
  1161  }