From 15eaeace394320d96b6bf193f9e049f9358d2b07 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 12 Dec 2018 19:58:20 +0400 Subject: MDEV-16987 - ALTER DATABASE possible in read-only mode Forbid ALTER DATABASE under read_only. --- sql/sql_parse.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9f8a625325f..95243ead2fe 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -831,6 +831,7 @@ static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables) DBUG_RETURN(FALSE); if (lex->sql_command == SQLCOM_CREATE_DB || + lex->sql_command == SQLCOM_ALTER_DB || lex->sql_command == SQLCOM_DROP_DB) DBUG_RETURN(TRUE); -- cgit v1.2.1 From 1a7158b88a117f6543e1318a7abdc490cdfd5e67 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 13 Dec 2018 19:51:40 +0100 Subject: remove unsed variable --- sql/opt_range.cc | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sql') diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 005ae92a665..b1f8366d83b 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3322,10 +3322,6 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param, { Field **field_ptr; TABLE *table= param->table; - partition_info *part_info= NULL; - #ifdef WITH_PARTITION_STORAGE_ENGINE - part_info= table->part_info; - #endif uint parts= 0; for (field_ptr= table->field; *field_ptr; field_ptr++) -- cgit v1.2.1 From d1f399408d245dd8b971ba331eaaedf488e083b6 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Sun, 16 Dec 2018 21:50:49 +0200 Subject: MDEV-6453: Assertion `inited==NONE || (inited==RND && scan)' failed in handler::ha_rnd_init(bool) with InnoDB, joins, AND/OR conditions The inited parameter handler is not initialised when we do a quick_select after a table scan. --- sql/sql_select.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ca9a6a46fda..6fafbbb11df 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -18883,6 +18883,10 @@ test_if_quick_select(JOIN_TAB *tab) delete tab->select->quick; tab->select->quick=0; + + if (tab->table->file->inited != handler::NONE) + tab->table->file->ha_index_or_rnd_end(); + return tab->select->test_quick_select(tab->join->thd, tab->keys, (table_map) 0, HA_POS_ERROR, 0, FALSE); -- cgit v1.2.1 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') 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/handler.h | 12 +++++++++--- sql/partition_info.cc | 4 ++-- sql/sql_const.h | 12 +++++++++++- sql/table.cc | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/handler.h b/sql/handler.h index 52396b84c0d..606adade679 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -384,6 +384,12 @@ enum enum_alter_inplace_result { #define HA_KEY_NULL_LENGTH 1 #define HA_KEY_BLOB_LENGTH 2 +/* Maximum length of any index lookup key, in bytes */ + +#define MAX_KEY_LENGTH (MAX_DATA_LENGTH_FOR_KEY \ + +(MAX_REF_PARTS \ + *(HA_KEY_NULL_LENGTH + HA_KEY_BLOB_LENGTH))) + #define HA_LEX_CREATE_TMP_TABLE 1 #define HA_LEX_CREATE_IF_NOT_EXISTS 2 #define HA_LEX_CREATE_TABLE_LIKE 4 @@ -3233,14 +3239,14 @@ public: uint max_key_parts() const { return MY_MIN(MAX_REF_PARTS, max_supported_key_parts()); } uint max_key_length() const - { return MY_MIN(MAX_KEY_LENGTH, max_supported_key_length()); } + { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_length()); } uint max_key_part_length() const - { return MY_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); } + { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_part_length()); } virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; } virtual uint max_supported_keys() const { return 0; } virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; } - virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; } + virtual uint max_supported_key_length() const { return MAX_DATA_LENGTH_FOR_KEY; } virtual uint max_supported_key_part_length() const { return 255; } virtual uint min_record_length(uint options) const { return 1; } diff --git a/sql/partition_info.cc b/sql/partition_info.cc index e6a30c8a7f0..7106e741331 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1990,12 +1990,12 @@ bool partition_info::check_partition_field_length() for (i= 0; i < num_part_fields; i++) store_length+= get_partition_field_store_length(part_field_array[i]); - if (store_length > MAX_KEY_LENGTH) + if (store_length > MAX_DATA_LENGTH_FOR_KEY) DBUG_RETURN(TRUE); store_length= 0; for (i= 0; i < num_subpart_fields; i++) store_length+= get_partition_field_store_length(subpart_field_array[i]); - if (store_length > MAX_KEY_LENGTH) + if (store_length > MAX_DATA_LENGTH_FOR_KEY) DBUG_RETURN(TRUE); DBUG_RETURN(FALSE); } diff --git a/sql/sql_const.h b/sql/sql_const.h index c37d8dd68f7..c0b343c6ca4 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -33,7 +33,17 @@ #define MAX_SYS_VAR_LENGTH 32 #define MAX_KEY MAX_INDEXES /* Max used keys */ #define MAX_REF_PARTS 32 /* Max parts used as ref */ -#define MAX_KEY_LENGTH 3072 /* max possible key */ + +/* + Maximum length of the data part of an index lookup key. + + The "data part" is defined as the value itself, not including the + NULL-indicator bytes or varchar length bytes ("the Extras"). We need this + value because there was a bug where length of the Extras were not counted. + + You probably need MAX_KEY_LENGTH, not this constant. +*/ +#define MAX_DATA_LENGTH_FOR_KEY 3072 #if SIZEOF_OFF_T > 4 #define MAX_REFLENGTH 8 /* Max length for record ref */ #else 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 f16d4d4c6ee81cfee3b0d1cb2f2219b1fa982e2e Mon Sep 17 00:00:00 2001 From: Sachin Date: Wed, 19 Dec 2018 16:33:00 +0530 Subject: MDEV-17720 slave_ddl_exec_mode=IDEMPOTENT does not handle DROP DATABASE Relevant if exists flag are added for create database and drop database. --- sql/sql_parse.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a9849c7248d..5ca22f0dedc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3884,6 +3884,9 @@ end_with_restore_list: my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; } + if (slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT && + !(lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)) + create_info.options|= HA_LEX_CREATE_IF_NOT_EXISTS; } #endif if (check_access(thd, CREATE_ACL, lex->name.str, NULL, NULL, 1, 0)) @@ -3915,6 +3918,9 @@ end_with_restore_list: my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; } + if (!thd->slave_expected_error && + slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT) + lex->check_exists= 1; } #endif if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0)) -- cgit v1.2.1