mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-10 18:49:02 -06:00
Merge pull request #4722 from dolthub/james/prefix-index
implementing prefix indexes for string types
This commit is contained in:
@@ -649,7 +649,33 @@ func (rcv *Index) MutateSystemDefined(n bool) bool {
|
||||
return rcv._tab.MutateBoolSlot(18, n)
|
||||
}
|
||||
|
||||
const IndexNumFields = 8
|
||||
func (rcv *Index) PrefixLengths(j int) uint16 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetUint16(a + flatbuffers.UOffsetT(j*2))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Index) PrefixLengthsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Index) MutatePrefixLengths(j int, n uint16) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateUint16(a+flatbuffers.UOffsetT(j*2), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const IndexNumFields = 9
|
||||
|
||||
func IndexStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(IndexNumFields)
|
||||
@@ -687,6 +713,12 @@ func IndexAddUniqueKey(builder *flatbuffers.Builder, uniqueKey bool) {
|
||||
func IndexAddSystemDefined(builder *flatbuffers.Builder, systemDefined bool) {
|
||||
builder.PrependBoolSlot(7, systemDefined, false)
|
||||
}
|
||||
func IndexAddPrefixLengths(builder *flatbuffers.Builder, prefixLengths flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(8, flatbuffers.UOffsetT(prefixLengths), 0)
|
||||
}
|
||||
func IndexStartPrefixLengthsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(2, numElems, 2)
|
||||
}
|
||||
func IndexEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ require (
|
||||
github.com/cenkalti/backoff/v4 v4.1.3
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/creasty/defaults v1.6.0
|
||||
github.com/dolthub/go-mysql-server v0.14.1-0.20221110233726-0dafee9b8f80
|
||||
github.com/dolthub/go-mysql-server v0.14.1-0.20221111192934-cf0c1818d579
|
||||
github.com/google/flatbuffers v2.0.6+incompatible
|
||||
github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6
|
||||
github.com/mitchellh/go-ps v1.0.0
|
||||
|
||||
@@ -180,8 +180,8 @@ github.com/dolthub/flatbuffers v1.13.0-dh.1 h1:OWJdaPep22N52O/0xsUevxJ6Qfw1M2txC
|
||||
github.com/dolthub/flatbuffers v1.13.0-dh.1/go.mod h1:CorYGaDmXjHz1Z7i50PYXG1Ricn31GcA2wNOTFIQAKE=
|
||||
github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U=
|
||||
github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0=
|
||||
github.com/dolthub/go-mysql-server v0.14.1-0.20221110233726-0dafee9b8f80 h1:38XwYasYADK4SO+rxwmTD2hE8zngczzKSNo2XmYFe0Q=
|
||||
github.com/dolthub/go-mysql-server v0.14.1-0.20221110233726-0dafee9b8f80/go.mod h1:KtpU4Sf7J+SIat/nxoA733QTn3tdL34NtoGxEBFcTsA=
|
||||
github.com/dolthub/go-mysql-server v0.14.1-0.20221111192934-cf0c1818d579 h1:rOV6whqkxka2wGMGD/DOgUgX0jWw/gaJwTMqJ1ye2wA=
|
||||
github.com/dolthub/go-mysql-server v0.14.1-0.20221111192934-cf0c1818d579/go.mod h1:KtpU4Sf7J+SIat/nxoA733QTn3tdL34NtoGxEBFcTsA=
|
||||
github.com/dolthub/ishell v0.0.0-20220112232610-14e753f0f371 h1:oyPHJlzumKta1vnOQqUnfdz+pk3EmnHS3Nd0cCT0I2g=
|
||||
github.com/dolthub/ishell v0.0.0-20220112232610-14e753f0f371/go.mod h1:dhGBqcCEfK5kuFmeO5+WOx3hqc1k3M29c1oS/R7N4ms=
|
||||
github.com/dolthub/jsonpath v0.0.0-20210609232853-d49537a30474 h1:xTrR+l5l+1Lfq0NvhiEsctylXinUMFhhsqaEcl414p8=
|
||||
|
||||
@@ -64,9 +64,9 @@ func createTestSchema(t *testing.T) schema.Schema {
|
||||
)
|
||||
sch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
_, err = sch.Indexes().AddIndexByColTags(testSchemaIndexName, []uint64{firstTag, lastTag}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err = sch.Indexes().AddIndexByColTags(testSchemaIndexName, []uint64{firstTag, lastTag}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
_, err = sch.Indexes().AddIndexByColTags(testSchemaIndexAge, []uint64{ageTag}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err = sch.Indexes().AddIndexByColTags(testSchemaIndexAge, []uint64{ageTag}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
return sch
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ func Schema() (schema.Schema, error) {
|
||||
)
|
||||
sch := schema.MustSchemaFromCols(typedColColl)
|
||||
|
||||
_, err := sch.Indexes().AddIndexByColTags(IndexName, []uint64{NameTag}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err := sch.Indexes().AddIndexByColTags(IndexName, []uint64{NameTag}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ var indexSchema schema.Index
|
||||
var compositeIndexSchema schema.Index
|
||||
|
||||
func init() {
|
||||
indexSchema, _ = sch.Indexes().AddIndexByColTags("idx_col1", []uint64{col1Tag}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
compositeIndexSchema, _ = sch.Indexes().AddIndexByColTags("idx_col1_col2", []uint64{col1Tag, col2Tag}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
indexSchema, _ = sch.Indexes().AddIndexByColTags("idx_col1", []uint64{col1Tag}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
compositeIndexSchema, _ = sch.Indexes().AddIndexByColTags("idx_col1_col2", []uint64{col1Tag, col2Tag}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
}
|
||||
|
||||
type rowV struct {
|
||||
|
||||
@@ -154,7 +154,7 @@ func SetupHookRefKeys(ctx context.Context, dEnv *env.DoltEnv) (*env.DoltEnv, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = sch.Indexes().AddIndexByColNames("blob_idx", []string{"c1"}, schema.IndexProperties{IsUserDefined: true})
|
||||
_, err = sch.Indexes().AddIndexByColNames("blob_idx", []string{"c1"}, nil, schema.IndexProperties{IsUserDefined: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ var sch, _ = schema.SchemaFromPKAndNonPKCols(testKeyColColl, testNonKeyColColl)
|
||||
var index schema.Index
|
||||
|
||||
func init() {
|
||||
index, _ = sch.Indexes().AddIndexByColTags(indexName, []uint64{ageColTag}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
index, _ = sch.Indexes().AddIndexByColTags(indexName, []uint64{ageColTag}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
}
|
||||
|
||||
func newTestRow() (Row, error) {
|
||||
|
||||
@@ -152,6 +152,7 @@ type encodedIndex struct {
|
||||
Comment string `noms:"comment" json:"comment"`
|
||||
Unique bool `noms:"unique" json:"unique"`
|
||||
IsSystemDefined bool `noms:"hidden,omitempty" json:"hidden,omitempty"` // Was previously named Hidden, do not change noms name
|
||||
PrefixLengths []uint16 `noms:"prefixLengths,omitempty" json:"prefixLengths,omitempty"`
|
||||
}
|
||||
|
||||
type encodedCheck struct {
|
||||
@@ -186,6 +187,12 @@ func (sd *schemaData) Copy() *schemaData {
|
||||
for j, tag := range idx.Tags {
|
||||
idxCol[i].Tags[j] = tag
|
||||
}
|
||||
if len(idx.PrefixLengths) > 0 {
|
||||
idxCol[i].PrefixLengths = make([]uint16, len(idx.PrefixLengths))
|
||||
for j, prefixLength := range idx.PrefixLengths {
|
||||
idxCol[i].PrefixLengths[j] = prefixLength
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,6 +245,7 @@ func toSchemaData(sch schema.Schema) (schemaData, error) {
|
||||
Comment: index.Comment(),
|
||||
Unique: index.IsUnique(),
|
||||
IsSystemDefined: !index.IsUserDefined(),
|
||||
PrefixLengths: index.PrefixLengths(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,6 +304,7 @@ func (sd schemaData) addChecksIndexesAndPkOrderingToSchema(sch schema.Schema) er
|
||||
_, err := sch.Indexes().UnsafeAddIndexByColTags(
|
||||
encodedIndex.Name,
|
||||
encodedIndex.Tags,
|
||||
encodedIndex.PrefixLengths,
|
||||
schema.IndexProperties{
|
||||
IsUnique: encodedIndex.Unique,
|
||||
IsUserDefined: !encodedIndex.IsSystemDefined,
|
||||
|
||||
@@ -46,7 +46,7 @@ func createTestSchema() schema.Schema {
|
||||
|
||||
colColl := schema.NewColCollection(columns...)
|
||||
sch := schema.MustSchemaFromCols(colColl)
|
||||
_, _ = sch.Indexes().AddIndexByColTags("idx_age", []uint64{3}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, _ = sch.Indexes().AddIndexByColTags("idx_age", []uint64{3}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
return sch
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ func (tsd testSchemaData) decodeSchema() (schema.Schema, error) {
|
||||
sch.SetCollation(tsd.Collation)
|
||||
|
||||
for _, encodedIndex := range tsd.IndexCollection {
|
||||
_, err = sch.Indexes().AddIndexByColTags(encodedIndex.Name, encodedIndex.Tags, schema.IndexProperties{IsUnique: encodedIndex.Unique, Comment: encodedIndex.Comment})
|
||||
_, err = sch.Indexes().AddIndexByColTags(encodedIndex.Name, encodedIndex.Tags, nil, schema.IndexProperties{IsUnique: encodedIndex.Unique, Comment: encodedIndex.Comment})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -333,6 +333,14 @@ func serializeSecondaryIndexes(b *fb.Builder, sch schema.Schema, indexes []schem
|
||||
}
|
||||
ko := b.EndVector(len(tags))
|
||||
|
||||
// serialize prefix lengths
|
||||
prefixLengths := idx.PrefixLengths()
|
||||
serial.IndexStartPrefixLengthsVector(b, len(prefixLengths))
|
||||
for j := len(prefixLengths) - 1; j >= 0; j-- {
|
||||
b.PrependUint16(prefixLengths[j])
|
||||
}
|
||||
po := b.EndVector(len(prefixLengths))
|
||||
|
||||
serial.IndexStart(b)
|
||||
serial.IndexAddName(b, no)
|
||||
serial.IndexAddComment(b, co)
|
||||
@@ -341,6 +349,7 @@ func serializeSecondaryIndexes(b *fb.Builder, sch schema.Schema, indexes []schem
|
||||
serial.IndexAddPrimaryKey(b, false)
|
||||
serial.IndexAddUniqueKey(b, idx.IsUnique())
|
||||
serial.IndexAddSystemDefined(b, !idx.IsUserDefined())
|
||||
serial.IndexAddPrefixLengths(b, po)
|
||||
offs[i] = serial.IndexEnd(b)
|
||||
}
|
||||
|
||||
@@ -372,7 +381,16 @@ func deserializeSecondaryIndexes(sch schema.Schema, s *serial.TableSchema) error
|
||||
tags[j] = col.Tag()
|
||||
}
|
||||
|
||||
_, err := sch.Indexes().AddIndexByColTags(name, tags, props)
|
||||
var prefixLengths []uint16
|
||||
prefixLengthsLength := idx.PrefixLengthsLength()
|
||||
if prefixLengthsLength > 0 {
|
||||
prefixLengths = make([]uint16, prefixLengthsLength)
|
||||
for j := range prefixLengths {
|
||||
prefixLengths[j] = idx.PrefixLengths(j)
|
||||
}
|
||||
}
|
||||
|
||||
_, err := sch.Indexes().AddIndexByColTags(name, tags, prefixLengths, props)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ type Index interface {
|
||||
// ToTableTuple returns a tuple that may be used to retrieve the original row from the indexed table when given
|
||||
// a full index key (and not a partial index key).
|
||||
ToTableTuple(ctx context.Context, fullKey types.Tuple, format *types.NomsBinFormat) (types.Tuple, error)
|
||||
// PrefixLengths returns the prefix lengths for the index
|
||||
PrefixLengths() []uint16
|
||||
}
|
||||
|
||||
var _ Index = (*indexImpl)(nil)
|
||||
@@ -66,6 +68,7 @@ type indexImpl struct {
|
||||
isUnique bool
|
||||
isUserDefined bool
|
||||
comment string
|
||||
prefixLengths []uint16
|
||||
}
|
||||
|
||||
func NewIndex(name string, tags, allTags []uint64, indexColl IndexCollection, props IndexProperties) Index {
|
||||
@@ -241,6 +244,11 @@ func (ix *indexImpl) ToTableTuple(ctx context.Context, fullKey types.Tuple, form
|
||||
return types.NewTuple(format, resVals...)
|
||||
}
|
||||
|
||||
// GetPrefixLengths implements Index.
|
||||
func (ix *indexImpl) PrefixLengths() []uint16 {
|
||||
return ix.prefixLengths
|
||||
}
|
||||
|
||||
// copy returns an exact copy of the calling index.
|
||||
func (ix *indexImpl) copy() *indexImpl {
|
||||
newIx := *ix
|
||||
@@ -248,5 +256,9 @@ func (ix *indexImpl) copy() *indexImpl {
|
||||
_ = copy(newIx.tags, ix.tags)
|
||||
newIx.allTags = make([]uint64, len(ix.allTags))
|
||||
_ = copy(newIx.allTags, ix.allTags)
|
||||
if len(ix.prefixLengths) > 0 {
|
||||
newIx.prefixLengths = make([]uint16, len(ix.prefixLengths))
|
||||
_ = copy(newIx.prefixLengths, ix.prefixLengths)
|
||||
}
|
||||
return &newIx
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ type IndexCollection interface {
|
||||
// It does not perform any kind of checking, and is intended for schema modifications.
|
||||
AddIndex(indexes ...Index)
|
||||
// AddIndexByColNames adds an index with the given name and columns (in index order).
|
||||
AddIndexByColNames(indexName string, cols []string, props IndexProperties) (Index, error)
|
||||
AddIndexByColNames(indexName string, cols []string, prefixLengths []uint16, props IndexProperties) (Index, error)
|
||||
// AddIndexByColTags adds an index with the given name and column tags (in index order).
|
||||
AddIndexByColTags(indexName string, tags []uint64, props IndexProperties) (Index, error)
|
||||
AddIndexByColTags(indexName string, tags []uint64, prefixLengths []uint16, props IndexProperties) (Index, error)
|
||||
// todo: this method is trash, clean up this interface
|
||||
UnsafeAddIndexByColTags(indexName string, tags []uint64, props IndexProperties) (Index, error)
|
||||
UnsafeAddIndexByColTags(indexName string, tags []uint64, prefixLengths []uint16, props IndexProperties) (Index, error)
|
||||
// AllIndexes returns a slice containing all of the indexes in this collection.
|
||||
AllIndexes() []Index
|
||||
// Contains returns whether the given index name already exists for this table.
|
||||
@@ -125,15 +125,15 @@ func (ixc *indexCollectionImpl) AddIndex(indexes ...Index) {
|
||||
}
|
||||
}
|
||||
|
||||
func (ixc *indexCollectionImpl) AddIndexByColNames(indexName string, cols []string, props IndexProperties) (Index, error) {
|
||||
func (ixc *indexCollectionImpl) AddIndexByColNames(indexName string, cols []string, prefixLengths []uint16, props IndexProperties) (Index, error) {
|
||||
tags, ok := ixc.columnNamesToTags(cols)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the table does not contain at least one of the following columns: `%v`", cols)
|
||||
}
|
||||
return ixc.AddIndexByColTags(indexName, tags, props)
|
||||
return ixc.AddIndexByColTags(indexName, tags, prefixLengths, props)
|
||||
}
|
||||
|
||||
func (ixc *indexCollectionImpl) AddIndexByColTags(indexName string, tags []uint64, props IndexProperties) (Index, error) {
|
||||
func (ixc *indexCollectionImpl) AddIndexByColTags(indexName string, tags []uint64, prefixLengths []uint16, props IndexProperties) (Index, error) {
|
||||
if strings.HasPrefix(indexName, "dolt_") {
|
||||
return nil, fmt.Errorf("indexes cannot be prefixed with `dolt_`")
|
||||
}
|
||||
@@ -161,6 +161,7 @@ func (ixc *indexCollectionImpl) AddIndexByColTags(indexName string, tags []uint6
|
||||
isUnique: props.IsUnique,
|
||||
isUserDefined: props.IsUserDefined,
|
||||
comment: props.Comment,
|
||||
prefixLengths: prefixLengths,
|
||||
}
|
||||
ixc.indexes[indexName] = index
|
||||
for _, tag := range tags {
|
||||
@@ -177,7 +178,7 @@ func validateColumnIndexable(c Column) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ixc *indexCollectionImpl) UnsafeAddIndexByColTags(indexName string, tags []uint64, props IndexProperties) (Index, error) {
|
||||
func (ixc *indexCollectionImpl) UnsafeAddIndexByColTags(indexName string, tags []uint64, prefixLengths []uint16, props IndexProperties) (Index, error) {
|
||||
index := &indexImpl{
|
||||
indexColl: ixc,
|
||||
name: indexName,
|
||||
@@ -186,6 +187,7 @@ func (ixc *indexCollectionImpl) UnsafeAddIndexByColTags(indexName string, tags [
|
||||
isUnique: props.IsUnique,
|
||||
isUserDefined: props.IsUserDefined,
|
||||
comment: props.Comment,
|
||||
prefixLengths: prefixLengths,
|
||||
}
|
||||
ixc.indexes[indexName] = index
|
||||
for _, tag := range tags {
|
||||
@@ -325,6 +327,7 @@ func (ixc *indexCollectionImpl) Merge(indexes ...Index) {
|
||||
isUnique: index.IsUnique(),
|
||||
isUserDefined: index.IsUserDefined(),
|
||||
comment: index.Comment(),
|
||||
prefixLengths: index.PrefixLengths(),
|
||||
}
|
||||
ixc.AddIndex(newIndex)
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ func TestIndexCollectionAddIndexByColNames(t *testing.T) {
|
||||
assert.False(t, indexColl.hasIndexOnTags(testIndex.index.IndexedColumnTags()...))
|
||||
assert.Nil(t, indexColl.GetByName(testIndex.index.Name()))
|
||||
|
||||
resIndex, err := indexColl.AddIndexByColNames(testIndex.index.Name(), testIndex.cols, IndexProperties{IsUnique: testIndex.index.IsUnique(), Comment: testIndex.index.Comment()})
|
||||
resIndex, err := indexColl.AddIndexByColNames(testIndex.index.Name(), testIndex.cols, nil, IndexProperties{IsUnique: testIndex.index.IsUnique(), Comment: testIndex.index.Comment()})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testIndex.index, resIndex)
|
||||
assert.Equal(t, testIndex.index, indexColl.GetByName(resIndex.Name()))
|
||||
@@ -216,20 +216,20 @@ func TestIndexCollectionAddIndexByColNames(t *testing.T) {
|
||||
|
||||
t.Run("Pre-existing", func(t *testing.T) {
|
||||
for _, testIndex := range testIndexes {
|
||||
_, err := indexColl.AddIndexByColNames(testIndex.index.Name(), testIndex.cols, IndexProperties{IsUnique: testIndex.index.IsUnique(), Comment: testIndex.index.Comment()})
|
||||
_, err := indexColl.AddIndexByColNames(testIndex.index.Name(), testIndex.cols, nil, IndexProperties{IsUnique: testIndex.index.IsUnique(), Comment: testIndex.index.Comment()})
|
||||
assert.NoError(t, err)
|
||||
_, err = indexColl.AddIndexByColNames(testIndex.index.Name()+"copy", testIndex.cols, IndexProperties{IsUnique: testIndex.index.IsUnique(), Comment: testIndex.index.Comment()})
|
||||
_, err = indexColl.AddIndexByColNames(testIndex.index.Name()+"copy", testIndex.cols, nil, IndexProperties{IsUnique: testIndex.index.IsUnique(), Comment: testIndex.index.Comment()})
|
||||
assert.NoError(t, err)
|
||||
_, err = indexColl.AddIndexByColNames(testIndex.index.Name(), []string{"v2"}, IndexProperties{IsUnique: testIndex.index.IsUnique(), Comment: testIndex.index.Comment()})
|
||||
_, err = indexColl.AddIndexByColNames(testIndex.index.Name(), []string{"v2"}, nil, IndexProperties{IsUnique: testIndex.index.IsUnique(), Comment: testIndex.index.Comment()})
|
||||
assert.Error(t, err)
|
||||
}
|
||||
indexColl.clear(t)
|
||||
})
|
||||
|
||||
t.Run("Non-existing Columns", func(t *testing.T) {
|
||||
_, err := indexColl.AddIndexByColNames("nonsense", []string{"v4"}, IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err := indexColl.AddIndexByColNames("nonsense", []string{"v4"}, nil, IndexProperties{IsUnique: false, Comment: ""})
|
||||
assert.Error(t, err)
|
||||
_, err = indexColl.AddIndexByColNames("nonsense", []string{"v1", "v2", "pk3"}, IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err = indexColl.AddIndexByColNames("nonsense", []string{"v1", "v2", "pk3"}, nil, IndexProperties{IsUnique: false, Comment: ""})
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
@@ -279,7 +279,7 @@ func TestIndexCollectionAddIndexByColTags(t *testing.T) {
|
||||
assert.False(t, indexColl.hasIndexOnTags(testIndex.IndexedColumnTags()...))
|
||||
assert.Nil(t, indexColl.GetByName(testIndex.Name()))
|
||||
|
||||
resIndex, err := indexColl.AddIndexByColTags(testIndex.Name(), testIndex.tags, IndexProperties{IsUnique: testIndex.IsUnique(), Comment: testIndex.Comment()})
|
||||
resIndex, err := indexColl.AddIndexByColTags(testIndex.Name(), testIndex.tags, nil, IndexProperties{IsUnique: testIndex.IsUnique(), Comment: testIndex.Comment()})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testIndex, resIndex)
|
||||
assert.Equal(t, testIndex, indexColl.GetByName(resIndex.Name()))
|
||||
@@ -299,20 +299,20 @@ func TestIndexCollectionAddIndexByColTags(t *testing.T) {
|
||||
|
||||
t.Run("Pre-existing", func(t *testing.T) {
|
||||
for _, testIndex := range testIndexes {
|
||||
_, err := indexColl.AddIndexByColTags(testIndex.Name(), testIndex.tags, IndexProperties{IsUnique: testIndex.IsUnique(), Comment: testIndex.Comment()})
|
||||
_, err := indexColl.AddIndexByColTags(testIndex.Name(), testIndex.tags, nil, IndexProperties{IsUnique: testIndex.IsUnique(), Comment: testIndex.Comment()})
|
||||
assert.NoError(t, err)
|
||||
_, err = indexColl.AddIndexByColTags(testIndex.Name()+"copy", testIndex.tags, IndexProperties{IsUnique: testIndex.IsUnique(), Comment: testIndex.Comment()})
|
||||
_, err = indexColl.AddIndexByColTags(testIndex.Name()+"copy", testIndex.tags, nil, IndexProperties{IsUnique: testIndex.IsUnique(), Comment: testIndex.Comment()})
|
||||
assert.NoError(t, err)
|
||||
_, err = indexColl.AddIndexByColTags(testIndex.Name(), []uint64{4}, IndexProperties{IsUnique: testIndex.IsUnique(), Comment: testIndex.Comment()})
|
||||
_, err = indexColl.AddIndexByColTags(testIndex.Name(), []uint64{4}, nil, IndexProperties{IsUnique: testIndex.IsUnique(), Comment: testIndex.Comment()})
|
||||
assert.Error(t, err)
|
||||
}
|
||||
indexColl.clear(t)
|
||||
})
|
||||
|
||||
t.Run("Non-existing Tags", func(t *testing.T) {
|
||||
_, err := indexColl.AddIndexByColTags("nonsense", []uint64{6}, IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err := indexColl.AddIndexByColTags("nonsense", []uint64{6}, nil, IndexProperties{IsUnique: false, Comment: ""})
|
||||
assert.Error(t, err)
|
||||
_, err = indexColl.AddIndexByColTags("nonsense", []uint64{3, 4, 10}, IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err = indexColl.AddIndexByColTags("nonsense", []uint64{3, 4, 10}, nil, IndexProperties{IsUnique: false, Comment: ""})
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
@@ -331,9 +331,9 @@ func TestIndexCollectionAllIndexes(t *testing.T) {
|
||||
name: "idx_z",
|
||||
tags: []uint64{3},
|
||||
})
|
||||
_, err := indexColl.AddIndexByColNames("idx_a", []string{"v2"}, IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err := indexColl.AddIndexByColNames("idx_a", []string{"v2"}, nil, IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
_, err = indexColl.AddIndexByColTags("idx_n", []uint64{5}, IndexProperties{IsUnique: false, Comment: "hello there"})
|
||||
_, err = indexColl.AddIndexByColTags("idx_n", []uint64{5}, nil, IndexProperties{IsUnique: false, Comment: "hello there"})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, []Index{
|
||||
@@ -501,7 +501,7 @@ func TestIndexCollectionDuplicateIndexes(t *testing.T) {
|
||||
assert.Nil(t, indexColl.GetByName(origIndex.index.Name()))
|
||||
|
||||
// Insert origIndex and see that no errors occur
|
||||
resOrigIndex, err := indexColl.AddIndexByColNames(origIndex.index.Name(), origIndex.cols, IndexProperties{IsUnique: origIndex.index.IsUnique(), Comment: origIndex.index.Comment()})
|
||||
resOrigIndex, err := indexColl.AddIndexByColNames(origIndex.index.Name(), origIndex.cols, nil, IndexProperties{IsUnique: origIndex.index.IsUnique(), Comment: origIndex.index.Comment()})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, origIndex.index, resOrigIndex)
|
||||
assert.Equal(t, origIndex.index, indexColl.GetByName(resOrigIndex.Name()))
|
||||
@@ -525,7 +525,7 @@ func TestIndexCollectionDuplicateIndexes(t *testing.T) {
|
||||
assert.Nil(t, indexColl.GetByName(copyIndex.index.Name()))
|
||||
|
||||
// Insert copyIndex and see that no errors occur
|
||||
resCopyIndex, err := indexColl.AddIndexByColNames(copyIndex.index.Name(), copyIndex.cols, IndexProperties{IsUnique: copyIndex.index.IsUnique(), Comment: copyIndex.index.Comment()})
|
||||
resCopyIndex, err := indexColl.AddIndexByColNames(copyIndex.index.Name(), copyIndex.cols, nil, IndexProperties{IsUnique: copyIndex.index.IsUnique(), Comment: copyIndex.index.Comment()})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, copyIndex.index, resCopyIndex)
|
||||
assert.Equal(t, copyIndex.index, indexColl.GetByName(resCopyIndex.Name()))
|
||||
|
||||
@@ -265,11 +265,15 @@ func replaceColumnInSchema(sch schema.Schema, oldCol schema.Column, newCol schem
|
||||
tags[i] = newCol.Tag
|
||||
}
|
||||
}
|
||||
_, err = newSch.Indexes().AddIndexByColTags(index.Name(), tags, schema.IndexProperties{
|
||||
IsUnique: index.IsUnique(),
|
||||
IsUserDefined: index.IsUserDefined(),
|
||||
Comment: index.Comment(),
|
||||
})
|
||||
_, err = newSch.Indexes().AddIndexByColTags(
|
||||
index.Name(),
|
||||
tags,
|
||||
index.PrefixLengths(),
|
||||
schema.IndexProperties{
|
||||
IsUnique: index.IsUnique(),
|
||||
IsUserDefined: index.IsUserDefined(),
|
||||
Comment: index.Comment(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -506,6 +506,7 @@ func TestBlobs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIndexPrefix(t *testing.T) {
|
||||
skipOldFormat(t)
|
||||
harness := newDoltHarness(t)
|
||||
enginetest.TestIndexPrefix(t, harness)
|
||||
for _, script := range DoltIndexPrefixScripts {
|
||||
|
||||
@@ -8126,7 +8126,7 @@ var DoltCommitTests = []queries.ScriptTest{
|
||||
|
||||
var DoltIndexPrefixScripts = []queries.ScriptTest{
|
||||
{
|
||||
Name: "varchar prefix",
|
||||
Name: "varchar primary key prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (v varchar(100))",
|
||||
},
|
||||
@@ -8135,22 +8135,84 @@ var DoltIndexPrefixScripts = []queries.ScriptTest{
|
||||
Query: "alter table t add primary key (v(10))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "alter table t add index (v(10))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "create table v_tbl (v varchar(100), primary key (v(10)))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "create table v_tbl (i int primary key, v varchar(100), index (v(10)))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "char prefix",
|
||||
Name: "varchar keyed secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (i int primary key, v varchar(10))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (v(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `i` int NOT NULL,\n `v` varchar(10),\n PRIMARY KEY (`i`),\n UNIQUE KEY `v` (`v`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values (0, 'aa'), (1, 'ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "insert into t values (0, 'aa'), (1, 'bb'), (2, 'cc')",
|
||||
Expected: []sql.Row{{sql.NewOkResult(3)}},
|
||||
},
|
||||
{
|
||||
Query: "select * from t where v = 'a'",
|
||||
Expected: []sql.Row{},
|
||||
},
|
||||
{
|
||||
Query: "select * from t where v = 'aa'",
|
||||
Expected: []sql.Row{
|
||||
{0, "aa"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "create table v_tbl (i int primary key, v varchar(100), index (v(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table v_tbl",
|
||||
Expected: []sql.Row{{"v_tbl", "CREATE TABLE `v_tbl` (\n `i` int NOT NULL,\n `v` varchar(100),\n PRIMARY KEY (`i`),\n KEY `v` (`v`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "varchar keyless secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (v varchar(10))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (v(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `v` varchar(10),\n UNIQUE KEY `v` (`v`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values ('aa'), ('ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table v_tbl (v varchar(100), index (v(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table v_tbl",
|
||||
Expected: []sql.Row{{"v_tbl", "CREATE TABLE `v_tbl` (\n `v` varchar(100),\n KEY `v` (`v`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "char primary key prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (c char(100))",
|
||||
},
|
||||
@@ -8159,18 +8221,354 @@ var DoltIndexPrefixScripts = []queries.ScriptTest{
|
||||
Query: "alter table t add primary key (c(10))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "alter table t add index (c(10))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "create table c_tbl (c char(100), primary key (c(10)))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "create table c_tbl (i int primary key, c char(100), index (c(10)))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "char keyed secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (i int primary key, c char(10))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (c(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `i` int NOT NULL,\n `c` char(10),\n PRIMARY KEY (`i`),\n UNIQUE KEY `c` (`c`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values (0, 'aa'), (1, 'ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table c_tbl (i int primary key, c varchar(100), index (c(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table c_tbl",
|
||||
Expected: []sql.Row{{"c_tbl", "CREATE TABLE `c_tbl` (\n `i` int NOT NULL,\n `c` varchar(100),\n PRIMARY KEY (`i`),\n KEY `c` (`c`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "char keyless secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (c char(10))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (c(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `c` char(10),\n UNIQUE KEY `c` (`c`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values ('aa'), ('ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table c_tbl (c char(100), index (c(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table c_tbl",
|
||||
Expected: []sql.Row{{"c_tbl", "CREATE TABLE `c_tbl` (\n `c` char(100),\n KEY `c` (`c`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "varbinary primary key prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (v varbinary(100))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add primary key (v(10))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "create table v_tbl (v varbinary(100), primary key (v(10)))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "varbinary keyed secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (i int primary key, v varbinary(10))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (v(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `i` int NOT NULL,\n `v` varbinary(10),\n PRIMARY KEY (`i`),\n UNIQUE KEY `v` (`v`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values (0, 'aa'), (1, 'ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table v_tbl (i int primary key, v varbinary(100), index (v(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table v_tbl",
|
||||
Expected: []sql.Row{{"v_tbl", "CREATE TABLE `v_tbl` (\n `i` int NOT NULL,\n `v` varbinary(100),\n PRIMARY KEY (`i`),\n KEY `v` (`v`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "varbinary keyless secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (v varbinary(10))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (v(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `v` varbinary(10),\n UNIQUE KEY `v` (`v`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values ('aa'), ('ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table v_tbl (v varbinary(100), index (v(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table v_tbl",
|
||||
Expected: []sql.Row{{"v_tbl", "CREATE TABLE `v_tbl` (\n `v` varbinary(100),\n KEY `v` (`v`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "binary primary key prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (b binary(100))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add primary key (b(10))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "create table b_tbl (b binary(100), primary key (b(10)))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "binary keyed secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (i int primary key, b binary(10))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (b(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `i` int NOT NULL,\n `b` binary(10),\n PRIMARY KEY (`i`),\n UNIQUE KEY `b` (`b`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values (0, 'aa'), (1, 'ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table b_tbl (i int primary key, b binary(100), index (b(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table b_tbl",
|
||||
Expected: []sql.Row{{"b_tbl", "CREATE TABLE `b_tbl` (\n `i` int NOT NULL,\n `b` binary(100),\n PRIMARY KEY (`i`),\n KEY `b` (`b`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "binary keyless secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (b binary(10))",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (b(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `b` binary(10),\n UNIQUE KEY `b` (`b`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values ('aa'), ('ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table b_tbl (b binary(100), index (b(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table b_tbl",
|
||||
Expected: []sql.Row{{"b_tbl", "CREATE TABLE `b_tbl` (\n `b` binary(100),\n KEY `b` (`b`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "blob primary key prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (b blob)",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add primary key (b(10))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "create table b_tbl (b blob, primary key (b(10)))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "blob keyed secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (i int primary key, b blob)",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (b(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `i` int NOT NULL,\n `b` blob,\n PRIMARY KEY (`i`),\n UNIQUE KEY `b` (`b`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values (0, 'aa'), (1, 'ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table b_tbl (i int primary key, b blob, index (b(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table b_tbl",
|
||||
Expected: []sql.Row{{"b_tbl", "CREATE TABLE `b_tbl` (\n `i` int NOT NULL,\n `b` blob,\n PRIMARY KEY (`i`),\n KEY `b` (`b`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "blob keyless secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (b blob)",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (b(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `b` blob,\n UNIQUE KEY `b` (`b`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values ('aa'), ('ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table b_tbl (b blob, index (b(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table b_tbl",
|
||||
Expected: []sql.Row{{"b_tbl", "CREATE TABLE `b_tbl` (\n `b` blob,\n KEY `b` (`b`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "text primary key prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (t text)",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add primary key (t(10))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
{
|
||||
Query: "create table b_tbl (t text, primary key (t(10)))",
|
||||
ExpectedErr: sql.ErrUnsupportedIndexPrefix,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "text keyed secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (i int primary key, t text)",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (t(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `i` int NOT NULL,\n `t` text,\n PRIMARY KEY (`i`),\n UNIQUE KEY `t` (`t`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values (0, 'aa'), (1, 'ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table t_tbl (i int primary key, t text, index (t(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t_tbl",
|
||||
Expected: []sql.Row{{"t_tbl", "CREATE TABLE `t_tbl` (\n `i` int NOT NULL,\n `t` text,\n PRIMARY KEY (`i`),\n KEY `t` (`t`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "text keyless secondary index prefix",
|
||||
SetUpScript: []string{
|
||||
"create table t (t text)",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "alter table t add unique index (t(1))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t",
|
||||
Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `t` text,\n UNIQUE KEY `t` (`t`(1))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
{
|
||||
Query: "insert into t values ('aa'), ('ab')",
|
||||
ExpectedErr: sql.ErrUniqueKeyViolation,
|
||||
},
|
||||
{
|
||||
Query: "create table t_tbl (t text, index (t(10)))",
|
||||
Expected: []sql.Row{{sql.NewOkResult(0)}},
|
||||
},
|
||||
{
|
||||
Query: "show create table t_tbl",
|
||||
Expected: []sql.Row{{"t_tbl", "CREATE TABLE `t_tbl` (\n `t` text,\n KEY `t` (`t`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -141,6 +141,11 @@ func validateIndexConsistency(
|
||||
def schema.Index,
|
||||
primary, secondary prolly.Map,
|
||||
) error {
|
||||
// TODO: fix this later
|
||||
if len(def.PrefixLengths()) > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if schema.IsKeyless(sch) {
|
||||
return validateKeylessIndex(ctx, sch, def, primary, secondary)
|
||||
}
|
||||
|
||||
@@ -255,6 +255,7 @@ func getSecondaryIndex(ctx context.Context, db, tbl string, t *doltdb.Table, sch
|
||||
order: sql.IndexOrderAsc,
|
||||
constrainedToLookupExpression: true,
|
||||
doltBinFormat: types.IsFormat_DOLT(vrw.Format()),
|
||||
prefixLengths: idx.PrefixLengths(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -386,12 +387,17 @@ type doltIndex struct {
|
||||
|
||||
cache cachedDurableIndexes
|
||||
doltBinFormat bool
|
||||
|
||||
prefixLengths []uint16
|
||||
}
|
||||
|
||||
var _ DoltIndex = (*doltIndex)(nil)
|
||||
|
||||
// CanSupport implements sql.Index
|
||||
func (di *doltIndex) CanSupport(...sql.Range) bool {
|
||||
if len(di.prefixLengths) > 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -591,6 +597,10 @@ func (di *doltIndex) coversColumns(s *durableIndexState, cols []uint64) bool {
|
||||
return s.coversAllColumns(di)
|
||||
}
|
||||
|
||||
if len(di.prefixLengths) > 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var idxCols *schema.ColCollection
|
||||
if types.IsFormat_DOLT(di.Format()) {
|
||||
// prolly indexes can cover an index lookup using
|
||||
@@ -672,6 +682,11 @@ func (di *doltIndex) Comment() string {
|
||||
return di.comment
|
||||
}
|
||||
|
||||
// PrefixLengths implements sql.Index
|
||||
func (di *doltIndex) PrefixLengths() []uint16 {
|
||||
return di.prefixLengths
|
||||
}
|
||||
|
||||
// IndexType implements sql.Index
|
||||
func (di *doltIndex) IndexType() string {
|
||||
return "BTREE"
|
||||
|
||||
@@ -294,6 +294,11 @@ func (idx fmtIndex) Comment() string {
|
||||
return idx.comment
|
||||
}
|
||||
|
||||
// PrefixLengths implements sql.Index
|
||||
func (idx fmtIndex) PrefixLengths() []uint16 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IndexType implements sql.Index
|
||||
func (idx fmtIndex) IndexType() string {
|
||||
return "BTREE"
|
||||
|
||||
@@ -1342,11 +1342,15 @@ func (t *AlterableDoltTable) RewriteInserter(
|
||||
colNames = append(colNames, colName)
|
||||
}
|
||||
}
|
||||
newSch.Indexes().AddIndexByColNames(index.Name(), colNames, schema.IndexProperties{
|
||||
IsUnique: index.IsUnique(),
|
||||
IsUserDefined: index.IsUserDefined(),
|
||||
Comment: index.Comment(),
|
||||
})
|
||||
newSch.Indexes().AddIndexByColNames(
|
||||
index.Name(),
|
||||
colNames,
|
||||
index.PrefixLengths(),
|
||||
schema.IndexProperties{
|
||||
IsUnique: index.IsUnique(),
|
||||
IsUserDefined: index.IsUserDefined(),
|
||||
Comment: index.Comment(),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
newSch = schema.CopyIndexes(oldSch, newSch)
|
||||
@@ -1501,7 +1505,7 @@ func validateSchemaChange(
|
||||
) error {
|
||||
for _, idxCol := range idxCols {
|
||||
col := newSchema.Schema[newSchema.Schema.IndexOfColName(idxCol.Name)]
|
||||
if idxCol.Length > 0 && sql.IsText(col.Type) {
|
||||
if col.PrimaryKey && idxCol.Length > 0 && sql.IsText(col.Type) {
|
||||
return sql.ErrUnsupportedIndexPrefix.New(col.Name)
|
||||
}
|
||||
}
|
||||
@@ -1757,6 +1761,29 @@ func (t *AlterableDoltTable) getFirstAutoIncrementValue(
|
||||
return seq, nil
|
||||
}
|
||||
|
||||
// hasNonZeroPrefixLength will return true if at least one of the sql.IndexColumns has a Length > 0
|
||||
func hasNonZeroPrefixLength(idxCols []sql.IndexColumn) bool {
|
||||
for _, idxCol := range idxCols {
|
||||
if idxCol.Length > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// allocatePrefixLengths will return a []uint16 populated with the Length field from sql.IndexColumn
|
||||
// if all the lengths have a value of 0, it will return nil
|
||||
func allocatePrefixLengths(idxCols []sql.IndexColumn) []uint16 {
|
||||
if !hasNonZeroPrefixLength(idxCols) {
|
||||
return nil
|
||||
}
|
||||
prefixLengths := make([]uint16, len(idxCols))
|
||||
for i, idxCol := range idxCols {
|
||||
prefixLengths[i] = uint16(idxCol.Length)
|
||||
}
|
||||
return prefixLengths
|
||||
}
|
||||
|
||||
// CreateIndex implements sql.IndexAlterableTable
|
||||
func (t *AlterableDoltTable) CreateIndex(ctx *sql.Context, idx sql.IndexDef) error {
|
||||
if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil {
|
||||
@@ -1765,6 +1792,7 @@ func (t *AlterableDoltTable) CreateIndex(ctx *sql.Context, idx sql.IndexDef) err
|
||||
if idx.Constraint != sql.IndexConstraint_None && idx.Constraint != sql.IndexConstraint_Unique {
|
||||
return fmt.Errorf("only the following types of index constraints are supported: none, unique")
|
||||
}
|
||||
|
||||
columns := make([]string, len(idx.Columns))
|
||||
for i, indexCol := range idx.Columns {
|
||||
columns[i] = indexCol.Name
|
||||
@@ -1775,18 +1803,12 @@ func (t *AlterableDoltTable) CreateIndex(ctx *sql.Context, idx sql.IndexDef) err
|
||||
return err
|
||||
}
|
||||
|
||||
for _, idxCol := range idx.Columns {
|
||||
col := t.DoltTable.sqlSch.Schema[t.DoltTable.sqlSch.IndexOfColName(idxCol.Name)]
|
||||
if idxCol.Length > 0 && sql.IsText(col.Type) {
|
||||
return sql.ErrUnsupportedIndexPrefix.New(col.Name)
|
||||
}
|
||||
}
|
||||
|
||||
ret, err := creation.CreateIndex(
|
||||
ctx,
|
||||
table,
|
||||
idx.Name,
|
||||
columns,
|
||||
allocatePrefixLengths(idx.Columns),
|
||||
idx.Constraint == sql.IndexConstraint_Unique,
|
||||
true,
|
||||
idx.Comment,
|
||||
@@ -2161,11 +2183,20 @@ func (t *AlterableDoltTable) UpdateForeignKey(ctx *sql.Context, fkName string, s
|
||||
// schema.Index interface (which is used internally to represent indexes across the codebase). In the
|
||||
// meantime, we must generate a duplicate key over the primary key.
|
||||
//TODO: use the primary key as-is
|
||||
idxReturn, err := creation.CreateIndex(ctx, tbl, "", sqlFk.Columns, false, false, "", editor.Options{
|
||||
ForeignKeyChecksDisabled: true,
|
||||
Deaf: t.opts.Deaf,
|
||||
Tempdir: t.opts.Tempdir,
|
||||
})
|
||||
idxReturn, err := creation.CreateIndex(
|
||||
ctx,
|
||||
tbl,
|
||||
"",
|
||||
sqlFk.Columns,
|
||||
nil,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
editor.Options{
|
||||
ForeignKeyChecksDisabled: true,
|
||||
Deaf: t.opts.Deaf,
|
||||
Tempdir: t.opts.Tempdir,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2199,11 +2230,20 @@ func (t *AlterableDoltTable) UpdateForeignKey(ctx *sql.Context, fkName string, s
|
||||
|
||||
// Our duplicate index is only unique if it's the entire primary key (which is by definition unique)
|
||||
unique := len(refPkTags) == len(refColTags)
|
||||
idxReturn, err := creation.CreateIndex(ctx, refTbl, "", colNames, unique, false, "", editor.Options{
|
||||
ForeignKeyChecksDisabled: true,
|
||||
Deaf: t.opts.Deaf,
|
||||
Tempdir: t.opts.Tempdir,
|
||||
})
|
||||
idxReturn, err := creation.CreateIndex(
|
||||
ctx,
|
||||
refTbl,
|
||||
"",
|
||||
colNames,
|
||||
nil,
|
||||
unique,
|
||||
false,
|
||||
"",
|
||||
editor.Options{
|
||||
ForeignKeyChecksDisabled: true,
|
||||
Deaf: t.opts.Deaf,
|
||||
Tempdir: t.opts.Tempdir,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2256,6 +2296,7 @@ func (t *AlterableDoltTable) CreateIndexForForeignKey(ctx *sql.Context, idx sql.
|
||||
table,
|
||||
idx.Name,
|
||||
columns,
|
||||
allocatePrefixLengths(idx.Columns),
|
||||
idx.Constraint == sql.IndexConstraint_Unique,
|
||||
false,
|
||||
"",
|
||||
|
||||
@@ -272,6 +272,7 @@ func (t *TempTable) CreateIndex(ctx *sql.Context, idx sql.IndexDef) error {
|
||||
t.table,
|
||||
idx.Name,
|
||||
cols,
|
||||
allocatePrefixLengths(idx.Columns),
|
||||
idx.Constraint == sql.IndexConstraint_Unique,
|
||||
true,
|
||||
idx.Comment,
|
||||
|
||||
@@ -244,9 +244,10 @@ func (m prollyIndexWriter) uniqueKeyError(ctx context.Context, keyStr string, ke
|
||||
}
|
||||
|
||||
type prollySecondaryIndexWriter struct {
|
||||
name string
|
||||
mut *prolly.MutableMap
|
||||
unique bool
|
||||
name string
|
||||
mut *prolly.MutableMap
|
||||
unique bool
|
||||
prefixLengths []uint16
|
||||
|
||||
// number of indexed cols
|
||||
idxCols int
|
||||
@@ -283,10 +284,28 @@ func (m prollySecondaryIndexWriter) ValidateKeyViolations(ctx context.Context, s
|
||||
return nil
|
||||
}
|
||||
|
||||
// trimKeyPart will trim entry into the sql.Row depending on the prefixLengths
|
||||
func (m prollySecondaryIndexWriter) trimKeyPart(to int, keyPart interface{}) interface{} {
|
||||
var prefixLength uint16
|
||||
if len(m.prefixLengths) > to {
|
||||
prefixLength = m.prefixLengths[to]
|
||||
}
|
||||
if prefixLength != 0 {
|
||||
switch kp := keyPart.(type) {
|
||||
case string:
|
||||
keyPart = kp[:prefixLength]
|
||||
case []uint8:
|
||||
keyPart = kp[:prefixLength]
|
||||
}
|
||||
}
|
||||
return keyPart
|
||||
}
|
||||
|
||||
func (m prollySecondaryIndexWriter) keyFromRow(ctx context.Context, sqlRow sql.Row) (val.Tuple, error) {
|
||||
for to := range m.keyMap {
|
||||
from := m.keyMap.MapOrdinal(to)
|
||||
if err := index.PutField(ctx, m.mut.NodeStore(), m.keyBld, to, sqlRow[from]); err != nil {
|
||||
keyPart := m.trimKeyPart(to, sqlRow[from])
|
||||
if err := index.PutField(ctx, m.mut.NodeStore(), m.keyBld, to, keyPart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -311,7 +330,8 @@ func (m prollySecondaryIndexWriter) checkForUniqueKeyErr(ctx context.Context, sq
|
||||
m.keyBld.Recycle()
|
||||
return nil
|
||||
}
|
||||
if err := index.PutField(ctx, ns, m.keyBld, to, sqlRow[from]); err != nil {
|
||||
keyPart := m.trimKeyPart(to, sqlRow[from])
|
||||
if err := index.PutField(ctx, ns, m.keyBld, to, keyPart); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,10 +180,11 @@ func (e secondaryUniqueKeyError) Error() string {
|
||||
}
|
||||
|
||||
type prollyKeylessSecondaryWriter struct {
|
||||
name string
|
||||
mut *prolly.MutableMap
|
||||
primary prollyKeylessWriter
|
||||
unique bool
|
||||
name string
|
||||
mut *prolly.MutableMap
|
||||
primary prollyKeylessWriter
|
||||
unique bool
|
||||
prefixLengths []uint16
|
||||
|
||||
keyBld *val.TupleBuilder
|
||||
prefixBld *val.TupleBuilder
|
||||
@@ -208,15 +209,33 @@ func (writer prollyKeylessSecondaryWriter) ValidateKeyViolations(ctx context.Con
|
||||
return nil
|
||||
}
|
||||
|
||||
// trimKeyPart will trim entry into the sql.Row depending on the prefixLengths
|
||||
func (writer prollyKeylessSecondaryWriter) trimKeyPart(to int, keyPart interface{}) interface{} {
|
||||
var prefixLength uint16
|
||||
if len(writer.prefixLengths) > to {
|
||||
prefixLength = writer.prefixLengths[to]
|
||||
}
|
||||
if prefixLength != 0 {
|
||||
switch kp := keyPart.(type) {
|
||||
case string:
|
||||
keyPart = kp[:prefixLength]
|
||||
case []uint8:
|
||||
keyPart = kp[:prefixLength]
|
||||
}
|
||||
}
|
||||
return keyPart
|
||||
}
|
||||
|
||||
// Insert implements the interface indexWriter.
|
||||
func (writer prollyKeylessSecondaryWriter) Insert(ctx context.Context, sqlRow sql.Row) error {
|
||||
for to := range writer.keyMap {
|
||||
from := writer.keyMap.MapOrdinal(to)
|
||||
if err := index.PutField(ctx, writer.mut.NodeStore(), writer.keyBld, to, sqlRow[from]); err != nil {
|
||||
keyPart := writer.trimKeyPart(to, sqlRow[from])
|
||||
if err := index.PutField(ctx, writer.mut.NodeStore(), writer.keyBld, to, keyPart); err != nil {
|
||||
return err
|
||||
}
|
||||
if to < writer.prefixBld.Desc.Count() {
|
||||
if err := index.PutField(ctx, writer.mut.NodeStore(), writer.prefixBld, to, sqlRow[from]); err != nil {
|
||||
if err := index.PutField(ctx, writer.mut.NodeStore(), writer.prefixBld, to, keyPart); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,16 +77,16 @@ func getSecondaryProllyIndexWriters(ctx context.Context, t *doltdb.Table, sqlSch
|
||||
|
||||
// mapping from secondary index key to primary key
|
||||
pkMap := makeIndexToIndexMapping(def.Schema().GetPKCols(), sch.GetPKCols())
|
||||
|
||||
writers[defName] = prollySecondaryIndexWriter{
|
||||
name: defName,
|
||||
mut: idxMap.Mutate(),
|
||||
unique: def.IsUnique(),
|
||||
idxCols: def.Count(),
|
||||
keyMap: keyMap,
|
||||
keyBld: val.NewTupleBuilder(keyDesc),
|
||||
pkMap: pkMap,
|
||||
pkBld: val.NewTupleBuilder(pkDesc),
|
||||
name: defName,
|
||||
mut: idxMap.Mutate(),
|
||||
unique: def.IsUnique(),
|
||||
prefixLengths: def.PrefixLengths(),
|
||||
idxCols: def.Count(),
|
||||
keyMap: keyMap,
|
||||
keyBld: val.NewTupleBuilder(keyDesc),
|
||||
pkMap: pkMap,
|
||||
pkBld: val.NewTupleBuilder(pkDesc),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,14 +115,15 @@ func getSecondaryKeylessProllyWriters(ctx context.Context, t *doltdb.Table, sqlS
|
||||
keyDesc, _ := m.Descriptors()
|
||||
|
||||
writers[defName] = prollyKeylessSecondaryWriter{
|
||||
name: defName,
|
||||
mut: m.Mutate(),
|
||||
primary: primary,
|
||||
unique: def.IsUnique(),
|
||||
keyBld: val.NewTupleBuilder(keyDesc),
|
||||
prefixBld: val.NewTupleBuilder(keyDesc.PrefixDesc(def.Count())),
|
||||
hashBld: val.NewTupleBuilder(val.NewTupleDescriptor(val.Type{Enc: val.Hash128Enc})),
|
||||
keyMap: keyMap,
|
||||
name: defName,
|
||||
mut: m.Mutate(),
|
||||
primary: primary,
|
||||
unique: def.IsUnique(),
|
||||
prefixLengths: def.PrefixLengths(),
|
||||
keyBld: val.NewTupleBuilder(keyDesc),
|
||||
prefixBld: val.NewTupleBuilder(keyDesc.PrefixDesc(def.Count())),
|
||||
hashBld: val.NewTupleBuilder(val.NewTupleDescriptor(val.Type{Enc: val.Hash128Enc})),
|
||||
keyMap: keyMap,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ func CreateIndex(
|
||||
table *doltdb.Table,
|
||||
indexName string,
|
||||
columns []string,
|
||||
prefixLengths []uint16,
|
||||
isUnique bool,
|
||||
isUserDefined bool,
|
||||
comment string,
|
||||
@@ -99,6 +100,7 @@ func CreateIndex(
|
||||
index, err := sch.Indexes().AddIndexByColNames(
|
||||
indexName,
|
||||
realColNames,
|
||||
prefixLengths,
|
||||
schema.IndexProperties{
|
||||
IsUnique: isUnique,
|
||||
IsUserDefined: isUserDefined,
|
||||
|
||||
@@ -62,7 +62,7 @@ func TestIndexEditorConcurrency(t *testing.T) {
|
||||
schema.NewColumn("v2", 2, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_concurrency", []string{"v1"}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_concurrency", []string{"v1"}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
indexSch := index.Schema()
|
||||
emptyMap, err := types.NewMap(context.Background(), vrw)
|
||||
@@ -158,7 +158,7 @@ func TestIndexEditorConcurrencyPostInsert(t *testing.T) {
|
||||
schema.NewColumn("v2", 2, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_concurrency", []string{"v1"}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_concurrency", []string{"v1"}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
indexSch := index.Schema()
|
||||
emptyMap, err := types.NewMap(context.Background(), vrw)
|
||||
@@ -250,7 +250,7 @@ func TestIndexEditorUniqueMultipleNil(t *testing.T) {
|
||||
schema.NewColumn("v1", 1, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_unique", []string{"v1"}, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_unique", []string{"v1"}, nil, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
indexSch := index.Schema()
|
||||
emptyMap, err := types.NewMap(context.Background(), vrw)
|
||||
@@ -297,7 +297,7 @@ func TestIndexEditorWriteAfterFlush(t *testing.T) {
|
||||
schema.NewColumn("v2", 2, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_concurrency", []string{"v1"}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_concurrency", []string{"v1"}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
indexSch := index.Schema()
|
||||
emptyMap, err := types.NewMap(context.Background(), vrw)
|
||||
@@ -365,7 +365,7 @@ func TestIndexEditorUniqueErrorDoesntPersist(t *testing.T) {
|
||||
schema.NewColumn("v1", 1, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_unq", []string{"v1"}, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_unq", []string{"v1"}, nil, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
indexSch := index.Schema()
|
||||
emptyMap, err := types.NewMap(context.Background(), vrw)
|
||||
@@ -618,7 +618,7 @@ func TestIndexRebuildingUniqueSuccessOneCol(t *testing.T) {
|
||||
originalTable, err := createTableWithoutIndexRebuilding(context.Background(), vrw, ns, sch, rowData)
|
||||
require.NoError(t, err)
|
||||
|
||||
index, err := sch.Indexes().AddIndexByColTags("idx_v1", []uint64{2}, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
index, err := sch.Indexes().AddIndexByColTags("idx_v1", []uint64{2}, nil, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
updatedTable, err := originalTable.UpdateSchema(context.Background(), sch)
|
||||
require.NoError(t, err)
|
||||
@@ -649,7 +649,7 @@ func TestIndexRebuildingUniqueSuccessTwoCol(t *testing.T) {
|
||||
originalTable, err := createTableWithoutIndexRebuilding(context.Background(), vrw, ns, sch, rowData)
|
||||
require.NoError(t, err)
|
||||
|
||||
index, err := sch.Indexes().AddIndexByColTags("idx_v1", []uint64{2, 3}, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
index, err := sch.Indexes().AddIndexByColTags("idx_v1", []uint64{2, 3}, nil, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
updatedTable, err := originalTable.UpdateSchema(context.Background(), sch)
|
||||
require.NoError(t, err)
|
||||
@@ -680,7 +680,7 @@ func TestIndexRebuildingUniqueFailOneCol(t *testing.T) {
|
||||
originalTable, err := createTableWithoutIndexRebuilding(context.Background(), vrw, ns, sch, rowData)
|
||||
require.NoError(t, err)
|
||||
|
||||
index, err := sch.Indexes().AddIndexByColTags("idx_v1", []uint64{2}, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
index, err := sch.Indexes().AddIndexByColTags("idx_v1", []uint64{2}, nil, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
updatedTable, err := originalTable.UpdateSchema(context.Background(), sch)
|
||||
require.NoError(t, err)
|
||||
@@ -712,7 +712,7 @@ func TestIndexRebuildingUniqueFailTwoCol(t *testing.T) {
|
||||
originalTable, err := createTableWithoutIndexRebuilding(context.Background(), vrw, ns, sch, rowData)
|
||||
require.NoError(t, err)
|
||||
|
||||
index, err := sch.Indexes().AddIndexByColTags("idx_v1", []uint64{2, 3}, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
index, err := sch.Indexes().AddIndexByColTags("idx_v1", []uint64{2, 3}, nil, schema.IndexProperties{IsUnique: true, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
updatedTable, err := originalTable.UpdateSchema(context.Background(), sch)
|
||||
require.NoError(t, err)
|
||||
@@ -738,7 +738,7 @@ func TestIndexEditorCapacityExceeded(t *testing.T) {
|
||||
schema.NewColumn("v1", 1, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_cap", []string{"v1"}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
index, err := tableSch.Indexes().AddIndexByColNames("idx_cap", []string{"v1"}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
indexSch := index.Schema()
|
||||
emptyMap, err := types.NewMap(ctx, vrw)
|
||||
@@ -837,9 +837,9 @@ func createTestSchema(t *testing.T) schema.Schema {
|
||||
)
|
||||
sch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
_, err = sch.Indexes().AddIndexByColTags(testSchemaIndexName, []uint64{firstTag, lastTag}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err = sch.Indexes().AddIndexByColTags(testSchemaIndexName, []uint64{firstTag, lastTag}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
_, err = sch.Indexes().AddIndexByColTags(testSchemaIndexAge, []uint64{ageTag}, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
_, err = sch.Indexes().AddIndexByColTags(testSchemaIndexAge, []uint64{ageTag}, nil, schema.IndexProperties{IsUnique: false, Comment: ""})
|
||||
require.NoError(t, err)
|
||||
return sch
|
||||
}
|
||||
|
||||
@@ -426,11 +426,11 @@ func TestKeylessTableEditorMultipleIndexErrorHandling(t *testing.T) {
|
||||
schema.NewColumn("v2", 2, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
idxv1, err := tableSch.Indexes().AddIndexByColNames("idx_v1", []string{"v1"}, schema.IndexProperties{
|
||||
idxv1, err := tableSch.Indexes().AddIndexByColNames("idx_v1", []string{"v1"}, nil, schema.IndexProperties{
|
||||
IsUnique: false,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
idxv2, err := tableSch.Indexes().AddIndexByColNames("idx_v2", []string{"v2"}, schema.IndexProperties{
|
||||
idxv2, err := tableSch.Indexes().AddIndexByColNames("idx_v2", []string{"v2"}, nil, schema.IndexProperties{
|
||||
IsUnique: false,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -583,7 +583,7 @@ func TestKeylessTableEditorIndexCardinality(t *testing.T) {
|
||||
schema.NewColumn("v2", 2, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
idxv1, err := tableSch.Indexes().AddIndexByColNames("idx_v1", []string{"v1"}, schema.IndexProperties{
|
||||
idxv1, err := tableSch.Indexes().AddIndexByColNames("idx_v1", []string{"v1"}, nil, schema.IndexProperties{
|
||||
IsUnique: false,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -392,11 +392,11 @@ func TestTableEditorMultipleIndexErrorHandling(t *testing.T) {
|
||||
schema.NewColumn("v2", 2, types.IntKind, false))
|
||||
tableSch, err := schema.SchemaFromCols(colColl)
|
||||
require.NoError(t, err)
|
||||
idxv1, err := tableSch.Indexes().AddIndexByColNames("idx_v1", []string{"v1"}, schema.IndexProperties{
|
||||
idxv1, err := tableSch.Indexes().AddIndexByColNames("idx_v1", []string{"v1"}, nil, schema.IndexProperties{
|
||||
IsUnique: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
idxv2, err := tableSch.Indexes().AddIndexByColNames("idx_v2", []string{"v2"}, schema.IndexProperties{
|
||||
idxv2, err := tableSch.Indexes().AddIndexByColNames("idx_v2", []string{"v2"}, nil, schema.IndexProperties{
|
||||
IsUnique: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -90,6 +90,8 @@ table Index {
|
||||
primary_key:bool;
|
||||
unique_key:bool;
|
||||
system_defined:bool;
|
||||
|
||||
prefix_lengths:[uint16];
|
||||
}
|
||||
|
||||
table CheckConstraint {
|
||||
|
||||
@@ -29,7 +29,7 @@ teardown() {
|
||||
dolt tag -v
|
||||
run dolt tag -v
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "tdkt7s7805k1ml4hu37pm688g5i0b8ie" ]] || false
|
||||
[[ "$output" =~ "7jrvg1ajcdq6t9sevcejv4e9o0fgrmle" ]] || false
|
||||
[[ ! "$output" =~ "r9jv07tf9un3fm1fg72v7ad9er89oeo7" ]] || false
|
||||
|
||||
# validate TEXT migration
|
||||
@@ -55,7 +55,7 @@ teardown() {
|
||||
dolt tag -v
|
||||
run dolt tag -v
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "tdkt7s7805k1ml4hu37pm688g5i0b8ie" ]] || false
|
||||
[[ "$output" =~ "7jrvg1ajcdq6t9sevcejv4e9o0fgrmle" ]] || false
|
||||
[[ ! "$output" =~ "r9jv07tf9un3fm1fg72v7ad9er89oeo7" ]] || false
|
||||
|
||||
# validate TEXT migration
|
||||
|
||||
Reference in New Issue
Block a user