diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/derived_handler.cc | 5 | ||||
-rw-r--r-- | sql/field.h | 21 | ||||
-rw-r--r-- | sql/ha_partition.cc | 29 | ||||
-rw-r--r-- | sql/ha_partition.h | 12 | ||||
-rw-r--r-- | sql/handler.cc | 9 | ||||
-rw-r--r-- | sql/handler.h | 14 | ||||
-rw-r--r-- | sql/mysqld.cc | 4 | ||||
-rw-r--r-- | sql/partition_info.h | 5 | ||||
-rw-r--r-- | sql/share/errmsg-utf8.txt | 6 | ||||
-rw-r--r-- | sql/sql_derived.cc | 5 | ||||
-rw-r--r-- | sql/sql_lex.cc | 4 | ||||
-rw-r--r-- | sql/sql_partition.cc | 122 | ||||
-rw-r--r-- | sql/sql_select.cc | 34 | ||||
-rw-r--r-- | sql/sql_select.h | 3 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 | ||||
-rw-r--r-- | sql/sql_type_geom.h | 8 |
16 files changed, 142 insertions, 141 deletions
diff --git a/sql/derived_handler.cc b/sql/derived_handler.cc index f48b95cbf76..70cc04bf9c7 100644 --- a/sql/derived_handler.cc +++ b/sql/derived_handler.cc @@ -44,11 +44,6 @@ Pushdown_derived::Pushdown_derived(TABLE_LIST *tbl, derived_handler *h) } -Pushdown_derived::~Pushdown_derived() -{ - delete handler; -} - int Pushdown_derived::execute() { diff --git a/sql/field.h b/sql/field.h index ace51b792ad..feed7206678 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1775,12 +1775,6 @@ public: Used by the ALTER TABLE */ virtual bool is_equal(const Column_definition &new_field) const= 0; - // Used as double dispatch pattern: calls virtual method of handler - virtual bool - can_be_converted_by_engine(const Column_definition &new_type) const - { - return false; - } /* convert decimal to longlong with overflow check */ longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag, int *err); @@ -4070,11 +4064,6 @@ public: void sql_type(String &str) const override; void sql_rpl_type(String*) const override; bool is_equal(const Column_definition &new_field) const override; - bool can_be_converted_by_engine(const Column_definition &new_type) const - override - { - return table->file->can_convert_string(this, new_type); - } uchar *pack(uchar *to, const uchar *from, uint max_length) override; const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data) override; @@ -4229,11 +4218,6 @@ public: uchar *new_ptr, uint32 length, uchar *new_null_ptr, uint new_null_bit) override; bool is_equal(const Column_definition &new_field) const override; - bool can_be_converted_by_engine(const Column_definition &new_type) const - override - { - return table->file->can_convert_varstring(this, new_type); - } void hash(ulong *nr, ulong *nr2) override; uint length_size() const override { return length_bytes; } void print_key_value(String *out, uint32 length) override; @@ -4672,11 +4656,6 @@ public: uint32 char_length() const override; uint32 character_octet_length() const override; bool is_equal(const Column_definition &new_field) const override; - bool can_be_converted_by_engine(const Column_definition &new_type) const - override - { - return table->file->can_convert_blob(this, new_type); - } void print_key_value(String *out, uint32 length) override; Binlog_type_info binlog_type_info() const override; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index d91c4dee8b1..063a65a6ee1 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -12130,35 +12130,12 @@ int ha_partition::info_push(uint info_type, void *info) bool -ha_partition::can_convert_string(const Field_string* field, - const Column_definition& new_type) const +ha_partition::can_convert_nocopy(const Field &field, + const Column_definition &new_type) const { for (uint index= 0; index < m_tot_parts; index++) { - if (!m_file[index]->can_convert_string(field, new_type)) - return false; - } - return true; -} - -bool -ha_partition::can_convert_varstring(const Field_varstring* field, - const Column_definition& new_type) const{ - for (uint index= 0; index < m_tot_parts; index++) - { - if (!m_file[index]->can_convert_varstring(field, new_type)) - return false; - } - return true; -} - -bool -ha_partition::can_convert_blob(const Field_blob* field, - const Column_definition& new_type) const -{ - for (uint index= 0; index < m_tot_parts; index++) - { - if (!m_file[index]->can_convert_blob(field, new_type)) + if (!m_file[index]->can_convert_nocopy(field, new_type)) return false; } return true; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 4a4b899708e..437280d6d5d 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1629,16 +1629,8 @@ public: friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2); friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2); - bool can_convert_string( - const Field_string* field, - const Column_definition& new_field) const override; - bool can_convert_varstring( - const Field_varstring* field, - const Column_definition& new_field) const override; - - bool can_convert_blob( - const Field_blob* field, - const Column_definition& new_field) const override; + bool can_convert_nocopy(const Field &field, + const Column_definition &new_field) const override; }; #endif /* HA_PARTITION_INCLUDED */ diff --git a/sql/handler.cc b/sql/handler.cc index 577d6ef9e26..90e3b20e3fb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7320,8 +7320,13 @@ int handler::check_duplicate_long_entries_update(const uchar *new_rec) { int error; field= keypart->field; - /* Compare fields if they are different then check for duplicates */ - if (field->cmp_binary_offset(reclength)) + /* + Compare fields if they are different then check for duplicates + cmp_binary_offset cannot differentiate between null and empty string + So also check for that too + */ + if((field->is_null(0) != field->is_null(reclength)) || + field->cmp_binary_offset(reclength)) { if((error= check_duplicate_long_entry_key(new_rec, i))) return error; diff --git a/sql/handler.h b/sql/handler.h index ed24f160385..ad18ad8b9e4 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -5097,18 +5097,8 @@ public: These functions check for such possibility. Implementation could be based on Field_xxx::is_equal() */ - virtual bool can_convert_string(const Field_string *field, - const Column_definition &new_type) const - { - return false; - } - virtual bool can_convert_varstring(const Field_varstring *field, - const Column_definition &new_type) const - { - return false; - } - virtual bool can_convert_blob(const Field_blob *field, - const Column_definition &new_type) const + virtual bool can_convert_nocopy(const Field &, + const Column_definition &) const { return false; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1722b1e188a..c25ae883e74 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4125,8 +4125,8 @@ static int init_common_variables() files= my_set_max_open_files(max_open_files); SYSVAR_AUTOSIZE_IF_CHANGED(open_files_limit, files, ulong); - if (files < wanted_files && global_system_variables.log_warnings) - sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); + if (files < max_open_files && global_system_variables.log_warnings) + sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, max_open_files); /* If we required too much tc_instances than we reduce */ SYSVAR_AUTOSIZE_IF_CHANGED(tc_instances, diff --git a/sql/partition_info.h b/sql/partition_info.h index e95daec7d31..287aa6d2200 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -429,8 +429,13 @@ public: return NULL; } uint next_part_no(uint new_parts) const; + + int gen_part_type(THD *thd, String *str) const; }; +void part_type_error(THD *thd, partition_info *work_part_info, + const char *part_type, partition_info *tab_part_info); + uint32 get_next_partition_id_range(struct st_partition_iter* part_iter); bool check_partition_dirs(partition_info *part_info); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 4c7f71f4718..de5117e0246 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -9773,9 +9773,9 @@ ER_UNUSED_23 spa "Nunca debería vd de ver esto" ER_PARTITION_WRONG_TYPE - chi "错误的分区类型,预期类型:%`s" - eng "Wrong partitioning type, expected type: %`s" - spa "Tipo de partición equivocada, tipo esperado: %`s" + chi "错误的分区类型,预期类型:%`s for partitioning by %`s" + eng "Wrong partition type %`s for partitioning by %`s" + spa "Tipo de partición equivocada, tipo esperado: %`s for partitioning by %`s" WARN_VERS_PART_FULL chi "版本化表%`s.%`s:partition%`s已满,添加更多历史分区(out of %s)" diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 579ea34b8e4..6f0857239dd 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1016,11 +1016,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) /* Create an object for execution of the query specifying the table */ if (!(derived->pushdown_derived= new (thd->mem_root) Pushdown_derived(derived, derived->dt_handler))) - { - delete derived->dt_handler; - derived->dt_handler= NULL; DBUG_RETURN(TRUE); - } } lex->current_select= first_select; @@ -1245,7 +1241,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) /* Execute the query that specifies the derived table by a foreign engine */ res= derived->pushdown_derived->execute(); unit->executed= true; - delete derived->pushdown_derived; DBUG_RETURN(res); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 57f7cfac595..b81ace9a2cc 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9761,7 +9761,7 @@ bool LEX::part_values_current(THD *thd) { if (unlikely(part_info->part_type != VERSIONING_PARTITION)) { - my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); + part_type_error(thd, NULL, "CURRENT", part_info); return true; } } @@ -9788,7 +9788,7 @@ bool LEX::part_values_history(THD *thd) { if (unlikely(part_info->part_type != VERSIONING_PARTITION)) { - my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); + part_type_error(thd, NULL, "HISTORY", part_info); return true; } } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 0db40c4f55c..9c7f25e8808 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2470,7 +2470,7 @@ end: @retval != 0 Failure */ -static int add_key_with_algorithm(String *str, partition_info *part_info) +static int add_key_with_algorithm(String *str, const partition_info *part_info) { int err= 0; err+= str->append(STRING_WITH_LEN("KEY ")); @@ -2499,6 +2499,78 @@ char *generate_partition_syntax_for_frm(THD *thd, partition_info *part_info, return res; } + +/* + Generate the partition type syntax from the partition data structure. + + @return Operation status. + @retval 0 Success + @retval > 0 Failure + @retval -1 Fatal error +*/ + +int partition_info::gen_part_type(THD *thd, String *str) const +{ + int err= 0; + switch (part_type) + { + case RANGE_PARTITION: + err+= str->append(STRING_WITH_LEN("RANGE ")); + break; + case LIST_PARTITION: + err+= str->append(STRING_WITH_LEN("LIST ")); + break; + case HASH_PARTITION: + if (linear_hash_ind) + err+= str->append(STRING_WITH_LEN("LINEAR ")); + if (list_of_part_fields) + { + err+= add_key_with_algorithm(str, this); + err+= add_part_field_list(thd, str, part_field_list); + } + else + err+= str->append(STRING_WITH_LEN("HASH ")); + break; + case VERSIONING_PARTITION: + err+= str->append(STRING_WITH_LEN("SYSTEM_TIME ")); + break; + default: + DBUG_ASSERT(0); + /* We really shouldn't get here, no use in continuing from here */ + my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATAL)); + return -1; + } + return err; +} + + +void part_type_error(THD *thd, partition_info *work_part_info, + const char *part_type, + partition_info *tab_part_info) +{ + StringBuffer<256> tab_part_type; + if (tab_part_info->gen_part_type(thd, &tab_part_type) < 0) + return; + tab_part_type.length(tab_part_type.length() - 1); + if (work_part_info) + { + DBUG_ASSERT(!part_type); + StringBuffer<256> work_part_type; + if (work_part_info->gen_part_type(thd, &work_part_type) < 0) + return; + work_part_type.length(work_part_type.length() - 1); + my_error(ER_PARTITION_WRONG_TYPE, MYF(0), work_part_type.c_ptr(), + tab_part_type.c_ptr()); + } + else + { + DBUG_ASSERT(part_type); + my_error(ER_PARTITION_WRONG_TYPE, MYF(0), part_type, + tab_part_type.c_ptr()); + } +} + + /* Generate the partition syntax from the partition data structure. Useful for support of generating defaults, SHOW CREATE TABLES @@ -2542,34 +2614,10 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info, DBUG_ENTER("generate_partition_syntax"); err+= str.append(STRING_WITH_LEN(" PARTITION BY ")); - switch (part_info->part_type) - { - case RANGE_PARTITION: - err+= str.append(STRING_WITH_LEN("RANGE ")); - break; - case LIST_PARTITION: - err+= str.append(STRING_WITH_LEN("LIST ")); - break; - case HASH_PARTITION: - if (part_info->linear_hash_ind) - err+= str.append(STRING_WITH_LEN("LINEAR ")); - if (part_info->list_of_part_fields) - { - err+= add_key_with_algorithm(&str, part_info); - err+= add_part_field_list(thd, &str, part_info->part_field_list); - } - else - err+= str.append(STRING_WITH_LEN("HASH ")); - break; - case VERSIONING_PARTITION: - err+= str.append(STRING_WITH_LEN("SYSTEM_TIME ")); - break; - default: - DBUG_ASSERT(0); - /* We really shouldn't get here, no use in continuing from here */ - my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATAL)); - DBUG_RETURN(NULL); - } + int err2= part_info->gen_part_type(thd, &str); + if (err2 < 0) + DBUG_RETURN(NULL); + err+= err2; if (part_info->part_type == VERSIONING_PARTITION) { Vers_part_info *vers_info= part_info->vers_info; @@ -5027,6 +5075,13 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, if ((alter_info->partition_flags & ALTER_PARTITION_ADD) || (alter_info->partition_flags & ALTER_PARTITION_REORGANIZE)) { + if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN) && + !(tab_part_info->part_type == RANGE_PARTITION || + tab_part_info->part_type == LIST_PARTITION)) + { + my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "CONVERT TABLE TO"); + goto err; + } if (thd->work_part_info->part_type != tab_part_info->part_type) { if (thd->work_part_info->part_type == NOT_A_PARTITION) @@ -5062,7 +5117,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, else if (thd->work_part_info->part_type == VERSIONING_PARTITION || tab_part_info->part_type == VERSIONING_PARTITION) { - my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); + part_type_error(thd, thd->work_part_info, NULL, tab_part_info); } else { @@ -5096,13 +5151,6 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, } if (alter_info->partition_flags & ALTER_PARTITION_ADD) { - if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN) && - !(tab_part_info->part_type == RANGE_PARTITION || - tab_part_info->part_type == LIST_PARTITION)) - { - my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "CONVERT TABLE TO"); - goto err; - } if (*fast_alter_table && thd->locked_tables_mode) { MEM_ROOT *old_root= thd->mem_root; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e8874a5ea78..f7861873192 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -67,6 +67,7 @@ #include "select_handler.h" #include "my_json_writer.h" #include "opt_trace.h" +#include "derived_handler.h" #include "create_tmp_table.h" /* @@ -14574,6 +14575,7 @@ void JOIN::cleanup(bool full) } } } + free_pushdown_handlers(*join_list); } /* Restore ref array to original state */ if (current_ref_ptrs != items0) @@ -14584,6 +14586,32 @@ void JOIN::cleanup(bool full) DBUG_VOID_RETURN; } +/** + Clean up all derived pushdown handlers in this join. + + @detail + Note that dt_handler is picked at the prepare stage (as opposed + to optimization stage where one could expect this). + Because of that, we have to do cleanups in this function that is called + from JOIN::cleanup() and not in JOIN_TAB::cleanup. + */ +void JOIN::free_pushdown_handlers(List<TABLE_LIST>& join_list) +{ + List_iterator<TABLE_LIST> li(join_list); + TABLE_LIST *table_ref; + while ((table_ref= li++)) + { + if (table_ref->nested_join) + free_pushdown_handlers(table_ref->nested_join->join_list); + if (table_ref->pushdown_derived) + { + delete table_ref->pushdown_derived; + table_ref->pushdown_derived= NULL; + } + delete table_ref->dt_handler; + table_ref->dt_handler= NULL; + } +} /** Remove the following expressions from ORDER BY and GROUP BY: @@ -28065,12 +28093,6 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) result, unit, first); } - if (unit->derived && unit->derived->pushdown_derived) - { - delete unit->derived->pushdown_derived; - unit->derived->pushdown_derived= NULL; - } - DBUG_RETURN(res || thd->is_error()); } diff --git a/sql/sql_select.h b/sql/sql_select.h index 5aa775f4a2d..c9e0fa25421 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1791,6 +1791,7 @@ private: bool add_having_as_table_cond(JOIN_TAB *tab); bool make_aggr_tables_info(); bool add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *fields); + void free_pushdown_handlers(List<TABLE_LIST>& join_list); void init_join_cache_and_keyread(); bool transform_in_predicates_into_equalities(THD *thd); bool transform_all_conds_and_on_exprs(THD *thd, @@ -2471,8 +2472,6 @@ public: Pushdown_derived(TABLE_LIST *tbl, derived_handler *h); - ~Pushdown_derived(); - int execute(); }; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7e35c17bb64..3cab075b944 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6582,7 +6582,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, bool is_equal= field->is_equal(*new_field); if (!is_equal) { - if (field->can_be_converted_by_engine(*new_field)) + if (field->table->file->can_convert_nocopy(*field, *new_field)) { /* New column type differs from the old one, but storage engine can diff --git a/sql/sql_type_geom.h b/sql/sql_type_geom.h index a2bcd45e0e8..3bc25808bc3 100644 --- a/sql/sql_type_geom.h +++ b/sql/sql_type_geom.h @@ -2,7 +2,7 @@ #define SQL_TYPE_GEOM_H_INCLUDED /* Copyright (c) 2015 MariaDB Foundation - Copyright (c) 2019 MariaDB + Copyright (c) 2019, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -397,12 +397,6 @@ public: !table->copy_blobs; } bool is_equal(const Column_definition &new_field) const override; - bool can_be_converted_by_engine(const Column_definition &new_type) - const override - { - return false; // Override the Field_blob behavior - } - int store(const char *to, size_t length, CHARSET_INFO *charset) override; int store(double nr) override; int store(longlong nr, bool unsigned_val) override; |