From da4efd56aa9bc3c39d94a73eb216ca7f559ce734 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 19 Dec 2018 10:38:29 +0530 Subject: Backported MDEV-11196(e4d10e09cf31) and MDEV-10360(8a8ba1949bf4) to 10.0 --- sql/table.cc | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'sql/table.cc') diff --git a/sql/table.cc b/sql/table.cc index 98bf6d8b4dd..5a34d47367a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1690,6 +1690,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, keyinfo= share->key_info; uint primary_key= my_strcasecmp(system_charset_info, share->keynames.type_names[0], primary_key_name) ? MAX_KEY : 0; + KEY* key_first_info= NULL; if (primary_key >= MAX_KEY && keyinfo->flags & HA_NOSAME) { @@ -1769,34 +1770,71 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, keyinfo->name_length+1); } + if (!key) + key_first_info= keyinfo; + if (ext_key_parts > share->key_parts && key) { KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part + (keyinfo-1)->ext_key_parts; + uint add_keyparts_for_this_key= add_first_key_parts; + uint length_bytes= 0, len_null_byte= 0, ext_key_length= 0; + Field *field; /* Do not extend the key that contains a component defined over the beginning of a field. */ for (i= 0; i < keyinfo->user_defined_key_parts; i++) - { + { uint fieldnr= keyinfo->key_part[i].fieldnr; + field= share->field[keyinfo->key_part[i].fieldnr-1]; + + if (field->null_ptr) + len_null_byte= HA_KEY_NULL_LENGTH; + + if (field->type() == MYSQL_TYPE_BLOB || + field->real_type() == MYSQL_TYPE_VARCHAR || + field->type() == MYSQL_TYPE_GEOMETRY) + { + length_bytes= HA_KEY_BLOB_LENGTH; + } + ext_key_length+= keyinfo->key_part[i].length + len_null_byte + + length_bytes; if (share->field[fieldnr-1]->key_length() != keyinfo->key_part[i].length) { - add_first_key_parts= 0; + add_keyparts_for_this_key= 0; break; } } - if (add_first_key_parts < keyinfo->ext_key_parts-keyinfo->user_defined_key_parts) - { + if (add_keyparts_for_this_key) + { + for (i= 0; i < add_keyparts_for_this_key; i++) + { + uint pk_part_length= key_first_info->key_part[i].store_length; + if (keyinfo->ext_key_part_map & 1< MAX_KEY_LENGTH) + { + add_keyparts_for_this_key= i; + break; + } + ext_key_length+= pk_part_length; + } + } + } + + if (add_keyparts_for_this_key < keyinfo->ext_key_parts - + keyinfo->user_defined_key_parts) + { share->ext_key_parts-= keyinfo->ext_key_parts; key_part_map ext_key_part_map= keyinfo->ext_key_part_map; keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; keyinfo->ext_key_flags= keyinfo->flags; keyinfo->ext_key_part_map= 0; - for (i= 0; i < add_first_key_parts; i++) + for (i= 0; i < add_keyparts_for_this_key; i++) { if (ext_key_part_map & 1< Date: Wed, 19 Dec 2018 10:34:30 +0530 Subject: MDEV-17589: Stack-buffer-overflow with indexed varchar (utf8) field Create a new constant MAX_DATA_LENGTH_FOR_KEY. Replace the value of MAX_KEY_LENGTH to also include the LENGTH and NULL BYTES of a field. --- sql/table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/table.cc') diff --git a/sql/table.cc b/sql/table.cc index 5a34d47367a..ded79de0e83 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1816,7 +1816,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, uint pk_part_length= key_first_info->key_part[i].store_length; if (keyinfo->ext_key_part_map & 1< MAX_KEY_LENGTH) + if (ext_key_length + pk_part_length > MAX_DATA_LENGTH_FOR_KEY) { add_keyparts_for_this_key= i; break; -- cgit v1.2.1 From fca44b7c1ffe5e32a94e8d4449bd1d9f91492c3a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 13 Dec 2018 23:12:14 +0100 Subject: MDEV-17909 Problem by MariaDB Update 10.1.32 -> 10.2.19 (Incorrect information in file: .frm) use frm_version, not mysql_version when parsing frm In particular, virtual columns are stored according to frm_version. And CHECK TABLE will overwrite mysql_version to the current server version, so it cannot correctly describe frm format. --- sql/table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/table.cc') diff --git a/sql/table.cc b/sql/table.cc index 0cf88aed4f6..dbf10bc8293 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1027,7 +1027,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, while (pos < end) { uint type, expr_length; - if (table->s->mysql_version >= 100202) + if (table->s->frm_version >= FRM_VER_EXPRESSSIONS) { uint field_nr, name_length; /* see pack_expression() for how data is stored */ -- cgit v1.2.1 From a79183b01e4e1f3af55abd102715560cecbbddae Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 19 Dec 2018 02:30:22 +0100 Subject: correct table name in CHECK failures during ALTER TABLE --- sql/table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/table.cc') diff --git a/sql/table.cc b/sql/table.cc index dbf10bc8293..7c53246a7d3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5178,7 +5178,7 @@ int TABLE::verify_constraints(bool ignore_failure) field_error.append((*chk)->name.str); my_error(ER_CONSTRAINT_FAILED, MYF(ignore_failure ? ME_JUST_WARNING : 0), field_error.c_ptr(), - s->db.str, s->table_name.str); + s->db.str, s->error_table_name()); return ignore_failure ? VIEW_CHECK_SKIP : VIEW_CHECK_ERROR; } } -- cgit v1.2.1