summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2002-12-05 22:03:24 +0200
committerunknown <heikki@hundin.mysql.fi>2002-12-05 22:03:24 +0200
commit446f877906f7cb7f1a4a65b185ca49d58f832121 (patch)
treef45e33c419fff3114e499f1a661e8e737301a675 /innobase
parente4add99924fc0210c635709ac7b8d88089c616a4 (diff)
downloadmariadb-git-446f877906f7cb7f1a4a65b185ca49d58f832121.tar.gz
row0mysql.c, dict0dict.c, db0err.h, ha_innobase.cc:
Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd sql/ha_innobase.cc: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd innobase/include/db0err.h: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd innobase/dict/dict0dict.c: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd innobase/row/row0mysql.c: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd
Diffstat (limited to 'innobase')
-rw-r--r--innobase/dict/dict0dict.c21
-rw-r--r--innobase/include/db0err.h2
-rw-r--r--innobase/row/row0mysql.c40
3 files changed, 56 insertions, 7 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 65f40d345d8..eb9610a6e73 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -1033,6 +1033,7 @@ dict_index_add_to_cache(
ulint n_ord;
ibool success;
ulint i;
+ ulint j;
ut_ad(index);
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -1063,6 +1064,26 @@ dict_index_add_to_cache(
return(FALSE);
}
+ /* Check that the same column does not appear twice in the index.
+ InnoDB assumes this in its algorithms, e.g., update of an index
+ entry */
+
+ for (i = 0; i < dict_index_get_n_fields(index); i++) {
+
+ for (j = 0; j < i; j++) {
+ if (dict_index_get_nth_field(index, j)->col
+ == dict_index_get_nth_field(index, i)->col) {
+
+ fprintf(stderr,
+"InnoDB: Error: column %s appears twice in index %s of table %s\n"
+"InnoDB: This is not allowed in InnoDB.\n"
+"InnoDB: UPDATE can cause such an index to become corrupt in InnoDB.\n",
+ dict_index_get_nth_field(index, i)->col->name,
+ index->name, table->name);
+ }
+ }
+ }
+
/* Build the cache internal representation of the index,
containing also the added system fields */
diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h
index ddfbd5b7862..df74b06dfc0 100644
--- a/innobase/include/db0err.h
+++ b/innobase/include/db0err.h
@@ -42,6 +42,8 @@ Created 5/24/1996 Heikki Tuuri
#define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint
to a table failed */
+#define DB_COL_APPEARS_TWICE_IN_INDEX 40
+
/* The following are partial failure codes */
#define DB_FAIL 1000
#define DB_OVERFLOW 1001
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 705ded785fc..325e931b455 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -1393,7 +1393,7 @@ int
row_create_index_for_mysql(
/*=======================*/
/* out: error number or DB_SUCCESS */
- dict_index_t* index, /* in: index defintion */
+ dict_index_t* index, /* in: index definition */
trx_t* trx) /* in: transaction handle */
{
ind_node_t* node;
@@ -1402,11 +1402,14 @@ row_create_index_for_mysql(
ulint namelen;
ulint keywordlen;
ulint err;
+ ulint i;
+ ulint j;
+ ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
- trx->op_info = "creating index";
+ trx->op_info = (char *) "creating index";
trx_start_if_not_started(trx);
@@ -1422,6 +1425,29 @@ row_create_index_for_mysql(
return(DB_SUCCESS);
}
+ /* Check that the same column does not appear twice in the index.
+ InnoDB assumes this in its algorithms, e.g., update of an index
+ entry */
+
+ for (i = 0; i < dict_index_get_n_fields(index); i++) {
+ for (j = 0; j < i; j++) {
+ if (0 == ut_strcmp(
+ dict_index_get_nth_field(index, j)->name,
+ dict_index_get_nth_field(index, i)->name)) {
+
+ fprintf(stderr,
+"InnoDB: Error: column %s appears twice in index %s\n"
+"InnoDB: This is not allowed in InnoDB.\n",
+ dict_index_get_nth_field(index, i)->name,
+ index->name);
+
+ err = DB_COL_APPEARS_TWICE_IN_INDEX;
+
+ goto error_handling;
+ }
+ }
+ }
+
heap = mem_heap_create(512);
trx->dict_operation = TRUE;
@@ -1434,11 +1460,13 @@ row_create_index_for_mysql(
SESS_COMM_EXECUTE, 0));
que_run_threads(thr);
- err = trx->error_state;
+ err = trx->error_state;
+
+ que_graph_free((que_t*) que_node_get_parent(thr));
+error_handling:
if (err != DB_SUCCESS) {
/* We have special error handling here */
- ut_a(err == DB_OUT_OF_FILE_SPACE);
trx->error_state = DB_SUCCESS;
@@ -1448,10 +1476,8 @@ row_create_index_for_mysql(
trx->error_state = DB_SUCCESS;
}
-
- que_graph_free((que_t*) que_node_get_parent(thr));
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}