diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-01-19 19:22:00 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-01-19 19:22:00 +0200 |
commit | ff979674e689266590672268692d85275a323e18 (patch) | |
tree | ab7becd376adda341b65a1a43a96f78eec7a541c /sql | |
parent | 9007ca68738cb11b24854aa1bfa12dcd204a459d (diff) | |
parent | fafdac3365f4943e73bcefd0e0d07d69997a9724 (diff) | |
download | mariadb-git-ff979674e689266590672268692d85275a323e18.tar.gz |
Merge tag 'mariadb-5.5.59' into 5.5-galera
Diffstat (limited to 'sql')
-rw-r--r-- | sql/CMakeLists.txt | 2 | ||||
-rw-r--r-- | sql/field.cc | 6 | ||||
-rw-r--r-- | sql/field_conv.cc | 6 | ||||
-rw-r--r-- | sql/filesort.cc | 7 | ||||
-rw-r--r-- | sql/item.cc | 7 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 13 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 1 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 4 | ||||
-rw-r--r-- | sql/item_subselect.cc | 2 | ||||
-rw-r--r-- | sql/item_sum.cc | 2 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 64 | ||||
-rw-r--r-- | sql/partition_info.cc | 20 | ||||
-rw-r--r-- | sql/partition_info.h | 1 | ||||
-rw-r--r-- | sql/share/errmsg-utf8.txt | 44 | ||||
-rw-r--r-- | sql/sql_base.cc | 12 | ||||
-rw-r--r-- | sql/sql_cache.cc | 21 | ||||
-rw-r--r-- | sql/sql_class.cc | 9 | ||||
-rw-r--r-- | sql/sql_class.h | 24 | ||||
-rw-r--r-- | sql/sql_derived.cc | 48 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_join_cache.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_partition.cc | 11 | ||||
-rw-r--r-- | sql/sql_select.cc | 15 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 14 | ||||
-rw-r--r-- | sql/table.cc | 11 | ||||
-rw-r--r-- | sql/table.h | 6 | ||||
-rw-r--r-- | sql/transaction.cc | 12 | ||||
-rw-r--r-- | sql/unireg.cc | 42 |
31 files changed, 303 insertions, 111 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 7fcdf601d81..8a6f32797e7 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2006, 2014, Oracle and/or its affiliates. -# Copyright (c) 2010, 2015, MariaDB +# Copyright (c) 2010, 2018, MariaDB # # 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 diff --git a/sql/field.cc b/sql/field.cc index 08ba437fa30..5b111ab5e03 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1758,7 +1758,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) { uint store_length; copy->str= ptr; - copy->length= pack_length(); + copy->length= pack_length_in_rec(); copy->field= this; if (flags & BLOB_FLAG) { @@ -8422,7 +8422,7 @@ int Field_bit::cmp_max(const uchar *a, const uchar *b, uint max_len) if ((flag= (int) (bits_a - bits_b))) return flag; } - return memcmp(a, b, field_length); + return memcmp(a, b, bytes_in_rec); } @@ -8437,7 +8437,7 @@ int Field_bit::key_cmp(const uchar *str, uint length) str++; length--; } - return memcmp(ptr, str, length); + return memcmp(ptr, str, bytes_in_rec); } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 5781f1da576..09792aa1660 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -589,7 +589,7 @@ void Copy_field::set(uchar *to,Field *from) { from_ptr=from->ptr; to_ptr=to; - from_length=from->pack_length(); + from_length=from->pack_length_in_rec(); if (from->maybe_null()) { from_null_ptr=from->null_ptr; @@ -640,9 +640,9 @@ void Copy_field::set(Field *to,Field *from,bool save) from_field=from; to_field=to; from_ptr=from->ptr; - from_length=from->pack_length(); + from_length=from->pack_length_in_rec(); to_ptr= to->ptr; - to_length=to_field->pack_length(); + to_length=to_field->pack_length_in_rec(); // set up null handling from_null_ptr=to_null_ptr=0; diff --git a/sql/filesort.cc b/sql/filesort.cc index 38404b01cf7..5674786d8b2 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -210,7 +210,9 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, { ulonglong keys= memory_available / (param.rec_length + sizeof(char*)); table_sort.keys= (uint) min(num_rows, keys); - sort_buff_sz= table_sort.keys*(param.rec_length+sizeof(char*)); + /* Cast to size_t to avoid overflow when result is greater than uint. */ + sort_buff_sz= ((size_t)table_sort.keys) * + (param.rec_length + sizeof(char*)); set_if_bigger(sort_buff_sz, param.rec_length * MERGEBUFF2); DBUG_EXECUTE_IF("make_sort_keys_alloc_fail", @@ -914,7 +916,8 @@ static void make_sortkey(register SORTPARAM *param, if (maybe_null) *to++=1; char *tmp_buffer= param->tmp_buffer ? param->tmp_buffer : (char*)to; - String tmp(tmp_buffer, param->sort_length, cs); + String tmp(tmp_buffer, param->tmp_buffer ? param->sort_length : + sort_field->length, cs); String *res= item->str_result(&tmp); if (!res) { diff --git a/sql/item.cc b/sql/item.cc index fa2e52bfd4a..576dce78299 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB Corporation + Copyright (c) 2010, 2018, 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 @@ -4771,7 +4771,8 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && select->having_fix_field && - select_ref != not_found_item && !group_by_ref) + select_ref != not_found_item && !group_by_ref && + !ref->alias_name_used) { /* Report the error if fields was found only in the SELECT item list and @@ -8491,7 +8492,7 @@ Item *Item_default_value::transform(Item_transformer transformer, uchar *args) bool Item_insert_value::eq(const Item *item, bool binary_cmp) const { return item->type() == INSERT_VALUE_ITEM && - ((Item_default_value *)item)->arg->eq(arg, binary_cmp); + ((Item_insert_value *)item)->arg->eq(arg, binary_cmp); } diff --git a/sql/item.h b/sql/item.h index 4d0860af547..e01cf5384b9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2,7 +2,7 @@ #define SQL_ITEM_INCLUDED /* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB + Copyright (c) 2009, 2018, 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 diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index ebe088e5092..62e76922c0e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2001,6 +2001,19 @@ bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const } +bool Item_func_interval::fix_fields(THD *thd, Item **ref) +{ + if (Item_int_func::fix_fields(thd, ref)) + return true; + for (uint i= 0 ; i < row->cols(); i++) + { + if (row->element_index(i)->check_cols(1)) + return true; + } + return false; +} + + void Item_func_interval::fix_length_and_dec() { uint rows= row->cols(); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index a8befa47b95..7b7ca9223fd 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -728,6 +728,7 @@ public: { allowed_arg_cols= 0; // Fetch this value from first argument } + bool fix_fields(THD *, Item **); longlong val_int(); void fix_length_and_dec(); const char *func_name() const { return "interval"; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 939e518e386..a7ca21b79de 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB + Copyright (c) 2009, 2018, 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 @@ -265,9 +265,9 @@ String *Item_func_sha2::val_str_ascii(String *str) size_t input_len; uint digest_length= 0; + input_string= args[0]->val_str(str); str->set_charset(&my_charset_bin); - input_string= args[0]->val_str(str); if (input_string == NULL) { null_value= TRUE; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 90f2bd5b9eb..46d41fd61e3 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -4927,7 +4927,7 @@ int subselect_hash_sj_engine::exec() if (has_covering_null_row) { - DBUG_ASSERT(count_partial_match_columns = field_count); + DBUG_ASSERT(count_partial_match_columns == field_count); count_pm_keys= 0; } else if (has_covering_null_columns) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 9a2e2e6cd4c..709c2b6f7b5 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3656,7 +3656,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) } } str->append(STRING_WITH_LEN(" separator \'")); - str->append(*separator); + str->append_for_single_quote(separator->ptr(), separator->length()); str->append(STRING_WITH_LEN("\')")); } diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 69a5367cdf1..028bf44bf79 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -2687,7 +2687,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, LooseScan detector in best_access_path) */ remaining_tables &= ~new_join_tab->table->map; - table_map dups_producing_tables; + table_map dups_producing_tables, prev_dups_producing_tables, + prev_sjm_lookup_tables; if (idx == join->const_tables) dups_producing_tables= 0; @@ -2698,7 +2699,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, if ((emb_sj_nest= new_join_tab->emb_sj_nest)) dups_producing_tables |= emb_sj_nest->sj_inner_tables; - Semi_join_strategy_picker **strategy; + Semi_join_strategy_picker **strategy, **prev_strategy; if (idx == join->const_tables) { /* First table, initialize pickers */ @@ -2750,23 +2751,54 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, 3. We have no clue what to do about fanount of semi-join Y. */ if ((dups_producing_tables & handled_fanout) || - (read_time < *current_read_time && + (read_time < *current_read_time && !(handled_fanout & pos->inner_tables_handled_with_other_sjs))) { - /* Mark strategy as used */ - (*strategy)->mark_used(); - pos->sj_strategy= sj_strategy; - if (sj_strategy == SJ_OPT_MATERIALIZE) - join->sjm_lookup_tables |= handled_fanout; + DBUG_ASSERT(pos->sj_strategy != sj_strategy); + /* + If the strategy choosen first time or + the strategy replace strategy which was used to exectly the same + tables + */ + if (pos->sj_strategy == SJ_OPT_NONE || + handled_fanout == + (prev_dups_producing_tables ^ dups_producing_tables)) + { + prev_strategy= strategy; + if (pos->sj_strategy == SJ_OPT_NONE) + { + prev_dups_producing_tables= dups_producing_tables; + prev_sjm_lookup_tables= join->sjm_lookup_tables; + } + /* Mark strategy as used */ + (*strategy)->mark_used(); + pos->sj_strategy= sj_strategy; + if (sj_strategy == SJ_OPT_MATERIALIZE) + join->sjm_lookup_tables |= handled_fanout; + else + join->sjm_lookup_tables &= ~handled_fanout; + *current_read_time= read_time; + *current_record_count= rec_count; + dups_producing_tables &= ~handled_fanout; + //TODO: update bitmap of semi-joins that were handled together with + // others. + if (is_multiple_semi_joins(join, join->positions, idx, + handled_fanout)) + pos->inner_tables_handled_with_other_sjs |= handled_fanout; + } else - join->sjm_lookup_tables &= ~handled_fanout; - *current_read_time= read_time; - *current_record_count= rec_count; - dups_producing_tables &= ~handled_fanout; - //TODO: update bitmap of semi-joins that were handled together with - // others. - if (is_multiple_semi_joins(join, join->positions, idx, handled_fanout)) - pos->inner_tables_handled_with_other_sjs |= handled_fanout; + { + /* Conflict fall to most general variant */ + (*prev_strategy)->set_empty(); + dups_producing_tables= prev_dups_producing_tables; + join->sjm_lookup_tables= prev_sjm_lookup_tables; + // mark it 'none' to avpoid loops + pos->sj_strategy= SJ_OPT_NONE; + // next skip to last; + strategy= pickers + + (sizeof(pickers)/sizeof(Semi_join_strategy_picker*) - 3); + continue; + } } else { diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 512bf296135..740e5087477 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -2132,6 +2132,24 @@ end: DBUG_RETURN(result); } + +bool partition_info::error_if_requires_values() const +{ + switch (part_type) { + case NOT_A_PARTITION: + case HASH_PARTITION: + break; + case RANGE_PARTITION: + my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "RANGE", "LESS THAN"); + return true; + case LIST_PARTITION: + my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "LIST", "IN"); + return true; + } + return false; +} + + /* The parser generates generic data structures, we need to set them up as the rest of the code expects to find them. This is in reality part @@ -2221,6 +2239,8 @@ int partition_info::fix_parser_data(THD *thd) part_elem= it++; List_iterator<part_elem_value> list_val_it(part_elem->list_val_list); num_elements= part_elem->list_val_list.elements; + if (!num_elements && error_if_requires_values()) + DBUG_RETURN(true); DBUG_ASSERT(part_type == RANGE_PARTITION ? num_elements == 1U : TRUE); for (j= 0; j < num_elements; j++) diff --git a/sql/partition_info.h b/sql/partition_info.h index cff941a858a..779948eddc9 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -313,6 +313,7 @@ public: void set_show_version_string(String *packet); void report_part_expr_error(bool use_subpart_expr); bool has_same_partitioning(partition_info *new_part_info); + bool error_if_requires_values() const; private: static int list_part_cmp(const void* a, const void* b); bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info, diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 51a9f6e3847..57ff5902178 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -1825,28 +1825,28 @@ ER_WRONG_AUTO_KEY 42000 S1009 ER_UNUSED_2 eng "You should never see it" ER_NORMAL_SHUTDOWN - cze "%s: norm-Bální ukončení\n" - dan "%s: Normal nedlukning\n" - nla "%s: Normaal afgesloten \n" - eng "%s: Normal shutdown\n" - est "%s: MariaDB lõpetas\n" - fre "%s: Arrêt normal du serveur\n" - ger "%s: Normal heruntergefahren\n" - greek "%s: Φυσιολογική διαδικασία shutdown\n" - hun "%s: Normal leallitas\n" - ita "%s: Shutdown normale\n" - kor "%s: 정상적인 shutdown\n" - nor "%s: Normal avslutning\n" - norwegian-ny "%s: Normal nedkopling\n" - pol "%s: Standardowe zakończenie działania\n" - por "%s: 'Shutdown' normal\n" - rum "%s: Terminare normala\n" - rus "%s: Корректная остановка\n" - serbian "%s: Normalno gašenje\n" - slo "%s: normálne ukončenie\n" - spa "%s: Apagado normal\n" - swe "%s: Normal avslutning\n" - ukr "%s: Нормальне завершення\n" + cze "%s: norm-Bální ukončení" + dan "%s: Normal nedlukning" + nla "%s: Normaal afgesloten" + eng "%s: Normal shutdown" + est "%s: MariaDB lõpetas" + fre "%s: Arrêt normal du serveur" + ger "%s: Normal heruntergefahren" + greek "%s: Φυσιολογική διαδικασία shutdown" + hun "%s: Normal leallitas" + ita "%s: Shutdown normale" + kor "%s: 정상적인 shutdown" + nor "%s: Normal avslutning" + norwegian-ny "%s: Normal nedkopling" + pol "%s: Standardowe zakończenie działania" + por "%s: 'Shutdown' normal" + rum "%s: Terminare normala" + rus "%s: Корректная остановка" + serbian "%s: Normalno gašenje" + slo "%s: normálne ukončenie" + spa "%s: Apagado normal" + swe "%s: Normal avslutning" + ukr "%s: Нормальне завершення" ER_GOT_SIGNAL cze "%s: p-Břijat signal %d, končím\n" dan "%s: Fangede signal %d. Afslutter!!\n" diff --git a/sql/sql_base.cc b/sql/sql_base.cc index bc89c2fbf2d..b1979de36e6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9610,7 +9610,17 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) DBUG_PRINT("info",("Performing FULLTEXT search")); while ((ifm=li++)) - ifm->init_search(no_order); +#if MYSQL_VERSION_ID < 100213 + if (unlikely(!ifm->fixed)) + /* + it mean that clause where was FT function was removed, so we have + to remove the function from the list. + */ + li.remove(); + else +#endif + ifm->init_search(no_order); + } return 0; } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8794cdb2a45..2a03b13aa75 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1184,7 +1184,11 @@ void Query_cache::end_of_result(THD *thd) #endif if (try_lock(thd, Query_cache::WAIT)) + { + if (is_disabled()) + query_cache_tls->first_query_block= NULL; // do not try again with QC DBUG_VOID_RETURN; + } query_block= query_cache_tls->first_query_block; if (query_block) @@ -1556,6 +1560,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", unlock(); + DEBUG_SYNC(thd, "wait_in_query_cache_store_query"); + // init_n_lock make query block locked BLOCK_UNLOCK_WR(query_block); } @@ -1757,7 +1763,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) sql++; continue; } - /* fall trough */ + /* fall through */ default: break; } @@ -2699,13 +2705,17 @@ void Query_cache::make_disabled() This function frees all resources allocated by the cache. You have to call init_cache() before using the cache again. This function - requires the structure_guard_mutex to be locked. + requires the cache to be locked (LOCKED_NO_WAIT, lock_and_suspend) or + disabling. */ void Query_cache::free_cache() { DBUG_ENTER("Query_cache::free_cache"); + DBUG_ASSERT(m_cache_lock_status == LOCKED_NO_WAIT || + m_cache_status == DISABLE_REQUEST); + /* Destroy locks */ Query_cache_block *block= queries_blocks; if (block) @@ -2713,6 +2723,13 @@ void Query_cache::free_cache() do { Query_cache_query *query= block->query(); + /* + There will not be new requests but some maybe not finished yet, + so wait for them by trying lock/unlock + */ + BLOCK_LOCK_WR(block); + BLOCK_UNLOCK_WR(block); + mysql_rwlock_destroy(&query->lock); block= block->next; } while (block != queries_blocks); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index fcba6661410..883f0c9cc88 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2441,6 +2441,8 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value, MEM_ROOT *runtime_memroot) { Item_change_record *change; + DBUG_ENTER("THD::nocheck_register_item_tree_change"); + DBUG_PRINT("enter", ("Register %p <- %p", old_value, (*place))); /* Now we use one node per change, which adds some memory overhead, but still is rather fast as we use alloc_root for allocations. @@ -2453,12 +2455,13 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value, OOM, thd->fatal_error() is called by the error handler of the memroot. Just return. */ - return; + DBUG_VOID_RETURN; } change= new (change_mem) Item_change_record; change->place= place; change->old_value= old_value; change_list.append(change); + DBUG_VOID_RETURN; } /** @@ -2499,7 +2502,11 @@ void THD::rollback_item_tree_changes() DBUG_ENTER("rollback_item_tree_changes"); while ((change= it++)) + { + DBUG_PRINT("info", ("revert %p -> %p", + change->old_value, (*change->place))); *change->place= change->old_value; + } /* We can forget about changes memory: it's allocated in runtime memroot */ change_list.empty(); DBUG_VOID_RETURN; diff --git a/sql/sql_class.h b/sql/sql_class.h index 70bf6f7783d..2bb2b12aebe 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1011,6 +1011,30 @@ typedef struct st_xid_state { bool in_thd; /* Error reported by the Resource Manager (RM) to the Transaction Manager. */ uint rm_error; + + /** + Check that XA transaction has an uncommitted work. Report an error + to the user in case when there is an uncommitted work for XA transaction. + + @return result of check + @retval false XA transaction is NOT in state IDLE, PREPARED + or ROLLBACK_ONLY. + @retval true XA transaction is in state IDLE or PREPARED + or ROLLBACK_ONLY. + */ + + bool check_has_uncommitted_xa() const + { + if (xa_state == XA_IDLE || + xa_state == XA_PREPARED || + xa_state == XA_ROLLBACK_ONLY) + { + my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]); + return true; + } + return false; + } + } XID_STATE; extern mysql_mutex_t LOCK_xid_cache; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 6cd4547aaf9..2a6d82c161a 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -361,6 +361,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) SELECT_LEX *parent_lex= derived->select_lex; Query_arena *arena, backup; DBUG_ENTER("mysql_derived_merge"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); if (derived->merged) DBUG_RETURN(FALSE); @@ -508,6 +511,9 @@ unconditional_materialization: bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) { DBUG_ENTER("mysql_derived_merge_for_insert"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); if (derived->merged_for_insert) DBUG_RETURN(FALSE); if (derived->init_derived(thd, FALSE)) @@ -554,6 +560,9 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived) { SELECT_LEX_UNIT *unit= derived->get_unit(); DBUG_ENTER("mysql_derived_init"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); // Skip already prepared views/DT if (!unit || unit->prepared) @@ -624,7 +633,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) SELECT_LEX_UNIT *unit= derived->get_unit(); DBUG_ENTER("mysql_derived_prepare"); bool res= FALSE; - DBUG_PRINT("enter", ("unit 0x%lx", (ulong) unit)); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); // Skip already prepared views/DT if (!unit || unit->prepared || @@ -781,6 +792,9 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) bool res= FALSE; DBUG_ENTER("mysql_derived_optimize"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); if (unit->optimized) DBUG_RETURN(FALSE); @@ -846,6 +860,9 @@ err: bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) { DBUG_ENTER("mysql_derived_create"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); TABLE *table= derived->table; SELECT_LEX_UNIT *unit= derived->get_unit(); @@ -895,9 +912,13 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) { - DBUG_ENTER("mysql_derived_fill"); + Field_iterator_table field_iterator; SELECT_LEX_UNIT *unit= derived->get_unit(); bool res= FALSE; + DBUG_ENTER("mysql_derived_fill"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); if (unit->executed && !unit->uncacheable && !unit->describe) DBUG_RETURN(FALSE); @@ -937,7 +958,27 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) if (derived_result->flush()) res= TRUE; unit->executed= TRUE; + + if (derived->field_translation) + { + /* reset translation table to materialized table */ + field_iterator.set_table(derived->table); + for (uint i= 0; + !field_iterator.end_of_fields(); + field_iterator.next(), i= i + 1) + { + Item *item; + + if (!(item= field_iterator.create_item(thd))) + { + res= TRUE; + break; + } + thd->change_item_tree(&derived->field_translation[i].item, item); + } + } } + if (res || !lex->describe) unit->cleanup(); lex->current_select= save_current_select; @@ -966,6 +1007,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) { DBUG_ENTER("mysql_derived_reinit"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); st_select_lex_unit *unit= derived->get_unit(); if (derived->table) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 074ea6e8f71..64c9497fb7d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2016, MariaDB + Copyright (c) 2010, 2018, 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 diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 820ac75c885..13f06024b22 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -394,7 +394,7 @@ void JOIN_CACHE::create_flag_fields() TABLE *table= tab->table; /* Create a field for the null bitmap from table if needed */ - if (tab->used_null_fields || tab->used_uneven_bit_fields) + if (tab->used_null_fields || tab->used_uneven_bit_fields) length+= add_flag_field_to_join_cache(table->null_flags, table->s->null_bytes, ©); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2c4926cf498..beabae844f1 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + Copyright (c) 2009, 2018, 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 diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 3dcf8769c14..cf34c567626 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2016, MariaDB + Copyright (c) 2010, 2018, 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 diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index ab31a8c1791..01dcc7cc2ac 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -4770,16 +4770,11 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), "LIST", "IN"); } - else if (tab_part_info->part_type == RANGE_PARTITION) - { - my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), - "RANGE", "LESS THAN"); - } else { - DBUG_ASSERT(tab_part_info->part_type == LIST_PARTITION); - my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), - "LIST", "IN"); + DBUG_ASSERT(tab_part_info->part_type == RANGE_PARTITION || + tab_part_info->part_type == LIST_PARTITION); + (void) tab_part_info->error_if_requires_values(); } goto err; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c7f547edbc0..9f89a261540 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016 Oracle and/or its affiliates. - Copyright (c) 2009, 2016 MariaDB + Copyright (c) 2009, 2018 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 @@ -11222,8 +11222,8 @@ static void update_depend_map(JOIN *join) uint i; for (i=0 ; i < ref->key_parts ; i++,item++) depend_map|=(*item)->used_tables(); - ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT; depend_map&= ~OUTER_REF_TABLE_BIT; + ref->depend_map= depend_map; for (JOIN_TAB **tab=join->map2table; depend_map ; tab++,depend_map>>=1 ) @@ -13980,9 +13980,9 @@ bool cond_is_datetime_is_null(Item *cond) ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) { Item **args= ((Item_func_isnull*) cond)->arguments(); - if (args[0]->type() == Item::FIELD_ITEM) + if (args[0]->real_item()->type() == Item::FIELD_ITEM) { - Field *field=((Item_field*) args[0])->field; + Field *field=((Item_field*) (args[0]->real_item()))->field; if (((field->type() == MYSQL_TYPE_DATE) || (field->type() == MYSQL_TYPE_DATETIME)) && @@ -14308,14 +14308,14 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) */ Item **args= ((Item_func_isnull*) cond)->arguments(); - Field *field=((Item_field*) args[0])->field; + Field *field=((Item_field*) (args[0]->real_item()))->field; Item *item0= new(thd->mem_root) Item_int((longlong)0, 1); Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0); if (!eq_cond) return cond; - if (field->table->pos_in_table_list->is_inner_table_of_outer_join()) + if (field->table->pos_in_table_list->is_inner_table_of_outer_join()) { // outer join: transform "col IS NULL" to "col IS NULL or col=0" Item *or_cond= new(thd->mem_root) Item_cond_or(eq_cond, cond); @@ -15537,7 +15537,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, else { field->set_notnull(); - memcpy(field->ptr, orig_field->ptr, field->pack_length()); + memcpy(field->ptr, orig_field->ptr, field->pack_length_in_rec()); } orig_field->move_field_offset(-diff); // Back to record[0] } @@ -21159,6 +21159,7 @@ get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables, if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))) DBUG_RETURN(0); + map&= ~const_tables; while ((table= ti++) && !(map & table->table->map)) ; if (map != table->table->map) DBUG_RETURN(0); // More than one table diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e0a6b155074..8dd38e286b2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4679,18 +4679,8 @@ opt_part_values: partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->part_type == RANGE_PARTITION) - { - my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), - "RANGE", "LESS THAN"); - MYSQL_YYABORT; - } - if (part_info->part_type == LIST_PARTITION) - { - my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), - "LIST", "IN"); - MYSQL_YYABORT; - } + if (part_info->error_if_requires_values()) + MYSQL_YYABORT; } else part_info->part_type= HASH_PARTITION; diff --git a/sql/table.cc b/sql/table.cc index 0c6e02b7a5c..5db14599adc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4117,6 +4117,9 @@ bool TABLE_LIST::create_field_translation(THD *thd) Query_arena *arena, backup; bool res= FALSE; DBUG_ENTER("TABLE_LIST::create_field_translation"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (alias ? alias : "<NULL>"), + get_unit())); if (thd->stmt_arena->is_conventional() || thd->stmt_arena->is_stmt_prepare_or_first_sp_execute()) @@ -5996,6 +5999,14 @@ void TABLE::create_key_part_by_field(KEY_PART_INFO *key_part_info, might be reused. */ key_part_info->store_length= key_part_info->length; + /* + For BIT fields null_bit is not set to 0 even if the field is defined + as NOT NULL, look at Field_bit::Field_bit + */ + if (!field->real_maybe_null()) + { + key_part_info->null_bit= 0; + } /* The total store length of the key part is the raw length of the field + diff --git a/sql/table.h b/sql/table.h index c981243f28c..98f8c7ad73f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2107,6 +2107,9 @@ struct TABLE_LIST inline void set_merged_derived() { DBUG_ENTER("set_merged_derived"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (alias ? alias : "<NULL>"), + get_unit())); derived_type= ((derived_type & DTYPE_MASK) | DTYPE_TABLE | DTYPE_MERGE); set_check_merged(); @@ -2119,6 +2122,9 @@ struct TABLE_LIST void set_materialized_derived() { DBUG_ENTER("set_materialized_derived"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (alias ? alias : "<NULL>"), + get_unit())); derived_type= ((derived_type & (derived ? DTYPE_MASK : DTYPE_VIEW)) | DTYPE_TABLE | DTYPE_MATERIALIZE); set_check_materialized(); diff --git a/sql/transaction.cc b/sql/transaction.cc index c293c651c04..56345748fd6 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -481,12 +481,8 @@ bool trans_savepoint(THD *thd, LEX_STRING name) !opt_using_transactions) DBUG_RETURN(FALSE); - enum xa_states xa_state= thd->transaction.xid_state.xa_state; - if (xa_state != XA_NOTR && xa_state != XA_ACTIVE) - { - my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]); + if (thd->transaction.xid_state.check_has_uncommitted_xa()) DBUG_RETURN(TRUE); - } sv= find_savepoint(thd, name); @@ -561,12 +557,8 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_STRING name) DBUG_RETURN(TRUE); } - enum xa_states xa_state= thd->transaction.xid_state.xa_state; - if (xa_state != XA_NOTR) - { - my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]); + if (thd->transaction.xid_state.check_has_uncommitted_xa()) DBUG_RETURN(TRUE); - } if (ha_rollback_to_savepoint(thd, sv)) res= TRUE; diff --git a/sql/unireg.cc b/sql/unireg.cc index 528c3025c57..936203a78ab 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, 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 @@ -90,6 +91,28 @@ handle_condition(THD *, } /* + In ALTER TABLE, mysql_create_frm() gets the temporary table name, + like #sql-3696_2. It's used for error messages, when a table cannot + be created because of some OS error. + If there's a user error (like, too long comment), we want to show + the real table name, though. +*/ +static const char *get_real_table_name(const char *table, + List<Create_field> &fields) +{ + const char *real_table_name= table; + List_iterator<Create_field> it(fields); + Create_field *field; + while ((field=it++)) + { + if (field->field && field->field->table && + (real_table_name= field->field->table->s->table_name.str)) + break; + } + return real_table_name; +} + +/* Create a frm (table definition) file SYNOPSIS @@ -232,15 +255,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, if (tmp_len < create_info->comment.length) { - char *real_table_name= (char*) table; - List_iterator<Create_field> it(create_fields); - Create_field *field; - while ((field=it++)) - { - if (field->field && field->field->table && - (real_table_name= field->field->table->s->table_name.str)) - break; - } + const char *real_table_name= get_real_table_name(table, create_fields); if ((thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { @@ -285,6 +300,15 @@ bool mysql_create_frm(THD *thd, const char *file_name, keybuff=(uchar*) my_malloc(key_buff_length, MYF(0)); key_info_length= pack_keys(keybuff, keys, key_info, data_offset); + if (key_info_length > UINT_MAX16) + { + my_printf_error(ER_CANT_CREATE_TABLE, + "Cannot create table %`s.%`s: index information is too long. " + "Decrease number of indexes or use shorter index names or shorter comments.", + MYF(0), db, get_real_table_name(table, create_fields)); + goto err; + } + /* Ensure that there are no forms in this newly created form file. Even if the form file exists, create_frm must truncate it to |