Commit 770dde69 authored by marko's avatar marko

branches/zip: row_merge_buf_add(): Correct the processing of

column prefixes in clustered indexes.

innodb-index.test: Add test cases for creating primary keys
containing column prefixes.
parent 06b6f544
...@@ -1031,8 +1031,8 @@ NULL NULL NULL null ...@@ -1031,8 +1031,8 @@ NULL NULL NULL null
alter table t1 add primary key (a), add key (b(20)); alter table t1 add primary key (a), add key (b(20));
ERROR 42000: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead ERROR 42000: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead
delete from t1 where d='null'; delete from t1 where d='null';
alter table t1 add primary key (a,b(255),c(255)), add key (b(255)); alter table t1 add primary key (a,b(255),c(255)), add key (b(767));
ERROR HY000: Too big row alter table t1 drop primary key, drop key b;
alter table t1 add primary key (a), add key (b(20)); alter table t1 add primary key (a), add key (b(20));
select count(*) from t1 where a=44; select count(*) from t1 where a=44;
count(*) count(*)
...@@ -1056,8 +1056,8 @@ show create table t1; ...@@ -1056,8 +1056,8 @@ show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL DEFAULT '0', `a` int(11) NOT NULL DEFAULT '0',
`b` blob, `b` blob NOT NULL,
`c` text, `c` text NOT NULL,
`d` text NOT NULL, `d` text NOT NULL,
PRIMARY KEY (`a`), PRIMARY KEY (`a`),
KEY `b` (`b`(20)) KEY `b` (`b`(20))
...@@ -1067,7 +1067,7 @@ Table Op Msg_type Msg_text ...@@ -1067,7 +1067,7 @@ Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
explain select * from t1 where b like 'adfd%'; explain select * from t1 where b like 'adfd%';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range b b 23 NULL 2 Using where 1 SIMPLE t1 range b b 22 NULL 2 Using where
select a,b=repeat(d,100*a),c=repeat(d,20*a) from t1; select a,b=repeat(d,100*a),c=repeat(d,20*a) from t1;
a b=repeat(d,100*a) c=repeat(d,20*a) a b=repeat(d,100*a) c=repeat(d,20*a)
22 1 1 22 1 1
......
...@@ -317,8 +317,8 @@ select a,length(b),length(c),d from t1; ...@@ -317,8 +317,8 @@ select a,length(b),length(c),d from t1;
--error ER_PRIMARY_CANT_HAVE_NULL --error ER_PRIMARY_CANT_HAVE_NULL
alter table t1 add primary key (a), add key (b(20)); alter table t1 add primary key (a), add key (b(20));
delete from t1 where d='null'; delete from t1 where d='null';
--error 139 alter table t1 add primary key (a,b(255),c(255)), add key (b(767));
alter table t1 add primary key (a,b(255),c(255)), add key (b(255)); alter table t1 drop primary key, drop key b;
alter table t1 add primary key (a), add key (b(20)); alter table t1 add primary key (a), add key (b(20));
select count(*) from t1 where a=44; select count(*) from t1 where a=44;
select a,b=repeat(d,100*a),c=repeat(d,20*a) from t1; select a,b=repeat(d,100*a),c=repeat(d,20*a) from t1;
......
...@@ -179,7 +179,6 @@ row_merge_buf_add( ...@@ -179,7 +179,6 @@ row_merge_buf_add(
column prefixes, or NULL */ column prefixes, or NULL */
{ {
ulint i; ulint i;
ulint j;
ulint n_fields; ulint n_fields;
ulint data_size; ulint data_size;
ulint extra_size; ulint extra_size;
...@@ -204,17 +203,19 @@ row_merge_buf_add( ...@@ -204,17 +203,19 @@ row_merge_buf_add(
data_size = 0; data_size = 0;
extra_size = UT_BITS_IN_BYTES(index->n_nullable); extra_size = UT_BITS_IN_BYTES(index->n_nullable);
for (i = j = 0; i < n_fields; i++, field++) { for (i = 0; i < n_fields; i++, field++) {
dict_field_t* ifield; dict_field_t* ifield;
const dict_col_t* col; const dict_col_t* col;
ulint col_no; ulint col_no;
const dfield_t* row_field; const dfield_t* row_field;
ulint len;
ifield = dict_index_get_nth_field(index, i); ifield = dict_index_get_nth_field(index, i);
col = ifield->col; col = ifield->col;
col_no = dict_col_get_no(col); col_no = dict_col_get_no(col);
row_field = dtuple_get_nth_field(row, col_no); row_field = dtuple_get_nth_field(row, col_no);
dfield_copy(field, row_field); dfield_copy(field, row_field);
len = field->len;
if (dfield_is_null(field)) { if (dfield_is_null(field)) {
ut_ad(!(col->prtype & DATA_NOT_NULL)); ut_ad(!(col->prtype & DATA_NOT_NULL));
...@@ -223,18 +224,19 @@ row_merge_buf_add( ...@@ -223,18 +224,19 @@ row_merge_buf_add(
} else if (UNIV_LIKELY(!ext)) { } else if (UNIV_LIKELY(!ext)) {
} else if (dict_index_is_clust(index)) { } else if (dict_index_is_clust(index)) {
/* Flag externally stored fields. */ /* Flag externally stored fields. */
if (j < ext->n_ext && col_no == ext->ext[j]) { byte* buf = row_ext_lookup(ext, col_no,
j++; field->data, len, &len);
if (UNIV_LIKELY_NULL(buf)) {
ut_a(field->len >= BTR_EXTERN_FIELD_REF_SIZE); if (i < dict_index_get_n_unique(index)) {
dfield_set_ext(field); dfield_set_data(field, buf, len);
} else {
dfield_set_ext(field);
len = field->len;
}
} }
} else { } else {
ulint len = field->len;
byte* buf = row_ext_lookup(ext, col_no, byte* buf = row_ext_lookup(ext, col_no,
row_field->data, field->data, len, &len);
row_field->len,
&len);
if (UNIV_LIKELY_NULL(buf)) { if (UNIV_LIKELY_NULL(buf)) {
dfield_set_data(field, buf, len); dfield_set_data(field, buf, len);
} }
...@@ -243,31 +245,33 @@ row_merge_buf_add( ...@@ -243,31 +245,33 @@ row_merge_buf_add(
/* If a column prefix index, take only the prefix */ /* If a column prefix index, take only the prefix */
if (ifield->prefix_len) { if (ifield->prefix_len) {
field->len = dtype_get_at_most_n_mbchars( field->len = len = dtype_get_at_most_n_mbchars(
col->prtype, col->prtype,
col->mbminlen, col->mbmaxlen, col->mbminlen, col->mbmaxlen,
ifield->prefix_len, ifield->prefix_len,
field->len, field->data); len, field->data);
} }
ut_ad(field->len <= col->len || col->mtype == DATA_BLOB); ut_ad(len <= col->len || col->mtype == DATA_BLOB);
if (ifield->fixed_len) { if (ifield->fixed_len) {
ut_ad(field->len == ifield->fixed_len); ut_ad(len == ifield->fixed_len);
ut_ad(!dfield_is_ext(field)); ut_ad(!dfield_is_ext(field));
} else if (dfield_is_ext(field)) { } else if (dfield_is_ext(field)) {
extra_size += 2; extra_size += 2;
} else if (field->len < 128 } else if (len < 128
|| (col->len < 256 && col->mtype != DATA_BLOB)) { || (col->len < 256 && col->mtype != DATA_BLOB)) {
extra_size++; extra_size++;
} else { } else {
/* For variable-length columns, we look up the
maximum length from the column itself. If this
is a prefix index column shorter than 256 bytes,
this will waste one byte. */
extra_size += 2; extra_size += 2;
} }
data_size += field->len; data_size += len;
} }
ut_ad(!ext || !dict_index_is_clust(index) || j == ext->n_ext);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
{ {
ulint size; ulint size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment