diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-18 17:30:02 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-18 17:30:02 +0300 |
commit | 23047d3ed42eacb5eaa5475a8fa4161550d01c52 (patch) | |
tree | e723067fea7cfb663ef7e4777e29ffd7dcd2905d /sql | |
parent | f86d97c3fee0127d83c009e448f419ac857c72c7 (diff) | |
parent | faf6d0ef3f9323c6d24f8cdb6533ed23d1a6bb40 (diff) | |
download | mariadb-git-23047d3ed42eacb5eaa5475a8fa4161550d01c52.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 11 | ||||
-rw-r--r-- | sql/field.h | 16 | ||||
-rw-r--r-- | sql/item.h | 26 | ||||
-rw-r--r-- | sql/item_func.cc | 11 | ||||
-rw-r--r-- | sql/item_subselect.cc | 9 | ||||
-rw-r--r-- | sql/item_sum.cc | 8 | ||||
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/sp_head.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 26 | ||||
-rw-r--r-- | sql/sql_repl.cc | 5 | ||||
-rw-r--r-- | sql/sql_statistics.cc | 1 | ||||
-rw-r--r-- | sql/sql_tvc.cc | 9 | ||||
-rw-r--r-- | sql/table.cc | 6 |
13 files changed, 104 insertions, 28 deletions
diff --git a/sql/field.cc b/sql/field.cc index 6234de43ec8..0f5caed57f6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1455,7 +1455,7 @@ void Field::error_generated_column_function_is_not_allowed(THD *thd, QT_ITEM_IDENT_SKIP_TABLE_NAMES)); my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(error ? 0 : ME_WARNING), - tmp.c_ptr(), vcol_info->get_vcol_type_name(), + tmp.c_ptr_safe(), vcol_info->get_vcol_type_name(), const_cast<const char*>(field_name.str)); } @@ -7680,6 +7680,15 @@ my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value) } +#ifdef HAVE_valgrind_or_MSAN +void Field_varstring::mark_unused_memory_as_defined() +{ + uint used_length= get_length(); + MEM_MAKE_DEFINED(get_data() + used_length, field_length - used_length); +} +#endif + + int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr, uint max_len) const { diff --git a/sql/field.h b/sql/field.h index d709a84e0fe..bef73705f60 100644 --- a/sql/field.h +++ b/sql/field.h @@ -977,6 +977,19 @@ public: DBUG_ASSERT(ls.length < UINT_MAX32); return store(ls.str, (uint) ls.length, cs); } + +#ifdef HAVE_valgrind_or_MSAN + /** + Mark unused memory in the field as defined. Mainly used to ensure + that if we write full field to disk (for example in + Count_distinct_field::add(), we don't write unitalized data to + disk which would confuse valgrind or MSAN. + */ + virtual void mark_unused_memory_as_defined() {} +#else + void mark_unused_memory_as_defined() {} +#endif + virtual double val_real()=0; virtual longlong val_int()=0; /* @@ -4096,6 +4109,9 @@ public: } int store(const char *to,size_t length,CHARSET_INFO *charset) override; using Field_str::store; +#ifdef HAVE_valgrind_or_MSAN + void mark_unused_memory_as_defined() override; +#endif double val_real() override; longlong val_int() override; String *val_str(String *, String *) override; diff --git a/sql/item.h b/sql/item.h index c5fd5d074f6..cb11b5d8773 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1592,7 +1592,14 @@ public: a constant expression. Used in the optimizer to propagate basic constants. */ virtual bool basic_const_item() const { return 0; } - /* + /** + Determines if the expression is allowed as + a virtual column assignment source: + INSERT INTO t1 (vcol) VALUES (10) -> error + INSERT INTO t1 (vcol) VALUES (NULL) -> ok + */ + virtual bool vcol_assignment_allowed_value() const { return false; } + /** Test if "this" is an ORDER position (rather than an expression). Notes: - can be called before fix_fields(). @@ -3616,6 +3623,7 @@ public: collation.set(cs, DERIVATION_IGNORABLE, MY_REPERTOIRE_ASCII); } enum Type type() const { return NULL_ITEM; } + bool vcol_assignment_allowed_value() const { return true; } double val_real(); longlong val_int(); String *val_str(String *str); @@ -3861,6 +3869,21 @@ public: const Type_handler *type_handler() const { return Type_handler_hybrid_field_type::type_handler(); } + bool vcol_assignment_allowed_value() const + { + switch (state) { + case NULL_VALUE: + case DEFAULT_VALUE: + case IGNORE_VALUE: + return true; + case NO_VALUE: + case SHORT_DATA_VALUE: + case LONG_DATA_VALUE: + break; + } + return false; + } + Item_param(THD *thd, const LEX_CSTRING *name_arg, uint pos_in_query_arg, uint len_in_query_arg); @@ -6255,6 +6278,7 @@ public: Item_default_value(THD *thd, Name_resolution_context *context_arg, Field *a) :Item_field(thd, context_arg) {} enum Type type() const { return DEFAULT_VALUE_ITEM; } + bool vcol_assignment_allowed_value() const { return arg == NULL; } bool eq(const Item *item, bool binary_cmp) const; bool fix_fields(THD *, Item **); void cleanup(); diff --git a/sql/item_func.cc b/sql/item_func.cc index 52eeaf10cd5..da185f9878b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2184,6 +2184,12 @@ longlong Item_func_bit_neg::val_int() void Item_func_int_val::fix_length_and_dec_int_or_decimal() { + /* + The INT branch of this code should be revised. + It creates too large data types, e.g. + CREATE OR REPLACE TABLE t2 AS SELECT FLOOR(9999999.999) AS fa; + results in a BININT(10) column, while INT(7) should probably be enough. + */ ulonglong tmp_max_length= (ulonglong ) args[0]->max_length - (args[0]->decimals ? args[0]->decimals + 1 : 0) + 2; max_length= tmp_max_length > (ulonglong) UINT_MAX32 ? @@ -2198,6 +2204,9 @@ void Item_func_int_val::fix_length_and_dec_int_or_decimal() */ if (args[0]->max_length - args[0]->decimals >= DECIMAL_LONGLONG_DIGITS - 2) { + fix_char_length( + my_decimal_precision_to_length_no_truncation( + args[0]->decimal_int_part(), 0, false)); set_handler(&type_handler_newdecimal); } else @@ -2314,6 +2323,8 @@ void Item_func_round::fix_length_and_dec_decimal(uint decimals_to_set) set_handler(&type_handler_newdecimal); unsigned_flag= args[0]->unsigned_flag; decimals= decimals_to_set; + if (!precision) + precision= 1; // DECIMAL(0,0) -> DECIMAL(1,0) max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, unsigned_flag); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 4bbb33d4eb7..be78f333951 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2192,10 +2192,13 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, } else { + /* + No need to use real_item for the item, as the ref items that are possible + in the subquery either belong to views or to the parent select. + For such case we need to refer to the reference and not to the original + item. + */ Item *item= (Item*) select_lex->item_list.head(); - if (item->type() != REF_ITEM || - ((Item_ref*)item)->ref_type() != Item_ref::VIEW_REF) - item= item->real_item(); if (select_lex->table_list.elements) { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 052ac173747..b676186f571 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1387,10 +1387,12 @@ Item_sum_sp::execute() bool res; uint old_server_status= thd->server_status; - /* We set server status so we can send a signal to exit from the - function with the return value. */ + /* + We set server status so we can send a signal to exit from the + function with the return value. + */ - thd->server_status= SERVER_STATUS_LAST_ROW_SENT; + thd->server_status|= SERVER_STATUS_LAST_ROW_SENT; res= Item_sp::execute(thd, &null_value, args, arg_count); thd->server_status= old_server_status; return res; diff --git a/sql/log_event.cc b/sql/log_event.cc index 1b273b19c33..d5ec2060c02 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3134,6 +3134,8 @@ const char *sql_ex_info::init(const char *buf, const char *buf_end, } else { + if (buf_end - buf < 7) + return 0; // Wrong data field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1; field_term = buf++; // Use first byte in string enclosed= buf++; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f840904def3..e61164e8e40 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -4648,7 +4648,7 @@ sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) else { thd->spcont->pause_state= FALSE; - if (thd->server_status == SERVER_STATUS_LAST_ROW_SENT) + if (thd->server_status & SERVER_STATUS_LAST_ROW_SENT) { my_message(ER_SP_FETCH_NO_DATA, ER_THD(thd, ER_SP_FETCH_NO_DATA), MYF(0)); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b5064fe9fd9..3413b3787bd 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8375,11 +8375,9 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values, if (table->next_number_field && rfield->field_index == table->next_number_field->field_index) table->auto_increment_field_not_null= TRUE; - Item::Type type= value->type(); const bool skip_sys_field= rfield->vers_sys_field(); // TODO: && !thd->vers_modify_history() [MDEV-16546] if ((rfield->vcol_info || skip_sys_field) && - type != Item::DEFAULT_VALUE_ITEM && - type != Item::NULL_ITEM && + !value->vcol_assignment_allowed_value() && table->s->table_category != TABLE_CATEGORY_TEMPORARY) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -8660,20 +8658,16 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, if (field->field_index == autoinc_index) table->auto_increment_field_not_null= TRUE; - if (unlikely(field->vcol_info) || (vers_sys_field && !ignore_errors)) + if ((unlikely(field->vcol_info) || (vers_sys_field && !ignore_errors)) && + !value->vcol_assignment_allowed_value() && + table->s->table_category != TABLE_CATEGORY_TEMPORARY) { - Item::Type type= value->type(); - if (type != Item::DEFAULT_VALUE_ITEM && - type != Item::NULL_ITEM && - table->s->table_category != TABLE_CATEGORY_TEMPORARY) - { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN, - ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN), - field->field_name.str, table->s->table_name.str); - if (vers_sys_field) - continue; - } + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN, + ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN), + field->field_name.str, table->s->table_name.str); + if (vers_sys_field) + continue; } if (use_value) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 55e5e940b19..83ae25c962d 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2006,7 +2006,7 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type, pos= my_b_tell(log); if (repl_semisync_master.update_sync_header(info->thd, - (uchar*) packet->ptr(), + (uchar*) packet->c_ptr_safe(), info->log_file_name + info->dirlen, pos, &need_sync)) { @@ -2030,7 +2030,8 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type, } } - if (need_sync && repl_semisync_master.flush_net(info->thd, packet->c_ptr())) + if (need_sync && repl_semisync_master.flush_net(info->thd, + packet->c_ptr_safe())) { info->error= ER_UNKNOWN_ERROR; return "Failed to run hook 'after_send_event'"; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 55e8e52c052..a6c489f02be 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1671,6 +1671,7 @@ public: */ virtual bool add() { + table_field->mark_unused_memory_as_defined(); return tree->unique_add(table_field->ptr); } diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 678dd81709e..e228b3ca211 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -52,7 +52,14 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li) while ((item= it++)) { - if (item->fix_fields(thd, 0)) + /* + Some items have already been fixed. + For example Item_splocal items get fixed in + Item_splocal::append_for_log(), which is called from subst_spvars() + while replacing their values to NAME_CONST()s. + So fix only those that have not been. + */ + if (item->fix_fields_if_needed(thd, 0)) DBUG_RETURN(true); } } diff --git a/sql/table.cc b/sql/table.cc index 92e3d2e4800..98d299afb37 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -7219,6 +7219,12 @@ void TABLE::mark_columns_needed_for_update() } need_signal= true; } + else + { + if (found_next_number_field) + mark_auto_increment_column(); + } + if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) { /* |