List:Internals« Previous MessageNext Message »
From:Alex Ivanov Date:November 24 2005 3:43pm
Subject:bk commit into 5.0 tree (aivanov:1.1989)
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.1989 05/11/24 18:42:52 aivanov@stripped +13 -0
  Ignore: just experimenting

  sql/ha_innodb.h
    1.108 05/11/24 18:42:43 aivanov@stripped +3 -4
    Ignore

  sql/ha_innodb.cc
    1.279 05/11/24 18:42:43 aivanov@stripped +23 -36
    Ignore

  mysql-test/t/innodb_gis.test
    1.3 05/11/24 18:42:43 aivanov@stripped +2 -1
    Ignore

  mysql-test/t/innodb.test
    1.117 05/11/24 18:42:43 aivanov@stripped +76 -12
    Ignore

  mysql-test/r/innodb.result
    1.146 05/11/24 18:42:43 aivanov@stripped +72 -11
    Ignore

  innobase/row/row0mysql.c
    1.115 05/11/24 18:42:43 aivanov@stripped +26 -38
    Ignore

  innobase/rem/rem0cmp.c
    1.29 05/11/24 18:42:42 aivanov@stripped +6 -5
    Ignore

  innobase/include/rem0cmp.h
    1.7 05/11/24 18:42:42 aivanov@stripped +2 -1
    Ignore

  innobase/include/dict0load.h
    1.7 05/11/24 18:42:42 aivanov@stripped +2 -1
    Ignore

  innobase/include/dict0dict.h
    1.36 05/11/24 18:42:42 aivanov@stripped +2 -1
    Ignore

  innobase/include/buf0buf.h
    1.32 05/11/24 18:42:42 aivanov@stripped +7 -3
    Ignore

  innobase/dict/dict0dict.c
    1.69 05/11/24 18:42:42 aivanov@stripped +13 -21
    Ignore

  innobase/btr/btr0sea.c
    1.35 05/11/24 18:42:42 aivanov@stripped +10 -18
    Ignore

# 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:	mysql.creware.com
# Root:	/home/alexi/dev/innodb-ss/mysql-5.0-xx52

--- 1.2/mysql-test/t/innodb_gis.test	2005-10-27 23:45:06 +04:00
+++ 1.3/mysql-test/t/innodb_gis.test	2005-11-24 18:42:43 +03:00
@@ -1,3 +1,4 @@
---source include/have_innodb.inc
+source include/have_geometry.inc;
+-- source include/have_innodb.inc
 SET storage_engine=innodb;
 --source include/gis_generic.inc

--- 1.34/innobase/btr/btr0sea.c	2005-08-19 13:53:56 +04:00
+++ 1.35/innobase/btr/btr0sea.c	2005-11-24 18:42:42 +03:00
@@ -904,6 +904,7 @@
 	ulint*		folds;
 	ulint		i;
 	mem_heap_t*	heap;
+	dict_index_t*	index;
 	ulint*		offsets;
 
 #ifdef UNIV_SYNC_DEBUG
@@ -932,11 +933,16 @@
 
 	n_fields = block->curr_n_fields;
 	n_bytes = block->curr_n_bytes;
+	index = block->index;
 
-	ut_a(n_fields + n_bytes > 0);
+	/* NOTE: The fields of block must not be accessed after
+	releasing btr_search_latch, as the index page might only
+	be s-latched! */
 
 	rw_lock_s_unlock(&btr_search_latch);
 	
+	ut_a(n_fields + n_bytes > 0);
+
 	n_recs = page_get_n_recs(page);
 
 	/* Calculate and cache fold values into an array for fast deletion
@@ -949,14 +955,6 @@
 	rec = page_get_infimum_rec(page);
 	rec = page_rec_get_next(rec);
 
-	if (!page_rec_is_supremum(rec)) {
-		ut_a(n_fields <= rec_get_n_fields(rec, block->index));
-
-		if (n_bytes > 0) {
-			ut_a(n_fields < rec_get_n_fields(rec, block->index));
-		}
-	}
-
 	tree_id = btr_page_get_index_id(page);
 	
 	prev_fold = 0;
@@ -964,18 +962,12 @@
 	heap = NULL;
 	offsets = NULL;
 
-	if (block->index == NULL) {
-
-		mem_analyze_corruption((byte*)block);
-
-		ut_a(block->index != NULL);
-	}
-
 	while (!page_rec_is_supremum(rec)) {
 		/* FIXME: in a mixed tree, not all records may have enough
 		ordering fields: */
-		offsets = rec_get_offsets(rec, block->index,
-				offsets, n_fields + (n_bytes > 0), &heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+					n_fields + (n_bytes > 0), &heap);
+		ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
 		fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
 
 		if (fold == prev_fold && prev_fold != 0) {

--- 1.68/innobase/dict/dict0dict.c	2005-09-23 17:40:53 +04:00
+++ 1.69/innobase/dict/dict0dict.c	2005-11-24 18:42:42 +03:00
@@ -2104,8 +2104,11 @@
 	dict_table_t*	table,	/* in: table */
 	const char**	columns,/* in: array of column names */
 	ulint		n_cols,	/* in: number of columns */
-	dict_index_t*	types_idx)/* in: NULL or an index to whose types the
-				column types must match */
+	dict_index_t*	types_idx, /* in: NULL or an index to whose types the
+				   column types must match */
+	ibool		check_charsets)	/* in: whether to check charsets.
+					only has an effect if types_idx !=
+					NULL. */
 {
 #ifndef UNIV_HOTBACKUP
 	dict_index_t*	index;
@@ -2135,7 +2138,8 @@
 
 				if (types_idx && !cmp_types_are_equal(
 				     dict_index_get_nth_type(index, i),
-				     dict_index_get_nth_type(types_idx, i))) {
+				     dict_index_get_nth_type(types_idx, i),
+				     check_charsets)) {
 
 				  	break;
 				}		
@@ -2212,7 +2216,8 @@
 /*======================*/
 					/* out: DB_SUCCESS or error code */
 	dict_foreign_t*	foreign,	/* in, own: foreign key constraint */
-	ibool		check_types)	/* in: TRUE=check type compatibility */
+	ibool		check_charsets)	/* in: TRUE=check charset
+					compatibility */
 {
 	dict_table_t*	for_table;
 	dict_table_t*	ref_table;
@@ -2248,16 +2253,10 @@
 	}
 
 	if (for_in_cache->referenced_table == NULL && ref_table) {
-		dict_index_t*	types_idx;
-		if (check_types) {
-			types_idx = for_in_cache->foreign_index;
-		} else {
-			types_idx = NULL;
-		}
 		index = dict_foreign_find_index(ref_table,
 			(const char**) for_in_cache->referenced_col_names,
 			for_in_cache->n_fields,
-			types_idx);
+			for_in_cache->foreign_index, check_charsets);
 
 		if (index == NULL) {
 			dict_foreign_error_report(ef, for_in_cache,
@@ -2281,16 +2280,10 @@
 	}
 
 	if (for_in_cache->foreign_table == NULL && for_table) {
-		dict_index_t*	types_idx;
-		if (check_types) {
-			types_idx = for_in_cache->referenced_index;
-		} else {
-			types_idx = NULL;
-		}
 		index = dict_foreign_find_index(for_table,
 			(const char**) for_in_cache->foreign_col_names,
 			for_in_cache->n_fields,
-			types_idx);
+			for_in_cache->referenced_index, check_charsets);
 
 		if (index == NULL) {
 			dict_foreign_error_report(ef, for_in_cache,
@@ -3097,7 +3090,7 @@
 	/* Try to find an index which contains the columns
 	as the first fields and in the right order */
 
-	index = dict_foreign_find_index(table, column_names, i, NULL);
+	index = dict_foreign_find_index(table, column_names, i, NULL, TRUE);
 
 	if (!index) {
 		mutex_enter(&dict_foreign_err_mutex);
@@ -3362,8 +3355,7 @@
 
 	if (referenced_table) {
 		index = dict_foreign_find_index(referenced_table,
-						column_names, i,
-						foreign->foreign_index);
+			column_names, i, foreign->foreign_index, TRUE);
 		if (!index) {
 			dict_foreign_free(foreign);
 			mutex_enter(&dict_foreign_err_mutex);

--- 1.31/innobase/include/buf0buf.h	2005-06-15 13:50:18 +04:00
+++ 1.32/innobase/include/buf0buf.h	2005-11-24 18:42:42 +03:00
@@ -745,8 +745,6 @@
 					buffer pool which are index pages,
 					but this flag is not set because
 					we do not keep track of all pages */
-	dict_index_t*	index;		/* index for which the adaptive
-					hash index has been created */
 	/* 2. Page flushing fields */
 
 	UT_LIST_NODE_T(buf_block_t) flush_list;
@@ -833,7 +831,7 @@
 					records with the same prefix should be
 					indexed in the hash index */
 					
-	/* The following 4 fields are protected by btr_search_latch: */
+	/* The following 6 fields are protected by btr_search_latch: */
 
 	ibool		is_hashed;	/* TRUE if hash index has already been
 					built on this page; note that it does
@@ -850,6 +848,12 @@
 	ulint		curr_side;	/* BTR_SEARCH_LEFT_SIDE or
 					BTR_SEARCH_RIGHT_SIDE in hash
 					indexing */
+	dict_index_t*	index;		/* Index for which the adaptive
+					hash index has been created.
+					This field may only be modified
+					while holding an s-latch or x-latch
+					on block->lock and an x-latch on
+					btr_search_latch. */
 	/* 6. Debug fields */
 #ifdef UNIV_SYNC_DEBUG
 	rw_lock_t	debug_latch;	/* in the debug version, each thread

--- 1.35/innobase/include/dict0dict.h	2005-09-23 17:22:23 +04:00
+++ 1.36/innobase/include/dict0dict.h	2005-11-24 18:42:42 +03:00
@@ -197,7 +197,8 @@
 /*======================*/
 					/* out: DB_SUCCESS or error code */
 	dict_foreign_t*	foreign,	/* in, own: foreign key constraint */
-	ibool		check_types);	/* in: TRUE=check type compatibility */
+	ibool		check_charsets);/* in: TRUE=check charset
+					compatibility */
 /*************************************************************************
 Checks if a table is referenced by foreign keys. */
 

--- 1.6/innobase/include/dict0load.h	2005-04-12 17:12:27 +04:00
+++ 1.7/innobase/include/dict0load.h	2005-11-24 18:42:42 +03:00
@@ -82,7 +82,8 @@
 /*===============*/
 					/* out: DB_SUCCESS or error code */
 	const char*	table_name,	/* in: table name */
-	ibool		check_types);	/* in: TRUE=check type compatibility */
+	ibool		check_charsets);/* in: TRUE=check charsets
+					compatibility */
 /************************************************************************
 Prints to the standard output information on all tables found in the data
 dictionary system table. */

--- 1.6/innobase/include/rem0cmp.h	2004-12-28 02:34:44 +03:00
+++ 1.7/innobase/include/rem0cmp.h	2005-11-24 18:42:42 +03:00
@@ -24,7 +24,8 @@
 				/* out: TRUE if the types are considered
 				equal in comparisons */
 	dtype_t*	type1,	/* in: type 1 */
-	dtype_t*	type2);	/* in: type 2 */
+	dtype_t*	type2,	/* in: type 2 */
+	ibool		check_charsets); /* in: whether to check charsets */
 /*****************************************************************
 This function is used to compare two data fields for which we know the
 data type. */

--- 1.28/innobase/rem/rem0cmp.c	2005-04-25 11:14:26 +04:00
+++ 1.29/innobase/rem/rem0cmp.c	2005-11-24 18:42:42 +03:00
@@ -99,7 +99,8 @@
 				/* out: TRUE if the types are considered
 				equal in comparisons */
 	dtype_t*	type1,	/* in: type 1 */
-	dtype_t*	type2)	/* in: type 2 */
+	dtype_t*	type2,	/* in: type 2 */
+	ibool		check_charsets) /* in: whether to check charsets */
 {
 	if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype)
 	    && dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) {
@@ -107,12 +108,12 @@
 		/* Both are non-binary string types: they can be compared if
 		and only if the charset-collation is the same */
 
-		if (dtype_get_charset_coll(type1->prtype)
-				== dtype_get_charset_coll(type2->prtype)) {
+		if (check_charsets) {
+			return(dtype_get_charset_coll(type1->prtype)
+			    == dtype_get_charset_coll(type2->prtype));
+		} else {
 			return(TRUE);
 		}
-
-		return(FALSE);
         }
 
 	if (dtype_is_binary_string_type(type1->mtype, type1->prtype)

--- 1.114/innobase/row/row0mysql.c	2005-09-23 12:20:22 +04:00
+++ 1.115/innobase/row/row0mysql.c	2005-11-24 18:42:43 +03:00
@@ -2132,7 +2132,7 @@
 
 	if (err == DB_SUCCESS) {
 		/* Check that also referencing constraints are ok */
-		err = dict_load_foreigns(name, trx->check_foreigns);
+		err = dict_load_foreigns(name, TRUE);
 	}
 
 	if (err != DB_SUCCESS) {
@@ -3590,7 +3590,8 @@
 	mem_heap_t*	heap			= NULL;
 	const char**	constraints_to_drop	= NULL;
 	ulint		n_constraints_to_drop	= 0;
-        ibool           recovering_temp_table   = FALSE;
+	ibool           recovering_temp_table   = FALSE;
+	ibool		old_is_tmp, new_is_tmp;
 	ulint		len;
 	ulint		i;
         ibool		success;
@@ -3630,6 +3631,9 @@
 	trx->op_info = "renaming table";
 	trx_start_if_not_started(trx);
 
+	old_is_tmp = row_is_mysql_tmp_table_name(old_name);
+	new_is_tmp = row_is_mysql_tmp_table_name(new_name);
+	
 	if (row_mysql_is_recovered_tmp_table(new_name)) {
 
                 recovering_temp_table = TRUE;
@@ -3676,7 +3680,7 @@
 	len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4
 		+ ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\'');
 
-	if (row_is_mysql_tmp_table_name(new_name)) {
+	if (new_is_tmp) {
 		db_name_len = dict_get_db_name_len(old_name) + 1;
 
 		/* MySQL is doing an ALTER TABLE command and it renames the
@@ -3829,7 +3833,7 @@
 		the table is stored in a single-table tablespace */
 
 		success = dict_table_rename_in_cache(table, new_name,
-				!row_is_mysql_tmp_table_name(new_name));
+				!new_is_tmp);
 		if (!success) {
 			trx->error_state = DB_SUCCESS;
 			trx_general_rollback_for_mysql(trx, FALSE, NULL);
@@ -3846,19 +3850,16 @@
 			goto funct_exit;
 		}
 
-		err = dict_load_foreigns(new_name, trx->check_foreigns);
-
-		if (row_is_mysql_tmp_table_name(old_name)) {
+		/* We only want to switch off some of the type checking in
+		an ALTER, not in a RENAME. */
+		
+		err = dict_load_foreigns(new_name,
+			old_is_tmp ? trx->check_foreigns : TRUE);
 
-			/* MySQL is doing an ALTER TABLE command and it
-			renames the created temporary table to the name
-			of the original table. In the ALTER TABLE we maybe
-			created some FOREIGN KEY constraints for the temporary
-			table. But we want to load also the foreign key
-			constraint definitions for the original table name. */
+		if (err != DB_SUCCESS) {
+			ut_print_timestamp(stderr);
 
-			if (err != DB_SUCCESS) {
-	    			ut_print_timestamp(stderr);
+			if (old_is_tmp) {
 				fputs("  InnoDB: Error: in ALTER TABLE ",
 					stderr);
 				ut_print_name(stderr, trx, new_name);
@@ -3866,36 +3867,23 @@
 	"InnoDB: has or is referenced in foreign key constraints\n"
 	"InnoDB: which are not compatible with the new table definition.\n",
 					stderr);
-
-				ut_a(dict_table_rename_in_cache(table,
-					old_name, FALSE));
-				trx->error_state = DB_SUCCESS;
-				trx_general_rollback_for_mysql(trx, FALSE,
-									NULL);
-				trx->error_state = DB_SUCCESS;
-			}
-		} else {
-			if (err != DB_SUCCESS) {
-
-	    			ut_print_timestamp(stderr);
-
+			} else {
 				fputs(
 				"  InnoDB: Error: in RENAME TABLE table ",
 					stderr);
 				ut_print_name(stderr, trx, new_name);
 				fputs("\n"
-     "InnoDB: is referenced in foreign key constraints\n"
-     "InnoDB: which are not compatible with the new table definition.\n",
+	"InnoDB: is referenced in foreign key constraints\n"
+	"InnoDB: which are not compatible with the new table definition.\n",
 					stderr);
-     
-				ut_a(dict_table_rename_in_cache(table,
-					old_name, FALSE));
-						
-				trx->error_state = DB_SUCCESS;
-				trx_general_rollback_for_mysql(trx, FALSE,
-									NULL);
-				trx->error_state = DB_SUCCESS;
 			}
+
+			ut_a(dict_table_rename_in_cache(table,
+					old_name, FALSE));
+			trx->error_state = DB_SUCCESS;
+			trx_general_rollback_for_mysql(trx, FALSE,
+				NULL);
+			trx->error_state = DB_SUCCESS;
 		}
 	}
 funct_exit:	

--- 1.145/mysql-test/r/innodb.result	2005-10-19 20:06:22 +04:00
+++ 1.146/mysql-test/r/innodb.result	2005-11-24 18:42:43 +03:00
@@ -2437,7 +2437,9 @@
 20	NULL
 drop table t1;
 create table t1 (v varchar(65530), key(v));
-ERROR HY000: Can't create table './test/t1' (errno: 139)
+Warnings:
+Warning	1071	Specified key was too long; max key length is 767 bytes
+drop table t1;
 create table t1 (v varchar(65536));
 Warnings:
 Note	1246	Converting column 'v' from VARCHAR to TEXT
@@ -2577,22 +2579,49 @@
 character set = latin1 engine = innodb;
 create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
 character set = latin1 engine = innodb;
+show create table t9;
+Table	Create Table
+t9	CREATE TABLE `t9` (
+  `col1` varchar(512) default NULL,
+  `col2` varchar(512) default NULL,
+  KEY `col1` (`col1`,`col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
 drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
-create table t1 (col1 varchar(768), index (col1))
+create table t1 (col1 varchar(768), index(col1))
 character set = latin1 engine = innodb;
-ERROR HY000: Can't create table './test/t1.frm' (errno: 139)
-create table t2 (col1 varchar(768) primary key)
+Warnings:
+Warning	1071	Specified key was too long; max key length is 767 bytes
+create table t2 (col1 varbinary(768), index(col1))
 character set = latin1 engine = innodb;
-ERROR HY000: Can't create table './test/t2.frm' (errno: 139)
-create table t3 (col1 varbinary(768) primary key)
+Warnings:
+Warning	1071	Specified key was too long; max key length is 767 bytes
+create table t3 (col1 text, index(col1(768)))
 character set = latin1 engine = innodb;
-ERROR HY000: Can't create table './test/t3.frm' (errno: 139)
-create table t4 (col1 text, index(col1(768)))
+Warnings:
+Warning	1071	Specified key was too long; max key length is 767 bytes
+create table t4 (col1 blob, index(col1(768)))
 character set = latin1 engine = innodb;
-ERROR HY000: Can't create table './test/t4.frm' (errno: 139)
-create table t5 (col1 blob, index(col1(768)))
+Warnings:
+Warning	1071	Specified key was too long; max key length is 767 bytes
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `col1` varchar(768) default NULL,
+  KEY `col1` (`col1`(767))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2, t3, t4;
+create table t1 (col1 varchar(768) primary key)
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t2 (col1 varbinary(768) primary key)
 character set = latin1 engine = innodb;
-ERROR HY000: Can't create table './test/t5.frm' (errno: 139)
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t3 (col1 text, primary key(col1(768)))
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t4 (col1 blob, primary key(col1(768)))
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
 CREATE TABLE t1
 (
 id INT PRIMARY KEY
@@ -2772,3 +2801,35 @@
 drop table t1;
 drop table t2;
 commit;
+set foreign_key_checks=0;
+create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+ERROR HY000: Can't create table './test/t1.frm' (errno: 150)
+set foreign_key_checks=1;
+drop table t2;
+set foreign_key_checks=0;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
+ERROR HY000: Can't create table './test/t2.frm' (errno: 150)
+set foreign_key_checks=1;
+drop table t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
+create table t1(a varchar(10) primary key) engine = innodb;
+alter table t1 modify column a int;
+Got one of the listed errors
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+alter table t1 convert to character set utf8;
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+rename table t3 to t1;
+ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2,t3;

--- 1.116/mysql-test/t/innodb.test	2005-10-19 20:06:22 +04:00
+++ 1.117/mysql-test/t/innodb.test	2005-11-24 18:42:43 +03:00
@@ -1356,8 +1356,8 @@
 # Clean up filename -- embedded server reports whole path without .frm,
 # regular server reports relative path with .frm (argh!)
 --replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ / t1.frm t1
---error 1005
 create table t1 (v varchar(65530), key(v));
+drop table t1;
 create table t1 (v varchar(65536));
 show create table t1;
 drop table t1;
@@ -1485,7 +1485,7 @@
 DROP TABLE t1;
 
 #
-# Test that index column max sizes are checked (bug #13315)
+# Test that index column max sizes are honored (bug #13315)
 #
 
 # prefix index
@@ -1512,22 +1512,36 @@
 create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
  character set = latin1 engine = innodb;
 
+show create table t9;
+
 drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
 
---error 1005
-create table t1 (col1 varchar(768), index (col1))
+# these should have their index length trimmed
+create table t1 (col1 varchar(768), index(col1))
+ character set = latin1 engine = innodb;
+create table t2 (col1 varbinary(768), index(col1))
+ character set = latin1 engine = innodb;
+create table t3 (col1 text, index(col1(768)))
  character set = latin1 engine = innodb;
---error 1005
-create table t2 (col1 varchar(768) primary key)
+create table t4 (col1 blob, index(col1(768)))
  character set = latin1 engine = innodb;
---error 1005
-create table t3 (col1 varbinary(768) primary key)
+
+show create table t1;
+
+drop table t1, t2, t3, t4;
+
+# these should be refused
+--error 1071
+create table t1 (col1 varchar(768) primary key)
  character set = latin1 engine = innodb;
---error 1005
-create table t4 (col1 text, index(col1(768)))
+--error 1071
+create table t2 (col1 varbinary(768) primary key)
  character set = latin1 engine = innodb;
---error 1005
-create table t5 (col1 blob, index(col1(768)))
+--error 1071
+create table t3 (col1 text, primary key(col1(768)))
+ character set = latin1 engine = innodb;
+--error 1071
+create table t4 (col1 blob, primary key(col1(768)))
  character set = latin1 engine = innodb;
 
 #
@@ -1751,3 +1765,53 @@
 drop table t1;
 drop table t2;
 commit;
+
+# tests for bugs #9802 and #13778
+
+# test that FKs between invalid types are not accepted
+
+set foreign_key_checks=0;
+create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+-- error 1005
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+set foreign_key_checks=1;
+drop table t2;
+
+# test that FKs between different charsets are not accepted in CREATE even
+# when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+-- error 1005
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
+set foreign_key_checks=1;
+drop table t1;
+
+# test that invalid datatype conversions with ALTER are not allowed
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
+create table t1(a varchar(10) primary key) engine = innodb;
+-- error 1025,1025
+alter table t1 modify column a int;
+set foreign_key_checks=1;
+drop table t2,t1;
+
+# test that charset conversions with ALTER are allowed when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+alter table t1 convert to character set utf8;
+set foreign_key_checks=1;
+drop table t2,t1;
+
+# test that RENAME does not allow invalid charsets when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+-- error 1025
+rename table t3 to t1;
+set foreign_key_checks=1;
+drop table t2,t3;

--- 1.278/sql/ha_innodb.cc	2005-11-19 15:11:49 +03:00
+++ 1.279/sql/ha_innodb.cc	2005-11-24 18:42:43 +03:00
@@ -142,16 +142,15 @@
 ulong 	innobase_cache_size 	= 0;
 ulong 	innobase_large_page_size = 0;
 
-/* The default values for the following, type long or longlong, start-up
-parameters are declared in mysqld.cc: */
+/* The default values for the following, type long, start-up parameters
+are declared in mysqld.cc: */
 
 long innobase_mirrored_log_groups, innobase_log_files_in_group,
-     innobase_log_buffer_size, innobase_buffer_pool_awe_mem_mb,
-     innobase_additional_mem_pool_size, innobase_file_io_threads,
-     innobase_lock_wait_timeout, innobase_force_recovery,
-     innobase_open_files;
-
-longlong innobase_buffer_pool_size, innobase_log_file_size;
+     innobase_log_file_size, innobase_log_buffer_size,
+     innobase_buffer_pool_awe_mem_mb,
+     innobase_buffer_pool_size, innobase_additional_mem_pool_size,
+     innobase_file_io_threads,  innobase_lock_wait_timeout,
+     innobase_force_recovery, innobase_open_files;
 
 /* The default values for the following char* start-up parameters
 are determined in innobase_init below: */
@@ -1211,25 +1210,6 @@
 
 	ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
 
-	/* Check that values don't overflow on 32-bit systems. */
-	if (sizeof(ulint) == 4) {
-		if (innobase_buffer_pool_size > UINT_MAX32) {
-			sql_print_error(
-				"innobase_buffer_pool_size can't be over 4GB"
-				" on 32-bit systems");
-
-			DBUG_RETURN(0);
-		}
-
-		if (innobase_log_file_size > UINT_MAX32) {
-			sql_print_error(
-				"innobase_log_file_size can't be over 4GB"
-				" on 32-bit systems");
-
-			DBUG_RETURN(0);
-		}
-	}
-
   	os_innodb_umask = (ulint)my_umask;
 
 	/* First calculate the default path for innodb_data_home_dir etc.,
@@ -2198,13 +2178,11 @@
 
 	DBUG_ENTER("innobase_savepoint");
 
-        /*
-          In the autocommit mode there is no sense to set a savepoint
-          (unless we are in sub-statement), so SQL layer ensures that
-          this method is never called in such situation.
-        */
-        DBUG_ASSERT(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
-                    thd->in_sub_stmt);
+	if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+		/* In the autocommit state there is no sense to set a
+		savepoint: we return immediate success */
+	        DBUG_RETURN(0);
+	}
 
 	trx = check_trx_exists(thd);
 
@@ -2519,6 +2497,12 @@
   	DBUG_RETURN(0);
 }
 
+uint
+ha_innobase::max_supported_key_part_length() const
+{
+	return(DICT_MAX_INDEX_COL_LEN - 1);
+}
+
 /**********************************************************************
 Closes a handle to an InnoDB table. */
 
@@ -3031,8 +3015,8 @@
 
 			if (key_part->length > 0 && cs->mbmaxlen > 1) {
 				len = (ulint) cs->cset->well_formed_len(cs, 
-					(const char *) src_start,
-					(const char *) src_start + key_part->length,
+					src_start,
+					src_start + key_part->length,
 					key_part->length / cs->mbmaxlen, 
 					&error);
 			} else {
@@ -4675,6 +4659,9 @@
 				0, prefix_len);
 	}
 
+	/* Even though we've defined max_supported_key_part_length, we
+	still do our own checking using field_lengths to be absolutely
+	sure we don't create too long indexes. */
 	error = row_create_index_for_mysql(index, trx, field_lengths);
 
 	error = convert_error_code_to_mysql(error, NULL);

--- 1.107/sql/ha_innodb.h	2005-11-17 17:06:04 +03:00
+++ 1.108/sql/ha_innodb.h	2005-11-24 18:42:43 +03:00
@@ -110,7 +110,7 @@
 				but currently MySQL does not work with keys
 				whose size is > MAX_KEY_LENGTH */
   	uint max_supported_key_length() const { return 3500; }
-  	uint max_supported_key_part_length() const { return 3500; }
+  	uint max_supported_key_part_length() const;
 	const key_map *keys_to_use_for_scanning() { return &key_map_full; }
   	bool has_transactions()  { return 1;}
 
@@ -206,9 +206,8 @@
 extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
 extern long innobase_lock_scan_time;
 extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
-extern longlong innobase_buffer_pool_size, innobase_log_file_size;
-extern long innobase_log_buffer_size;
-extern long innobase_additional_mem_pool_size;
+extern long innobase_log_file_size, innobase_log_buffer_size;
+extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
 extern long innobase_buffer_pool_awe_mem_mb;
 extern long innobase_file_io_threads, innobase_lock_wait_timeout;
 extern long innobase_force_recovery;
Thread
bk commit into 5.0 tree (aivanov:1.1989)Alex Ivanov24 Nov