diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-12-14 11:34:30 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-12-14 11:34:30 +0200 |
commit | 866ccc8890a3932e260e43fa5fc7ab8170e6cc3d (patch) | |
tree | 33a95867072308d4973d3a812bcc088dcbf55a64 /sql | |
parent | 159a6c2e608d04732cb678c7691345b9b1dc69b1 (diff) | |
parent | 1b5f0cbd465f92ffc278a924e765e41413d97420 (diff) | |
download | mariadb-git-866ccc8890a3932e260e43fa5fc7ab8170e6cc3d.tar.gz |
Merge bb-10.2-ext into 10.3
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 51 | ||||
-rw-r--r-- | sql/field.h | 4 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 6 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 34 | ||||
-rw-r--r-- | sql/item_strfunc.h | 8 | ||||
-rw-r--r-- | sql/sql_load.cc | 82 | ||||
-rw-r--r-- | sql/sql_show.cc | 1 |
7 files changed, 99 insertions, 87 deletions
diff --git a/sql/field.cc b/sql/field.cc index 51562dd4198..7d8f8a9af20 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1253,6 +1253,20 @@ warn: } +bool Field::load_data_set_null(THD *thd) +{ + reset(); + set_null(); + if (!maybe_null()) + { + if (this != table->next_number_field) + set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1); + } + set_has_explicit_value(); // Do not auto-update this field + return false; +} + + /** Numeric fields base class constructor. */ @@ -5152,6 +5166,27 @@ int Field_timestamp::set_time() return 0; } + +bool Field_timestamp::load_data_set_null(THD *thd) +{ + if (!maybe_null()) + { + /* + Timestamp fields that are NOT NULL are autoupdated if there is no + corresponding value in the data file. + */ + set_time(); + } + else + { + reset(); + set_null(); + } + set_has_explicit_value(); // Do not auto-update this field + return false; +} + + #ifdef NOT_USED static void store_native(ulonglong num, uchar *to, uint bytes) { @@ -8734,6 +8769,22 @@ bool Field_geom::can_optimize_range(const Item_bool_func *cond, return item->cmp_type() == STRING_RESULT; } + +bool Field_geom::load_data_set_null(THD *thd) +{ + Field_blob::reset(); + if (!maybe_null()) + { + my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field_name.str, + thd->get_stmt_da()->current_row_for_warning()); + return true; + } + set_null(); + set_has_explicit_value(); // Do not auto-update this field + return false; +} + + #endif /*HAVE_SPATIAL*/ /**************************************************************************** diff --git a/sql/field.h b/sql/field.h index eb6510bc9a4..624921b628e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1161,6 +1161,8 @@ public: { if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; } inline bool maybe_null(void) const { return null_ptr != 0 || table->maybe_null; } + // Set to NULL on LOAD DATA or LOAD XML + virtual bool load_data_set_null(THD *thd); /* @return true if this field is NULL-able (even if temporarily) */ inline bool real_maybe_null(void) const { return null_ptr != 0; } @@ -2457,6 +2459,7 @@ public: { return get_equal_const_item_datetime(thd, ctx, const_item); } + bool load_data_set_null(THD *thd); uint size_of() const { return sizeof(*this); } }; @@ -3649,6 +3652,7 @@ public: but the underlying blob must still be reset. */ int reset(void) { return Field_blob::reset() || !maybe_null(); } + bool load_data_set_null(THD *thd); geometry_type get_geometry_type() { return geom_type; }; static geometry_type geometry_type_merge(geometry_type, geometry_type); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 191616365fd..dff5fb5df0f 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -6960,20 +6960,20 @@ longlong Item_func_dyncol_exists::val_int() null_value= 1; return 1; } - if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci)) + if (my_charset_same(nm->charset(), DYNCOL_UTF)) { buf.str= (char *) nm->ptr(); buf.length= nm->length(); } else { - uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1; + uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1; uint dummy_errors; buf.str= (char *) current_thd->alloc(strlen); if (buf.str) { buf.length= - copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci, + copy_and_convert(buf.str, strlen, DYNCOL_UTF, nm->ptr(), nm->length(), nm->charset(), &dummy_errors); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 90bfb11e822..483a6468c2e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2918,6 +2918,20 @@ String *Item_func_make_set::val_str(String *str) } +void Item_func_char::print(String *str, enum_query_type query_type) +{ + str->append(Item_func_char::func_name()); + str->append('('); + print_args(str, 0, query_type); + if (collation.collation != &my_charset_bin) + { + str->append(C_STRING_WITH_LEN(" using ")); + str->append(collation.collation->csname); + } + str->append(')'); +} + + String *Item_func_char::val_str(String *str) { DBUG_ASSERT(fixed == 1); @@ -4517,20 +4531,19 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg) if (res) { // guaranty UTF-8 string for names - if (my_charset_same(res->charset(), &my_charset_utf8_general_ci)) + if (my_charset_same(res->charset(), DYNCOL_UTF)) { keys_str[i].length= res->length(); keys_str[i].str= thd->strmake(res->ptr(), res->length()); } else { - uint strlen= res->length() * my_charset_utf8_general_ci.mbmaxlen + 1; + uint strlen= res->length() * DYNCOL_UTF->mbmaxlen + 1; uint dummy_errors; - char *str= (char *) thd->alloc(strlen); - if (str) + if (char *str= (char *) thd->alloc(strlen)) { keys_str[i].length= - copy_and_convert(str, strlen, &my_charset_utf8_general_ci, + copy_and_convert(str, strlen, DYNCOL_UTF, res->ptr(), res->length(), res->charset(), &dummy_errors); keys_str[i].str= str; @@ -4750,9 +4763,10 @@ String *Item_func_dyncol_json::val_str(String *str) char *ptr; size_t length, alloc_length; dynstr_reassociate(&json, &ptr, &length, &alloc_length); - str->reset(ptr, length, alloc_length, &my_charset_utf8_general_ci); + str->reset(ptr, length, alloc_length, DYNCOL_UTF); null_value= FALSE; } + str->set_charset(DYNCOL_UTF); return str; null: @@ -4852,20 +4866,20 @@ bool Item_dyncol_get::get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val, return 1; } - if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci)) + if (my_charset_same(nm->charset(), DYNCOL_UTF)) { buf.str= (char *) nm->ptr(); buf.length= nm->length(); } else { - uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1; + uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1; uint dummy_errors; buf.str= (char *) thd->alloc(strlen); if (buf.str) { buf.length= - copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci, + copy_and_convert(buf.str, strlen, DYNCOL_UTF, nm->ptr(), nm->length(), nm->charset(), &dummy_errors); } @@ -5289,7 +5303,6 @@ String *Item_func_dyncol_list::val_str(String *str) goto null; str->length(0); - str->set_charset(&my_charset_utf8_general_ci); for (i= 0; i < count; i++) { append_identifier(current_thd, str, names[i].str, names[i].length); @@ -5299,6 +5312,7 @@ String *Item_func_dyncol_list::val_str(String *str) null_value= FALSE; if (names) my_free(names); + str->set_charset(DYNCOL_UTF); return str; null: diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 5b5826b4637..faad324403a 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -978,6 +978,7 @@ public: max_length= arg_count * 4; } const char *func_name() const { return "char"; } + void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) { return get_item_copy<Item_func_char>(thd, this); } }; @@ -1585,14 +1586,14 @@ public: class Item_func_dyncol_json: public Item_str_func { public: - Item_func_dyncol_json(THD *thd, Item *str): Item_str_func(thd, str) {} + Item_func_dyncol_json(THD *thd, Item *str): Item_str_func(thd, str) + {collation.set(DYNCOL_UTF);} const char *func_name() const{ return "column_json"; } String *val_str(String *); void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; maybe_null= 1; - collation.set(&my_charset_bin); decimals= 0; } Item *get_copy(THD *thd) @@ -1645,7 +1646,8 @@ public: class Item_func_dyncol_list: public Item_str_func { public: - Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str) {}; + Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str) + {collation.set(DYNCOL_UTF);} void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; }; const char *func_name() const{ return "column_list"; } String *val_str(String *); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index d972947c718..9a15d4b9c0d 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1015,7 +1015,6 @@ continue_loop:; } - static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, List<Item> &fields_vars, List<Item> &set_fields, @@ -1094,28 +1093,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, } else { - Field *field= real_item->field; - if (field->reset()) - { - my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name.str, - thd->get_stmt_da()->current_row_for_warning()); + DBUG_ASSERT(real_item->field->table == table); + if (real_item->field->load_data_set_null(thd)) DBUG_RETURN(1); - } - field->set_null(); - if (!field->maybe_null()) - { - /* - Timestamp fields that are NOT NULL are autoupdated if there is no - corresponding value in the data file. - */ - if (field->type() == MYSQL_TYPE_TIMESTAMP) - field->set_time(); - else if (field != table->next_number_field) - field->set_warning(Sql_condition::WARN_LEVEL_WARN, - ER_WARN_NULL_TO_NOTNULL, 1); - } - /* Do not auto-update this field. */ - field->set_has_explicit_value(); } continue; @@ -1262,6 +1242,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, for ( ; ; it.rewind()) { + bool err; if (thd->killed) { thd->send_kill_message(); @@ -1313,21 +1294,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, } else { - Field *field= real_item->field; - field->reset(); - field->set_null(); - if (field == table->next_number_field) - table->auto_increment_field_not_null= TRUE; - if (!field->maybe_null()) - { - if (field->type() == FIELD_TYPE_TIMESTAMP) - field->set_time(); - else if (field != table->next_number_field) - field->set_warning(Sql_condition::WARN_LEVEL_WARN, - ER_WARN_NULL_TO_NOTNULL, 1); - } - /* Do not auto-update this field. */ - field->set_has_explicit_value(); + DBUG_ASSERT(real_item->field->table == table); + if (real_item->field->load_data_set_null(thd)) + DBUG_RETURN(1); } continue; } @@ -1361,39 +1330,8 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, skip_lines--; continue; } - - if (item) - { - /* Have not read any field, thus input file is simply ended */ - if (item == fields_vars.head()) - break; - - for ( ; item; item= it++) - { - Item_field *real_item= item->field_for_view_update(); - if (item->type() == Item::STRING_ITEM) - ((Item_user_var_as_out_param *)item)->set_null_value(cs); - else if (!real_item) - { - my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name.str); - DBUG_RETURN(1); - } - else - { - /* - QQ: We probably should not throw warning for each field. - But how about intention to always have the same number - of warnings in THD::cuted_fields (and get rid of cuted_fields - in the end ?) - */ - thd->cuted_fields++; - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WARN_TOO_FEW_RECORDS, - ER_THD(thd, ER_WARN_TOO_FEW_RECORDS), - thd->get_stmt_da()->current_row_for_warning()); - } - } - } + + DBUG_ASSERT(!item); if (thd->killed || fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values, @@ -1410,7 +1348,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, DBUG_RETURN(-1); } - if (write_record(thd, table, &info)) + err= write_record(thd, table, &info); + table->auto_increment_field_not_null= false; + if (err) DBUG_RETURN(1); /* diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c374425f74a..8ac472bd626 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2791,6 +2791,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) { thd_info->proc_info= "Busy"; thd_info->progress= 0.0; + thd_info->db= ""; } thd_info->state_info= thread_state_info(tmp); |