List:Internals« Previous MessageNext Message »
From:Osku Salerma Date:September 21 2005 5:06pm
Subject:bk commit into 5.0 tree (osku:1.1980) BUG#13315
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of osku. When osku 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.1980 05/09/21 20:06:36 osku@127.(none) +9 -0
  InnoDB: Fix bug #13315, index columns having a maximum length of 767.

  sql/ha_innodb.cc
    1.256 05/09/21 20:06:32 osku@127.(none) +11 -3
    Create temporary field_lengths buffer and pass it to
    row_create_index_for_mysql.

  mysql-test/t/innodb.test
    1.109 05/09/21 20:06:32 osku@127.(none) +46 -0
    New tests.

  mysql-test/r/innodb.result
    1.134 05/09/21 20:06:32 osku@127.(none) +34 -0
    New tests.

  innobase/row/row0mysql.c
    1.114 05/09/21 20:06:32 osku@127.(none) +18 -4
    Add field_lengths parameter to row_create_index_for_mysql and use it to
    check for too long index columns.

  innobase/rem/rem0rec.c
    1.20 05/09/21 20:06:32 osku@127.(none) +1 -1
    Adapt to DICT_MAX_COL_PREFIX_LEN rename.

  innobase/include/row0mysql.h
    1.45 05/09/21 20:06:32 osku@127.(none) +8 -2
    Add field_lengths parameter to row_create_index_for_mysql.

  innobase/include/dict0mem.h
    1.25 05/09/21 20:06:32 osku@127.(none) +8 -8
    Rename DICT_MAX_COL_PREFIX_LEN to DICT_MAX_INDEX_COL_LEN.

  innobase/dict/dict0dict.c
    1.67 05/09/21 20:06:32 osku@127.(none) +1 -1
    Adapt to DICT_MAX_COL_PREFIX_LEN rename.

  innobase/data/data0data.c
    1.18 05/09/21 20:06:32 osku@127.(none) +5 -5
    Adapt to DICT_MAX_COL_PREFIX_LEN rename.

# 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:	osku
# Host:	127.(none)
# Root:	/home/osku/mysql/5.0/13315

--- 1.17/innobase/data/data0data.c	2005-04-22 14:49:46 +03:00
+++ 1.18/innobase/data/data0data.c	2005-09-21 20:06:32 +03:00
@@ -561,12 +561,12 @@
 		}
 	
 		/* We do not store externally fields which are smaller than
-		DICT_MAX_COL_PREFIX_LEN */
+		DICT_MAX_INDEX_COL_LEN */
 
-		ut_a(DICT_MAX_COL_PREFIX_LEN > REC_1BYTE_OFFS_LIMIT);
+		ut_a(DICT_MAX_INDEX_COL_LEN > REC_1BYTE_OFFS_LIMIT);
 
 		if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10
-						+ DICT_MAX_COL_PREFIX_LEN) {
+						+ DICT_MAX_INDEX_COL_LEN) {
 			/* Cannot shorten more */
 
 			mem_heap_free(heap);
@@ -588,10 +588,10 @@
 		dfield = dtuple_get_nth_field(entry, longest_i);
 		vector->fields[n_fields].field_no = longest_i;
 
-		ut_a(dfield->len > DICT_MAX_COL_PREFIX_LEN);
+		ut_a(dfield->len > DICT_MAX_INDEX_COL_LEN);
 		
 		vector->fields[n_fields].len = dfield->len
-						- DICT_MAX_COL_PREFIX_LEN;
+						- DICT_MAX_INDEX_COL_LEN;
 
 		vector->fields[n_fields].data = mem_heap_alloc(heap,
 						vector->fields[n_fields].len);

--- 1.66/innobase/dict/dict0dict.c	2005-09-06 14:38:17 +03:00
+++ 1.67/innobase/dict/dict0dict.c	2005-09-21 20:06:32 +03:00
@@ -1625,7 +1625,7 @@
 	variable-length fields, so that the extern flag can be embedded in
 	the length word. */
 
-	if (field->fixed_len > DICT_MAX_COL_PREFIX_LEN) {
+	if (field->fixed_len > DICT_MAX_INDEX_COL_LEN) {
 		field->fixed_len = 0;
 	}
 

--- 1.24/innobase/include/dict0mem.h	2005-01-14 13:54:15 +02:00
+++ 1.25/innobase/include/dict0mem.h	2005-09-21 20:06:32 +03:00
@@ -152,12 +152,12 @@
 				in some of the functions below */
 };
 
-/* DICT_MAX_COL_PREFIX_LEN is measured in bytes. Starting from 4.1.6, we
-set max col prefix len to < 3 * 256, so that one can create a column prefix
-index on 255 characters of a TEXT field also in the UTF-8 charset. In that
-charset, a character may take at most 3 bytes. */
+/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the max index column
+length + 1. Starting from 4.1.6, we set it to < 3 * 256, so that one can
+create a column prefix index on 255 characters of a TEXT field also in the
+UTF-8 charset. In that charset, a character may take at most 3 bytes. */
 
-#define DICT_MAX_COL_PREFIX_LEN	768
+#define DICT_MAX_INDEX_COL_LEN		768
 
 /* Data structure for a field in an index */
 struct dict_field_struct{
@@ -169,12 +169,12 @@
 					prefix in bytes in a MySQL index of
 					type, e.g., INDEX (textcol(25));
 					must be smaller than
-					DICT_MAX_COL_PREFIX_LEN; NOTE that
-					in the UTF-8 charset, MySQL sets this
+					DICT_MAX_INDEX_COL_LEN; NOTE that in
+					the UTF-8 charset, MySQL sets this
 					to 3 * the prefix len in UTF-8 chars */
 	ulint		fixed_len;	/* 0 or the fixed length of the
 					column if smaller than
-					DICT_MAX_COL_PREFIX_LEN */
+					DICT_MAX_INDEX_COL_LEN */
 	ulint		fixed_offs;	/* offset to the field, or
 					ULINT_UNDEFINED if it is not fixed
 					within the record (due to preceding

--- 1.44/innobase/include/row0mysql.h	2005-09-06 14:38:17 +03:00
+++ 1.45/innobase/include/row0mysql.h	2005-09-21 20:06:32 +03:00
@@ -335,8 +335,14 @@
 row_create_index_for_mysql(
 /*=======================*/
 					/* out: error number or DB_SUCCESS */
-	dict_index_t*	index,		/* in: index defintion */
-	trx_t*		trx);		/* in: transaction handle */
+	dict_index_t*	index,		/* in: index definition */
+	trx_t*		trx,		/* in: transaction handle */
+	ulint*		field_lengths); /* in: if not NULL, must contain
+					   dict_index_get_n_fields(index)
+					   actual field lengths for the
+					   index columns, which are
+					   then checked for not being too
+					   large. */
 /*************************************************************************
 Scans a table create SQL string and adds to the data dictionary
 the foreign key constraints declared in the string. This function

--- 1.19/innobase/rem/rem0rec.c	2005-06-30 13:20:28 +03:00
+++ 1.20/innobase/rem/rem0rec.c	2005-09-21 20:06:32 +03:00
@@ -621,7 +621,7 @@
 		if (field->fixed_len) {
 			/* fixed-length fields cannot be external
 			(Fixed-length fields longer than
-			DICT_MAX_COL_PREFIX_LEN will be treated as
+			DICT_MAX_INDEX_COL_LEN will be treated as
 			variable-length ones in dict_index_add_col().) */
 			ut_ad(i != ith);
 			continue;

--- 1.113/innobase/row/row0mysql.c	2005-09-06 14:38:17 +03:00
+++ 1.114/innobase/row/row0mysql.c	2005-09-21 20:06:32 +03:00
@@ -1973,13 +1973,20 @@
 /*=======================*/
 					/* out: error number or DB_SUCCESS */
 	dict_index_t*	index,		/* in: index definition */
-	trx_t*		trx)		/* in: transaction handle */
+	trx_t*		trx,		/* in: transaction handle */
+	ulint*		field_lengths)	/* in: if not NULL, must contain
+					   dict_index_get_n_fields(index)
+					   actual field lengths for the
+					   index columns, which are
+					   then checked for not being too
+					   large. */
 {
 	ind_node_t*	node;
 	mem_heap_t*	heap;
 	que_thr_t*	thr;
 	ulint		err;
 	ulint		i, j;
+	ulint		len;
 	
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
@@ -2018,10 +2025,17 @@
 			}
 		}
 		
-		/* Check also that prefix_len < DICT_MAX_COL_PREFIX_LEN */
+		/* Check also that prefix_len and actual length <
+	        DICT_MAX_INDEX_COL_LEN */
 
-		if (dict_index_get_nth_field(index, i)->prefix_len
-						>= DICT_MAX_COL_PREFIX_LEN) {
+		len = dict_index_get_nth_field(index, i)->prefix_len;
+
+		if (field_lengths)
+		{
+			len = ut_max(len, field_lengths[i]);
+		}
+		
+		if (len >= DICT_MAX_INDEX_COL_LEN) {
 			err = DB_TOO_BIG_RECORD;
 
 			goto error_handling;

--- 1.133/mysql-test/r/innodb.result	2005-09-13 01:44:44 +03:00
+++ 1.134/mysql-test/r/innodb.result	2005-09-21 20:06:32 +03:00
@@ -2550,3 +2550,37 @@
 ) ENGINE=InnoDB;
 Got one of the listed errors
 DROP TABLE t1;
+create table t1 (col1 varchar(2000), index (col1(767)))
+character set = latin1 engine = innodb;
+create table t2 (col1 char(255), index (col1))
+character set = latin1 engine = innodb;
+create table t3 (col1 binary(255), index (col1))
+character set = latin1 engine = innodb;
+create table t4 (col1 varchar(767), index (col1))
+character set = latin1 engine = innodb;
+create table t5 (col1 varchar(767) primary key)
+character set = latin1 engine = innodb;
+create table t6 (col1 varbinary(767) primary key)
+character set = latin1 engine = innodb;
+create table t7 (col1 text, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t8 (col1 blob, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
+character set = latin1 engine = innodb;
+drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
+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)
+character set = latin1 engine = innodb;
+ERROR HY000: Can't create table './test/t2.frm' (errno: 139)
+create table t3 (col1 varbinary(768) primary key)
+character set = latin1 engine = innodb;
+ERROR HY000: Can't create table './test/t3.frm' (errno: 139)
+create table t4 (col1 text, 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)))
+character set = latin1 engine = innodb;
+ERROR HY000: Can't create table './test/t5.frm' (errno: 139)

--- 1.108/mysql-test/t/innodb.test	2005-09-14 01:41:37 +03:00
+++ 1.109/mysql-test/t/innodb.test	2005-09-21 20:06:32 +03:00
@@ -1473,3 +1473,49 @@
  FOREIGN KEY (b) REFERENCES test.t1(id)
 ) ENGINE=InnoDB;
 DROP TABLE t1;
+
+#
+# Test that index column max sizes are checked (bug #13315)
+#
+
+# prefix index
+create table t1 (col1 varchar(2000), index (col1(767)))
+ character set = latin1 engine = innodb;
+
+# normal indexes
+create table t2 (col1 char(255), index (col1))
+ character set = latin1 engine = innodb;
+create table t3 (col1 binary(255), index (col1))
+ character set = latin1 engine = innodb;
+create table t4 (col1 varchar(767), index (col1))
+ character set = latin1 engine = innodb;
+create table t5 (col1 varchar(767) primary key)
+ character set = latin1 engine = innodb;
+create table t6 (col1 varbinary(767) primary key)
+ character set = latin1 engine = innodb;
+create table t7 (col1 text, index(col1(767)))
+ character set = latin1 engine = innodb;
+create table t8 (col1 blob, index(col1(767)))
+ character set = latin1 engine = innodb;
+
+# multi-column indexes are allowed to be longer
+create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
+ character set = latin1 engine = innodb;
+
+drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
+
+--error 1005
+create table t1 (col1 varchar(768), index (col1))
+ character set = latin1 engine = innodb;
+--error 1005
+create table t2 (col1 varchar(768) primary key)
+ character set = latin1 engine = innodb;
+--error 1005
+create table t3 (col1 varbinary(768) primary key)
+ character set = latin1 engine = innodb;
+--error 1005
+create table t4 (col1 text, index(col1(768)))
+ character set = latin1 engine = innodb;
+--error 1005
+create table t5 (col1 blob, index(col1(768)))
+ character set = latin1 engine = innodb;

--- 1.255/sql/ha_innodb.cc	2005-09-06 14:38:17 +03:00
+++ 1.256/sql/ha_innodb.cc	2005-09-21 20:06:32 +03:00
@@ -4488,7 +4488,8 @@
 	ulint		is_unsigned;
   	ulint		i;
   	ulint		j;
-
+	ulint*		field_lengths;
+	
   	DBUG_ENTER("create_index");
 
 	key = form->key_info + key_num;
@@ -4510,6 +4511,9 @@
 
 	index = dict_mem_index_create((char*) table_name, key->name, 0,
 						ind_type, n_fields);
+
+	field_lengths = (ulint*) my_malloc(sizeof(ulint) * n_fields, MYF(0));
+	
 	for (i = 0; i < n_fields; i++) {
 		key_part = key->key_part + i;
 
@@ -4564,6 +4568,8 @@
 		        prefix_len = 0;
 		}
 
+		field_lengths[i] = key_part->length;
+
 		/* We assume all fields should be sorted in ascending
 		order, hence the '0': */
 
@@ -4572,10 +4578,12 @@
 				0, prefix_len);
 	}
 
-	error = row_create_index_for_mysql(index, trx);
+	error = row_create_index_for_mysql(index, trx, field_lengths);
 
 	error = convert_error_code_to_mysql(error, NULL);
 
+	my_free((char*) field_lengths, MYF(0));
+	
 	DBUG_RETURN(error);
 }
 
@@ -4598,7 +4606,7 @@
 	index = dict_mem_index_create((char*) table_name,
 				      (char*) "GEN_CLUST_INDEX",
 				      0, DICT_CLUSTERED, 0);
-	error = row_create_index_for_mysql(index, trx);
+	error = row_create_index_for_mysql(index, trx, NULL);
 
 	error = convert_error_code_to_mysql(error, NULL);
 
Thread
bk commit into 5.0 tree (osku:1.1980) BUG#13315Osku Salerma21 Sep