dict0dict.h, dict0dict.c, row0row.c, pars0opt.c:
Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref() innobase/pars/pars0opt.c: Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref() innobase/row/row0row.c: Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref() innobase/dict/dict0dict.c: Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref() innobase/include/dict0dict.h: Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref()
This commit is contained in:
parent
8bf8c85968
commit
a2d94d92f5
@ -526,8 +526,10 @@ dict_index_contains_col_or_prefix(
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Looks for a matching field in an index. The column and the prefix len have
|
||||
to be the same. */
|
||||
Looks for a matching field in an index. The column has to be the same. The
|
||||
column in index must be complete, or must contain a prefix longer than the
|
||||
column in index2. That is, we must be able to construct the prefix in index2
|
||||
from the prefix in index. */
|
||||
|
||||
ulint
|
||||
dict_index_get_nth_field_pos(
|
||||
@ -555,7 +557,9 @@ dict_index_get_nth_field_pos(
|
||||
field = dict_index_get_nth_field(index, pos);
|
||||
|
||||
if (field->col == field2->col
|
||||
&& field->prefix_len == field2->prefix_len) {
|
||||
&& (field->prefix_len == 0
|
||||
|| (field->prefix_len >= field2->prefix_len
|
||||
&& field2->prefix_len != 0))) {
|
||||
|
||||
return(pos);
|
||||
}
|
||||
|
@ -566,8 +566,10 @@ dict_index_contains_col_or_prefix(
|
||||
dict_index_t* index, /* in: index */
|
||||
ulint n); /* in: column number */
|
||||
/************************************************************************
|
||||
Looks for a matching field in an index. The column and the prefix len has
|
||||
to be the same. */
|
||||
Looks for a matching field in an index. The column has to be the same. The
|
||||
column in index must be complete, or must contain a prefix longer than the
|
||||
column in index2. That is, we must be able to construct the prefix in index2
|
||||
from the prefix in index. */
|
||||
|
||||
ulint
|
||||
dict_index_get_nth_field_pos(
|
||||
|
@ -1094,6 +1094,19 @@ opt_clust_access(
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
pos = dict_index_get_nth_field_pos(index, clust_index, i);
|
||||
|
||||
ut_a(pos != ULINT_UNDEFINED);
|
||||
|
||||
/* We optimize here only queries to InnoDB's internal system
|
||||
tables, and they should not contain column prefix indexes. */
|
||||
|
||||
if (dict_index_get_nth_field(index, pos)->prefix_len != 0
|
||||
|| dict_index_get_nth_field(clust_index, i)
|
||||
->prefix_len != 0) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error in pars0opt.c: table %s has prefix_len != 0\n",
|
||||
index->table_name);
|
||||
}
|
||||
|
||||
*(plan->clust_map + i) = pos;
|
||||
|
||||
ut_ad((pos != ULINT_UNDEFINED)
|
||||
|
@ -334,6 +334,7 @@ row_build_row_ref(
|
||||
ulint ref_len;
|
||||
ulint pos;
|
||||
byte* buf;
|
||||
ulint clust_col_prefix_len;
|
||||
ulint i;
|
||||
|
||||
ut_ad(index && rec && heap);
|
||||
@ -366,6 +367,22 @@ row_build_row_ref(
|
||||
field = rec_get_nth_field(rec, pos, &len);
|
||||
|
||||
dfield_set_data(dfield, field, len);
|
||||
|
||||
/* If the primary key contains a column prefix, then the
|
||||
secondary index may contain a longer prefix of the same
|
||||
column, or the full column, and we must adjust the length
|
||||
accordingly. */
|
||||
|
||||
clust_col_prefix_len =
|
||||
dict_index_get_nth_field(clust_index, i)->prefix_len;
|
||||
|
||||
if (clust_col_prefix_len > 0) {
|
||||
if (len != UNIV_SQL_NULL
|
||||
&& len > clust_col_prefix_len) {
|
||||
|
||||
dfield_set_len(dfield, clust_col_prefix_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ut_ad(dtuple_check_typed(ref));
|
||||
@ -396,6 +413,7 @@ row_build_row_ref_in_tuple(
|
||||
ulint len;
|
||||
ulint ref_len;
|
||||
ulint pos;
|
||||
ulint clust_col_prefix_len;
|
||||
ulint i;
|
||||
|
||||
ut_a(ref && index && rec);
|
||||
@ -433,6 +451,22 @@ row_build_row_ref_in_tuple(
|
||||
field = rec_get_nth_field(rec, pos, &len);
|
||||
|
||||
dfield_set_data(dfield, field, len);
|
||||
|
||||
/* If the primary key contains a column prefix, then the
|
||||
secondary index may contain a longer prefix of the same
|
||||
column, or the full column, and we must adjust the length
|
||||
accordingly. */
|
||||
|
||||
clust_col_prefix_len =
|
||||
dict_index_get_nth_field(clust_index, i)->prefix_len;
|
||||
|
||||
if (clust_col_prefix_len > 0) {
|
||||
if (len != UNIV_SQL_NULL
|
||||
&& len > clust_col_prefix_len) {
|
||||
|
||||
dfield_set_len(dfield, clust_col_prefix_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ut_ad(dtuple_check_typed(ref));
|
||||
|
Loading…
x
Reference in New Issue
Block a user