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() ...@@ -4927,7 +4927,7 @@ int subselect_hash_sj_engine::exec()
if (has_covering_null_row) 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; count_pm_keys= 0;
} }
else if (has_covering_null_columns) else if (has_covering_null_columns)
......
...@@ -3656,7 +3656,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) ...@@ -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(STRING_WITH_LEN(" separator \'"));
str->append(*separator); str->append_for_single_quote(separator->ptr(), separator->length());
str->append(STRING_WITH_LEN("\')")); str->append(STRING_WITH_LEN("\')"));
} }
......
...@@ -2687,7 +2687,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, ...@@ -2687,7 +2687,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
LooseScan detector in best_access_path) LooseScan detector in best_access_path)
*/ */
remaining_tables &= ~new_join_tab->table->map; 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) if (idx == join->const_tables)
dups_producing_tables= 0; dups_producing_tables= 0;
...@@ -2698,7 +2699,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, ...@@ -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)) if ((emb_sj_nest= new_join_tab->emb_sj_nest))
dups_producing_tables |= emb_sj_nest->sj_inner_tables; 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) if (idx == join->const_tables)
{ {
/* First table, initialize pickers */ /* First table, initialize pickers */
...@@ -2750,23 +2751,54 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, ...@@ -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. 3. We have no clue what to do about fanount of semi-join Y.
*/ */
if ((dups_producing_tables & handled_fanout) || 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))) !(handled_fanout & pos->inner_tables_handled_with_other_sjs)))
{ {
/* Mark strategy as used */ DBUG_ASSERT(pos->sj_strategy != sj_strategy);
(*strategy)->mark_used(); /*
pos->sj_strategy= sj_strategy; If the strategy choosen first time or
if (sj_strategy == SJ_OPT_MATERIALIZE) the strategy replace strategy which was used to exectly the same
join->sjm_lookup_tables |= handled_fanout; 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 else
join->sjm_lookup_tables &= ~handled_fanout; {
*current_read_time= read_time; /* Conflict fall to most general variant */
*current_record_count= rec_count; (*prev_strategy)->set_empty();
dups_producing_tables &= ~handled_fanout; dups_producing_tables= prev_dups_producing_tables;
//TODO: update bitmap of semi-joins that were handled together with join->sjm_lookup_tables= prev_sjm_lookup_tables;
// others. // mark it 'none' to avpoid loops
if (is_multiple_semi_joins(join, join->positions, idx, handled_fanout)) pos->sj_strategy= SJ_OPT_NONE;
pos->inner_tables_handled_with_other_sjs |= handled_fanout; // next skip to last;
strategy= pickers +
(sizeof(pickers)/sizeof(Semi_join_strategy_picker*) - 3);
continue;
}
} }
else else
{ {
......
...@@ -2132,6 +2132,24 @@ bool partition_info::fix_column_value_functions(THD *thd, ...@@ -2132,6 +2132,24 @@ bool partition_info::fix_column_value_functions(THD *thd,
DBUG_RETURN(result); 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 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 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) ...@@ -2221,6 +2239,8 @@ int partition_info::fix_parser_data(THD *thd)
part_elem= it++; part_elem= it++;
List_iterator<part_elem_value> list_val_it(part_elem->list_val_list); List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
num_elements= part_elem->list_val_list.elements; num_elements= part_elem->list_val_list.elements;
if (!num_elements && error_if_requires_values())
DBUG_RETURN(true);
DBUG_ASSERT(part_type == RANGE_PARTITION ? DBUG_ASSERT(part_type == RANGE_PARTITION ?
num_elements == 1U : TRUE); num_elements == 1U : TRUE);
for (j= 0; j < num_elements; j++) for (j= 0; j < num_elements; j++)
......
...@@ -313,6 +313,7 @@ class partition_info : public Sql_alloc ...@@ -313,6 +313,7 @@ class partition_info : public Sql_alloc
void set_show_version_string(String *packet); void set_show_version_string(String *packet);
void report_part_expr_error(bool use_subpart_expr); void report_part_expr_error(bool use_subpart_expr);
bool has_same_partitioning(partition_info *new_part_info); bool has_same_partitioning(partition_info *new_part_info);
bool error_if_requires_values() const;
private: private:
static int list_part_cmp(const void* a, const void* b); static int list_part_cmp(const void* a, const void* b);
bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info, bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info,
......
...@@ -1825,28 +1825,28 @@ ER_WRONG_AUTO_KEY 42000 S1009 ...@@ -1825,28 +1825,28 @@ ER_WRONG_AUTO_KEY 42000 S1009
ER_UNUSED_2 ER_UNUSED_2
eng "You should never see it" eng "You should never see it"
ER_NORMAL_SHUTDOWN ER_NORMAL_SHUTDOWN
cze "%s: norm-Bální ukončení\n" cze "%s: norm-Bální ukončení"
dan "%s: Normal nedlukning\n" dan "%s: Normal nedlukning"
nla "%s: Normaal afgesloten \n" nla "%s: Normaal afgesloten"
eng "%s: Normal shutdown\n" eng "%s: Normal shutdown"
est "%s: MariaDB lõpetas\n" est "%s: MariaDB lõpetas"
fre "%s: Arrêt normal du serveur\n" fre "%s: Arrêt normal du serveur"
ger "%s: Normal heruntergefahren\n" ger "%s: Normal heruntergefahren"
greek "%s: Φυσιολογική διαδικασία shutdown\n" greek "%s: Φυσιολογική διαδικασία shutdown"
hun "%s: Normal leallitas\n" hun "%s: Normal leallitas"
ita "%s: Shutdown normale\n" ita "%s: Shutdown normale"
kor "%s: 정상적인 shutdown\n" kor "%s: 정상적인 shutdown"
nor "%s: Normal avslutning\n" nor "%s: Normal avslutning"
norwegian-ny "%s: Normal nedkopling\n" norwegian-ny "%s: Normal nedkopling"
pol "%s: Standardowe zakończenie działania\n" pol "%s: Standardowe zakończenie działania"
por "%s: 'Shutdown' normal\n" por "%s: 'Shutdown' normal"
rum "%s: Terminare normala\n" rum "%s: Terminare normala"
rus "%s: Корректная остановка\n" rus "%s: Корректная остановка"
serbian "%s: Normalno gašenje\n" serbian "%s: Normalno gašenje"
slo "%s: normálne ukončenie\n" slo "%s: normálne ukončenie"
spa "%s: Apagado normal\n" spa "%s: Apagado normal"
swe "%s: Normal avslutning\n" swe "%s: Normal avslutning"
ukr "%s: Нормальне завершення\n" ukr "%s: Нормальне завершення"
ER_GOT_SIGNAL ER_GOT_SIGNAL
cze "%s: p-Břijat signal %d, končím\n" cze "%s: p-Břijat signal %d, končím\n"
dan "%s: Fangede signal %d. Afslutter!!\n" dan "%s: Fangede signal %d. Afslutter!!\n"
......
...@@ -9550,7 +9550,17 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) ...@@ -9550,7 +9550,17 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
DBUG_PRINT("info",("Performing FULLTEXT search")); DBUG_PRINT("info",("Performing FULLTEXT search"));
while ((ifm=li++)) 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; return 0;
} }
......
...@@ -1184,7 +1184,11 @@ void Query_cache::end_of_result(THD *thd) ...@@ -1184,7 +1184,11 @@ void Query_cache::end_of_result(THD *thd)
#endif #endif
if (try_lock(thd, Query_cache::WAIT)) 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; DBUG_VOID_RETURN;
}
query_block= query_cache_tls->first_query_block; query_block= query_cache_tls->first_query_block;
if (query_block) if (query_block)
...@@ -1556,6 +1560,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", ...@@ -1556,6 +1560,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
unlock(); unlock();
DEBUG_SYNC(thd, "wait_in_query_cache_store_query");
// init_n_lock make query block locked // init_n_lock make query block locked
BLOCK_UNLOCK_WR(query_block); BLOCK_UNLOCK_WR(query_block);
} }
...@@ -1757,7 +1763,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) ...@@ -1757,7 +1763,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
sql++; sql++;
continue; continue;
} }
/* fall trough */ /* fall through */
default: default:
break; break;
} }
...@@ -2679,13 +2685,17 @@ void Query_cache::make_disabled() ...@@ -2679,13 +2685,17 @@ void Query_cache::make_disabled()
This function frees all resources allocated by the cache. You This function frees all resources allocated by the cache. You
have to call init_cache() before using the cache again. This function 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() void Query_cache::free_cache()
{ {
DBUG_ENTER("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 */ /* Destroy locks */
Query_cache_block *block= queries_blocks; Query_cache_block *block= queries_blocks;
if (block) if (block)
...@@ -2693,6 +2703,13 @@ void Query_cache::free_cache() ...@@ -2693,6 +2703,13 @@ void Query_cache::free_cache()
do do
{ {
Query_cache_query *query= block->query(); 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); mysql_rwlock_destroy(&query->lock);
block= block->next; block= block->next;
} while (block != queries_blocks); } while (block != queries_blocks);
......
...@@ -2192,6 +2192,8 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value, ...@@ -2192,6 +2192,8 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
MEM_ROOT *runtime_memroot) MEM_ROOT *runtime_memroot)
{ {
Item_change_record *change; 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, Now we use one node per change, which adds some memory overhead,
but still is rather fast as we use alloc_root for allocations. 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, ...@@ -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 OOM, thd->fatal_error() is called by the error handler of the
memroot. Just return. memroot. Just return.
*/ */
return; DBUG_VOID_RETURN;
} }
change= new (change_mem) Item_change_record; change= new (change_mem) Item_change_record;
change->place= place; change->place= place;
change->old_value= old_value; change->old_value= old_value;
change_list.append(change); change_list.append(change);
DBUG_VOID_RETURN;
} }
/** /**
...@@ -2250,7 +2253,11 @@ void THD::rollback_item_tree_changes() ...@@ -2250,7 +2253,11 @@ void THD::rollback_item_tree_changes()
DBUG_ENTER("rollback_item_tree_changes"); DBUG_ENTER("rollback_item_tree_changes");
while ((change= it++)) while ((change= it++))
{
DBUG_PRINT("info", ("revert %p -> %p",
change->old_value, (*change->place)));
*change->place= change->old_value; *change->place= change->old_value;
}
/* We can forget about changes memory: it's allocated in runtime memroot */ /* We can forget about changes memory: it's allocated in runtime memroot */
change_list.empty(); change_list.empty();
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
......
...@@ -991,6 +991,30 @@ typedef struct st_xid_state { ...@@ -991,6 +991,30 @@ typedef struct st_xid_state {
bool in_thd; bool in_thd;
/* Error reported by the Resource Manager (RM) to the Transaction Manager. */ /* Error reported by the Resource Manager (RM) to the Transaction Manager. */
uint rm_error; 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; } XID_STATE;
extern mysql_mutex_t LOCK_xid_cache; extern mysql_mutex_t LOCK_xid_cache;
......
...@@ -361,6 +361,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -361,6 +361,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
SELECT_LEX *parent_lex= derived->select_lex; SELECT_LEX *parent_lex= derived->select_lex;
Query_arena *arena, backup; Query_arena *arena, backup;
DBUG_ENTER("mysql_derived_merge"); DBUG_ENTER("mysql_derived_merge");
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
(derived->alias ? derived->alias : "<NULL>"),
derived->get_unit()));
if (derived->merged) if (derived->merged)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
...@@ -508,6 +511,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -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) bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
DBUG_ENTER("mysql_derived_merge_for_insert"); 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) if (derived->merged_for_insert)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
if (derived->init_derived(thd, FALSE)) if (derived->init_derived(thd, FALSE))
...@@ -554,6 +560,9 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -554,6 +560,9 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
SELECT_LEX_UNIT *unit= derived->get_unit(); SELECT_LEX_UNIT *unit= derived->get_unit();
DBUG_ENTER("mysql_derived_init"); 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 // Skip already prepared views/DT
if (!unit || unit->prepared) if (!unit || unit->prepared)
...@@ -624,7 +633,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -624,7 +633,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
SELECT_LEX_UNIT *unit= derived->get_unit(); SELECT_LEX_UNIT *unit= derived->get_unit();
DBUG_ENTER("mysql_derived_prepare"); DBUG_ENTER("mysql_derived_prepare");
bool res= FALSE; 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 // Skip already prepared views/DT
if (!unit || unit->prepared || if (!unit || unit->prepared ||
...@@ -781,6 +792,9 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -781,6 +792,9 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
bool res= FALSE; bool res= FALSE;
DBUG_ENTER("mysql_derived_optimize"); DBUG_ENTER("mysql_derived_optimize");
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
(derived->alias ? derived->alias : "<NULL>"),
derived->get_unit()));
if (unit->optimized) if (unit->optimized)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
...@@ -846,6 +860,9 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -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) bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
DBUG_ENTER("mysql_derived_create"); DBUG_ENTER("mysql_derived_create");
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
(derived->alias ? derived->alias : "<NULL>"),
derived->get_unit()));
TABLE *table= derived->table; TABLE *table= derived->table;
SELECT_LEX_UNIT *unit= derived->get_unit(); SELECT_LEX_UNIT *unit= derived->get_unit();
...@@ -895,9 +912,13 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -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) 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(); SELECT_LEX_UNIT *unit= derived->get_unit();
bool res= FALSE; 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) if (unit->executed && !unit->uncacheable && !unit->describe)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
...@@ -937,7 +958,27 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -937,7 +958,27 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
if (derived_result->flush()) if (derived_result->flush())
res= TRUE; res= TRUE;
unit->executed= 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) if (res || !lex->describe)
unit->cleanup(); unit->cleanup();
lex->current_select= save_current_select; lex->current_select= save_current_select;
...@@ -966,6 +1007,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -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) bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
DBUG_ENTER("mysql_derived_reinit"); 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(); st_select_lex_unit *unit= derived->get_unit();
if (derived->table) if (derived->table)
......
/* /*
Copyright (c) 2000, 2016, Oracle and/or its affiliates. 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 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 it under the terms of the GNU General Public License as published by
......
...@@ -394,7 +394,7 @@ void JOIN_CACHE::create_flag_fields() ...@@ -394,7 +394,7 @@ void JOIN_CACHE::create_flag_fields()
TABLE *table= tab->table; TABLE *table= tab->table;
/* Create a field for the null bitmap from table if needed */ /* 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, length+= add_flag_field_to_join_cache(table->null_flags,
table->s->null_bytes, table->s->null_bytes,
&copy); &copy);
......
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. /* 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 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 it under the terms of the GNU General Public License as published by
......
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. /* 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 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 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, ...@@ -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), my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
"LIST", "IN"); "LIST", "IN");
} }
else if (tab_part_info->part_type == RANGE_PARTITION)
{
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
"RANGE", "LESS THAN");
}
else else
{ {
DBUG_ASSERT(tab_part_info->part_type == LIST_PARTITION); DBUG_ASSERT(tab_part_info->part_type == RANGE_PARTITION ||
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), tab_part_info->part_type == LIST_PARTITION);
"LIST", "IN"); (void) tab_part_info->error_if_requires_values();
} }
goto err; goto err;
} }
......
/* Copyright (c) 2000, 2016 Oracle and/or its affiliates. /* 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 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 it under the terms of the GNU General Public License as published by
...@@ -11222,8 +11222,8 @@ static void update_depend_map(JOIN *join) ...@@ -11222,8 +11222,8 @@ static void update_depend_map(JOIN *join)
uint i; uint i;
for (i=0 ; i < ref->key_parts ; i++,item++) for (i=0 ; i < ref->key_parts ; i++,item++)
depend_map|=(*item)->used_tables(); depend_map|=(*item)->used_tables();
ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
depend_map&= ~OUTER_REF_TABLE_BIT; depend_map&= ~OUTER_REF_TABLE_BIT;
ref->depend_map= depend_map;
for (JOIN_TAB **tab=join->map2table; for (JOIN_TAB **tab=join->map2table;
depend_map ; depend_map ;
tab++,depend_map>>=1 ) tab++,depend_map>>=1 )
...@@ -13980,9 +13980,9 @@ bool cond_is_datetime_is_null(Item *cond) ...@@ -13980,9 +13980,9 @@ bool cond_is_datetime_is_null(Item *cond)
((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
{ {
Item **args= ((Item_func_isnull*) cond)->arguments(); 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) || if (((field->type() == MYSQL_TYPE_DATE) ||
(field->type() == MYSQL_TYPE_DATETIME)) && (field->type() == MYSQL_TYPE_DATETIME)) &&
...@@ -14308,14 +14308,14 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) ...@@ -14308,14 +14308,14 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
   
*/ */
Item **args= ((Item_func_isnull*) cond)->arguments(); 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 *item0= new(thd->mem_root) Item_int((longlong)0, 1);
Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0); Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0);
if (!eq_cond) if (!eq_cond)
return 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" // 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); 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, ...@@ -15537,7 +15537,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
else else
{ {
field->set_notnull(); 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] 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, ...@@ -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))) if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)))
DBUG_RETURN(0); DBUG_RETURN(0);
   
map&= ~const_tables;
while ((table= ti++) && !(map & table->table->map)) ; while ((table= ti++) && !(map & table->table->map)) ;
if (map != table->table->map) if (map != table->table->map)
DBUG_RETURN(0); // More than one table DBUG_RETURN(0); // More than one table
......
This diff is collapsed.
...@@ -4679,18 +4679,8 @@ opt_part_values: ...@@ -4679,18 +4679,8 @@ opt_part_values:
partition_info *part_info= lex->part_info; partition_info *part_info= lex->part_info;
if (! lex->is_partition_management()) if (! lex->is_partition_management())
{ {
if (part_info->part_type == RANGE_PARTITION) if (part_info->error_if_requires_values())
{ MYSQL_YYABORT;
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;
}
} }
else else
part_info->part_type= HASH_PARTITION; part_info->part_type= HASH_PARTITION;
......
...@@ -4108,6 +4108,9 @@ bool TABLE_LIST::create_field_translation(THD *thd) ...@@ -4108,6 +4108,9 @@ bool TABLE_LIST::create_field_translation(THD *thd)
Query_arena *arena, backup; Query_arena *arena, backup;
bool res= FALSE; bool res= FALSE;
DBUG_ENTER("TABLE_LIST::create_field_translation"); 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() || if (thd->stmt_arena->is_conventional() ||
thd->stmt_arena->is_stmt_prepare_or_first_sp_execute()) 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, ...@@ -5987,6 +5990,14 @@ void TABLE::create_key_part_by_field(KEY_PART_INFO *key_part_info,
might be reused. might be reused.
*/ */
key_part_info->store_length= key_part_info->length; 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 + 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