diff --git a/src/box/alter.cc b/src/box/alter.cc index ff834f760548ed3b9211632eb78f723848636ac1..6556d7f81f1b7443e7772ccd616207cd0f298024 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -1555,6 +1555,41 @@ class RebuildFuncIndex: public RebuildIndex old_index_def_arg) {} }; +/** + * Drop the old index with data and create a disabled index in place of it. + */ +class DisableFuncIndex: public AlterSpaceOp +{ + struct index_def *new_index_def; + struct index_def *old_index_def; +public: + DisableFuncIndex(struct alter_space *alter, + struct index_def *old_index_def_arg) + : AlterSpaceOp(alter), old_index_def(old_index_def_arg) + { + /* Functional indexes are only implemented in memtx. */ + assert(!strcmp(alter->old_space->engine->name, "memtx")); + new_index_def = index_def_dup(old_index_def); + index_def_set_func(new_index_def, NULL); + } + + virtual void alter_def(struct alter_space *alter); + virtual ~DisableFuncIndex(); +}; + +void +DisableFuncIndex::alter_def(struct alter_space *alter) +{ + rlist_del_entry(old_index_def, link); + index_def_list_add(&alter->key_list, new_index_def); +} + +DisableFuncIndex::~DisableFuncIndex() +{ + if (new_index_def != NULL) + index_def_delete(new_index_def); +} + /** TruncateIndex - truncate an index. */ class TruncateIndex: public AlterSpaceOp { @@ -5500,10 +5535,20 @@ on_replace_dd_func_index(struct trigger *trigger, void *event) auto scoped_guard = make_scoped_guard([=] {alter_space_delete(alter);}); if (alter_space_move_indexes(alter, 0, index->def->iid) != 0) return -1; - try { - (void) new RebuildFuncIndex(alter, index->def, func); - } catch (Exception *e) { - return -1; + if (func != NULL) { + /* Set func, rebuild the functional index. */ + try { + (void)new RebuildFuncIndex(alter, index->def, func); + } catch (Exception *e) { + return -1; + } + } else { + /* Reset func, disable the functional index. */ + try { + (void)new DisableFuncIndex(alter, index->def); + } catch (Exception *e) { + return -1; + } } if (alter_space_move_indexes(alter, index->def->iid + 1, space->index_id_max + 1) != 0)