summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2005-05-13 12:55:59 +0300
committerunknown <marko@hundin.mysql.fi>2005-05-13 12:55:59 +0300
commit67d0502bcf05ee19edf0710ef153ca6b68244b26 (patch)
treef7a65769b2ebf26f3ccd3ac5abe47be27756c038 /innobase
parent807a543b8b795adb1b9c6546d1e2a044ecf1950e (diff)
downloadmariadb-git-67d0502bcf05ee19edf0710ef153ca6b68244b26.tar.gz
InnoDB ON UPDATE CASCADE fixes:
Enforce maximum char_length of UTF-8 data (Bug #10409). Pad UTF-8 variable-length CHAR columns with 0x20. Pad UCS2 CHAR columns with 0x0020 (Bug #10511). innobase/data/data0type.c: dtype_get_at_most_n_mbchars(): Avoid division by zero in assertion when this function is called with dtype->mbmaxlen==0 innobase/row/row0ins.c: row_ins_cascade_calc_update_vec(): Enforce maximum char_length of UTF-8 data (Bug #10409). Pad UTF-8 CHAR columns with 0x20. Pad UCS2 CHAR columns with 0x0020 (Bug #10511).
Diffstat (limited to 'innobase')
-rw-r--r--innobase/data/data0type.c3
-rw-r--r--innobase/row/row0ins.c58
2 files changed, 41 insertions, 20 deletions
diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c
index 36b0f9603e5..d4264ad2926 100644
--- a/innobase/data/data0type.c
+++ b/innobase/data/data0type.c
@@ -63,9 +63,10 @@ dtype_get_at_most_n_mbchars(
{
#ifndef UNIV_HOTBACKUP
ut_a(data_len != UNIV_SQL_NULL);
- ut_a(!(prefix_len % dtype->mbmaxlen));
+ ut_ad(!dtype->mbmaxlen || !(prefix_len % dtype->mbmaxlen));
if (dtype->mbminlen != dtype->mbmaxlen) {
+ ut_a(!(prefix_len % dtype->mbmaxlen));
return(innobase_get_at_most_n_mbchars(
dtype_get_charset_coll(dtype->prtype),
prefix_len, data_len, str));
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index f1a43868ba5..776094d0de5 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -478,7 +478,7 @@ row_ins_cascade_calc_update_vec(
if (parent_ufield->field_no == parent_field_no) {
- ulint fixed_size;
+ ulint min_size;
/* A field in the parent index record is
updated. Let us make the update vector
@@ -508,10 +508,13 @@ row_ins_cascade_calc_update_vec(
column, do not allow the update */
if (ufield->new_val.len != UNIV_SQL_NULL
- && ufield->new_val.len
- > dtype_get_len(type)) {
+ && dtype_get_at_most_n_mbchars(
+ type, dtype_get_len(type),
+ ufield->new_val.len,
+ ufield->new_val.data)
+ < ufield->new_val.len) {
- return(ULINT_UNDEFINED);
+ return(ULINT_UNDEFINED);
}
/* If the parent column type has a different
@@ -519,29 +522,46 @@ row_ins_cascade_calc_update_vec(
need to pad with spaces the new value of the
child column */
- fixed_size = dtype_get_fixed_size(type);
-
- /* TODO: pad in UCS-2 with 0x0020.
- TODO: How does the special truncation of
- UTF-8 CHAR cols affect this? */
+ min_size = dtype_get_min_size(type);
- if (fixed_size
+ if (min_size
&& ufield->new_val.len != UNIV_SQL_NULL
- && ufield->new_val.len < fixed_size) {
+ && ufield->new_val.len < min_size) {
+ char* pad_start;
+ const char* pad_end;
ufield->new_val.data =
mem_heap_alloc(heap,
- fixed_size);
- ufield->new_val.len = fixed_size;
- ut_a(dtype_get_pad_char(type)
- != ULINT_UNDEFINED);
-
- memset(ufield->new_val.data,
- (byte)dtype_get_pad_char(type),
- fixed_size);
+ min_size);
+ pad_start = ufield->new_val.data
+ + ufield->new_val.len;
+ pad_end = ufield->new_val.data
+ + min_size;
+ ufield->new_val.len = min_size;
ut_memcpy(ufield->new_val.data,
parent_ufield->new_val.data,
parent_ufield->new_val.len);
+
+ switch (UNIV_EXPECT(
+ dtype_get_mbminlen(type), 1)) {
+ default:
+ ut_error;
+ case 1:
+ /* space=0x20 */
+ memset(pad_start, 0x20,
+ pad_end - pad_start);
+ break;
+ case 2:
+ /* space=0x0020 */
+ ut_a(!(ufield->new_val.len
+ % 2));
+ ut_a(!(min_size % 2));
+ do {
+ *pad_start++ = 0x00;
+ *pad_start++ = 0x20;
+ } while (pad_start < pad_end);
+ break;
+ }
}
ufield->extern_storage = FALSE;