summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2004-09-16 20:50:24 +0300
committerunknown <heikki@hundin.mysql.fi>2004-09-16 20:50:24 +0300
commita2d94d92f5b462d64aa33cdef8e0a0c0ae2297ae (patch)
tree4af62c5047a3c9d07dd0bae6236b6e6677cb207c /innobase
parent8bf8c8596873b534ad4a13eb73152c617c50c21b (diff)
downloadmariadb-git-a2d94d92f5b462d64aa33cdef8e0a0c0ae2297ae.tar.gz
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()
Diffstat (limited to 'innobase')
-rw-r--r--innobase/dict/dict0dict.c10
-rw-r--r--innobase/include/dict0dict.h6
-rw-r--r--innobase/pars/pars0opt.c13
-rw-r--r--innobase/row/row0row.c34
4 files changed, 58 insertions, 5 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index bd07c5abffe..61bf3fae137 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -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);
}
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index 835c2c2b2e6..9940be9832d 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -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(
diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c
index 5cc2e39b438..51aaf02b736 100644
--- a/innobase/pars/pars0opt.c
+++ b/innobase/pars/pars0opt.c
@@ -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)
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index 680539764fd..f075caa7d75 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -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));