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)