Commit 4d305fb9 authored by Otto Kekäläinen's avatar Otto Kekäläinen
Browse files

Imported Upstream version 5.5.52

parent 95c6357a
...@@ -33,8 +33,8 @@ insert into t2 select ...@@ -33,8 +33,8 @@ insert into t2 select
from t1 A, t1 B, t1 C; from t1 A, t1 B, t1 C;
explain explain
select count(length(a) + length(filler)) from t2 where a>='a-1000-a' and a <'a-1001-a'; select count(length(a) + length(filler)) from t2 force index (a) where a>='a-1000-a' and a <'a-1001-a';
select count(length(a) + length(filler)) from t2 where a>='a-1000-a' and a <'a-1001-a'; select count(length(a) + length(filler)) from t2 force index (a) where a>='a-1000-a' and a <'a-1001-a';
drop table t2; drop table t2;
# Try a very big rowid # Try a very big rowid
......
...@@ -698,30 +698,27 @@ my_context_destroy(struct my_context *c) ...@@ -698,30 +698,27 @@ my_context_destroy(struct my_context *c)
int int
my_context_spawn(struct my_context *c, void (*f)(void *), void *d) my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
{ {
void *current_fiber;
c->user_func= f; c->user_func= f;
c->user_arg= d; c->user_arg= d;
return my_context_continue(c);
}
int
my_context_continue(struct my_context *c)
{
/* /*
This seems to be a common trick to run ConvertThreadToFiber() only on the This seems to be a common trick to run ConvertThreadToFiber() only on the
first occurence in a thread, in a way that works on multiple Windows first occurence in a thread, in a way that works on multiple Windows
versions. versions.
*/ */
current_fiber= GetCurrentFiber(); void *current_fiber= GetCurrentFiber();
if (current_fiber == NULL || current_fiber == (void *)0x1e00) if (current_fiber == NULL || current_fiber == (void *)0x1e00)
current_fiber= ConvertThreadToFiber(c); current_fiber= ConvertThreadToFiber(c);
c->app_fiber= current_fiber; c->app_fiber= current_fiber;
DBUG_SWAP_CODE_STATE(&c->dbug_state); DBUG_SWAP_CODE_STATE(&c->dbug_state);
SwitchToFiber(c->lib_fiber); SwitchToFiber(c->lib_fiber);
DBUG_SWAP_CODE_STATE(&c->dbug_state); DBUG_SWAP_CODE_STATE(&c->dbug_state);
return c->return_value;
}
int
my_context_continue(struct my_context *c)
{
DBUG_SWAP_CODE_STATE(&c->dbug_state);
SwitchToFiber(c->lib_fiber);
DBUG_SWAP_CODE_STATE(&c->dbug_state);
return c->return_value; return c->return_value;
} }
......
/* /* Copyright (c) 2000, 2010, Oracle and/or its affiliates
Copyright (c) 2000, 2010, Oracle and/or its affiliates Copyright (c) 2009, 2016, MariaDB
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
...@@ -49,7 +49,8 @@ int my_redel(const char *org_name, const char *tmp_name, ...@@ -49,7 +49,8 @@ int my_redel(const char *org_name, const char *tmp_name,
DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d", DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d",
org_name,tmp_name,MyFlags)); org_name,tmp_name,MyFlags));
if (my_copystat(org_name,tmp_name,MyFlags) < 0) if (!my_disable_copystat_in_redel &&
my_copystat(org_name,tmp_name,MyFlags) < 0)
goto end; goto end;
if (MyFlags & MY_REDEL_MAKE_BACKUP) if (MyFlags & MY_REDEL_MAKE_BACKUP)
{ {
......
...@@ -99,6 +99,7 @@ my_bool my_disable_sync=0; ...@@ -99,6 +99,7 @@ my_bool my_disable_sync=0;
my_bool my_disable_async_io=0; my_bool my_disable_async_io=0;
my_bool my_disable_flush_key_blocks=0; my_bool my_disable_flush_key_blocks=0;
my_bool my_disable_symlinks=0; my_bool my_disable_symlinks=0;
my_bool my_disable_copystat_in_redel=0;
/* /*
Note that PSI_hook and PSI_server are unconditionally Note that PSI_hook and PSI_server are unconditionally
......
...@@ -190,6 +190,7 @@ int Url_http::send(const char* data, size_t data_length) ...@@ -190,6 +190,7 @@ int Url_http::send(const char* data, size_t data_length)
break; break;
closesocket(fd); closesocket(fd);
fd= INVALID_SOCKET;
} }
freeaddrinfo(addrs); freeaddrinfo(addrs);
......
...@@ -159,6 +159,10 @@ char *argv[]; ...@@ -159,6 +159,10 @@ char *argv[];
if (argc > 4) if (argc > 4)
for (n = atoi(argv[3]); n > 0; n--) { for (n = atoi(argv[3]); n > 0; n--) {
if(sizeof(buf)-1 < strlen(argv[1]))
{
exit(EXIT_FAILURE);
}
(void) strcpy(buf, argv[1]); (void) strcpy(buf, argv[1]);
} }
else if (argc > 3) else if (argc > 3)
......
...@@ -217,7 +217,7 @@ sub remove_remote_root { ...@@ -217,7 +217,7 @@ sub remove_remote_root {
sub remove_test_database { sub remove_test_database {
print " - Dropping test database...\n"; print " - Dropping test database...\n";
if (do_query("DROP DATABASE test;")) { if (do_query("DROP DATABASE IF EXISTS test;")) {
print " ... Success!\n"; print " ... Success!\n";
} else { } else {
print " ... Failed! Not critical, keep moving...\n"; print " ... Failed! Not critical, keep moving...\n";
......
...@@ -324,7 +324,7 @@ remove_remote_root() { ...@@ -324,7 +324,7 @@ remove_remote_root() {
remove_test_database() { remove_test_database() {
echo " - Dropping test database..." echo " - Dropping test database..."
do_query "DROP DATABASE test;" do_query "DROP DATABASE IF EXISTS test;"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo " ... Success!" echo " ... Success!"
else else
......
...@@ -131,12 +131,6 @@ post_init_event_thread(THD *thd) ...@@ -131,12 +131,6 @@ post_init_event_thread(THD *thd)
thd->cleanup(); thd->cleanup();
return TRUE; return TRUE;
} }
mysql_mutex_lock(&LOCK_thread_count);
threads.append(thd);
thread_count++;
inc_thread_running();
mysql_mutex_unlock(&LOCK_thread_count);
return FALSE; return FALSE;
} }
...@@ -158,7 +152,6 @@ deinit_event_thread(THD *thd) ...@@ -158,7 +152,6 @@ deinit_event_thread(THD *thd)
DBUG_PRINT("exit", ("Event thread finishing")); DBUG_PRINT("exit", ("Event thread finishing"));
mysql_mutex_lock(&LOCK_thread_count); mysql_mutex_lock(&LOCK_thread_count);
thread_count--; thread_count--;
dec_thread_running();
delete thd; delete thd;
mysql_cond_broadcast(&COND_thread_count); mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count); mysql_mutex_unlock(&LOCK_thread_count);
...@@ -195,6 +188,8 @@ pre_init_event_thread(THD* thd) ...@@ -195,6 +188,8 @@ pre_init_event_thread(THD* thd)
thd->client_capabilities|= CLIENT_MULTI_RESULTS; thd->client_capabilities|= CLIENT_MULTI_RESULTS;
mysql_mutex_lock(&LOCK_thread_count); mysql_mutex_lock(&LOCK_thread_count);
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
threads.append(thd);
thread_count++;
mysql_mutex_unlock(&LOCK_thread_count); mysql_mutex_unlock(&LOCK_thread_count);
/* /*
...@@ -241,13 +236,8 @@ event_scheduler_thread(void *arg) ...@@ -241,13 +236,8 @@ event_scheduler_thread(void *arg)
my_free(arg); my_free(arg);
if (!res) if (!res)
scheduler->run(thd); scheduler->run(thd);
else
{
thd->proc_info= "Clearing";
net_end(&thd->net);
delete thd;
}
deinit_event_thread(thd);
DBUG_LEAVE; // Against gcc warnings DBUG_LEAVE; // Against gcc warnings
my_thread_end(); my_thread_end();
return 0; return 0;
...@@ -308,6 +298,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) ...@@ -308,6 +298,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
DBUG_ENTER("Event_worker_thread::run"); DBUG_ENTER("Event_worker_thread::run");
DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd)); DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd));
inc_thread_running();
if (res) if (res)
goto end; goto end;
...@@ -334,6 +325,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) ...@@ -334,6 +325,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
event->name.str)); event->name.str));
delete event; delete event;
dec_thread_running();
deinit_event_thread(thd); deinit_event_thread(thd);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -432,13 +424,9 @@ Event_scheduler::start(int *err_no) ...@@ -432,13 +424,9 @@ Event_scheduler::start(int *err_no)
" Can not create thread for event scheduler (errno=%d)", " Can not create thread for event scheduler (errno=%d)",
*err_no); *err_no);
new_thd->proc_info= "Clearing";
DBUG_ASSERT(new_thd->net.buff != 0);
net_end(&new_thd->net);
state= INITIALIZED; state= INITIALIZED;
scheduler_thd= NULL; scheduler_thd= NULL;
delete new_thd; deinit_event_thread(new_thd);
delete scheduler_param_value; delete scheduler_param_value;
ret= true; ret= true;
...@@ -505,7 +493,6 @@ Event_scheduler::run(THD *thd) ...@@ -505,7 +493,6 @@ Event_scheduler::run(THD *thd)
} }
LOCK_DATA(); LOCK_DATA();
deinit_event_thread(thd);
scheduler_thd= NULL; scheduler_thd= NULL;
state= INITIALIZED; state= INITIALIZED;
DBUG_PRINT("info", ("Broadcasting COND_state back to the stoppers")); DBUG_PRINT("info", ("Broadcasting COND_state back to the stoppers"));
...@@ -564,10 +551,7 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) ...@@ -564,10 +551,7 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
sql_print_error("Event_scheduler::execute_top: Can not create event worker" sql_print_error("Event_scheduler::execute_top: Can not create event worker"
" thread (errno=%d). Stopping event scheduler", res); " thread (errno=%d). Stopping event scheduler", res);
new_thd->proc_info= "Clearing"; deinit_event_thread(new_thd);
DBUG_ASSERT(new_thd->net.buff != 0);
net_end(&new_thd->net);
goto error; goto error;
} }
...@@ -579,9 +563,6 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) ...@@ -579,9 +563,6 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
error: error:
DBUG_PRINT("error", ("Event_scheduler::execute_top() res: %d", res)); DBUG_PRINT("error", ("Event_scheduler::execute_top() res: %d", res));
if (new_thd)
delete new_thd;
delete event_name; delete event_name;
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
......
...@@ -359,7 +359,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= ...@@ -359,7 +359,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
//MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP
MYSQL_TYPE_LONGLONG, MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_VARCHAR,
//MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24
MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG,
//MYSQL_TYPE_DATE MYSQL_TYPE_TIME //MYSQL_TYPE_DATE MYSQL_TYPE_TIME
MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR,
//MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR
......
...@@ -1238,7 +1238,8 @@ int ha_commit_trans(THD *thd, bool all) ...@@ -1238,7 +1238,8 @@ int ha_commit_trans(THD *thd, bool all)
uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all); uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
/* rw_trans is TRUE when we in a transaction changing data */ /* rw_trans is TRUE when we in a transaction changing data */
bool rw_trans= is_real_trans && (rw_ha_count > 0); bool rw_trans= is_real_trans &&
(rw_ha_count > !thd->is_current_stmt_binlog_disabled());
MDL_request mdl_request; MDL_request mdl_request;
if (rw_trans) if (rw_trans)
......
...@@ -2778,9 +2778,28 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref) ...@@ -2778,9 +2778,28 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
if (context) if (context)
{ {
Name_resolution_context *ctx= new Name_resolution_context(); Name_resolution_context *ctx= new Name_resolution_context();
ctx->outer_context= NULL; // We don't build a complete name resolver if (context->select_lex == new_parent)
ctx->table_list= NULL; // We rely on first_name_resolution_table instead {
/*
This field was pushed in then pulled out
(for example left part of IN)
*/
ctx->outer_context= context->outer_context;
}
else if (context->outer_context)
{
/* just pull to the upper context */
ctx->outer_context= context->outer_context->outer_context;
}
else
{
/* No upper context (merging Derived/VIEW where context chain ends) */
ctx->outer_context= NULL;
}
ctx->table_list= context->first_name_resolution_table;
ctx->select_lex= new_parent; ctx->select_lex= new_parent;
if (context->select_lex == NULL)
ctx->select_lex= NULL;
ctx->first_name_resolution_table= context->first_name_resolution_table; ctx->first_name_resolution_table= context->first_name_resolution_table;
ctx->last_name_resolution_table= context->last_name_resolution_table; ctx->last_name_resolution_table= context->last_name_resolution_table;
ctx->error_processor= context->error_processor; ctx->error_processor= context->error_processor;
...@@ -5883,10 +5902,6 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length) ...@@ -5883,10 +5902,6 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
field= new Field_double((uchar*) 0, max_length, null_ptr, 0, Field::NONE, field= new Field_double((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
name, decimals, 0, unsigned_flag); name, decimals, 0, unsigned_flag);
break; break;
case MYSQL_TYPE_NULL:
field= new Field_null((uchar*) 0, max_length, Field::NONE,
name, &my_charset_bin);
break;
case MYSQL_TYPE_INT24: case MYSQL_TYPE_INT24:
field= new Field_medium((uchar*) 0, max_length, null_ptr, 0, Field::NONE, field= new Field_medium((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
name, 0, unsigned_flag); name, 0, unsigned_flag);
...@@ -5920,6 +5935,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length) ...@@ -5920,6 +5935,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
DBUG_ASSERT(0); DBUG_ASSERT(0);
/* If something goes awfully wrong, it's better to get a string than die */ /* If something goes awfully wrong, it's better to get a string than die */
case MYSQL_TYPE_STRING: case MYSQL_TYPE_STRING:
case MYSQL_TYPE_NULL:
if (fixed_length && !too_big_for_varchar()) if (fixed_length && !too_big_for_varchar())
{ {
field= new Field_string(max_length, maybe_null, name, field= new Field_string(max_length, maybe_null, name,
......
...@@ -2661,6 +2661,9 @@ double my_double_round(double value, longlong dec, bool dec_unsigned, ...@@ -2661,6 +2661,9 @@ double my_double_round(double value, longlong dec, bool dec_unsigned,
volatile double value_div_tmp= value / tmp; volatile double value_div_tmp= value / tmp;
volatile double value_mul_tmp= value * tmp; volatile double value_mul_tmp= value * tmp;
if (!dec_negative && my_isinf(tmp)) // "dec" is too large positive number
return value;
if (dec_negative && my_isinf(tmp)) if (dec_negative && my_isinf(tmp))
tmp2= 0.0; tmp2= 0.0;
else if (!dec_negative && my_isinf(value_mul_tmp)) else if (!dec_negative && my_isinf(value_mul_tmp))
......
...@@ -79,7 +79,6 @@ void Item_subselect::init(st_select_lex *select_lex, ...@@ -79,7 +79,6 @@ void Item_subselect::init(st_select_lex *select_lex,
DBUG_PRINT("enter", ("select_lex: 0x%lx this: 0x%lx", DBUG_PRINT("enter", ("select_lex: 0x%lx this: 0x%lx",
(ulong) select_lex, (ulong) this)); (ulong) select_lex, (ulong) this));
unit= select_lex->master_unit(); unit= select_lex->master_unit();
thd= unit->thd;
if (unit->item) if (unit->item)
{ {
...@@ -90,7 +89,7 @@ void Item_subselect::init(st_select_lex *select_lex, ...@@ -90,7 +89,7 @@ void Item_subselect::init(st_select_lex *select_lex,
engine= unit->item->engine; engine= unit->item->engine;
own_engine= FALSE; own_engine= FALSE;
parsing_place= unit->item->parsing_place; parsing_place= unit->item->parsing_place;
thd->change_item_tree((Item**)&unit->item, this); unit->thd->change_item_tree((Item**)&unit->item, this);
engine->change_result(this, result, TRUE); engine->change_result(this, result, TRUE);
} }
else else
...@@ -104,9 +103,9 @@ void Item_subselect::init(st_select_lex *select_lex, ...@@ -104,9 +103,9 @@ void Item_subselect::init(st_select_lex *select_lex,
NO_MATTER : NO_MATTER :
outer_select->parsing_place); outer_select->parsing_place);
if (unit->is_union()) if (unit->is_union())
engine= new subselect_union_engine(thd, unit, result, this); engine= new subselect_union_engine(unit, result, this);
else else
engine= new subselect_single_select_engine(thd, select_lex, result, this); engine= new subselect_single_select_engine(select_lex, result, this);
} }
{ {
SELECT_LEX *upper= unit->outer_select(); SELECT_LEX *upper= unit->outer_select();
...@@ -220,6 +219,10 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) ...@@ -220,6 +219,10 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
uint8 uncacheable; uint8 uncacheable;
bool res; bool res;
thd= thd_param;
DBUG_ASSERT(unit->thd == thd);
status_var_increment(thd_param->status_var.feature_subquery); status_var_increment(thd_param->status_var.feature_subquery);
DBUG_ASSERT(fixed == 0); DBUG_ASSERT(fixed == 0);
...@@ -242,7 +245,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) ...@@ -242,7 +245,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
return TRUE; return TRUE;
if (!(res= engine->prepare())) if (!(res= engine->prepare(thd)))
{ {
// all transformation is done (used by prepared statements) // all transformation is done (used by prepared statements)
changed= 1; changed= 1;
...@@ -2651,7 +2654,10 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref) ...@@ -2651,7 +2654,10 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
{ {
uint outer_cols_num; uint outer_cols_num;
List<Item> *inner_cols; List<Item> *inner_cols;
char const *save_where= thd->where; char const *save_where= thd_arg->where;
thd= thd_arg;
DBUG_ASSERT(unit->thd == thd);
if (test_strategy(SUBS_SEMI_JOIN)) if (test_strategy(SUBS_SEMI_JOIN))
return !( (*ref)= new Item_int(1)); return !( (*ref)= new Item_int(1));
...@@ -2769,7 +2775,8 @@ bool Item_in_subselect::setup_mat_engine() ...@@ -2769,7 +2775,8 @@ bool Item_in_subselect::setup_mat_engine()
if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine))) if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (mat_engine->init(&select_engine->join->fields_list, if (mat_engine->prepare(thd) ||
mat_engine->init(&select_engine->join->fields_list,
engine->get_identifier())) engine->get_identifier()))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
...@@ -2885,10 +2892,10 @@ void subselect_engine::set_thd(THD *thd_arg) ...@@ -2885,10 +2892,10 @@ void subselect_engine::set_thd(THD *thd_arg)
subselect_single_select_engine:: subselect_single_select_engine::
subselect_single_select_engine(THD *thd_arg, st_select_lex *select, subselect_single_select_engine(st_select_lex *select,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
Item_subselect *item_arg) Item_subselect *item_arg)
:subselect_engine(thd_arg, item_arg, result_arg), :subselect_engine(item_arg, result_arg),
prepared(0), executed(0), prepared(0), executed(0),
select_lex(select), join(0) select_lex(select), join(0)
{ {
...@@ -2966,10 +2973,10 @@ void subselect_uniquesubquery_engine::cleanup() ...@@ -2966,10 +2973,10 @@ void subselect_uniquesubquery_engine::cleanup()
} }
subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit *u, subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
Item_subselect *item_arg) Item_subselect *item_arg)
:subselect_engine(thd_arg, item_arg, result_arg) :subselect_engine(item_arg, result_arg)
{ {
unit= u; unit= u;
unit->item= item_arg; unit->item= item_arg;
...@@ -3002,10 +3009,11 @@ subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit ...@@ -3002,10 +3009,11 @@ subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit
@retval 1 if error @retval 1 if error
*/ */
int subselect_single_select_engine::prepare() int subselect_single_select_engine::prepare(THD *thd)
{ {
if (prepared) if (prepared)
return 0; return 0;
set_thd(thd);
if (select_lex->join) if (select_lex->join)
{ {
select_lex->cleanup(); select_lex->cleanup();
...@@ -3034,12 +3042,13 @@ int subselect_single_select_engine::prepare() ...@@ -3034,12 +3042,13 @@ int subselect_single_select_engine::prepare()
return 0; return 0;
} }
int subselect_union_engine::prepare() int subselect_union_engine::prepare(THD *thd_arg)
{ {
set_thd(thd_arg);
return unit->prepare(thd, result, SELECT_NO_UNLOCK); return unit->prepare(thd, result, SELECT_NO_UNLOCK);
} }
int subselect_uniquesubquery_engine::prepare() int subselect_uniquesubquery_engine::prepare(THD *)
{ {
/* Should never be called. */ /* Should never be called. */
DBUG_ASSERT(FALSE); DBUG_ASSERT(FALSE);
...@@ -3299,7 +3308,7 @@ int subselect_uniquesubquery_engine::scan_table() ...@@ -3299,7 +3308,7 @@ int subselect_uniquesubquery_engine::scan_table()
} }
table->file->extra_opt(HA_EXTRA_CACHE, table->file->extra_opt(HA_EXTRA_CACHE,
current_thd->variables.read_buff_size); get_thd()->variables.read_buff_size);
table->null_row= 0; table->null_row= 0;
for (;;) for (;;)
{ {
...@@ -3737,7 +3746,7 @@ table_map subselect_union_engine::upper_select_const_tables() ...@@ -3737,7 +3746,7 @@ table_map subselect_union_engine::upper_select_const_tables()
void subselect_single_select_engine::print(String *str, void subselect_single_select_engine::print(String *str,
enum_query_type query_type) enum_query_type query_type)
{ {
select_lex->print(thd, str, query_type); select_lex->print(get_thd(), str, query_type);
} }
...@@ -4267,6 +4276,7 @@ bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root) ...@@ -4267,6 +4276,7 @@ bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root)
bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id) bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
{ {
THD *thd= get_thd();
select_union *result_sink; select_union *result_sink;
/* Options to create_tmp_table. */ /* Options to create_tmp_table. */
ulonglong tmp_create_options= thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS; ulonglong tmp_create_options= thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS;
...@@ -4499,13 +4509,14 @@ subselect_hash_sj_engine::~subselect_hash_sj_engine() ...@@ -4499,13 +4509,14 @@ subselect_hash_sj_engine::~subselect_hash_sj_engine()
} }
int subselect_hash_sj_engine::prepare() int subselect_hash_sj_engine::prepare(THD *thd_arg)
{ {
/* /*
Create and optimize the JOIN that will be used to materialize Create and optimize the JOIN that will be used to materialize
the subquery if not yet created. the subquery if not yet created.
*/ */
return materialize_engine->prepare(); set_thd(thd_arg);
return materialize_engine->prepare(thd);
} }
...@@ -4877,7 +4888,7 @@ int subselect_hash_sj_engine::exec() ...@@ -4877,7 +4888,7 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH_MERGE) if (strategy == PARTIAL_MATCH_MERGE)
{ {
pm_engine= pm_engine=
new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*) new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*)
lookup_engine, tmp_table, lookup_engine, tmp_table,
count_pm_keys, count_pm_keys,
has_covering_null_row, has_covering_null_row,
...@@ -4886,6 +4897,7 @@ int subselect_hash_sj_engine::exec() ...@@ -4886,6 +4897,7 @@ int subselect_hash_sj_engine::exec()
item, result, item, result,
semi_join_conds->argument_list()); semi_join_conds->argument_list());
if (!pm_engine || if (!pm_engine ||
pm_engine->prepare(thd) ||
((subselect_rowid_merge_engine*) pm_engine)-> ((subselect_rowid_merge_engine*) pm_engine)->
init(nn_key_parts, &partial_match_key_parts)) init(nn_key_parts, &partial_match_key_parts))
{ {
...@@ -4903,13 +4915,14 @@ int subselect_hash_sj_engine::exec() ...@@ -4903,13 +4915,14 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH_SCAN) if (strategy == PARTIAL_MATCH_SCAN)
{ {
if (!(pm_engine= if (!(pm_engine=
new subselect_table_scan_engine(thd, (subselect_uniquesubquery_engine*) new subselect_table_scan_engine((subselect_uniquesubquery_engine*)
lookup_engine, tmp_table, lookup_engine, tmp_table,
item, result, item, result,
semi_join_conds->argument_list(), semi_join_conds->argument_list(),
has_covering_null_row, has_covering_null_row,
has_covering_null_columns, has_covering_null_columns,
count_columns_with_nulls))) count_columns_with_nulls)) ||
pm_engine->prepare(thd))
{ {
/* This is an irrecoverable error. */ /* This is an irrecoverable error. */
res= 1; res= 1;
...@@ -5356,14 +5369,14 @@ void Ordered_key::print(String *str) ...@@ -5356,14 +5369,14 @@ void Ordered_key::print(String *str)
subselect_partial_match_engine::subselect_partial_match_engine( subselect_partial_match_engine::subselect_partial_match_engine(
THD *thd_arg, subselect_uniquesubquery_engine *engine_arg, subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg, TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg, bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg) uint count_columns_with_nulls_arg)
:subselect_engine(thd_arg, item_arg, result_arg), :subselect_engine(item_arg, result_arg),
tmp_table(tmp_table_arg), lookup_engine(engine_arg), tmp_table(tmp_table_arg), lookup_engine(engine_arg),
equi_join_conds(equi_join_conds_arg), equi_join_conds(equi_join_conds_arg),
has_covering_null_row(has_covering_null_row_arg), has_covering_null_row(has_covering_null_row_arg),
...@@ -5488,6 +5501,7 @@ bool ...@@ -5488,6 +5501,7 @@ bool
subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts, subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
MY_BITMAP *partial_match_key_parts) MY_BITMAP *partial_match_key_parts)
{ {
THD *thd= get_thd();
/* The length in bytes of the rowids (positions) of tmp_table. */ /* The length in bytes of the rowids (positions) of tmp_table. */
uint rowid_length= tmp_table->file->ref_length; uint rowid_length= tmp_table->file->ref_length;
ha_rows row_count= tmp_table->file->stats.records; ha_rows row_count= tmp_table->file->stats.records;
...@@ -5976,7 +5990,7 @@ bool subselect_rowid_merge_engine::partial_match() ...@@ -5976,7 +5990,7 @@ bool subselect_rowid_merge_engine::partial_match()
subselect_table_scan_engine::subselect_table_scan_engine( subselect_table_scan_engine::subselect_table_scan_engine(
THD *thd_arg, subselect_uniquesubquery_engine *engine_arg, subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, TABLE *tmp_table_arg,
Item_subselect *item_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
...@@ -5984,7 +5998,7 @@ subselect_table_scan_engine::subselect_table_scan_engine( ...@@ -5984,7 +5998,7 @@ subselect_table_scan_engine::subselect_table_scan_engine(
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg, bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg) uint count_columns_with_nulls_arg)
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg, :subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg,
result_arg, equi_join_conds_arg, result_arg, equi_join_conds_arg,
has_covering_null_row_arg, has_covering_null_row_arg,
has_covering_null_columns_arg, has_covering_null_columns_arg,
...@@ -6026,7 +6040,7 @@ bool subselect_table_scan_engine::partial_match() ...@@ -6026,7 +6040,7 @@ bool subselect_table_scan_engine::partial_match()
} }
tmp_table->file->extra_opt(HA_EXTRA_CACHE, tmp_table->file->extra_opt(HA_EXTRA_CACHE,
current_thd->variables.read_buff_size); get_thd()->variables.read_buff_size);
for (;;) for (;;)
{ {
error= tmp_table->file->ha_rnd_next(tmp_table->record[0]); error= tmp_table->file->ha_rnd_next(tmp_table->record[0]);
......
...@@ -715,15 +715,15 @@ class subselect_engine: public Sql_alloc ...@@ -715,15 +715,15 @@ class subselect_engine: public Sql_alloc
INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE, INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE,
ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE}; ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE};
subselect_engine(THD *thd_arg, Item_subselect *si, subselect_engine(Item_subselect *si,
select_result_interceptor *res) select_result_interceptor *res):
thd(NULL)
{ {
result= res; result= res;
item= si; item= si;
cmp_type= res_type= STRING_RESULT; cmp_type= res_type= STRING_RESULT;
res_field_type= MYSQL_TYPE_VAR_STRING; res_field_type= MYSQL_TYPE_VAR_STRING;
maybe_null= 0; maybe_null= 0;
set_thd(thd_arg);
} }
virtual ~subselect_engine() {}; // to satisfy compiler virtual ~subselect_engine() {}; // to satisfy compiler
virtual void cleanup()= 0; virtual void cleanup()= 0;
...@@ -733,8 +733,8 @@ class subselect_engine: public Sql_alloc ...@@ -733,8 +733,8 @@ class subselect_engine: public Sql_alloc
Should be called before prepare(). Should be called before prepare().
*/ */
void set_thd(THD *thd_arg); void set_thd(THD *thd_arg);
THD * get_thd() { return thd; } THD * get_thd() { return thd ? thd : current_thd; }
virtual int prepare()= 0; virtual int prepare(THD *)= 0;
virtual void fix_length_and_dec(Item_cache** row)= 0; virtual void fix_length_and_dec(Item_cache** row)= 0;
/* /*
Execute the engine Execute the engine
...@@ -789,11 +789,11 @@ class subselect_single_select_engine: public subselect_engine ...@@ -789,11 +789,11 @@ class subselect_single_select_engine: public subselect_engine
st_select_lex *select_lex; /* corresponding select_lex */ st_select_lex *select_lex; /* corresponding select_lex */
JOIN * join; /* corresponding JOIN structure */ JOIN * join; /* corresponding JOIN structure */
public: public:
subselect_single_select_engine(THD *thd_arg, st_select_lex *select, subselect_single_select_engine(st_select_lex *select,
select_result_interceptor *result, select_result_interceptor *result,
Item_subselect *item); Item_subselect *item);
void cleanup(); void cleanup();
int prepare(); int prepare(THD *thd);
void fix_length_and_dec(Item_cache** row); void fix_length_and_dec(Item_cache** row);
int exec(); int exec();
uint cols(); uint cols();
...@@ -823,11 +823,11 @@ class subselect_union_engine: public subselect_engine ...@@ -823,11 +823,11 @@ class subselect_union_engine: public subselect_engine
{ {
st_select_lex_unit *unit; /* corresponding unit structure */ st_select_lex_unit *unit; /* corresponding unit structure */
public: public:
subselect_union_engine(THD *thd_arg, st_select_lex_unit *u, subselect_union_engine(st_select_lex_unit *u,
select_result_interceptor *result, select_result_interceptor *result,
Item_subselect *item); Item_subselect *item);
void cleanup(); void cleanup();
int prepare(); int prepare(THD *);
void fix_length_and_dec(Item_cache** row); void fix_length_and_dec(Item_cache** row);
int exec(); int exec();
uint cols(); uint cols();
...@@ -880,11 +880,11 @@ class subselect_uniquesubquery_engine: public subselect_engine ...@@ -880,11 +880,11 @@ class subselect_uniquesubquery_engine: public subselect_engine
// constructor can assign THD because it will be called after JOIN::prepare // constructor can assign THD because it will be called after JOIN::prepare
subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg, subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
Item_subselect *subs, Item *where) Item_subselect *subs, Item *where)
:subselect_engine(thd_arg, subs, 0), tab(tab_arg), cond(where) :subselect_engine(subs, 0), tab(tab_arg), cond(where)
{} {}
~subselect_uniquesubquery_engine(); ~subselect_uniquesubquery_engine();
void cleanup(); void cleanup();
int prepare(); int prepare(THD *);
void fix_length_and_dec(Item_cache** row); void fix_length_and_dec(Item_cache** row);
int exec(); int exec();
uint cols() { return 1; } uint cols() { return 1; }
...@@ -1012,7 +1012,7 @@ class subselect_hash_sj_engine : public subselect_engine ...@@ -1012,7 +1012,7 @@ class subselect_hash_sj_engine : public subselect_engine
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate, subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
subselect_single_select_engine *old_engine) subselect_single_select_engine *old_engine)
: subselect_engine(thd, in_predicate, NULL), : subselect_engine(in_predicate, NULL),
tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine), tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine),
materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL), materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL),
count_partial_match_columns(0), count_null_only_columns(0), count_partial_match_columns(0), count_null_only_columns(0),
...@@ -1022,7 +1022,7 @@ class subselect_hash_sj_engine : public subselect_engine ...@@ -1022,7 +1022,7 @@ class subselect_hash_sj_engine : public subselect_engine
bool init(List<Item> *tmp_columns, uint subquery_id); bool init(List<Item> *tmp_columns, uint subquery_id);
void cleanup(); void cleanup();
int prepare(); int prepare(THD *);
int exec(); int exec();
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
uint cols() uint cols()
...@@ -1301,15 +1301,14 @@ class subselect_partial_match_engine : public subselect_engine ...@@ -1301,15 +1301,14 @@ class subselect_partial_match_engine : public subselect_engine
protected: protected:
virtual bool partial_match()= 0; virtual bool partial_match()= 0;
public: public:
subselect_partial_match_engine(THD *thd_arg, subselect_partial_match_engine(subselect_uniquesubquery_engine *engine_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg, TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg, bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg); uint count_columns_with_nulls_arg);
int prepare() { return 0; } int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; }
int exec(); int exec();
void fix_length_and_dec(Item_cache**) {} void fix_length_and_dec(Item_cache**) {}
uint cols() { /* TODO: what is the correct value? */ return 1; } uint cols() { /* TODO: what is the correct value? */ return 1; }
...@@ -1396,8 +1395,7 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine ...@@ -1396,8 +1395,7 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
bool exists_complementing_null_row(MY_BITMAP *keys_to_complement); bool exists_complementing_null_row(MY_BITMAP *keys_to_complement);
bool partial_match(); bool partial_match();
public: public:
subselect_rowid_merge_engine(THD *thd_arg, subselect_rowid_merge_engine(subselect_uniquesubquery_engine *engine_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, uint merge_keys_count_arg, TABLE *tmp_table_arg, uint merge_keys_count_arg,
bool has_covering_null_row_arg, bool has_covering_null_row_arg,
bool has_covering_null_columns_arg, bool has_covering_null_columns_arg,
...@@ -1405,7 +1403,7 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine ...@@ -1405,7 +1403,7 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
Item_subselect *item_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg) List<Item> *equi_join_conds_arg)
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, :subselect_partial_match_engine(engine_arg, tmp_table_arg,
item_arg, result_arg, equi_join_conds_arg, item_arg, result_arg, equi_join_conds_arg,
has_covering_null_row_arg, has_covering_null_row_arg,
has_covering_null_columns_arg, has_covering_null_columns_arg,
...@@ -1424,8 +1422,7 @@ class subselect_table_scan_engine: public subselect_partial_match_engine ...@@ -1424,8 +1422,7 @@ class subselect_table_scan_engine: public subselect_partial_match_engine
protected: protected:
bool partial_match(); bool partial_match();
public: public:
subselect_table_scan_engine(THD *thd_arg, subselect_table_scan_engine(subselect_uniquesubquery_engine *engine_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg, TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
......
...@@ -1462,7 +1462,7 @@ my_decimal *Item_sum_sum::val_decimal(my_decimal *val) ...@@ -1462,7 +1462,7 @@ my_decimal *Item_sum_sum::val_decimal(my_decimal *val)
if (aggr) if (aggr)
aggr->endup(); aggr->endup();
if (hybrid_type == DECIMAL_RESULT) if (hybrid_type == DECIMAL_RESULT)
return (dec_buffs + curr_dec_buff); return null_value ? NULL : (dec_buffs + curr_dec_buff);
return val_decimal_from_real(val); return val_decimal_from_real(val);
} }
...@@ -1762,6 +1762,8 @@ double Item_sum_std::val_real() ...@@ -1762,6 +1762,8 @@ double Item_sum_std::val_real()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
double nr= Item_sum_variance::val_real(); double nr= Item_sum_variance::val_real();
if (my_isinf(nr))
return DBL_MAX;
DBUG_ASSERT(nr >= 0.0); DBUG_ASSERT(nr >= 0.0);
return sqrt(nr); return sqrt(nr);
} }
......
...@@ -2316,26 +2316,17 @@ static void network_init(void) ...@@ -2316,26 +2316,17 @@ static void network_init(void)
saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor; saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
saPipeSecurity.bInheritHandle = FALSE; saPipeSecurity.bInheritHandle = FALSE;
if ((hPipe= CreateNamedPipe(pipe_name, if ((hPipe= CreateNamedPipe(pipe_name,
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_READMODE_BYTE | PIPE_UNLIMITED_INSTANCES,
PIPE_WAIT, (int) global_system_variables.net_buffer_length,
PIPE_UNLIMITED_INSTANCES, (int) global_system_variables.net_buffer_length,
(int) global_system_variables.net_buffer_length, NMPWAIT_USE_DEFAULT_WAIT,
(int) global_system_variables.net_buffer_length, &saPipeSecurity)) == INVALID_HANDLE_VALUE)
NMPWAIT_USE_DEFAULT_WAIT, {
&saPipeSecurity)) == INVALID_HANDLE_VALUE) sql_perror("Create named pipe failed");
{ unireg_abort(1);
LPVOID lpMsgBuf; }
int error=GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
sql_perror((char *)lpMsgBuf);
LocalFree(lpMsgBuf);
unireg_abort(1);
}
} }
#endif #endif
...@@ -3464,6 +3455,7 @@ static int init_common_variables() ...@@ -3464,6 +3455,7 @@ static int init_common_variables()
max_system_variables.pseudo_thread_id= (ulong)~0; max_system_variables.pseudo_thread_id= (ulong)~0;
server_start_time= flush_status_time= my_time(0); server_start_time= flush_status_time= my_time(0);
my_disable_copystat_in_redel= 1;
rpl_filter= new Rpl_filter; rpl_filter= new Rpl_filter;
binlog_filter= new Rpl_filter; binlog_filter= new Rpl_filter;
......
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. /* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2012, Monty Program Ab Copyright (c) 2012, 2016, MariaDB
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
...@@ -885,7 +885,7 @@ my_real_read(NET *net, size_t *complen) ...@@ -885,7 +885,7 @@ my_real_read(NET *net, size_t *complen)
my_progname,vio_errno(net->vio)); my_progname,vio_errno(net->vio));
} }
#ifndef MYSQL_SERVER #ifndef MYSQL_SERVER
if (vio_errno(net->vio) == SOCKET_EINTR) if ((long)length < 0 && vio_errno(net->vio) == SOCKET_EINTR)
{ {
DBUG_PRINT("warning",("Interrupted read. Retrying...")); DBUG_PRINT("warning",("Interrupted read. Retrying..."));
continue; continue;
......
...@@ -10409,8 +10409,10 @@ get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key, ...@@ -10409,8 +10409,10 @@ get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
KEY *table_key=quick->head->key_info+quick->index; KEY *table_key=quick->head->key_info+quick->index;
flag=EQ_RANGE; flag=EQ_RANGE;
if ((table_key->flags & HA_NOSAME) && if ((table_key->flags & HA_NOSAME) &&
min_part == key_tree->part &&
key_tree->part == table_key->key_parts-1) key_tree->part == table_key->key_parts-1)
{ {
DBUG_ASSERT(min_part == max_part);
if ((table_key->flags & HA_NULL_PART_KEY) && if ((table_key->flags & HA_NULL_PART_KEY) &&
null_part_in_key(key, null_part_in_key(key,
param->min_key, param->min_key,
......
...@@ -441,7 +441,19 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -441,7 +441,19 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
} }
thd->prepare_derived_at_open= FALSE; thd->prepare_derived_at_open= FALSE;
table->next_global= save_next_global; /*
MERGE engine may adjust table->next_global chain, thus we have to
append save_next_global after merge children.
*/
if (save_next_global)
{
TABLE_LIST *table_list_iterator= table;
while (table_list_iterator->next_global)
table_list_iterator= table_list_iterator->next_global;
table_list_iterator->next_global= save_next_global;
save_next_global->prev_global= &table_list_iterator->next_global;
}
table->next_local= save_next_local; table->next_local= save_next_local;
thd->open_options&= ~extra_open_options; thd->open_options&= ~extra_open_options;
......
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