From 0d4eb351f5d19083b3618c3e923614bc09173a9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= <marko.makela@mariadb.com>
Date: Wed, 26 Sep 2018 17:22:53 +0300
Subject: [PATCH] WIP: Remove dict_field_t::name

---
 storage/innobase/btr/btr0cur.cc           |  3 +-
 storage/innobase/dict/dict0boot.cc        | 16 ++---
 storage/innobase/dict/dict0crea.cc        |  4 +-
 storage/innobase/dict/dict0dict.cc        | 36 +++--------
 storage/innobase/dict/dict0load.cc        |  8 +--
 storage/innobase/dict/dict0mem.cc         | 73 ++++++-----------------
 storage/innobase/dict/dict0stats.cc       | 32 ++++++----
 storage/innobase/fts/fts0fts.cc           | 10 +---
 storage/innobase/fts/fts0sql.cc           |  3 +-
 storage/innobase/handler/ha_innodb.cc     | 68 +++------------------
 storage/innobase/handler/handler0alter.cc |  7 ++-
 storage/innobase/include/dict0mem.h       |  7 +--
 storage/innobase/pars/pars0pars.cc        |  2 +-
 storage/innobase/row/row0ftsort.cc        |  3 -
 storage/innobase/row/row0import.cc        | 27 +++------
 storage/innobase/row/row0merge.cc         | 13 ++--
 storage/innobase/row/row0quiesce.cc       |  5 +-
 17 files changed, 102 insertions(+), 215 deletions(-)

diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 45192dda16d..d763b3184c7 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -970,7 +970,8 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index)
 				       TABLE_STATS_NAME)
 			       || !strcmp(index->table->name.m_name,
 					  INDEX_STATS_NAME))) {
-			ut_ad(!strcmp(field->name, "table_name"));
+			ut_ad(!strcmp(field->col->name(*index->table),
+				      "table_name"));
 			/* Interpret "table_name" as VARCHAR(199) even
 			if it was incorrectly defined as VARCHAR(64).
 			While the caller of ha_innobase enforces the
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index 5b176796644..a1bf7b93b0f 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -360,7 +360,7 @@ dict_boot(void)
 	index = dict_mem_index_create(table, "CLUST_IND",
 				      DICT_UNIQUE | DICT_CLUSTERED, 1);
 
-	dict_mem_index_add_field(index, "NAME", 0);
+	dict_mem_index_add_field(index, &table->cols[0]);
 
 	index->id = DICT_TABLES_ID;
 	index = dict_index_add_to_cache(
@@ -372,7 +372,7 @@ dict_boot(void)
 
 	/*-------------------------*/
 	index = dict_mem_index_create(table, "ID_IND", DICT_UNIQUE, 1);
-	dict_mem_index_add_field(index, "ID", 0);
+	dict_mem_index_add_field(index, &table->cols[1]);
 
 	index->id = DICT_TABLE_IDS_ID;
 	index = dict_index_add_to_cache(
@@ -401,8 +401,8 @@ dict_boot(void)
 	index = dict_mem_index_create(table, "CLUST_IND",
 				      DICT_UNIQUE | DICT_CLUSTERED, 2);
 
-	dict_mem_index_add_field(index, "TABLE_ID", 0);
-	dict_mem_index_add_field(index, "POS", 0);
+	dict_mem_index_add_field(index, &table->cols[0]);
+	dict_mem_index_add_field(index, &table->cols[1]);
 
 	index->id = DICT_COLUMNS_ID;
 	index = dict_index_add_to_cache(
@@ -444,8 +444,8 @@ dict_boot(void)
 	index = dict_mem_index_create(table, "CLUST_IND",
 				      DICT_UNIQUE | DICT_CLUSTERED, 2);
 
-	dict_mem_index_add_field(index, "TABLE_ID", 0);
-	dict_mem_index_add_field(index, "ID", 0);
+	dict_mem_index_add_field(index, &table->cols[0]);
+	dict_mem_index_add_field(index, &table->cols[1]);
 
 	index->id = DICT_INDEXES_ID;
 	index = dict_index_add_to_cache(
@@ -473,8 +473,8 @@ dict_boot(void)
 	index = dict_mem_index_create(table, "CLUST_IND",
 				      DICT_UNIQUE | DICT_CLUSTERED, 2);
 
-	dict_mem_index_add_field(index, "INDEX_ID", 0);
-	dict_mem_index_add_field(index, "POS", 0);
+	dict_mem_index_add_field(index, &table->cols[0]);
+	dict_mem_index_add_field(index, &table->cols[1]);
 
 	index->id = DICT_FIELDS_ID;
 	index = dict_index_add_to_cache(
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index e145422c5bd..584657449ce 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -670,8 +670,8 @@ dict_create_sys_fields_tuple(
 	/* 4: COL_NAME -------------------------*/
 	dfield = dtuple_get_nth_field(entry, DICT_COL__SYS_FIELDS__COL_NAME);
 
-	dfield_set_data(dfield, field->name,
-			ut_strlen(field->name));
+	const char* name = field->col->name(*index->table);
+	dfield_set_data(dfield, name, strlen(name));
 	/*---------------------------------*/
 
 	return(entry);
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 3a4c8c19c00..c5b5719d2f3 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2246,7 +2246,8 @@ dict_index_too_big_for_tree(
 		/* Check the size limit on leaf pages. */
 		if (rec_max_size >= page_rec_max) {
 			ib::error_or_warn(strict)
-				<< "Cannot add field " << field->name
+				<< "Cannot add field "
+				<< field->col->name(*table)
 				<< " in table " << table->name
 				<< " because after adding it, the row size is "
 				<< rec_max_size
@@ -2546,6 +2547,7 @@ dict_index_remove_from_cache(
 	dict_index_remove_from_cache_low(table, index, FALSE);
 }
 
+#if 0
 /** Tries to find column names for the index and sets the col field of the
 index.
 @param[in]	table	table
@@ -2645,6 +2647,7 @@ dict_index_find_cols(
 
 	return(TRUE);
 }
+#endif
 
 /*******************************************************************//**
 Adds a column to index. */
@@ -2657,7 +2660,6 @@ dict_index_add_col(
 	ulint			prefix_len)	/*!< in: column prefix length */
 {
 	dict_field_t*	field;
-	const char*	col_name;
 
 	if (col->is_virtual()) {
 		dict_v_col_t*	v_col = reinterpret_cast<dict_v_col_t*>(col);
@@ -2672,14 +2674,9 @@ dict_index_add_col(
 			v_col->v_indexes->push_back(
 				dict_v_idx_t(index, index->n_def));
 		}
-
-		col_name = dict_table_get_v_col_name_mysql(
-			table, dict_col_get_no(col));
-	} else {
-		col_name = dict_table_get_col_name(table, dict_col_get_no(col));
 	}
 
-	dict_mem_index_add_field(index, col_name, prefix_len);
+	dict_mem_index_add_field(index, col, prefix_len);
 
 	field = dict_index_get_nth_field(index, unsigned(index->n_def) - 1);
 
@@ -6771,12 +6768,7 @@ dict_foreign_qualify_index(
 	}
 
 	for (ulint i = 0; i < n_cols; i++) {
-		dict_field_t*	field;
-		const char*	col_name;
-		ulint		col_no;
-
-		field = dict_index_get_nth_field(index, i);
-		col_no = dict_col_get_no(field->col);
+		dict_field_t* field = dict_index_get_nth_field(index, i);
 
 		if (field->prefix_len != 0) {
 			/* We do not accept column prefix
@@ -6799,19 +6791,9 @@ dict_foreign_qualify_index(
 			return(false);
 		}
 
-		if (field->col->is_virtual()) {
-			col_name = "";
-			for (ulint j = 0; j < table->n_v_def; j++) {
-				col_name = dict_table_get_v_col_name(table, j);
-				if (innobase_strcasecmp(field->name,col_name) == 0) {
-					break;
-				}
-			}
-		} else {
-			col_name = col_names
-				? col_names[col_no]
-				: dict_table_get_col_name(table, col_no);
-		}
+		const char* col_name = col_names && !field->col->is_virtual()
+			? col_names[field->col->ind]
+			: field->col->name(*table);
 
 		if (0 != innobase_strcasecmp(columns[i], col_name)) {
 			return(false);
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 1f1a6c0bc48..a9b8c874bdc 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -2105,16 +2105,14 @@ dict_load_field_low(
 		goto err_len;
 	}
 
+	/* FIXME: look up field in index->table->col_names or index->table->v_col_names */
+
 	if (index) {
 		dict_mem_index_add_field(
-			index, mem_heap_strdupl(heap, (const char*) field, len),
-			prefix_len);
+			index, NULL/*FIXME: col*/, prefix_len);
 	} else {
 		ut_a(sys_field);
 		ut_a(pos);
-
-		sys_field->name = mem_heap_strdupl(
-			heap, (const char*) field, len);
 		sys_field->prefix_len = prefix_len;
 		*pos = position;
 	}
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index e6c5050d949..97770863a16 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -520,36 +520,6 @@ dict_mem_table_col_rename_low(
 			t_col_names + (prefix_len + from_len),
 			full_len - (prefix_len + from_len));
 
-		/* Replace the field names in every index. */
-		for (dict_index_t* index = dict_table_get_first_index(table);
-		     index != NULL;
-		     index = dict_table_get_next_index(index)) {
-			ulint	n_fields = dict_index_get_n_fields(index);
-
-			for (ulint i = 0; i < n_fields; i++) {
-				dict_field_t*	field
-					= dict_index_get_nth_field(
-						index, i);
-
-				/* if is_virtual and that in field->col does
-				not match, continue */
-				if ((!is_virtual) !=
-				    (!field->col->is_virtual())) {
-					continue;
-				}
-
-				ulint		name_ofs
-					= ulint(field->name - t_col_names);
-				if (name_ofs <= prefix_len) {
-					field->name = col_names + name_ofs;
-				} else {
-					ut_a(name_ofs < full_len);
-					field->name = col_names
-						+ name_ofs + to_len - from_len;
-				}
-			}
-		}
-
 		if (is_virtual) {
 			table->v_col_names = col_names;
 		} else {
@@ -608,16 +578,16 @@ dict_mem_table_col_rename_low(
 			foreign->foreign_index = new_index;
 
 		} else {
-
+			const dict_table_t& t = *foreign->foreign_index->table;
 			for (unsigned f = 0; f < foreign->n_fields; f++) {
 				/* These can point straight to
 				table->col_names, because the foreign key
 				constraints will be freed at the same time
 				when the table object is freed. */
 				foreign->foreign_col_names[f]
-					= dict_index_get_nth_field(
-						foreign->foreign_index,
-						f)->name;
+					= dict_index_get_nth_col(
+						foreign->foreign_index, f)
+					->name(t);
 			}
 		}
 	}
@@ -629,6 +599,7 @@ dict_mem_table_col_rename_low(
 		foreign = *it;
 
 		ut_ad(foreign->referenced_index != NULL);
+		const dict_table_t& t = *foreign->referenced_index->table;
 
 		for (unsigned f = 0; f < foreign->n_fields; f++) {
 			/* foreign->referenced_col_names[] need to be
@@ -636,8 +607,8 @@ dict_mem_table_col_rename_low(
 			orphan when foreign_key_checks=0 and the
 			parent table is dropped. */
 
-			const char* col_name = dict_index_get_nth_field(
-				foreign->referenced_index, f)->name;
+			const char* col_name = dict_index_get_nth_col(
+				foreign->referenced_index, f)->name(t);
 
 			if (strcmp(foreign->referenced_col_names[f],
 				   col_name)) {
@@ -881,6 +852,7 @@ dict_mem_fill_vcol_has_index(
 	}
 }
 
+#if 0
 /** Fill the virtual column set with the virtual column of the index
 if the index contains given column name.
 @param[in]	col_name	column name
@@ -904,7 +876,7 @@ dict_mem_fill_vcol_from_v_indexes(
 		virtual column because field name is NULL.
 		Later virtual column set will be
 		refreshed during loading of table. */
-		if (!dict_index_has_virtual(index)
+	if (!dict_index_has_virtual(index)
 		    || index->has_new_v_col) {
 			continue;
 		}
@@ -920,6 +892,7 @@ dict_mem_fill_vcol_from_v_indexes(
 		}
 	}
 }
+#endif
 
 /** Fill the virtual column set with virtual columns which have base columns
 as the given col_name
@@ -1033,7 +1006,7 @@ void
 dict_mem_index_add_field(
 /*=====================*/
 	dict_index_t*	index,		/*!< in: index */
-	const char*	name,		/*!< in: column name */
+	dict_col_t*	col,		/*!< in: column */
 	ulint		prefix_len)	/*!< in: 0 or the column prefix length
 					in a MySQL index like
 					INDEX (textcol(25)) */
@@ -1046,8 +1019,7 @@ dict_mem_index_add_field(
 	index->n_def++;
 
 	field = dict_index_get_nth_field(index, unsigned(index->n_def) - 1);
-
-	field->name = name;
+	field->col = col;
 	field->prefix_len = (unsigned int) prefix_len;
 }
 
@@ -1219,7 +1191,8 @@ inline void dict_index_t::instant_add_field(const dict_index_t& instant)
 	fields = static_cast<dict_field_t*>(
 		mem_heap_dup(heap, instant.fields, n_fields * sizeof *fields));
 
-	ut_d(unsigned n_null = 0);
+#ifdef UNIV_DEBUG
+	unsigned n_null = 0;
 
 	for (unsigned i = 0; i < n_fields; i++) {
 		DBUG_ASSERT(fields[i].same(instant.fields[i]));
@@ -1227,11 +1200,11 @@ inline void dict_index_t::instant_add_field(const dict_index_t& instant)
 		DBUG_ASSERT(!icol->is_virtual());
 		dict_col_t* col = fields[i].col = &table->cols[
 			icol - instant.table->cols];
-		fields[i].name = col->name(*table);
-		ut_d(n_null += col->is_nullable());
+		n_null += col->is_nullable();
 	}
 
 	ut_ad(n_null == n_nullable);
+#endif
 }
 
 /** Adjust metadata for instant ADD COLUMN.
@@ -1322,7 +1295,6 @@ void dict_table_t::instant_add_column(const dict_table_t& table)
 				}
 				field.col = &cols[n];
 				DBUG_ASSERT(!field.col->is_virtual());
-				field.name = field.col->name(*this);
 			}
 		}
 	}
@@ -1399,7 +1371,6 @@ dict_table_t::rollback_instant(
 				}
 				field.col = &cols[n];
 				DBUG_ASSERT(!field.col->is_virtual());
-				field.name = field.col->name(*this);
 			}
 		}
 	} while ((index = dict_table_get_next_index(index)) != NULL);
@@ -1449,13 +1420,10 @@ void dict_table_t::rollback_instant(unsigned n)
 	if (dict_index_is_auto_gen_clust(index)) {
 		DBUG_ASSERT(index->n_uniq == 1);
 		dict_field_t* field = index->fields;
-		field->name = sys;
 		field->col = dict_table_get_sys_col(this, DATA_ROW_ID);
 		field++;
-		field->name = sys + sizeof "DB_ROW_ID";
 		field->col = dict_table_get_sys_col(this, DATA_TRX_ID);
 		field++;
-		field->name = sys + sizeof "DB_ROW_ID\0DB_TRX_ID";
 		field->col = dict_table_get_sys_col(this, DATA_ROLL_PTR);
 
 		/* Replace the DB_ROW_ID column in secondary indexes. */
@@ -1465,21 +1433,16 @@ void dict_table_t::rollback_instant(unsigned n)
 			DBUG_ASSERT(field->col->prtype
 				    == DATA_NOT_NULL + DATA_TRX_ID);
 			field->col--;
-			field->name = sys;
 		}
 
 		return;
 	}
 
 	dict_field_t* field = &index->fields[index->n_uniq];
-	field->name = sys + sizeof "DB_ROW_ID";
-	field->col = dict_table_get_sys_col(this, DATA_TRX_ID);
-	field++;
-	field->name = sys + sizeof "DB_ROW_ID\0DB_TRX_ID";
-	field->col = dict_table_get_sys_col(this, DATA_ROLL_PTR);
+	field[0].col = dict_table_get_sys_col(this, DATA_TRX_ID);
+	field[1].col = dict_table_get_sys_col(this, DATA_ROLL_PTR);
 }
 
-
 /** Check if record in clustered index is historical row.
 @param[in]	rec	clustered row
 @param[in]	offsets	offsets
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index ed333caffe5..b76346edf76 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -380,6 +380,15 @@ dict_stats_table_clone_create(
 	heap_size += sizeof(dict_table_t);
 	heap_size += strlen(table->name.m_name) + 1;
 
+	const char* col_names = table->col_names;
+	for (unsigned i = table->n_cols; i--; ) {
+		col_names += strlen(col_names) + 1;
+	}
+	const char* v_col_names = table->v_col_names;
+	for (unsigned i = table->n_v_cols; i--; ) {
+		v_col_names += strlen(v_col_names) + 1;
+	}
+
 	for (index = dict_table_get_first_index(table);
 	     index != NULL;
 	     index = dict_table_get_next_index(index)) {
@@ -395,12 +404,11 @@ dict_stats_table_clone_create(
 		heap_size += sizeof(dict_index_t);
 		heap_size += strlen(index->name) + 1;
 		heap_size += n_uniq * sizeof(index->fields[0]);
-		for (ulint i = 0; i < n_uniq; i++) {
-			heap_size += strlen(index->fields[i].name) + 1;
-		}
 		heap_size += n_uniq * sizeof(index->stat_n_diff_key_vals[0]);
 		heap_size += n_uniq * sizeof(index->stat_n_sample_sizes[0]);
 		heap_size += n_uniq * sizeof(index->stat_n_non_null_key_vals[0]);
+		heap_size += col_names - table->col_names;
+		heap_size += v_col_names - table->v_col_names;
 	}
 
 	/* Allocate the memory and copy the members */
@@ -419,6 +427,14 @@ dict_stats_table_clone_create(
 	t->heap = heap;
 
 	t->name.m_name = mem_heap_strdup(heap, table->name.m_name);
+	t->col_names = static_cast<char*>(
+		mem_heap_dup(heap, table->col_names,
+			     col_names - table->col_names));
+	t->v_col_names = table->v_col_names
+		? static_cast<char*>(
+			mem_heap_dup(heap, table->v_col_names,
+				     v_col_names - table->v_col_names))
+		: NULL;
 
 	t->corrupted = table->corrupted;
 
@@ -462,11 +478,6 @@ dict_stats_table_clone_create(
 		idx->fields = (dict_field_t*) mem_heap_alloc(
 			heap, idx->n_uniq * sizeof(idx->fields[0]));
 
-		for (ulint i = 0; i < idx->n_uniq; i++) {
-			idx->fields[i].name = mem_heap_strdup(
-				heap, index->fields[i].name);
-		}
-
 		/* hook idx into t->indexes */
 		UT_LIST_ADD_LAST(t->indexes, idx);
 
@@ -2554,7 +2565,7 @@ dict_stats_save(
 
 			/* craft a string that contains the column names */
 			snprintf(stat_description, sizeof(stat_description),
-				 "%s", index->fields[0].name());
+				 "%s", index->fields[0].col->name(*table));
 			for (unsigned j = 1; j <= i; j++) {
 				size_t	len;
 
@@ -2562,7 +2573,8 @@ dict_stats_save(
 
 				snprintf(stat_description + len,
 					 sizeof(stat_description) - len,
-					 ",%s", index->fields[j].name());
+					 ",%s",
+					 index->fields[j].col->name(*table));
 			}
 
 			ret = dict_stats_save_index_stat(
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index a558775a97a..f020964cadc 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1809,11 +1809,7 @@ fts_create_one_common_table(
 			new_table, "FTS_COMMON_TABLE_IND",
 			DICT_UNIQUE|DICT_CLUSTERED, 1);
 
-		if (!is_config) {
-			dict_mem_index_add_field(index, "doc_id", 0);
-		} else {
-			dict_mem_index_add_field(index, "key", 0);
-		}
+		dict_mem_index_add_field(index, &new_table->cols[0]);
 
 		/* We save and restore trx->dict_operation because
 		row_create_index_for_mysql() changes the operation to
@@ -2024,8 +2020,8 @@ fts_create_one_index_table(
 		dict_index_t*	index = dict_mem_index_create(
 			new_table, "FTS_INDEX_TABLE_IND",
 			DICT_UNIQUE|DICT_CLUSTERED, 2);
-		dict_mem_index_add_field(index, "word", 0);
-		dict_mem_index_add_field(index, "first_doc_id", 0);
+		dict_mem_index_add_field(index, &new_table->cols[0]);
+		dict_mem_index_add_field(index, &new_table->cols[1]);
 
 		trx_dict_op_t op = trx_get_dict_operation(trx);
 
diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc
index 6f66486ed6e..438372b5f0e 100644
--- a/storage/innobase/fts/fts0sql.cc
+++ b/storage/innobase/fts/fts0sql.cc
@@ -273,7 +273,8 @@ fts_get_select_columns_str(
 		sel_str = mem_heap_printf(heap, "sel%lu", (ulong) i);
 
 		/* Set copy_name to TRUE since it's dynamic. */
-		pars_info_bind_id(info, TRUE, sel_str, field->name);
+		pars_info_bind_id(info, TRUE, sel_str,
+				  field->col->name(*index->table));
 
 		str = mem_heap_printf(
 			heap, "%s%s$%s", str, (*str) ? ", " : "", sel_str);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 1eae180f9df..b7857068a5f 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -7341,62 +7341,7 @@ build_template_field(
 		templ->col_no = i;
 		templ->clust_rec_field_no = dict_col_get_clust_pos(
 						col, clust_index);
-		/* If clustered index record field is not found, lets print out
-		field names and all the rest to understand why field is not found. */
-		if (templ->clust_rec_field_no == ULINT_UNDEFINED) {
-			const char* tb_col_name = dict_table_get_col_name(clust_index->table, i);
-			dict_field_t* field=NULL;
-			size_t size = 0;
-
-			for(ulint j=0; j < clust_index->n_user_defined_cols; j++) {
-				dict_field_t* ifield = &(clust_index->fields[j]);
-				if (ifield && !memcmp(tb_col_name, ifield->name,
-						strlen(tb_col_name))) {
-					field = ifield;
-					break;
-				}
-			}
-
-			ib::info() << "Looking for field " << i << " name "
-				<< (tb_col_name ? tb_col_name : "NULL")
-				<< " from table " << clust_index->table->name;
-
-
-			for(ulint j=0; j < clust_index->n_user_defined_cols; j++) {
-				dict_field_t* ifield = &(clust_index->fields[j]);
-				ib::info() << "InnoDB Table "
-					<< clust_index->table->name
-					<< "field " << j << " name "
-					<< (ifield ? ifield->name() : "NULL");
-			}
-
-			for(ulint j=0; j < table->s->stored_fields; j++) {
-				ib::info() << "MySQL table "
-					<< table->s->table_name.str
-					<< " field " << j << " name "
-					<< table->field[j]->field_name.str;
-			}
-
-			ib::error() << "Clustered record field for column " << i
-				<< " not found table n_user_defined "
-				<< clust_index->n_user_defined_cols
-				<< " index n_user_defined "
-				<< clust_index->table->n_cols - DATA_N_SYS_COLS
-				<< " InnoDB table "
-				<< clust_index->table->name
-				<< " field name "
-				<< (field ? field->name() : "NULL")
-				<< " MySQL table "
-				<< table->s->table_name.str
-				<< " field name "
-				<< (tb_col_name ? tb_col_name : "NULL")
-				<< " n_fields "
-				<< table->s->stored_fields
-				<< " query "
-				<< innobase_get_stmt_unsafe(current_thd, &size);
-
-			ut_a(templ->clust_rec_field_no != ULINT_UNDEFINED);
-		}
+		ut_a(templ->clust_rec_field_no != ULINT_UNDEFINED);
 		templ->rec_field_is_prefix = FALSE;
 		templ->rec_prefix_field_no = ULINT_UNDEFINED;
 
@@ -11137,7 +11082,10 @@ create_index(
 			}
 
 			dict_mem_index_add_field(
-				index, key_part->field->field_name.str, 0);
+				index, &table->cols[
+					key_part->field->field_index
+					/* FIXME: - num_v */
+						    ], 0);
 		}
 
 		DBUG_RETURN(convert_error_code_to_mysql(
@@ -11188,8 +11136,6 @@ create_index(
 		if (field == NULL)
 		  ut_error;
 
-		const char*	field_name = key_part->field->field_name.str;
-
 		col_type = get_innobase_type_from_mysql_type(
 			&is_unsigned, key_part->field);
 
@@ -11228,7 +11174,9 @@ create_index(
 			index->type |= DICT_VIRTUAL;
 		}
 
-		dict_mem_index_add_field(index, field_name, prefix_len);
+		dict_mem_index_add_field(index, &table->cols[/* FIXME */
+						 key_part->field->field_index],
+					 prefix_len);
 	}
 
 	ut_ad(key->flags & HA_FULLTEXT || !(index->type & DICT_FTS));
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 0b0c7a0e42e..14e57cfea46 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -2704,11 +2704,12 @@ innobase_fts_check_doc_id_index(
 		field = dict_index_get_nth_field(index, 0);
 
 		/* The column would be of a BIGINT data type */
-		if (strcmp(field->name, FTS_DOC_ID_COL_NAME) == 0
-		    && field->col->mtype == DATA_INT
+		if (field->col->mtype == DATA_INT
 		    && field->col->len == 8
 		    && field->col->prtype & DATA_NOT_NULL
-		    && !field->col->is_virtual()) {
+		    && !field->col->is_virtual()
+		    && !strcmp(field->col->name(*table),
+			       FTS_DOC_ID_COL_NAME)) {
 			if (fts_doc_col_no) {
 				*fts_doc_col_no = dict_col_get_no(field->col);
 			}
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 3e06def55b0..7631ee4171b 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -419,8 +419,8 @@ void
 dict_mem_index_add_field(
 /*=====================*/
 	dict_index_t*	index,		/*!< in: index */
-	const char*	name,		/*!< in: column name */
-	ulint		prefix_len);	/*!< in: 0 or the column prefix length
+	dict_col_t*	col,		/*!< in: column */
+	ulint		prefix_len = 0);/*!< in: 0 or the column prefix length
 					in a MySQL index like
 					INDEX (textcol(25)) */
 /**********************************************************************//**
@@ -758,7 +758,6 @@ be REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes */
 /** Data structure for a field in an index */
 struct dict_field_t{
 	dict_col_t*	col;		/*!< pointer to the table column */
-	id_name_t	name;		/*!< name of the column */
 	unsigned	prefix_len:12;	/*!< 0 or the length of the column
 					prefix in bytes in a MySQL index of
 					type, e.g., INDEX (textcol(25));
@@ -772,7 +771,7 @@ struct dict_field_t{
 					DICT_ANTELOPE_MAX_INDEX_COL_LEN */
 
 	/** Zero-initialize all fields */
-	dict_field_t() : col(NULL), name(NULL), prefix_len(0), fixed_len(0) {}
+	dict_field_t() : col(NULL), prefix_len(0), fixed_len(0) {}
 
 	/** Check whether two index fields are equivalent.
 	@param[in]	old	the other index field
diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc
index 8a30e611eb4..ddb3d073bf0 100644
--- a/storage/innobase/pars/pars0pars.cc
+++ b/storage/innobase/pars/pars0pars.cc
@@ -1980,7 +1980,7 @@ pars_create_index(
 	column = column_list;
 
 	while (column) {
-		dict_mem_index_add_field(index, column->name, 0);
+		dict_mem_index_add_field(index, column->name);
 
 		column->resolved = TRUE;
 		column->token_type = SYM_COLUMN;
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index a351a1ae01b..5b1633ff939 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -99,7 +99,6 @@ row_merge_create_fts_sort_index(
 
 	/* The first field is on the Tokenized Word */
 	field = dict_index_get_nth_field(new_index, 0);
-	field->name = NULL;
 	field->prefix_len = 0;
 	field->col = static_cast<dict_col_t*>(
 		mem_heap_alloc(new_index->heap, sizeof(dict_col_t)));
@@ -114,7 +113,6 @@ row_merge_create_fts_sort_index(
 
 	/* Doc ID */
 	field = dict_index_get_nth_field(new_index, 1);
-	field->name = NULL;
 	field->prefix_len = 0;
 	field->col = static_cast<dict_col_t*>(
 		mem_heap_alloc(new_index->heap, sizeof(dict_col_t)));
@@ -156,7 +154,6 @@ row_merge_create_fts_sort_index(
 
 	/* The third field is on the word's position in the original doc */
 	field = dict_index_get_nth_field(new_index, 2);
-	field->name = NULL;
 	field->prefix_len = 0;
 	field->col = static_cast<dict_col_t*>(
 		mem_heap_alloc(new_index->heap, sizeof(dict_col_t)));
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index d402f6ee67e..15bda1729b6 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -933,19 +933,7 @@ row_import::~row_import() UNIV_NOTHROW
 {
 	for (ulint i = 0; m_indexes != 0 && i < m_n_indexes; ++i) {
 		UT_DELETE_ARRAY(m_indexes[i].m_name);
-
-		if (m_indexes[i].m_fields == NULL) {
-			continue;
-		}
-
-		dict_field_t*	fields = m_indexes[i].m_fields;
-		ulint		n_fields = m_indexes[i].m_n_fields;
-
-		for (ulint j = 0; j < n_fields; ++j) {
-			UT_DELETE_ARRAY(const_cast<char*>(fields[j].name()));
-		}
-
-		UT_DELETE_ARRAY(fields);
+		UT_DELETE_ARRAY(m_indexes[i].m_fields);
 	}
 
 	for (ulint i = 0; m_col_names != 0 && i < m_n_cols; ++i) {
@@ -1069,14 +1057,17 @@ row_import::match_index_columns(
 	const dict_field_t*	cfg_field = cfg_index->m_fields;
 
 	for (ulint i = 0; i < index->n_fields; ++i, ++field, ++cfg_field) {
+		const char* const name = field->col->name(*index->table);
+		/* TODO: how does this work with virtual columns? */
+		const char* const cname = m_col_names[field->col->ind];
 
-		if (strcmp(field->name(), cfg_field->name()) != 0) {
+		if (strcmp(name, cname)) {
 			ib_errf(thd, IB_LOG_LEVEL_ERROR,
 				ER_TABLE_SCHEMA_MISMATCH,
 				"Index field name %s doesn't match"
 				" tablespace metadata field name %s"
 				" for field position " ULINTPF,
-				field->name(), cfg_field->name(), i);
+				name, cname, i);
 
 			err = DB_ERROR;
 		}
@@ -1086,7 +1077,7 @@ row_import::match_index_columns(
 				ER_TABLE_SCHEMA_MISMATCH,
 				"Index %s field %s prefix len %u"
 				" doesn't match metadata file value %u",
-				index->name(), field->name(),
+				index->name(), name,
 				field->prefix_len, cfg_field->prefix_len);
 
 			err = DB_ERROR;
@@ -1097,7 +1088,7 @@ row_import::match_index_columns(
 				ER_TABLE_SCHEMA_MISMATCH,
 				"Index %s field %s fixed len %u"
 				" doesn't match metadata file value %u",
-				index->name(), field->name(),
+				index->name(), name,
 				field->fixed_len,
 				cfg_field->fixed_len);
 
@@ -2445,7 +2436,7 @@ row_import_cfg_read_index_fields(
 			return(DB_OUT_OF_MEMORY);
 		}
 
-		field->name = reinterpret_cast<const char*>(name);
+		/* field->name = reinterpret_cast<const char*>(name); */
 
 		dberr_t	err = row_import_cfg_read_string(file, name, len);
 
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index ad44742e57b..cbe192d04a4 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -4450,26 +4450,23 @@ row_merge_create_index(
 	index->set_committed(index_def->rebuild);
 
 	for (i = 0; i < n_fields; i++) {
-		const char*	name;
 		index_field_t*	ifield = &index_def->fields[i];
+		dict_col_t* col;
 
 		if (ifield->is_v_col) {
 			if (ifield->col_no >= table->n_v_def) {
 				ut_ad(ifield->col_no < table->n_v_def
 				      + add_v->n_v_col);
-				ut_ad(ifield->col_no >= table->n_v_def);
-				name = add_v->v_col_name[
-					ifield->col_no - table->n_v_def];
+				col = NULL;
 				index->has_new_v_col = true;
 			} else {
-				name = dict_table_get_v_col_name(
-					table, ifield->col_no);
+				col = &table->v_cols[ifield->col_no].m_col;
 			}
 		} else {
-			name = dict_table_get_col_name(table, ifield->col_no);
+			col = &table->cols[ifield->col_no];
 		}
 
-		dict_mem_index_add_field(index, name, ifield->prefix_len);
+		dict_mem_index_add_field(index, col, ifield->prefix_len);
 	}
 
 	DBUG_RETURN(index);
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index 4bfa7e0760f..1bbcd80aee7 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -73,8 +73,9 @@ row_quiesce_write_index_fields(
 			return(DB_IO_ERROR);
 		}
 
+		const char* name = field->col->name(*index->table);
 		/* Include the NUL byte in the length. */
-		ib_uint32_t	len = static_cast<ib_uint32_t>(strlen(field->name) + 1);
+		ib_uint32_t	len = static_cast<ib_uint32_t>(strlen(name) + 1);
 		ut_a(len > 1);
 
 		mach_write_to_4(row, len);
@@ -83,7 +84,7 @@ row_quiesce_write_index_fields(
 				close(fileno(file)););
 
 		if (fwrite(row, 1,  sizeof(len), file) != sizeof(len)
-		    || fwrite(field->name, 1, len, file) != len) {
+		    || fwrite(name, 1, len, file) != len) {
 
 			ib_senderrf(
 				thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR,
-- 
2.19.0

