Commit 050dd45b authored by Otto Kekäläinen's avatar Otto Kekäläinen
Browse files

New upstream version 5.5.59

parent f06c422f
......@@ -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)
......
......@@ -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("\')"));
}
......
......@@ -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 */
......@@ -2753,6 +2754,22 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
(read_time < *current_read_time &&
!(handled_fanout & pos->inner_tables_handled_with_other_sjs)))
{
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;
......@@ -2765,10 +2782,25 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
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))
if (is_multiple_semi_joins(join, join->positions, idx,
handled_fanout))
pos->inner_tables_handled_with_other_sjs |= handled_fanout;
}
else
{
/* 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
{
/* We decided not to apply the strategy. */
(*strategy)->set_empty();
......
......@@ -2132,6 +2132,24 @@ bool partition_info::fix_column_value_functions(THD *thd,
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++)
......
......@@ -313,6 +313,7 @@ class partition_info : public Sql_alloc
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,
......
......@@ -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"
......
......@@ -9550,7 +9550,17 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
DBUG_PRINT("info",("Performing FULLTEXT search"));
while ((ifm=li++))
#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;
}
......
......@@ -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;
}
......@@ -2679,13 +2685,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)
......@@ -2693,6 +2703,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);
......
......@@ -2192,6 +2192,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.
......@@ -2204,12 +2206,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;
}
/**
......@@ -2250,7 +2253,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;
......
......@@ -991,6 +991,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;
......
......@@ -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 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
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 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
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)
......
/*
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
......
/* 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
......
/* 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
......
......@@ -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;
}
......
/* 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,7 +14308,7 @@ 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);
......@@ -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
......
This diff is collapsed.
......@@ -4679,19 +4679,9 @@ 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");
if (part_info->error_if_requires_values())
MYSQL_YYABORT;
}
if (part_info->part_type == LIST_PARTITION)
{
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
"LIST", "IN");
MYSQL_YYABORT;
}
}
else
part_info->part_type= HASH_PARTITION;
}
......
......@@ -4108,6 +4108,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())
......@@ -5987,6 +5990,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 +
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment