MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Alex Ivanov Notebook Date:April 20 2006 9:07pm
Subject:bk commit into 5.0 tree (aivanov:1.2152) BUG#18934
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of alexi. When alexi does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2152 06/04/21 01:07:37 aivanov@stripped +11 -0
  Applied innodb-5.0-ss476 snapshot.
   Fix BUG#18934: "InnoDB crashes when table uses column like DB_ROW_ID".
   Also, fix memory leaks in row_create_table_for_mysql() in rare
   corner cases.

  mysql-test/t/innodb.test
    1.130 06/04/21 01:07:33 aivanov@stripped +3 -11
    Applied innodb-5.0-ss476 snapshot.
     Fix result for test case for Bug#18934.
     (Removed test case for Bug#14360 is to be restored by the next cset).

  mysql-test/r/innodb.result
    1.160 06/04/21 01:07:33 aivanov@stripped +3 -10
    Applied innodb-5.0-ss476 snapshot.
     Fix result for test case for Bug#18934.
     (Other changes are to be restored by the next cset).

  innobase/row/row0mysql.c
    1.119 06/04/21 01:07:33 aivanov@stripped +18 -0
    Applied innodb-5.0-ss476 snapshot.
     Refuse tables that use reserved column names (Bug#18934).

  innobase/log/log0recv.c
    1.52 06/04/21 01:07:32 aivanov@stripped +3 -3
    Applied innodb-5.0-ss476 snapshot.

  innobase/include/univ.i
    1.48 06/04/21 01:07:32 aivanov@stripped +3 -0
    Applied innodb-5.0-ss476 snapshot.

  innobase/include/dict0mem.h
    1.27 06/04/21 01:07:32 aivanov@stripped +7 -0
    Applied innodb-5.0-ss476 snapshot.
     Add dict_mem_table_free(), use it instead of duplicating
     the code everywhere.

  innobase/include/dict0dict.h
    1.39 06/04/21 01:07:32 aivanov@stripped +9 -0
    Applied innodb-5.0-ss476 snapshot.
     Refuse tables that use reserved column name (Bug#18934).

  innobase/ibuf/ibuf0ibuf.c
    1.41 06/04/21 01:07:32 aivanov@stripped +3 -3
    Applied innodb-5.0-ss476 snapshot.

  innobase/dict/dict0mem.c
    1.19 06/04/21 01:07:32 aivanov@stripped +18 -0
    Applied innodb-5.0-ss476 snapshot.
     Add dict_mem_table_free(), use it instead of duplicating
     the code everywhere.

  innobase/dict/dict0load.c
    1.42 06/04/21 01:07:32 aivanov@stripped +11 -6
    Applied innodb-5.0-ss476 snapshot.
     dict_load_table(): Refuse to load tables with other TYPE
     than DICT_TABLE_ORDINARY.

  innobase/dict/dict0dict.c
    1.75 06/04/21 01:07:32 aivanov@stripped +34 -4
    Applied innodb-5.0-ss476 snapshot.
     Refuse tables that use reserved column names (Bug#18934).

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	aivanov
# Host:	mysqld.localdomain
# Root:	/home/alexi/innodb/mysql-5.0-work

--- 1.74/innobase/dict/dict0dict.c	2006-04-20 23:18:24 +04:00
+++ 1.75/innobase/dict/dict0dict.c	2006-04-21 01:07:32 +04:00
@@ -1249,15 +1249,13 @@
 	/* Remove table from LRU list of tables */
 	UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
 
-	mutex_free(&(table->autoinc_mutex));
-
 	size = mem_heap_get_size(table->heap);
 
 	ut_ad(dict_sys->size >= size);
 
 	dict_sys->size -= size;
 
-	mem_heap_free(table->heap);
+	dict_mem_table_free(table);
 }
 
 /**************************************************************************
@@ -1378,6 +1376,38 @@
 	HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
 }
 
+/********************************************************************
+If the given column name is reserved for InnoDB system columns, return
+TRUE. */
+
+ibool
+dict_col_name_is_reserved(
+/*======================*/
+				/* out: TRUE if name is reserved */
+	const char*	name)	/* in: column name */
+{
+	/* This check reminds that if a new system column is added to
+	the program, it should be dealt with here. */
+#if DATA_N_SYS_COLS != 4
+#error "DATA_N_SYS_COLS != 4"
+#endif
+
+	static const char*	reserved_names[] = {
+		"DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID"
+	};
+
+	ulint			i;
+
+	for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
+		if (strcmp(name, reserved_names[i]) == 0) {
+
+			return(TRUE);
+		}
+	}
+
+	return(FALSE);
+}
+
 /**************************************************************************
 Adds an index to the dictionary cache. */
 
@@ -1551,7 +1581,7 @@
 
 	dict_sys->size -= size;
 
-	mem_heap_free(index->heap);
+	dict_mem_index_free(index);
 }
 
 /***********************************************************************

--- 1.41/innobase/dict/dict0load.c	2006-01-31 21:41:42 +03:00
+++ 1.42/innobase/dict/dict0load.c	2006-04-21 01:07:32 +04:00
@@ -767,7 +767,7 @@
 	if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
 			|| rec_get_deleted_flag(rec, sys_tables->comp)) {
 		/* Not found */
-
+	err_exit:
 		btr_pcur_close(&pcur);
 		mtr_commit(&mtr);
 		mem_heap_free(heap);
@@ -779,11 +779,8 @@
 
 	/* Check if the table name in record is the searched one */
 	if (len != ut_strlen(name) || ut_memcmp(name, field, len) != 0) {
-		btr_pcur_close(&pcur);
-		mtr_commit(&mtr);
-		mem_heap_free(heap);
-		
-		return(NULL);
+
+		goto err_exit;
 	}
 
 	ut_a(0 == ut_strcmp("SPACE",
@@ -843,6 +840,14 @@
 
 	field = rec_get_nth_field_old(rec, 5, &len);
 	table->type = mach_read_from_4(field);
+
+	if (UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) {
+		ut_print_timestamp(stderr);
+		fprintf(stderr,
+			"  InnoDB: table %s: unknown table type %lu\n",
+			name, (ulong) table->type);
+		goto err_exit;
+	}
 
 	if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
 		ut_error;

--- 1.18/innobase/dict/dict0mem.c	2006-04-20 23:18:24 +04:00
+++ 1.19/innobase/dict/dict0mem.c	2006-04-21 01:07:32 +04:00
@@ -97,6 +97,21 @@
 	return(table);
 }
 
+/********************************************************************
+Free a table memory object. */
+
+void
+dict_mem_table_free(
+/*================*/
+	dict_table_t*	table)		/* in: table */
+{
+	ut_ad(table);
+	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+
+	mutex_free(&(table->autoinc_mutex));
+	mem_heap_free(table->heap);
+}
+
 /**************************************************************************
 Creates a cluster memory object. */
 
@@ -290,5 +305,8 @@
 /*================*/
 	dict_index_t*	index)	/* in: index */
 {
+	ut_ad(index);
+	ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+
 	mem_heap_free(index->heap);
 }

--- 1.40/innobase/ibuf/ibuf0ibuf.c	2005-06-27 19:57:39 +04:00
+++ 1.41/innobase/ibuf/ibuf0ibuf.c	2006-04-21 01:07:32 +04:00
@@ -1160,9 +1160,9 @@
 	dict_index_t*	index)	/* in: dummy index */
 {
 	dict_table_t*	table = index->table;
-	mem_heap_free(index->heap);
-	mutex_free(&(table->autoinc_mutex));
-	mem_heap_free(table->heap);
+
+	dict_mem_index_free(index);
+	dict_mem_table_free(table);
 }
 
 /*************************************************************************

--- 1.38/innobase/include/dict0dict.h	2006-04-20 23:18:24 +04:00
+++ 1.39/innobase/include/dict0dict.h	2006-04-21 01:07:32 +04:00
@@ -98,6 +98,15 @@
 dict_col_get_clust_pos(
 /*===================*/
 	dict_col_t*	col);
+/********************************************************************
+If the given column name is reserved for InnoDB system columns, return
+TRUE. */
+
+ibool
+dict_col_name_is_reserved(
+/*======================*/
+				/* out: TRUE if name is reserved */
+	const char*	name);	/* in: column name */
 /************************************************************************
 Initializes the autoinc counter. It is not an error to initialize an already
 initialized counter. */

--- 1.26/innobase/include/dict0mem.h	2006-04-20 23:18:24 +04:00
+++ 1.27/innobase/include/dict0mem.h	2006-04-21 01:07:32 +04:00
@@ -56,6 +56,13 @@
 					a member of a cluster */
 	ulint		n_cols,		/* in: number of columns */
 	ibool		comp);		/* in: TRUE=compact page format */
+/********************************************************************
+Free a table memory object. */
+
+void
+dict_mem_table_free(
+/*================*/
+	dict_table_t*	table);		/* in: table */
 /**************************************************************************
 Creates a cluster memory object. */
 

--- 1.47/innobase/include/univ.i	2006-04-20 23:18:25 +04:00
+++ 1.48/innobase/include/univ.i	2006-04-21 01:07:32 +04:00
@@ -261,6 +261,9 @@
 /* Tell the compiler that cond is unlikely to hold */
 #define UNIV_UNLIKELY(cond) UNIV_EXPECT(cond, FALSE)
 
+/* Compile-time constant of the given array's size. */
+#define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
 #include <stdio.h>
 #include "ut0dbg.h"
 #include "ut0ut.h"

--- 1.51/innobase/log/log0recv.c	2005-06-27 19:57:50 +04:00
+++ 1.52/innobase/log/log0recv.c	2006-04-21 01:07:32 +04:00
@@ -890,9 +890,9 @@
 	ut_ad(!page || ptr);
 	if (index) {
 		dict_table_t*	table = index->table;
-		mem_heap_free(index->heap);
-		mutex_free(&(table->autoinc_mutex));
-		mem_heap_free(table->heap);
+
+		dict_mem_index_free(index);
+		dict_mem_table_free(table);
 	}
 	
 	return(ptr);

--- 1.118/innobase/row/row0mysql.c	2006-04-20 23:18:25 +04:00
+++ 1.119/innobase/row/row0mysql.c	2006-04-21 01:07:33 +04:00
@@ -1673,7 +1673,9 @@
 
 	if (!ptr) {
 		/* table name does not begin with "/rsql" */
+		dict_mem_table_free(table);
 		trx_commit_for_mysql(trx);
+
 		return(DB_ERROR);
 	}
 	else {
@@ -1785,6 +1787,7 @@
 	const char*	table_name;
 	ulint		table_name_len;
 	ulint		err;
+	ulint		i;
 
 	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 #ifdef UNIV_SYNC_DEBUG
@@ -1802,6 +1805,7 @@
 		"InnoDB: with raw, and innodb_force_... is removed.\n",
 		stderr);
 
+		dict_mem_table_free(table);
 		trx_commit_for_mysql(trx);
 
 		return(DB_ERROR);
@@ -1816,9 +1820,23 @@
     "InnoDB: MySQL system tables must be of the MyISAM type!\n",
 		table->name);
 
+		dict_mem_table_free(table);
 		trx_commit_for_mysql(trx);
 
 		return(DB_ERROR);
+	}
+
+	/* Check that no reserved column names are used. */
+	for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
+		dict_col_t*	col = dict_table_get_nth_col(table, i);
+
+		if (dict_col_name_is_reserved(col->name)) {
+
+			dict_mem_table_free(table);
+			trx_commit_for_mysql(trx);
+
+			return(DB_ERROR);
+		}
 	}
 
 	trx_start_if_not_started(trx);

--- 1.159/mysql-test/r/innodb.result	2006-04-11 15:13:48 +04:00
+++ 1.160/mysql-test/r/innodb.result	2006-04-21 01:07:33 +04:00
@@ -1821,7 +1821,7 @@
 innodb_sync_spin_loops	20
 show variables like "innodb_thread_concurrency";
 Variable_name	Value
-innodb_thread_concurrency	8
+innodb_thread_concurrency	0
 set global innodb_thread_concurrency=1001;
 show variables like "innodb_thread_concurrency";
 Variable_name	Value
@@ -3232,12 +3232,5 @@
 drop trigger t3t;
 drop trigger t4t;
 drop table t1, t2, t3, t4, t5;
-create table t1(a date) engine=innodb;
-create table t2(a date, key(a)) engine=innodb;
-insert into t1 values('2005-10-01');
-insert into t2 values('2005-10-01');
-select * from t1, t2
-where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
-a	a
-2005-10-01	2005-10-01
-drop table t1, t2;
+CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
+ERROR HY000: Can't create table './test/t1.frm' (errno: -1)

--- 1.129/mysql-test/t/innodb.test	2006-04-11 15:13:48 +04:00
+++ 1.130/mysql-test/t/innodb.test	2006-04-21 01:07:33 +04:00
@@ -2128,14 +2128,6 @@
 disconnect a;
 disconnect b;
 
-#
-# Bug #14360: problem with intervals
-#
-
-create table t1(a date) engine=innodb;
-create table t2(a date, key(a)) engine=innodb; 
-insert into t1 values('2005-10-01');
-insert into t2 values('2005-10-01');
-select * from t1, t2
-  where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
-drop table t1, t2;
+# bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID"
+--error 1005
+CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
Thread
bk commit into 5.0 tree (aivanov:1.2152) BUG#18934Alex Ivanov Notebook20 Apr