diff --git a/src/box/alter.cc b/src/box/alter.cc index eb548e0b10741f6a0c44aad21cda46899d388e29..7f130297e8d65fafd8b1f97daeb181c1d1963667 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -1100,7 +1100,7 @@ class ModifyIndex: public AlterSpaceOp old_index_def->key_def->part_count) != 0) { /* * Primary parts have been changed - - * update non-unique secondary indexes. + * update secondary indexes. */ alter->pk_def = new_index_def->key_def; } @@ -1411,9 +1411,7 @@ alter_space_move_indexes(struct alter_space *alter, uint32_t begin, struct index_def *old_def = old_index->def; struct index_def *new_def; uint32_t min_field_count = alter->new_min_field_count; - if ((old_def->opts.is_unique && - !old_def->key_def->is_nullable) || - old_def->type != TREE || alter->pk_def == NULL) { + if (alter->pk_def == NULL || !index_depends_on_pk(old_index)) { if (is_min_field_count_changed) { new_def = index_def_dup(old_def); index_def_update_optionality(new_def, @@ -1425,9 +1423,8 @@ alter_space_move_indexes(struct alter_space *alter, uint32_t begin, continue; } /* - * Rebuild non-unique secondary keys along with - * the primary, since primary key parts have - * changed. + * Rebuild secondary indexes that depend on the + * primary key since primary key parts have changed. */ new_def = index_def_new(old_def->space_id, old_def->iid, old_def->name, strlen(old_def->name), diff --git a/src/box/index.cc b/src/box/index.cc index 11a6683dd388531fa86a9e7cfb4764b7e25d652f..6cd04833847ddc2bf61b97c4f23d8d7083dc5afe 100644 --- a/src/box/index.cc +++ b/src/box/index.cc @@ -560,6 +560,11 @@ generic_index_update_def(struct index *) { } +bool generic_index_depends_on_pk(struct index *) +{ + return false; +} + ssize_t generic_index_size(struct index *index) { diff --git a/src/box/index.h b/src/box/index.h index 2e43d9991516ccdc891e0bc2fc595061a20c9aae..f19fbd167f0ad5d1039769ad359e0a53966b926b 100644 --- a/src/box/index.h +++ b/src/box/index.h @@ -373,6 +373,12 @@ struct index_vtab { * require index rebuild. */ void (*update_def)(struct index *); + /** + * Return true if the index depends on the primary + * key definition and hence needs to be updated if + * the primary key is modified. + */ + bool (*depends_on_pk)(struct index *); ssize_t (*size)(struct index *); ssize_t (*bsize)(struct index *); @@ -505,6 +511,12 @@ index_update_def(struct index *index) index->vtab->update_def(index); } +static inline bool +index_depends_on_pk(struct index *index) +{ + return index->vtab->depends_on_pk(index); +} + static inline ssize_t index_size(struct index *index) { @@ -616,6 +628,7 @@ void generic_index_abort_create(struct index *); void generic_index_commit_modify(struct index *, int64_t); void generic_index_commit_drop(struct index *); void generic_index_update_def(struct index *); +bool generic_index_depends_on_pk(struct index *); ssize_t generic_index_size(struct index *); int generic_index_min(struct index *, const char *, uint32_t, struct tuple **); int generic_index_max(struct index *, const char *, uint32_t, struct tuple **); diff --git a/src/box/memtx_bitset.c b/src/box/memtx_bitset.c index 0e546217496e1a97f1f3fbb40a8b7c7c5289693c..e66247eeadeca109e17676cb0c78713a6318df59 100644 --- a/src/box/memtx_bitset.c +++ b/src/box/memtx_bitset.c @@ -461,6 +461,7 @@ static const struct index_vtab memtx_bitset_index_vtab = { /* .commit_modify = */ generic_index_commit_modify, /* .commit_drop = */ generic_index_commit_drop, /* .update_def = */ generic_index_update_def, + /* .depends_on_pk = */ generic_index_depends_on_pk, /* .size = */ memtx_bitset_index_size, /* .bsize = */ memtx_bitset_index_bsize, /* .min = */ generic_index_min, diff --git a/src/box/memtx_hash.c b/src/box/memtx_hash.c index 9c72af5dbdc06837676fe4beb24b2317c52bf018..c4081edce15a038b988495925a5e775dd303f85b 100644 --- a/src/box/memtx_hash.c +++ b/src/box/memtx_hash.c @@ -385,6 +385,7 @@ static const struct index_vtab memtx_hash_index_vtab = { /* .commit_modify = */ generic_index_commit_modify, /* .commit_drop = */ generic_index_commit_drop, /* .update_def = */ memtx_hash_index_update_def, + /* .depends_on_pk = */ generic_index_depends_on_pk, /* .size = */ memtx_hash_index_size, /* .bsize = */ memtx_hash_index_bsize, /* .min = */ generic_index_min, diff --git a/src/box/memtx_rtree.c b/src/box/memtx_rtree.c index 373d658e5acb612af01f2be8b7a8da0b2238bbb4..7cd3ac30f669c4f9e76bc08ce0e058b3d09b0bc7 100644 --- a/src/box/memtx_rtree.c +++ b/src/box/memtx_rtree.c @@ -299,6 +299,7 @@ static const struct index_vtab memtx_rtree_index_vtab = { /* .commit_modify = */ generic_index_commit_modify, /* .commit_drop = */ generic_index_commit_drop, /* .update_def = */ generic_index_update_def, + /* .depends_on_pk = */ generic_index_depends_on_pk, /* .size = */ memtx_rtree_index_size, /* .bsize = */ memtx_rtree_index_bsize, /* .min = */ generic_index_min, diff --git a/src/box/memtx_tree.c b/src/box/memtx_tree.c index 7178a4bc6efa92bc87443c5d27dc8fbd1d9a6b90..a06b590dfde9ef9cbbba319ce67ecccf6afc7a30 100644 --- a/src/box/memtx_tree.c +++ b/src/box/memtx_tree.c @@ -316,6 +316,14 @@ memtx_tree_index_update_def(struct index *base) index->tree.arg = memtx_tree_index_cmp_def(index); } +static bool +memtx_tree_index_depends_on_pk(struct index *base) +{ + struct index_def *def = base->def; + /* See comment to memtx_tree_index_cmp_def(). */ + return !def->opts.is_unique || def->key_def->is_nullable; +} + static ssize_t memtx_tree_index_size(struct index *base) { @@ -586,6 +594,7 @@ static const struct index_vtab memtx_tree_index_vtab = { /* .commit_modify = */ generic_index_commit_modify, /* .commit_drop = */ generic_index_commit_drop, /* .update_def = */ memtx_tree_index_update_def, + /* .depends_on_pk = */ memtx_tree_index_depends_on_pk, /* .size = */ memtx_tree_index_size, /* .bsize = */ memtx_tree_index_bsize, /* .min = */ generic_index_min, diff --git a/src/box/sysview_index.c b/src/box/sysview_index.c index e2b2fb96b4d92260f6e3909c2297c294509f0537..729614017ae209f221c0dc0a43756c6207cde53a 100644 --- a/src/box/sysview_index.c +++ b/src/box/sysview_index.c @@ -165,6 +165,7 @@ static const struct index_vtab sysview_index_vtab = { /* .commit_modify = */ generic_index_commit_modify, /* .commit_drop = */ generic_index_commit_drop, /* .update_def = */ generic_index_update_def, + /* .depends_on_pk = */ generic_index_depends_on_pk, /* .size = */ generic_index_size, /* .bsize = */ sysview_index_bsize, /* .min = */ generic_index_min, diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 226737086a34a707253493d0da6aab0d66b64c37..2e50bf48ec62b42abca7a5b2e7bd4016cd91f59a 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -906,6 +906,17 @@ vinyl_index_commit_drop(struct index *index) vy_log_tx_try_commit(); } +static bool +vinyl_index_depends_on_pk(struct index *index) +{ + (void)index; + /* + * All secondary Vinyl indexes are non-clustered and hence + * have to be updated if the primary key is modified. + */ + return true; +} + static void vinyl_init_system_space(struct space *space) { @@ -3948,6 +3959,7 @@ static const struct index_vtab vinyl_index_vtab = { /* .commit_modify = */ generic_index_commit_modify, /* .commit_drop = */ vinyl_index_commit_drop, /* .update_def = */ generic_index_update_def, + /* .depends_on_pk = */ vinyl_index_depends_on_pk, /* .size = */ vinyl_index_size, /* .bsize = */ vinyl_index_bsize, /* .min = */ generic_index_min,