summaryrefslogtreecommitdiff
path: root/innobase/row/row0row.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/row/row0row.c')
-rw-r--r--innobase/row/row0row.c72
1 files changed, 63 insertions, 9 deletions
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index 680539764fd..38714b0c49b 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -113,6 +113,8 @@ row_build_index_entry(
dfield_t* dfield2;
dict_col_t* col;
ulint i;
+ ulint storage_len;
+ dtype_t* cur_type;
ut_ad(row && index && heap);
ut_ad(dtuple_check_typed(row));
@@ -139,10 +141,17 @@ row_build_index_entry(
/* If a column prefix index, take only the prefix */
if (ind_field->prefix_len > 0
- && dfield_get_len(dfield2) != UNIV_SQL_NULL
- && dfield_get_len(dfield2) > ind_field->prefix_len) {
+ && dfield_get_len(dfield2) != UNIV_SQL_NULL) {
- dfield_set_len(dfield, ind_field->prefix_len);
+ cur_type = dict_col_get_type(
+ dict_field_get_col(ind_field));
+
+ storage_len = dtype_get_at_most_n_mbchars(
+ cur_type,
+ ind_field->prefix_len,
+ dfield_get_len(dfield2), dfield2->data);
+
+ dfield_set_len(dfield, storage_len);
}
}
@@ -334,6 +343,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 +376,24 @@ 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) {
+
+ dfield_set_len(dfield,
+ dtype_get_at_most_n_mbchars(
+ dfield_get_type(dfield),
+ clust_col_prefix_len, len, field));
+ }
+ }
}
ut_ad(dtuple_check_typed(ref));
@@ -383,12 +411,13 @@ row_build_row_ref_in_tuple(
dtuple_t* ref, /* in/out: row reference built; see the
NOTE below! */
dict_index_t* index, /* in: index */
- rec_t* rec) /* in: record in the index;
+ rec_t* rec, /* in: record in the index;
NOTE: the data fields in ref will point
directly into this record, therefore,
the buffer page of this record must be
at least s-latched and the latch held
as long as the row reference is used! */
+ trx_t* trx) /* in: transaction */
{
dict_index_t* clust_index;
dfield_t* dfield;
@@ -396,6 +425,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);
@@ -403,9 +433,9 @@ row_build_row_ref_in_tuple(
if (!index->table) {
fputs("InnoDB: table ", stderr);
notfound:
- ut_print_name(stderr, index->table_name);
+ ut_print_name(stderr, trx, index->table_name);
fputs(" for index ", stderr);
- ut_print_name(stderr, index->name);
+ ut_print_name(stderr, trx, index->name);
fputs(" not found\n", stderr);
ut_error;
}
@@ -433,6 +463,24 @@ 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) {
+
+ dfield_set_len(dfield,
+ dtype_get_at_most_n_mbchars(
+ dfield_get_type(dfield),
+ clust_col_prefix_len, len, field));
+ }
+ }
}
ut_ad(dtuple_check_typed(ref));
@@ -460,6 +508,7 @@ row_build_row_ref_from_row(
dict_col_t* col;
ulint ref_len;
ulint i;
+ dtype_t* cur_type;
ut_ad(ref && table && row);
@@ -481,10 +530,15 @@ row_build_row_ref_from_row(
dfield_copy(dfield, dfield2);
if (field->prefix_len > 0
- && dfield->len != UNIV_SQL_NULL
- && dfield->len > field->prefix_len) {
+ && dfield->len != UNIV_SQL_NULL) {
+
+ cur_type = dict_col_get_type(
+ dict_field_get_col(field));
- dfield->len = field->prefix_len;
+ dfield->len = dtype_get_at_most_n_mbchars(
+ cur_type,
+ field->prefix_len,
+ dfield->len, dfield->data);
}
}