summaryrefslogtreecommitdiff
path: root/innobase/row/row0mysql.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/row/row0mysql.c')
-rw-r--r--innobase/row/row0mysql.c68
1 files changed, 57 insertions, 11 deletions
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 9ce86b5d487..ba56b3071cd 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -313,6 +313,7 @@ row_create_prebuilt(
prebuilt = mem_heap_alloc(heap, sizeof(row_prebuilt_t));
prebuilt->magic_n = ROW_PREBUILT_ALLOCATED;
+ prebuilt->magic_n2 = ROW_PREBUILT_ALLOCATED;
prebuilt->table = table;
@@ -378,11 +379,12 @@ row_prebuilt_free(
{
ulint i;
- if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
+ if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED
+ || prebuilt->magic_n2 != ROW_PREBUILT_ALLOCATED) {
fprintf(stderr,
- "InnoDB: Error: trying to free a corrupt\n"
- "InnoDB: table handle. Magic n %lu, table name %s\n",
- prebuilt->magic_n, prebuilt->table->name);
+"InnoDB: Error: trying to free a corrupt\n"
+"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name %s\n",
+ prebuilt->magic_n, prebuilt->magic_n2, prebuilt->table->name);
mem_analyze_corruption((byte*)prebuilt);
@@ -390,6 +392,7 @@ row_prebuilt_free(
}
prebuilt->magic_n = ROW_PREBUILT_FREED;
+ prebuilt->magic_n2 = ROW_PREBUILT_FREED;
btr_pcur_free_for_mysql(prebuilt->pcur);
btr_pcur_free_for_mysql(prebuilt->clust_pcur);
@@ -420,7 +423,23 @@ row_prebuilt_free(
for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
if (prebuilt->fetch_cache[i] != NULL) {
- mem_free(prebuilt->fetch_cache[i]);
+
+ if ((ROW_PREBUILT_FETCH_MAGIC_N !=
+ mach_read_from_4((prebuilt->fetch_cache[i]) - 4))
+ || (ROW_PREBUILT_FETCH_MAGIC_N !=
+ mach_read_from_4((prebuilt->fetch_cache[i])
+ + prebuilt->mysql_row_len))) {
+ fprintf(stderr,
+ "InnoDB: Error: trying to free a corrupt\n"
+ "InnoDB: fetch buffer.\n");
+
+ mem_analyze_corruption(
+ prebuilt->fetch_cache[i]);
+
+ ut_a(0);
+ }
+
+ mem_free((prebuilt->fetch_cache[i]) - 4);
}
}
@@ -1435,7 +1454,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;
@@ -1444,7 +1463,9 @@ 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());
@@ -1465,6 +1486,31 @@ 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)) {
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" InnoDB: Error: column %s appears twice in index %s of table %s\n"
+"InnoDB: This is not allowed in InnoDB.\n",
+ dict_index_get_nth_field(index, i)->name,
+ index->name, index->table_name);
+
+ err = DB_COL_APPEARS_TWICE_IN_INDEX;
+
+ goto error_handling;
+ }
+ }
+ }
+
heap = mem_heap_create(512);
trx->dict_operation = TRUE;
@@ -1477,11 +1523,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;
@@ -1491,8 +1539,6 @@ row_create_index_for_mysql(
trx->error_state = DB_SUCCESS;
}
-
- que_graph_free((que_t*) que_node_get_parent(thr));
trx->op_info = (char *) "";