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#13315 | Osku Salerma | 21 Sep |