Bug#12637786 Wrong secondary index entries on CHAR and VARCHAR columns
row_build_index_entry(): In innodb_file_format=Barracuda (ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED), a secondary index on a full column can refer to a field that is stored off-page in the clustered index record. Take that into account. rb:692 approved by Jimmy Yang
This commit is contained in:
parent
e25fb73be2
commit
eeb028bbc1
@ -967,6 +967,19 @@ ERROR HY000: Too big row
|
|||||||
alter table t1 row_format=compact;
|
alter table t1 row_format=compact;
|
||||||
create index t1u on t1 (u(1));
|
create index t1u on t1 (u(1));
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
SET @r=REPEAT('a',500);
|
||||||
|
CREATE TABLE t1(a INT,
|
||||||
|
v1 VARCHAR(500), v2 VARCHAR(500), v3 VARCHAR(500),
|
||||||
|
v4 VARCHAR(500), v5 VARCHAR(500), v6 VARCHAR(500),
|
||||||
|
v7 VARCHAR(500), v8 VARCHAR(500), v9 VARCHAR(500),
|
||||||
|
v10 VARCHAR(500), v11 VARCHAR(500), v12 VARCHAR(500),
|
||||||
|
v13 VARCHAR(500), v14 VARCHAR(500), v15 VARCHAR(500),
|
||||||
|
v16 VARCHAR(500), v17 VARCHAR(500), v18 VARCHAR(500)
|
||||||
|
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||||
|
CREATE INDEX idx1 ON t1(a,v1);
|
||||||
|
INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
|
||||||
|
UPDATE t1 SET a=1000;
|
||||||
|
DROP TABLE t1;
|
||||||
set global innodb_file_per_table=0;
|
set global innodb_file_per_table=0;
|
||||||
set global innodb_file_format=Antelope;
|
set global innodb_file_format=Antelope;
|
||||||
set global innodb_file_format_check=Antelope;
|
set global innodb_file_format_check=Antelope;
|
||||||
|
@ -404,6 +404,22 @@ alter table t1 row_format=compact;
|
|||||||
create index t1u on t1 (u(1));
|
create index t1u on t1 (u(1));
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
# Bug#12637786
|
||||||
|
SET @r=REPEAT('a',500);
|
||||||
|
CREATE TABLE t1(a INT,
|
||||||
|
v1 VARCHAR(500), v2 VARCHAR(500), v3 VARCHAR(500),
|
||||||
|
v4 VARCHAR(500), v5 VARCHAR(500), v6 VARCHAR(500),
|
||||||
|
v7 VARCHAR(500), v8 VARCHAR(500), v9 VARCHAR(500),
|
||||||
|
v10 VARCHAR(500), v11 VARCHAR(500), v12 VARCHAR(500),
|
||||||
|
v13 VARCHAR(500), v14 VARCHAR(500), v15 VARCHAR(500),
|
||||||
|
v16 VARCHAR(500), v17 VARCHAR(500), v18 VARCHAR(500)
|
||||||
|
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||||
|
CREATE INDEX idx1 ON t1(a,v1);
|
||||||
|
INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
|
||||||
|
UPDATE t1 SET a=1000;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
eval set global innodb_file_per_table=$per_table;
|
eval set global innodb_file_per_table=$per_table;
|
||||||
eval set global innodb_file_format=$format;
|
eval set global innodb_file_format=$format;
|
||||||
eval set global innodb_file_format_check=$format;
|
eval set global innodb_file_format_check=$format;
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2011-06-30 The InnoDB Team
|
||||||
|
|
||||||
|
* row/row0row.c:
|
||||||
|
Fix Bug#12637786 Wrong secondary index entries on CHAR and VARCHAR
|
||||||
|
columns in ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPRESSED
|
||||||
|
|
||||||
2011-06-16 The InnoDB Team
|
2011-06-16 The InnoDB Team
|
||||||
|
|
||||||
* btr/btr0cur.c, buf/buf0buddy.c, buf/buf0buf.c, buf/buf0lru.c,
|
* btr/btr0cur.c, buf/buf0buddy.c, buf/buf0buf.c, buf/buf0lru.c,
|
||||||
|
@ -101,12 +101,27 @@ row_build_index_entry(
|
|||||||
|
|
||||||
dfield_copy(dfield, dfield2);
|
dfield_copy(dfield, dfield2);
|
||||||
|
|
||||||
if (dfield_is_null(dfield) || ind_field->prefix_len == 0) {
|
if (dfield_is_null(dfield)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a column prefix index, take only the prefix.
|
if (ind_field->prefix_len == 0
|
||||||
Prefix-indexed columns may be externally stored. */
|
&& (!dfield_is_ext(dfield)
|
||||||
|
|| dict_index_is_clust(index))) {
|
||||||
|
/* The dfield_copy() above suffices for
|
||||||
|
columns that are stored in-page, or for
|
||||||
|
clustered index record columns that are not
|
||||||
|
part of a column prefix in the PRIMARY KEY. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the column is stored externally (off-page) in
|
||||||
|
the clustered index, it must be an ordering field in
|
||||||
|
the secondary index. In the Antelope format, only
|
||||||
|
prefix-indexed columns may be stored off-page in the
|
||||||
|
clustered index record. In the Barracuda format, also
|
||||||
|
fully indexed long CHAR or VARCHAR columns may be
|
||||||
|
stored off-page. */
|
||||||
ut_ad(col->ord_part);
|
ut_ad(col->ord_part);
|
||||||
|
|
||||||
if (UNIV_LIKELY_NULL(ext)) {
|
if (UNIV_LIKELY_NULL(ext)) {
|
||||||
@ -119,13 +134,34 @@ row_build_index_entry(
|
|||||||
}
|
}
|
||||||
dfield_set_data(dfield, buf, len);
|
dfield_set_data(dfield, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ind_field->prefix_len == 0) {
|
||||||
|
/* In the Barracuda format
|
||||||
|
(ROW_FORMAT=DYNAMIC or
|
||||||
|
ROW_FORMAT=COMPRESSED), we can have a
|
||||||
|
secondary index on an entire column
|
||||||
|
that is stored off-page in the
|
||||||
|
clustered index. As this is not a
|
||||||
|
prefix index (prefix_len == 0),
|
||||||
|
include the entire off-page column in
|
||||||
|
the secondary index record. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} else if (dfield_is_ext(dfield)) {
|
} else if (dfield_is_ext(dfield)) {
|
||||||
|
/* This table should be in Antelope format
|
||||||
|
(ROW_FORMAT=REDUNDANT or ROW_FORMAT=COMPACT).
|
||||||
|
In that format, the maximum column prefix
|
||||||
|
index length is 767 bytes, and the clustered
|
||||||
|
index record contains a 768-byte prefix of
|
||||||
|
each off-page column. */
|
||||||
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
|
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
|
||||||
len -= BTR_EXTERN_FIELD_REF_SIZE;
|
len -= BTR_EXTERN_FIELD_REF_SIZE;
|
||||||
ut_a(ind_field->prefix_len <= len
|
ut_a(ind_field->prefix_len <= len
|
||||||
|| dict_index_is_clust(index));
|
|| dict_index_is_clust(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If a column prefix index, take only the prefix. */
|
||||||
|
ut_ad(ind_field->prefix_len);
|
||||||
len = dtype_get_at_most_n_mbchars(
|
len = dtype_get_at_most_n_mbchars(
|
||||||
col->prtype, col->mbminlen, col->mbmaxlen,
|
col->prtype, col->mbminlen, col->mbmaxlen,
|
||||||
ind_field->prefix_len, len, dfield_get_data(dfield));
|
ind_field->prefix_len, len, dfield_get_data(dfield));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user