summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMichael Widenius <monty@mysql.com>2009-04-25 13:05:32 +0300
committerMichael Widenius <monty@mysql.com>2009-04-25 13:05:32 +0300
commite726e587ec6287472dd450dbcbddf07669b3e028 (patch)
treee644a6134bfe892512501c648c938a2e93f08130 /sql
parent210a412522b10115d34b431c66acf403faab7bfe (diff)
parent086185089e6c7bef58dde49b02950689af9fee63 (diff)
downloadmariadb-git-e726e587ec6287472dd450dbcbddf07669b3e028.tar.gz
Merged with mysql-5.1 tree.
client/mysqltest.cc: Manually merged configure.in: Manually merged mysql-test/r/variables.result: Manually merged mysql-test/t/variables.test: Manually merged mysys/my_pread.c: Manually merged mysys/my_read.c: Manually merged sql/mysqld.cc: Manually merged storage/csv/ha_tina.h: Manually merged storage/myisam/ha_myisam.cc: Manually merged storage/myisam/mi_check.c: Manually merged storage/myisam/mi_search.c: Manually merged
Diffstat (limited to 'sql')
-rw-r--r--sql/event_data_objects.cc4
-rw-r--r--sql/event_parse_data.cc4
-rw-r--r--sql/events.cc2
-rw-r--r--sql/gen_lex_hash.cc6
-rw-r--r--sql/item.cc19
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_create.cc1
-rw-r--r--sql/item_func.cc4
-rw-r--r--sql/item_strfunc.cc14
-rw-r--r--sql/item_timefunc.cc64
-rw-r--r--sql/lock.cc4
-rw-r--r--sql/log_event.cc55
-rw-r--r--sql/log_event.h4
-rw-r--r--sql/log_event_old.cc4
-rw-r--r--sql/mysql_priv.h21
-rw-r--r--sql/mysqld.cc69
-rw-r--r--sql/net_serv.cc6
-rw-r--r--sql/opt_range.cc67
-rw-r--r--sql/rpl_utility.h6
-rw-r--r--sql/set_var.cc93
-rw-r--r--sql/set_var.h16
-rw-r--r--sql/slave.cc43
-rw-r--r--sql/sp_head.cc5
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/spatial.h2
-rw-r--r--sql/sql_cache.cc4
-rw-r--r--sql/sql_class.cc11
-rw-r--r--sql/sql_class.h8
-rw-r--r--sql/sql_connect.cc2
-rw-r--r--sql/sql_crypt.cc2
-rw-r--r--sql/sql_error.cc2
-rw-r--r--sql/sql_insert.cc29
-rw-r--r--sql/sql_lex.cc10
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_load.cc4
-rw-r--r--sql/sql_parse.cc93
-rw-r--r--sql/sql_plugin.cc35
-rw-r--r--sql/sql_prepare.cc8
-rw-r--r--sql/sql_profile.cc2
-rw-r--r--sql/sql_repl.cc8
-rw-r--r--sql/sql_select.cc12
-rw-r--r--sql/sql_select.h6
-rw-r--r--sql/sql_servers.cc12
-rw-r--r--sql/sql_show.cc11
-rw-r--r--sql/sql_string.cc4
-rw-r--r--sql/sql_table.cc22
-rw-r--r--sql/sql_trigger.cc2
-rw-r--r--sql/sql_udf.cc2
-rw-r--r--sql/sql_view.cc7
-rw-r--r--sql/strfunc.cc202
-rw-r--r--sql/table.cc1
-rw-r--r--sql/tztime.cc78
-rw-r--r--sql/udf_example.c4
-rw-r--r--sql/uniques.cc2
54 files changed, 889 insertions, 213 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index b98922e2408..fdc18954c55 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -380,7 +380,7 @@ bool
Event_job_data::load_from_row(THD *thd, TABLE *table)
{
char *ptr;
- uint len;
+ size_t len;
LEX_STRING tz_name;
DBUG_ENTER("Event_job_data::load_from_row");
@@ -580,7 +580,7 @@ bool
Event_timed::load_from_row(THD *thd, TABLE *table)
{
char *ptr;
- uint len;
+ size_t len;
DBUG_ENTER("Event_timed::load_from_row");
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc
index 63ecc3006dd..86905b38627 100644
--- a/sql/event_parse_data.cc
+++ b/sql/event_parse_data.cc
@@ -527,8 +527,8 @@ Event_parse_data::init_definer(THD *thd)
const char *definer_user= thd->lex->definer->user.str;
const char *definer_host= thd->lex->definer->host.str;
- int definer_user_len= thd->lex->definer->user.length;
- int definer_host_len= thd->lex->definer->host.length;
+ size_t definer_user_len= thd->lex->definer->user.length;
+ size_t definer_host_len= thd->lex->definer->host.length;
DBUG_PRINT("info",("init definer_user thd->mem_root: 0x%lx "
"definer_user: 0x%lx", (long) thd->mem_root,
diff --git a/sql/events.cc b/sql/events.cc
index d7443695f4a..e1b4dd4d513 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -693,7 +693,7 @@ send_show_create_event(THD *thd, Event_timed *et, Protocol *protocol)
&sql_mode))
DBUG_RETURN(TRUE);
- field_list.push_back(new Item_empty_string("sql_mode", sql_mode.length));
+ field_list.push_back(new Item_empty_string("sql_mode", (uint) sql_mode.length));
tz_name= et->time_zone->get_name();
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index 214ee4c99d2..5a0904f87b9 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -204,7 +204,7 @@ void insert_symbols()
for (cur= symbols; i<array_elements(symbols); cur++, i++){
hash_lex_struct *root=
get_hash_struct_by_len(&root_by_len,cur->length,&max_len);
- insert_into_hash(root,cur->name,0,i,0);
+ insert_into_hash(root,cur->name,0,(uint) i,0);
}
}
@@ -516,7 +516,7 @@ static SYMBOL *get_hash_symbol(const char *s,\n\
res= symbols+ires;\n\
else\n\
res= sql_functions-ires-1;\n\
- register uint count= cur_str-s;\n\
+ register uint count= (uint) (cur_str - s);\n\
return lex_casecmp(cur_str,res->name+count,len-count) ? 0 : res;\n\
}\n\
\n\
@@ -545,7 +545,7 @@ static SYMBOL *get_hash_symbol(const char *s,\n\
register int16 ires= (int16)(cur_struct>>16);\n\
if (ires==array_elements(symbols)) return 0;\n\
register SYMBOL *res= symbols+ires;\n\
- register uint count= cur_str-s;\n\
+ register uint count= (uint) (cur_str - s);\n\
return lex_casecmp(cur_str,res->name+count,len-count)!=0 ? 0 : res;\n\
}\n\
\n\
diff --git a/sql/item.cc b/sql/item.cc
index 35a88d10fe0..010e4cb441a 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1527,7 +1527,8 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
else
{
// Cannot apply conversion
- set(0, DERIVATION_NONE, 0);
+ set(&my_charset_bin, DERIVATION_NONE,
+ (dt.repertoire|repertoire));
return 1;
}
}
@@ -1610,15 +1611,31 @@ bool agg_item_collations(DTCollation &c, const char *fname,
{
uint i;
Item **arg;
+ bool unknown_cs= 0;
+
c.set(av[0]->collation);
for (i= 1, arg= &av[item_sep]; i < count; i++, arg++)
{
if (c.aggregate((*arg)->collation, flags))
{
+ if (c.derivation == DERIVATION_NONE &&
+ c.collation == &my_charset_bin)
+ {
+ unknown_cs= 1;
+ continue;
+ }
my_coll_agg_error(av, count, fname, item_sep);
return TRUE;
}
}
+
+ if (unknown_cs &&
+ c.derivation != DERIVATION_EXPLICIT)
+ {
+ my_coll_agg_error(av, count, fname, item_sep);
+ return TRUE;
+ }
+
if ((flags & MY_COLL_DISALLOW_NONE) &&
c.derivation == DERIVATION_NONE)
{
diff --git a/sql/item.h b/sql/item.h
index eb1b28b4004..9daf353998d 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1093,7 +1093,7 @@ inline void Item_sp_variable::make_field(Send_field *field)
if (name)
it->set_name(name, (uint) strlen(name), system_charset_info);
else
- it->set_name(m_name.str, m_name.length, system_charset_info);
+ it->set_name(m_name.str, (uint) m_name.length, system_charset_info);
it->make_field(field);
}
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 4a440c00da5..35c757309e5 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -3791,6 +3791,7 @@ Create_func_load_file Create_func_load_file::s_singleton;
Item*
Create_func_load_file::create(THD *thd, Item *arg1)
{
+ thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_load_file(arg1);
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index fb4594e0e63..fa835542eb1 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2737,7 +2737,7 @@ longlong Item_func_find_in_set::val_int()
if (is_last_item && !is_separator)
str_end= substr_end;
if (!my_strnncoll(cs, (const uchar *) str_begin,
- str_end - str_begin,
+ (uint) (str_end - str_begin),
find_str, find_str_len))
return (longlong) position;
else
@@ -4828,7 +4828,7 @@ Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
component(*component_arg), cache_present(0)
{
/* set_name() will allocate the name */
- set_name(name_arg, name_len_arg, system_charset_info);
+ set_name(name_arg, (uint) name_len_arg, system_charset_info);
}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 298fbc39144..59f9dccfc79 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1827,17 +1827,17 @@ bool Item_func_user::init(const char *user, const char *host)
if (user)
{
CHARSET_INFO *cs= str_value.charset();
- uint res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
+ size_t res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
- if (str_value.alloc(res_length))
+ if (str_value.alloc((uint) res_length))
{
null_value=1;
return TRUE;
}
- res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), res_length,
+ res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), (uint) res_length,
"%s@%s", user, host);
- str_value.length(res_length);
+ str_value.length((uint) res_length);
str_value.mark_as_const();
}
return FALSE;
@@ -2541,7 +2541,7 @@ String *Item_func_rpad::val_str(String *str)
memcpy(to,ptr_pad,(size_t) pad_byte_length);
to+= pad_byte_length;
}
- res->length(to- (char*) res->ptr());
+ res->length((uint) (to- (char*) res->ptr()));
return (res);
err:
@@ -2809,7 +2809,7 @@ String *Item_func_charset::val_str(String *str)
CHARSET_INFO *cs= args[0]->collation.collation;
null_value= 0;
- str->copy(cs->csname, strlen(cs->csname),
+ str->copy(cs->csname, (uint) strlen(cs->csname),
&my_charset_latin1, collation.collation, &dummy_errors);
return str;
}
@@ -2821,7 +2821,7 @@ String *Item_func_collation::val_str(String *str)
CHARSET_INFO *cs= args[0]->collation.collation;
null_value= 0;
- str->copy(cs->name, strlen(cs->name),
+ str->copy(cs->name, (uint) strlen(cs->name),
&my_charset_latin1, collation.collation, &dummy_errors);
return str;
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index deffb0d56ca..c1b8cab600b 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -391,7 +391,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
if (tmp - val > 6)
tmp= (char*) val + 6;
l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
- frac_part= 6 - (tmp - val);
+ frac_part= 6 - (uint) (tmp - val);
if (frac_part > 0)
l_time->second_part*= (ulong) log_10_int[frac_part];
val= tmp;
@@ -643,14 +643,14 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
if (!l_time->month)
return 1;
str->append(locale->month_names->type_names[l_time->month-1],
- strlen(locale->month_names->type_names[l_time->month-1]),
+ (uint) strlen(locale->month_names->type_names[l_time->month-1]),
system_charset_info);
break;
case 'b':
if (!l_time->month)
return 1;
str->append(locale->ab_month_names->type_names[l_time->month-1],
- strlen(locale->ab_month_names->type_names[l_time->month-1]),
+ (uint) strlen(locale->ab_month_names->type_names[l_time->month-1]),
system_charset_info);
break;
case 'W':
@@ -659,7 +659,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),0);
str->append(locale->day_names->type_names[weekday],
- strlen(locale->day_names->type_names[weekday]),
+ (uint) strlen(locale->day_names->type_names[weekday]),
system_charset_info);
break;
case 'a':
@@ -668,13 +668,13 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),0);
str->append(locale->ab_day_names->type_names[weekday],
- strlen(locale->ab_day_names->type_names[weekday]),
+ (uint) strlen(locale->ab_day_names->type_names[weekday]),
system_charset_info);
break;
case 'D':
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
- length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 1, '0');
if (l_time->day >= 10 && l_time->day <= 19)
str->append(STRING_WITH_LEN("th"));
@@ -697,62 +697,62 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
}
break;
case 'Y':
- length= int10_to_str(l_time->year, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->year, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 4, '0');
break;
case 'y':
- length= int10_to_str(l_time->year%100, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->year%100, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'm':
- length= int10_to_str(l_time->month, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->month, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'c':
- length= int10_to_str(l_time->month, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->month, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 1, '0');
break;
case 'd':
- length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'e':
- length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 1, '0');
break;
case 'f':
- length= int10_to_str(l_time->second_part, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->second_part, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 6, '0');
break;
case 'H':
- length= int10_to_str(l_time->hour, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->hour, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'h':
case 'I':
hours_i= (l_time->hour%24 + 11)%12+1;
- length= int10_to_str(hours_i, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(hours_i, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'i': /* minutes */
- length= int10_to_str(l_time->minute, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->minute, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'j':
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
- length= int10_to_str(calc_daynr(l_time->year,l_time->month,
+ length= (uint) (int10_to_str(calc_daynr(l_time->year,l_time->month,
l_time->day) -
- calc_daynr(l_time->year,1,1) + 1, intbuff, 10) - intbuff;
+ calc_daynr(l_time->year,1,1) + 1, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 3, '0');
break;
case 'k':
- length= int10_to_str(l_time->hour, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->hour, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 1, '0');
break;
case 'l':
hours_i= (l_time->hour%24 + 11)%12+1;
- length= int10_to_str(hours_i, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(hours_i, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 1, '0');
break;
case 'p':
@@ -771,7 +771,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
break;
case 'S':
case 's':
- length= int10_to_str(l_time->second, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(l_time->second, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'T':
@@ -789,11 +789,11 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
uint year;
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
- length= int10_to_str(calc_week(l_time,
+ length= (uint) (int10_to_str(calc_week(l_time,
(*ptr) == 'U' ?
WEEK_FIRST_WEEKDAY : WEEK_MONDAY_FIRST,
&year),
- intbuff, 10) - intbuff;
+ intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
}
break;
@@ -803,12 +803,12 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
uint year;
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
- length= int10_to_str(calc_week(l_time,
+ length= (uint) (int10_to_str(calc_week(l_time,
((*ptr) == 'V' ?
(WEEK_YEAR | WEEK_FIRST_WEEKDAY) :
(WEEK_YEAR | WEEK_MONDAY_FIRST)),
&year),
- intbuff, 10) - intbuff;
+ intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 2, '0');
}
break;
@@ -823,7 +823,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
WEEK_YEAR | WEEK_FIRST_WEEKDAY :
WEEK_YEAR | WEEK_MONDAY_FIRST),
&year);
- length= int10_to_str(year, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(year, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 4, '0');
}
break;
@@ -832,7 +832,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
return 1;
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),1);
- length= int10_to_str(weekday, intbuff, 10) - intbuff;
+ length= (uint) (int10_to_str(weekday, intbuff, 10) - intbuff);
str->append_with_prefill(intbuff, length, 1, '0');
break;
@@ -882,7 +882,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
value= value*LL(10) + (longlong) (*str - '0');
if (transform_msec && i == count - 1) // microseconds always last
{
- long msec_length= 6 - (str - start);
+ long msec_length= 6 - (uint) (str - start);
if (msec_length > 0)
value*= (long) log_10_int[msec_length];
}
@@ -1061,7 +1061,7 @@ String* Item_func_monthname::val_str(String* str)
}
null_value=0;
month_name= locale->month_names->type_names[month-1];
- str->copy(month_name, strlen(month_name), &my_charset_utf8_bin,
+ str->copy(month_name, (uint) strlen(month_name), &my_charset_utf8_bin,
collation.collation, &err);
return str;
}
@@ -1211,7 +1211,7 @@ String* Item_func_dayname::val_str(String* str)
return (String*) 0;
day_name= locale->day_names->type_names[weekday];
- str->copy(day_name, strlen(day_name), &my_charset_utf8_bin,
+ str->copy(day_name, (uint) strlen(day_name), &my_charset_utf8_bin,
collation.collation, &err);
return str;
}
@@ -3177,14 +3177,14 @@ String *Item_func_get_format::val_str(String *str)
format++)
{
uint format_name_len;
- format_name_len= strlen(format_name);
+ format_name_len= (uint) strlen(format_name);
if (val_len == format_name_len &&
!my_strnncoll(&my_charset_latin1,
(const uchar *) val->ptr(), val_len,
(const uchar *) format_name, val_len))
{
const char *format_str= get_date_time_format_str(format, type);
- str->set(format_str, strlen(format_str), &my_charset_bin);
+ str->set(format_str, (uint) strlen(format_str), &my_charset_bin);
return str;
}
}
diff --git a/sql/lock.cc b/sql/lock.cc
index 8f58dd6ee86..e75186d276e 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -461,7 +461,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
for (i= 0; i < sql_lock->table_count; i++)
{
TABLE *tbl= *table;
- tbl->lock_position= table - sql_lock->table;
+ tbl->lock_position= (uint) (table - sql_lock->table);
tbl->lock_data_start= found;
found+= tbl->lock_count;
table++;
@@ -862,7 +862,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{
my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias);
/* Clear the lock type of the lock data that are stored already. */
- sql_lock->lock_count= locks - sql_lock->locks;
+ sql_lock->lock_count= (uint) (locks - sql_lock->locks);
reset_lock_data(sql_lock);
my_free((uchar*) sql_lock,MYF(0));
DBUG_RETURN(0);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 68d4c69f398..4c82d686d5a 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -382,7 +382,7 @@ static void cleanup_load_tmpdir()
uint i;
char fname[FN_REFLEN], prefbuf[31], *p;
- if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
+ if (!(dirp=my_dir(slave_load_tmpdir,MYF(0))))
return;
/*
@@ -1279,7 +1279,7 @@ void Log_event::print_header(IO_CACHE* file,
char emit_buf[256]; // Enough for storing one line
my_b_printf(file, "# Position Timestamp Type Master ID "
"Size Master Pos Flags \n");
- int const bytes_written=
+ size_t const bytes_written=
my_snprintf(emit_buf, sizeof(emit_buf),
"# %8.8lx %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x %02x %02x "
@@ -1288,7 +1288,6 @@ void Log_event::print_header(IO_CACHE* file,
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
- DBUG_ASSERT(bytes_written >= 0);
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
my_b_write(file, (uchar*) emit_buf, bytes_written);
ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
@@ -1314,12 +1313,11 @@ void Log_event::print_header(IO_CACHE* file,
TODO: Rewrite my_b_printf() to support full printf() syntax.
*/
char emit_buf[256];
- int const bytes_written=
+ size_t const bytes_written=
my_snprintf(emit_buf, sizeof(emit_buf),
"# %8.8lx %-48.48s |%16s|\n",
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
hex_string, char_string);
- DBUG_ASSERT(bytes_written >= 0);
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
my_b_write(file, (uchar*) emit_buf, bytes_written);
hex_string[0]= 0;
@@ -1334,12 +1332,11 @@ void Log_event::print_header(IO_CACHE* file,
if (hex_string[0])
{
char emit_buf[256];
- int const bytes_written=
+ size_t const bytes_written=
my_snprintf(emit_buf, sizeof(emit_buf),
"# %8.8lx %-48.48s |%s|\n",
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
hex_string, char_string);
- DBUG_ASSERT(bytes_written >= 0);
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
my_b_write(file, (uchar*) emit_buf, bytes_written);
}
@@ -1627,7 +1624,7 @@ beg:
case MYSQL_TYPE_DATETIME:
{
- uint d, t;
+ size_t d, t;
uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
d= i64 / 1000000;
t= i64 % 1000000;
@@ -4197,7 +4194,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
table_name = fields + field_block_len;
db = table_name + table_name_len + 1;
fname = db + db_len + 1;
- fname_len = strlen(fname);
+ fname_len = (uint) strlen(fname);
// null termination is accomplished by the caller doing buf[event_len]=0
DBUG_RETURN(0);
@@ -5699,7 +5696,7 @@ void Slave_log_event::init_from_mem_pool(int data_size)
master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
master_host = mem_pool + SL_MASTER_HOST_OFFSET;
- master_host_len = strlen(master_host);
+ master_host_len = (uint) strlen(master_host);
// safety
master_log = master_host + master_host_len + 1;
if (master_log > mem_pool + data_size)
@@ -5707,7 +5704,7 @@ void Slave_log_event::init_from_mem_pool(int data_size)
master_host = 0;
return;
}
- master_log_len = strlen(master_log);
+ master_log_len = (uint) strlen(master_log);
}
@@ -6180,6 +6177,12 @@ int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
thd_proc_info(thd, proc_info);
if (get_create_or_append())
{
+ /*
+ Usually lex_start() is called by mysql_parse(), but we need it here
+ as the present method does not call mysql_parse().
+ */
+ lex_start(thd);
+ mysql_reset_thd_for_next_command(thd);
my_delete(fname, MYF(0)); // old copy may exist already
if ((fd= my_create(fname, CREATE_MODE,
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
@@ -6199,6 +6202,10 @@ int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
get_type_str(), fname);
goto err;
}
+
+ DBUG_EXECUTE_IF("remove_slave_load_file_before_write",
+ my_close(fd,MYF(0)); fd= -1; my_delete(fname, MYF(0)););
+
if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
{
rli->report(ERROR_LEVEL, my_errno,
@@ -6620,7 +6627,7 @@ void Execute_load_query_log_event::print(FILE* file,
my_b_printf(&cache, "\'");
if (dup_handling == LOAD_DUP_REPLACE)
my_b_printf(&cache, " REPLACE");
- my_b_printf(&cache, " INTO");
+ my_b_printf(&cache, " INTO ");
my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
}
@@ -6701,7 +6708,7 @@ Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
/* Ordinary load data */
break;
}
- p= strmake(p, STRING_WITH_LEN(" INTO"));
+ p= strmake(p, STRING_WITH_LEN(" INTO "));
p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
error= Query_log_event::do_apply_event(rli, buf, p-buf);
@@ -6988,8 +6995,8 @@ int Rows_log_event::get_data_size()
{
int const type_code= get_type_code();
- uchar buf[sizeof(m_width)+1];
- uchar *end= net_store_length(buf, (m_width + 7) / 8);
+ uchar buf[sizeof(m_width) + 1];
+ uchar *end= net_store_length(buf, m_width);
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
@@ -6997,12 +7004,12 @@ int Rows_log_event::get_data_size()
(m_rows_cur - m_rows_buf););
int data_size= ROWS_HEADER_LEN;
data_size+= no_bytes_in_map(&m_cols);
- data_size+= end - buf;
+ data_size+= (uint) (end - buf);
if (type_code == UPDATE_ROWS_EVENT)
data_size+= no_bytes_in_map(&m_cols_ai);
- data_size+= (m_rows_cur - m_rows_buf);
+ data_size+= (uint) (m_rows_cur - m_rows_buf);
return data_size;
}
@@ -7578,7 +7585,7 @@ bool Rows_log_event::write_data_body(IO_CACHE*file)
Note that this should be the number of *bits*, not the number of
bytes.
*/
- uchar sbuf[sizeof(m_width)];
+ uchar sbuf[sizeof(m_width) + 1];
my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
bool res= false;
uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
@@ -7740,6 +7747,8 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
m_null_bits(0),
m_meta_memory(NULL)
{
+ uchar cbuf[sizeof(m_colcnt) + 1];
+ uchar *cbuf_end;
DBUG_ASSERT(m_table_id != ~0UL);
/*
In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
@@ -7756,7 +7765,9 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
m_data_size+= m_dblen + 2; // Include length and terminating \0
m_data_size+= m_tbllen + 2; // Include length and terminating \0
- m_data_size+= 1 + m_colcnt; // COLCNT and column types
+ cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
+ DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
+ m_data_size+= (cbuf_end - cbuf) + m_colcnt; // COLCNT and column types
/* If malloc fails, caught in is_valid() */
if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
@@ -7895,7 +7906,7 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
- bytes_read= ptr_after_colcnt - (uchar *)buf;
+ bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
if (bytes_read < event_len)
{
@@ -8048,7 +8059,7 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file)
uchar const dbuf[]= { (uchar) m_dblen };
uchar const tbuf[]= { (uchar) m_tbllen };
- uchar cbuf[sizeof(m_colcnt)];
+ uchar cbuf[sizeof(m_colcnt) + 1];
uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
@@ -9269,7 +9280,7 @@ bool
Incident_log_event::write_data_body(IO_CACHE *file)
{
DBUG_ENTER("Incident_log_event::write_data_body");
- DBUG_RETURN(write_str(file, m_message.str, m_message.length));
+ DBUG_RETURN(write_str(file, m_message.str, (uint) m_message.length));
}
diff --git a/sql/log_event.h b/sql/log_event.h
index 82fc8d771e1..bda53da8ab0 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -3316,7 +3316,7 @@ public:
virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ }
- virtual int get_data_size() { return m_data_size; }
+ virtual int get_data_size() { return (uint) m_data_size; }
#ifndef MYSQL_CLIENT
virtual int save_field_metadata();
virtual bool write_data_header(IO_CACHE *file);
@@ -3899,7 +3899,7 @@ public:
return m_incident > INCIDENT_NONE && m_incident < INCIDENT_COUNT;
}
virtual int get_data_size() {
- return INCIDENT_HEADER_LEN + 1 + m_message.length;
+ return INCIDENT_HEADER_LEN + 1 + (uint) m_message.length;
}
private:
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index cc4d24bc2dd..37eeee05a4d 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1382,9 +1382,9 @@ int Old_rows_log_event::get_data_size()
(m_rows_cur - m_rows_buf););
int data_size= ROWS_HEADER_LEN;
data_size+= no_bytes_in_map(&m_cols);
- data_size+= end - buf;
+ data_size+= (uint) (end - buf);
- data_size+= (m_rows_cur - m_rows_buf);
+ data_size+= (uint) (m_rows_cur - m_rows_buf);
return data_size;
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index a8c7246d7e3..816efe05c18 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -523,6 +523,20 @@ protected:
#define MODE_NO_ENGINE_SUBSTITUTION (MODE_HIGH_NOT_PRECEDENCE*2)
#define MODE_PAD_CHAR_TO_FULL_LENGTH (ULL(1) << 31)
+/* @@optimizer_switch flags. These must be in sync with optimizer_switch_typelib */
+#define OPTIMIZER_SWITCH_INDEX_MERGE 1
+#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2
+#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4
+#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8
+#define OPTIMIZER_SWITCH_LAST 16
+
+/* The following must be kept in sync with optimizer_switch_str in mysqld.cc */
+#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
+
+
/*
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
use strictly more than 64 bits by adding one more define above, you should
@@ -1829,6 +1843,10 @@ extern enum_field_types agg_field_type(Item **items, uint nitems);
/* strfunc.cc */
ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
char **err_pos, uint *err_len, bool *set_warning);
+ulonglong find_set_from_flags(TYPELIB *lib, uint default_name,
+ ulonglong cur_set, ulonglong default_set,
+ const char *str, uint length, CHARSET_INFO *cs,
+ char **err_pos, uint *err_len, bool *set_warning);
uint find_type(const TYPELIB *lib, const char *find, uint length,
bool part_match);
uint find_type2(const TYPELIB *lib, const char *find, uint length,
@@ -2058,6 +2076,9 @@ extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
extern SHOW_COMP_OPTION have_crypt;
extern SHOW_COMP_OPTION have_compress;
+extern int orig_argc;
+extern char **orig_argv;
+extern const char *load_default_groups[];
#ifndef __WIN__
extern pthread_t signal_thread;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 8af23d7fb2b..44e1cafcb87 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -300,6 +300,25 @@ static const unsigned int sql_mode_names_len[]=
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
sql_mode_names,
(unsigned int *)sql_mode_names_len };
+
+static const char *optimizer_switch_names[]=
+{
+ "index_merge","index_merge_union","index_merge_sort_union",
+ "index_merge_intersection", "default", NullS
+};
+/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
+static const unsigned int optimizer_switch_names_len[]=
+{
+ sizeof("index_merge") - 1,
+ sizeof("index_merge_union") - 1,
+ sizeof("index_merge_sort_union") - 1,
+ sizeof("index_merge_intersection") - 1,
+ sizeof("default") - 1
+};
+TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
+ optimizer_switch_names,
+ (unsigned int *)optimizer_switch_names_len };
+
static const char *tc_heuristic_recover_names[]=
{
"COMMIT", "ROLLBACK", NullS
@@ -366,6 +385,10 @@ static ulong max_used_connections;
static ulong my_bind_addr; /**< the address we bind to */
static volatile ulong cached_thread_count= 0;
static const char *sql_mode_str= "OFF";
+/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
+static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
+ "index_merge_sort_union=on,"
+ "index_merge_intersection=on";
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
static char *opt_init_slave, *language_ptr, *opt_init_connect;
static char *default_character_set_name;
@@ -653,6 +676,9 @@ static int defaults_argc;
static char **defaults_argv;
static char *opt_bin_logname;
+int orig_argc;
+char **orig_argv;
+
static my_socket unix_sock, base_ip_sock, extra_ip_sock;
struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
@@ -3014,8 +3040,7 @@ pthread_handler_t handle_shutdown(void *arg)
}
#endif
-#if !defined(EMBEDDED_LIBRARY)
-static const char *load_default_groups[]= {
+const char *load_default_groups[]= {
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
"mysql_cluster",
#endif
@@ -3023,11 +3048,10 @@ static const char *load_default_groups[]= {
"mariadb", MARIADB_BASE_VERSION,
0, 0};
-#if defined(__WIN__)
+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
static const int load_default_groups_sz=
sizeof(load_default_groups)/sizeof(load_default_groups[0]);
#endif
-#endif /*!EMBEDDED_LIBRARY*/
/**
@@ -3313,6 +3337,8 @@ static int init_common_variables(const char *conf_file_name, int argc,
SQLCOM_END + 8);
#endif
+ orig_argc=argc;
+ orig_argv=argv;
load_defaults(conf_file_name, groups, &argc, &argv);
defaults_argv=argv;
defaults_argc=argc;
@@ -3989,6 +4015,7 @@ server.");
if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
mysqld_get_one_option)))
unireg_abort(ho_error);
+ my_getopt_skip_unknown= TRUE;
if (defaults_argc)
{
@@ -5707,6 +5734,7 @@ enum options_mysqld
OPT_SYSDATE_IS_NOW,
OPT_OPTIMIZER_SEARCH_DEPTH,
OPT_OPTIMIZER_PRUNE_LEVEL,
+ OPT_OPTIMIZER_SWITCH,
OPT_UPDATABLE_VIEWS_WITH_LIMIT,
OPT_SP_AUTOMATIC_PRIVILEGES,
OPT_MAX_SP_RECURSION_DEPTH,
@@ -6905,6 +6933,13 @@ The minimum value for this variable is 4096.",
(uchar**) &global_system_variables.optimizer_search_depth,
(uchar**) &max_system_variables.optimizer_search_depth,
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
+ {"optimizer_switch", OPT_OPTIMIZER_SWITCH,
+ "optimizer_switch=option=val[,option=val...], where option={index_merge, "
+ "index_merge_union, index_merge_sort_union, index_merge_intersection} and "
+ "val={on, off, default}.",
+ (uchar**) &optimizer_switch_str, (uchar**) &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
+ /*OPTIMIZER_SWITCH_DEFAULT*/0,
+ 0, 0, 0, 0, 0},
{"plugin_dir", OPT_PLUGIN_DIR,
"Directory for plugins.",
(uchar**) &opt_plugin_dir_ptr, (uchar**) &opt_plugin_dir_ptr, 0,
@@ -7819,7 +7854,8 @@ static int mysql_init_variables(void)
when collecting index statistics for MyISAM tables.
*/
global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
-
+
+ global_system_variables.optimizer_switch= OPTIMIZER_SWITCH_DEFAULT;
/* Variables that depends on compile options */
#ifndef DBUG_OFF
default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
@@ -8460,6 +8496,29 @@ mysqld_get_one_option(int optid,
sql_mode);
break;
}
+ case OPT_OPTIMIZER_SWITCH:
+ {
+ bool not_used;
+ char *error= 0;
+ uint error_len= 0;
+ optimizer_switch_str= argument;
+ global_system_variables.optimizer_switch=
+ (ulong)find_set_from_flags(&optimizer_switch_typelib,
+ optimizer_switch_typelib.count,
+ global_system_variables.optimizer_switch,
+ global_system_variables.optimizer_switch,
+ argument, strlen(argument), NULL,
+ &error, &error_len, &not_used);
+ if (error)
+ {
+ char buf[512];
+ char *cbuf= buf;
+ cbuf += my_snprintf(buf, 512, "Error in parsing optimizer_switch setting near %*s\n", error_len, error);
+ sql_perror(buf);
+ return 1;
+ }
+ break;
+ }
case OPT_ONE_THREAD:
global_system_variables.thread_handling=
SCHEDULER_ONE_THREAD_PER_CONNECTION;
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 1098e8e6832..0a8720bae64 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -249,7 +249,7 @@ static int net_data_is_ready(my_socket sd)
tv.tv_sec= tv.tv_usec= 0;
- if ((res= select(sd+1, &sfds, NULL, NULL, &tv)) < 0)
+ if ((res= select((int) (sd + 1), &sfds, NULL, NULL, &tv)) < 0)
return 0;
else
return test(res ? FD_ISSET(sd, &sfds) : 0);
@@ -429,7 +429,7 @@ net_write_command(NET *net,uchar command,
const uchar *header, size_t head_len,
const uchar *packet, size_t len)
{
- ulong length=len+1+head_len; /* 1 extra byte for command */
+ size_t length=len+1+head_len; /* 1 extra byte for command */
uchar buff[NET_HEADER_SIZE+1];
uint header_size=NET_HEADER_SIZE+1;
DBUG_ENTER("net_write_command");
@@ -495,7 +495,7 @@ net_write_buff(NET *net, const uchar *packet, ulong len)
{
ulong left_length;
if (net->compress && net->max_packet > MAX_PACKET_LENGTH)
- left_length= MAX_PACKET_LENGTH - (net->write_pos - net->buff);
+ left_length= (ulong) (MAX_PACKET_LENGTH - (net->write_pos - net->buff));
else
left_length= (ulong) (net->buff_end - net->write_pos);
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index c17b7cf270a..220d281cf33 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2386,7 +2386,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
objects are not allowed so don't use ROR-intersection for
table deletes.
*/
- if ((thd->lex->sql_command != SQLCOM_DELETE))
+ if ((thd->lex->sql_command != SQLCOM_DELETE) &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
{
/*
Get best non-covering ROR-intersection plan and prepare data for
@@ -2410,25 +2411,28 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
}
else
{
- /* Try creating index_merge/ROR-union scan. */
- SEL_IMERGE *imerge;
- TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
- LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */
- DBUG_PRINT("info",("No range reads possible,"
- " trying to construct index_merge"));
- List_iterator_fast<SEL_IMERGE> it(tree->merges);
- while ((imerge= it++))
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
{
- new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
- if (new_conj_trp)
- set_if_smaller(param.table->quick_condition_rows,
- new_conj_trp->records);
- if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
- best_conj_trp->read_cost))
- best_conj_trp= new_conj_trp;
+ /* Try creating index_merge/ROR-union scan. */
+ SEL_IMERGE *imerge;
+ TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
+ LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */
+ DBUG_PRINT("info",("No range reads possible,"
+ " trying to construct index_merge"));
+ List_iterator_fast<SEL_IMERGE> it(tree->merges);
+ while ((imerge= it++))
+ {
+ new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
+ if (new_conj_trp)
+ set_if_smaller(param.table->quick_condition_rows,
+ new_conj_trp->records);
+ if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
+ best_conj_trp->read_cost))
+ best_conj_trp= new_conj_trp;
+ }
+ if (best_conj_trp)
+ best_trp= best_conj_trp;
}
- if (best_conj_trp)
- best_trp= best_conj_trp;
}
}
@@ -3768,11 +3772,19 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
"full table scan, bailing out"));
DBUG_RETURN(NULL);
}
- if (all_scans_rors)
+
+ /*
+ If all scans happen to be ROR, proceed to generate a ROR-union plan (it's
+ guaranteed to be cheaper than non-ROR union), unless ROR-unions are
+ disabled in @@optimizer_switch
+ */
+ if (all_scans_rors &&
+ optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION))
{
roru_read_plans= (TABLE_READ_PLAN**)range_scans;
goto skip_to_ror_scan;
}
+
if (cpk_scan)
{
/*
@@ -3786,8 +3798,11 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
imerge_cost += get_sweep_read_cost(param, non_cpk_scan_records);
DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g",
imerge_cost));
- if (imerge_cost > read_time)
+ if (imerge_cost > read_time ||
+ !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))
+ {
goto build_ror_index_merge;
+ }
/* Add Unique operations cost */
unique_calc_buff_size=
@@ -3823,7 +3838,9 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
}
build_ror_index_merge:
- if (!all_scans_ror_able || param->thd->lex->sql_command == SQLCOM_DELETE)
+ if (!all_scans_ror_able ||
+ param->thd->lex->sql_command == SQLCOM_DELETE ||
+ !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION))
DBUG_RETURN(imerge_trp);
/* Ok, it is possible to build a ROR-union, try it. */
@@ -4496,7 +4513,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
double min_cost= DBL_MAX;
DBUG_ENTER("get_best_ror_intersect");
- if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
+ if ((tree->n_ror_scans < 2) || !param->table->file->stats.records ||
+ !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT))
DBUG_RETURN(NULL);
/*
@@ -4686,6 +4704,9 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
DBUG_ENTER("get_best_covering_ror_intersect");
+ if (!optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT))
+ DBUG_RETURN(NULL);
+
for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
(*scan)->key_components=
param->table->key_info[(*scan)->keynr].key_parts;
@@ -9474,7 +9495,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
}
/* If we got to this point, cur_index_info passes the test. */
- key_infix_parts= cur_key_infix_len ?
+ key_infix_parts= cur_key_infix_len ? (uint)
(first_non_infix_part - first_non_group_part) : 0;
cur_used_key_parts= cur_group_key_parts + key_infix_parts;
diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h
index 8e2f4a7374f..1f4ca246ff1 100644
--- a/sql/rpl_utility.h
+++ b/sql/rpl_utility.h
@@ -294,12 +294,14 @@ namespace {
}
#endif
+// NB. number of printed bit values is limited to sizeof(buf) - 1
#define DBUG_PRINT_BITSET(N,FRM,BS) \
do { \
char buf[256]; \
- for (uint i = 0 ; i < (BS)->n_bits ; ++i) \
+ uint i; \
+ for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
- buf[(BS)->n_bits] = '\0'; \
+ buf[i] = '\0'; \
DBUG_PRINT((N), ((FRM), buf)); \
} while (0)
diff --git a/sql/set_var.cc b/sql/set_var.cc
index c1071c90223..21500666f49 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -487,6 +487,8 @@ static sys_var_thd_ulong sys_optimizer_prune_level(&vars, "optimizer_prun
&SV::optimizer_prune_level);
static sys_var_thd_ulong sys_optimizer_search_depth(&vars, "optimizer_search_depth",
&SV::optimizer_search_depth);
+static sys_var_thd_optimizer_switch sys_optimizer_switch(&vars, "optimizer_switch",
+ &SV::optimizer_switch);
static sys_var_const sys_pid_file(&vars, "pid_file",
OPT_GLOBAL, SHOW_CHAR,
(uchar*) pidfile_name);
@@ -3943,6 +3945,97 @@ ulong fix_sql_mode(ulong sql_mode)
}
+bool
+sys_var_thd_optimizer_switch::
+symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
+{
+ char buff[STRING_BUFFER_USUAL_SIZE*8];
+ String tmp(buff, sizeof(buff), &my_charset_latin1);
+ int i;
+ ulonglong bit;
+ tmp.length(0);
+
+ for (i= 0, bit=1; bit != OPTIMIZER_SWITCH_LAST; i++, bit= bit << 1)
+ {
+ tmp.append(optimizer_switch_typelib.type_names[i],
+ optimizer_switch_typelib.type_lengths[i]);
+ tmp.append('=');
+ tmp.append((val & bit)? "on":"off");
+ tmp.append(',');
+ }
+
+ if (tmp.length())
+ tmp.length(tmp.length() - 1); /* trim the trailing comma */
+
+ rep->str= thd->strmake(tmp.ptr(), tmp.length());
+
+ rep->length= rep->str ? tmp.length() : 0;
+
+ return rep->length != tmp.length();
+}
+
+
+uchar *sys_var_thd_optimizer_switch::value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
+{
+ LEX_STRING opts;
+ ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
+ thd->variables.*offset);
+ (void) symbolic_mode_representation(thd, val, &opts);
+ return (uchar *) opts.str;
+}
+
+
+/*
+ Check (and actually parse) string representation of @@optimizer_switch.
+*/
+
+bool sys_var_thd_optimizer_switch::check(THD *thd, set_var *var)
+{
+ bool not_used;
+ char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
+ uint error_len= 0;
+ String str(buff, sizeof(buff), system_charset_info), *res;
+
+ if (!(res= var->value->val_str(&str)))
+ {
+ strmov(buff, "NULL");
+ goto err;
+ }
+
+ if (res->length() == 0)
+ {
+ buff[0]= 0;
+ goto err;
+ }
+
+ var->save_result.ulong_value=
+ (ulong)find_set_from_flags(&optimizer_switch_typelib,
+ optimizer_switch_typelib.count,
+ thd->variables.optimizer_switch,
+ global_system_variables.optimizer_switch,
+ res->c_ptr_safe(), res->length(), NULL,
+ &error, &error_len, &not_used);
+ if (error_len)
+ {
+ strmake(buff, error, min(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+err:
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
+ return TRUE;
+}
+
+
+void sys_var_thd_optimizer_switch::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= OPTIMIZER_SWITCH_DEFAULT;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
/****************************************************************************
Named list handling
****************************************************************************/
diff --git a/sql/set_var.h b/sql/set_var.h
index b6c67d1ab4a..10e6e0f9c35 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -31,7 +31,7 @@ typedef struct system_variables SV;
typedef struct my_locale_st MY_LOCALE;
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib,
- slave_exec_mode_typelib;
+ optimizer_switch_typelib, slave_exec_mode_typelib;
typedef int (*sys_check_func)(THD *, set_var *);
typedef bool (*sys_update_func)(THD *, set_var *);
@@ -532,6 +532,20 @@ public:
};
+class sys_var_thd_optimizer_switch :public sys_var_thd_enum
+{
+public:
+ sys_var_thd_optimizer_switch(sys_var_chain *chain, const char *name_arg,
+ ulong SV::*offset_arg)
+ :sys_var_thd_enum(chain, name_arg, offset_arg, &optimizer_switch_typelib)
+ {}
+ bool check(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ static bool symbolic_mode_representation(THD *thd, ulonglong sql_mode,
+ LEX_STRING *rep);
+};
+
extern void fix_sql_mode_var(THD *thd, enum_var_type type);
class sys_var_thd_sql_mode :public sys_var_thd_enum
diff --git a/sql/slave.cc b/sql/slave.cc
index 6d48e57d298..f5e8a11efe9 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2633,6 +2633,41 @@ err:
DBUG_RETURN(0); // Can't return anything here
}
+/*
+ Check the temporary directory used by commands like
+ LOAD DATA INFILE.
+ */
+static
+int check_temp_dir(char* tmp_dir, char *tmp_file)
+{
+ int fd;
+ MY_DIR *dirp;
+
+ DBUG_ENTER("check_temp_dir");
+
+ /*
+ Check if the directory exists.
+ */
+ if (!(dirp=my_dir(tmp_dir,MYF(MY_WME))))
+ DBUG_RETURN(1);
+ my_dirend(dirp);
+
+ /*
+ Check permissions to create a file.
+ */
+ if ((fd= my_create(tmp_file, CREATE_MODE,
+ O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
+ MYF(MY_WME))) < 0)
+ DBUG_RETURN(1);
+
+ /*
+ Clean up.
+ */
+ my_close(fd, MYF(0));
+ my_delete(tmp_file, MYF(0));
+
+ DBUG_RETURN(0);
+}
/**
Slave SQL thread entry point.
@@ -2764,6 +2799,14 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
llstr(rli->group_master_log_pos,llbuff),rli->group_relay_log_name,
llstr(rli->group_relay_log_pos,llbuff1));
+ if (check_temp_dir(slave_load_tmpdir, rli->slave_patternload_file))
+ {
+ rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
+ "Unable to use slave's temporary directory %s - %s",
+ slave_load_tmpdir, thd->main_da.message());
+ goto err;
+ }
+
/* execute init_slave variable */
if (sys_init_slave.value_length)
{
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index ef6cb556f4c..fcf51aac1b5 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -956,6 +956,8 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
qbuf.length(0);
cur= query_str->str;
prev_pos= res= 0;
+ thd->query_name_consts= 0;
+
for (Item_splocal **splocal= sp_vars_uses.front();
splocal < sp_vars_uses.back(); splocal++)
{
@@ -989,6 +991,8 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
res|= qbuf.append(')');
if (res)
break;
+
+ thd->query_name_consts++;
}
res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos);
if (res)
@@ -2853,6 +2857,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
*nextp= m_ip+1;
thd->query= query;
thd->query_length= query_length;
+ thd->query_name_consts= 0;
if (!thd->is_error())
thd->main_da.reset_diagnostics_area();
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 3d7597e2402..c17b67f962a 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -367,7 +367,7 @@ public:
char *name(uint *lenp = 0) const
{
if (lenp)
- *lenp= m_name.length;
+ *lenp= (uint) m_name.length;
return m_name.str;
}
diff --git a/sql/spatial.h b/sql/spatial.h
index 69a1f24506e..dbf5da6665b 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -281,7 +281,7 @@ public:
uint32 len, String *res);
int as_wkt(String *wkt, const char **end)
{
- uint32 len= get_class_info()->m_name.length;
+ uint32 len= (uint) get_class_info()->m_name.length;
if (wkt->reserve(len + 2, 512))
return 1;
wkt->qs_append(get_class_info()->m_name.str, len);
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 5ff5e596f63..d56e246edae 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1114,7 +1114,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
{
memcpy(thd->query+thd->query_length+1, thd->db, thd->db_length);
DBUG_PRINT("qcache", ("database: %s length: %u",
- thd->db, thd->db_length));
+ thd->db, (unsigned) thd->db_length));
}
else
{
@@ -1310,7 +1310,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
{
memcpy(sql+query_length+1, thd->db, thd->db_length);
DBUG_PRINT("qcache", ("database: '%s' length: %u",
- thd->db, thd->db_length));
+ thd->db, (unsigned)thd->db_length));
}
else
{
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 2ed0a339628..6b990aea537 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -606,6 +606,7 @@ THD::THD()
one_shot_set= 0;
file_id = 0;
query_id= 0;
+ query_name_consts= 0;
warn_id= 0;
db_charset= global_system_variables.collation_database;
bzero(ha_data, sizeof(ha_data));
@@ -2358,7 +2359,7 @@ void Query_arena::set_query_arena(Query_arena *set)
void Query_arena::cleanup_stmt()
{
- DBUG_ASSERT("Query_arena::cleanup_stmt()" == "not implemented");
+ DBUG_ASSERT(! "Query_arena::cleanup_stmt() not implemented");
}
/*
@@ -2860,6 +2861,14 @@ Security_context::restore_security_context(THD *thd,
}
#endif
+
+bool Security_context::user_matches(Security_context *them)
+{
+ return ((user != NULL) && (them->user != NULL) &&
+ !strcmp(user, them->user));
+}
+
+
/****************************************************************************
Handling of open and locked tables states.
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 16956e07274..3183699fcd0 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -323,6 +323,8 @@ struct system_variables
ulong net_write_timeout;
ulong optimizer_prune_level;
ulong optimizer_search_depth;
+ /* A bitmap for switching optimizations on/off */
+ ulong optimizer_switch;
ulong preload_buff_size;
ulong profiling_history_size;
ulong query_cache_type;
@@ -670,7 +672,7 @@ public:
*/
char *db;
- uint db_length;
+ size_t db_length;
public:
@@ -817,6 +819,7 @@ public:
void
restore_security_context(THD *thd, Security_context *backup);
#endif
+ bool user_matches(Security_context *);
};
@@ -1782,6 +1785,9 @@ public:
sp_cache *sp_proc_cache;
sp_cache *sp_func_cache;
+ /** number of name_const() substitutions, see sp_head.cc:subst_spvars() */
+ uint query_name_consts;
+
/*
If we do a purge of binary logs, log index info of the threads
that are currently reading it needs to be adjusted. To do that
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index ef3cfaa4e11..1b6c337a43e 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -54,7 +54,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
USER_RESOURCES *mqh)
{
int return_val= 0;
- uint temp_len, user_len;
+ size_t temp_len, user_len;
char temp_user[USER_HOST_BUFF_SIZE];
struct user_conn *uc;
diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc
index 53babf517c1..f7f63efa077 100644
--- a/sql/sql_crypt.cc
+++ b/sql/sql_crypt.cc
@@ -31,7 +31,7 @@
SQL_CRYPT::SQL_CRYPT(const char *password)
{
ulong rand_nr[2];
- hash_password(rand_nr,password, strlen(password));
+ hash_password(rand_nr,password, (uint) strlen(password));
crypt_init(rand_nr);
}
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index bd8f9469571..9ea7facbe41 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -251,7 +251,7 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
protocol->store(warning_level_names[err->level].str,
warning_level_names[err->level].length, system_charset_info);
protocol->store((uint32) err->code);
- protocol->store(err->msg, strlen(err->msg), system_charset_info);
+ protocol->store(err->msg, (uint) strlen(err->msg), system_charset_info);
if (protocol->write())
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index aa8c6099fca..09e977ea801 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1680,11 +1680,12 @@ public:
ulong auto_increment_offset;
timestamp_auto_set_type timestamp_field_type;
LEX_STRING query;
+ Time_zone *time_zone;
delayed_row(LEX_STRING const query_arg, enum_duplicates dup_arg,
bool ignore_arg, bool log_query_arg)
: record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg),
- forced_insert_id(0), query(query_arg)
+ forced_insert_id(0), query(query_arg), time_zone(0)
{}
~delayed_row()
{
@@ -1906,7 +1907,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
pthread_mutex_lock(&LOCK_thread_count);
thread_count++;
pthread_mutex_unlock(&LOCK_thread_count);
- di->thd.set_db(table_list->db, strlen(table_list->db));
+ di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
di->thd.query= my_strdup(table_list->table_name, MYF(MY_WME));
if (di->thd.db == NULL || di->thd.query == NULL)
{
@@ -2174,6 +2175,19 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
thd->first_successful_insert_id_in_prev_stmt;
row->timestamp_field_type= table->timestamp_field_type;
+ /* Add session variable timezone
+ Time_zone object will not be freed even the thread is ended.
+ So we can get time_zone object from thread which handling delayed statement.
+ See the comment of my_tz_find() for detail.
+ */
+ if (thd->time_zone_used)
+ {
+ row->time_zone = thd->variables.time_zone;
+ }
+ else
+ {
+ row->time_zone = NULL;
+ }
/* Copy session variables. */
row->auto_increment_increment= thd->variables.auto_increment_increment;
row->auto_increment_offset= thd->variables.auto_increment_offset;
@@ -2674,6 +2688,14 @@ bool Delayed_insert::handle_inserts(void)
if (log_query && mysql_bin_log.is_open())
{
+ bool backup_time_zone_used = thd.time_zone_used;
+ Time_zone *backup_time_zone = thd.variables.time_zone;
+ if (row->time_zone != NULL)
+ {
+ thd.time_zone_used = true;
+ thd.variables.time_zone = row->time_zone;
+ }
+
/*
If the query has several rows to insert, only the first row will come
here. In row-based binlogging, this means that the first row will be
@@ -2685,6 +2707,9 @@ bool Delayed_insert::handle_inserts(void)
thd.binlog_query(THD::ROW_QUERY_TYPE,
row->query.str, row->query.length,
FALSE, FALSE);
+
+ thd.time_zone_used = backup_time_zone_used;
+ thd.variables.time_zone = backup_time_zone;
}
if (table->s->blob_fields)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 1c1f3bbe06f..da00ab7a239 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -253,7 +253,7 @@ void Lex_input_stream::body_utf8_append_literal(THD *thd,
{
thd->convert_string(&utf_txt,
&my_charset_utf8_general_ci,
- txt->str, txt->length,
+ txt->str, (uint) txt->length,
txt_cs);
}
else
@@ -435,7 +435,7 @@ bool is_keyword(const char *name, uint len)
bool is_lex_native_function(const LEX_STRING *name)
{
DBUG_ASSERT(name != NULL);
- return (get_hash_symbol(name->str, name->length, 1) != 0);
+ return (get_hash_symbol(name->str, (uint) name->length, 1) != 0);
}
/* make a copy of token before ptr and set yytoklen */
@@ -1082,7 +1082,7 @@ int MYSQLlex(void *arg, void *yythd)
if (c != '.')
{ // Found complete integer number.
yylval->lex_str=get_token(lip, 0, lip->yyLength());
- return int_token(yylval->lex_str.str,yylval->lex_str.length);
+ return int_token(yylval->lex_str.str, (uint) yylval->lex_str.length);
}
// fall through
case MY_LEX_REAL: // Incomplete real number
@@ -1988,8 +1988,8 @@ void st_select_lex::print_order(String *str,
if (order->counter_used)
{
char buffer[20];
- uint length= my_snprintf(buffer, 20, "%d", order->counter);
- str->append(buffer, length);
+ size_t length= my_snprintf(buffer, 20, "%d", order->counter);
+ str->append(buffer, (uint) length);
}
else
(*order->item)->print(str, query_type);
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index a48b99d07c7..f34a1c7c36f 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1370,7 +1370,7 @@ public:
/** Get the utf8-body length. */
uint get_body_utf8_length()
{
- return m_body_utf8_ptr - m_body_utf8;
+ return (uint) (m_body_utf8_ptr - m_body_utf8);
}
void body_utf8_start(THD *thd, const char *begin_ptr);
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 41c96a13829..278e01d4de6 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -557,8 +557,8 @@ static bool write_execute_load_query_log_event(THD *thd,
{
Execute_load_query_log_event
e(thd, thd->query, thd->query_length,
- (char*)thd->lex->fname_start - (char*)thd->query,
- (char*)thd->lex->fname_end - (char*)thd->query,
+ (uint) ((char*)thd->lex->fname_start - (char*)thd->query),
+ (uint) ((char*)thd->lex->fname_end - (char*)thd->query),
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
transactional_table, FALSE, killed_err_arg);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 5b316f130b9..54365da5496 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2578,6 +2578,43 @@ mysql_execute_command(THD *thd)
{
select_result *result;
+ /*
+ If:
+ a) we inside an SP and there was NAME_CONST substitution,
+ b) binlogging is on (STMT mode),
+ c) we log the SP as separate statements
+ raise a warning, as it may cause problems
+ (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
+ */
+ if (thd->query_name_consts &&
+ mysql_bin_log.is_open() &&
+ thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
+ !mysql_bin_log.is_query_in_union(thd, thd->query_id))
+ {
+ List_iterator_fast<Item> it(select_lex->item_list);
+ Item *item;
+ uint splocal_refs= 0;
+ /* Count SP local vars in the top-level SELECT list */
+ while ((item= it++))
+ {
+ if (item->is_splocal())
+ splocal_refs++;
+ }
+ /*
+ If it differs from number of NAME_CONST substitution applied,
+ we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
+ that may cause a problem with binary log (see BUG#35383),
+ raise a warning.
+ */
+ if (splocal_refs != thd->query_name_consts)
+ push_warning(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR,
+"Invoked routine ran a statement that may cause problems with "
+"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
+"section of the manual.");
+ }
+
select_lex->options|= SELECT_NO_UNLOCK;
unit->set_limit(select_lex);
@@ -4151,9 +4188,32 @@ end_with_restore_list:
res= (sp_result= lex->sphead->create(thd));
switch (sp_result) {
- case SP_OK:
+ case SP_OK: {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* only add privileges if really neccessary */
+
+ Security_context security_context;
+ bool restore_backup_context= false;
+ Security_context *backup= NULL;
+ LEX_USER *definer= thd->lex->definer;
+ /*
+ Check if the definer exists on slave,
+ then use definer privilege to insert routine privileges to mysql.procs_priv.
+
+ For current user of SQL thread has GLOBAL_ACL privilege,
+ which doesn't any check routine privileges,
+ so no routine privilege record will insert into mysql.procs_priv.
+ */
+ if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str))
+ {
+ security_context.change_security_context(thd,
+ &thd->lex->definer->user,
+ &thd->lex->definer->host,
+ &thd->lex->sphead->m_db,
+ &backup);
+ restore_backup_context= true;
+ }
+
if (sp_automatic_privileges && !opt_noacl &&
check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
lex->sphead->m_db.str, name,
@@ -4165,8 +4225,19 @@ end_with_restore_list:
ER_PROC_AUTO_GRANT_FAIL,
ER(ER_PROC_AUTO_GRANT_FAIL));
}
+
+ /*
+ Restore current user with GLOBAL_ACL privilege of SQL thread
+ */
+ if (restore_backup_context)
+ {
+ DBUG_ASSERT(thd->slave_thread == 1);
+ thd->security_ctx->restore_security_context(thd, backup);
+ }
+
#endif
break;
+ }
case SP_WRITE_ROW_FAILED:
my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
break;
@@ -6878,8 +6949,26 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp)
{
+
+ /*
+ If we're SUPER, we can KILL anything, including system-threads.
+ No further checks.
+
+ KILLer: thd->security_ctx->user could in theory be NULL while
+ we're still in "unauthenticated" state. This is a theoretical
+ case (the code suggests this could happen, so we play it safe).
+
+ KILLee: tmp->security_ctx->user will be NULL for system threads.
+ We need to check so Jane Random User doesn't crash the server
+ when trying to kill a) system threads or b) unauthenticated users'
+ threads (Bug#43748).
+
+ If user of both killer and killee are non-NULL, proceed with
+ slayage if both are string-equal.
+ */
+
if ((thd->security_ctx->master_access & SUPER_ACL) ||
- !strcmp(thd->security_ctx->user, tmp->security_ctx->user))
+ thd->security_ctx->user_matches(tmp->security_ctx))
{
tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
error=0;
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 6a59154dd22..a1748c0f5f5 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1139,8 +1139,9 @@ int plugin_init(int *argc, char **argv, int flags)
for (plugin= *builtins; plugin->info; plugin++)
{
if (opt_ignore_builtin_innodb &&
- !my_strcasecmp(&my_charset_latin1, plugin->name, "InnoDB"))
- continue;
+ !my_strnncoll(&my_charset_latin1, (const uchar*) plugin->name,
+ 6, (const uchar*) "InnoDB", 6))
+ continue;
/* by default, ndbcluster and federated are disabled */
def_enabled=
my_strcasecmp(&my_charset_latin1, plugin->name, "NDBCLUSTER") != 0 &&
@@ -1633,8 +1634,8 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
{
TABLE_LIST tables;
TABLE *table;
- int error, argc;
- char *argv[2];
+ int error, argc=orig_argc;
+ char **argv=orig_argv;
struct st_plugin_int *tmp;
DBUG_ENTER("mysql_install_plugin");
@@ -1650,21 +1651,31 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
pthread_mutex_lock(&LOCK_plugin);
rw_wrlock(&LOCK_system_variables_hash);
- /* handle_options() assumes arg0 (program name) always exists */
- argv[0]= const_cast<char*>(""); // without a cast gcc emits a warning
- argv[1]= 0;
- argc= 1;
+
+ my_load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv, NULL);
error= plugin_add(thd->mem_root, name, dl, &argc, argv, REPORT_TO_USER);
+ if (argv)
+ free_defaults(argv);
rw_unlock(&LOCK_system_variables_hash);
if (error || !(tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
goto err;
- if (plugin_initialize(tmp))
+ if (tmp->state == PLUGIN_IS_DISABLED)
{
- my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
- "Plugin initialization function failed.");
- goto deinit;
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_CANT_INITIALIZE_UDF, ER(ER_CANT_INITIALIZE_UDF),
+ name->str, "Plugin is disabled");
+ }
+ else
+ {
+ DBUG_ASSERT(tmp->state == PLUGIN_IS_UNINITIALIZED);
+ if (plugin_initialize(tmp))
+ {
+ my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
+ "Plugin initialization function failed.");
+ goto deinit;
+ }
}
/*
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 19a782a514c..427402133d2 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -759,13 +759,13 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
Item_param *param= *it;
if (param->state != Item_param::LONG_DATA_VALUE)
{
- if (is_param_null(null_array, it - begin))
+ if (is_param_null(null_array, (uint) (it - begin)))
param->set_null();
else
{
if (read_pos >= data_end)
DBUG_RETURN(1);
- param->set_param_func(param, &read_pos, data_end - read_pos);
+ param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
if (param->state == Item_param::NO_VALUE)
DBUG_RETURN(1);
}
@@ -797,13 +797,13 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
Item_param *param= *it;
if (param->state != Item_param::LONG_DATA_VALUE)
{
- if (is_param_null(null_array, it - begin))
+ if (is_param_null(null_array, (uint) (it - begin)))
param->set_null();
else
{
if (read_pos >= data_end)
DBUG_RETURN(1);
- param->set_param_func(param, &read_pos, data_end - read_pos);
+ param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
if (param->state == Item_param::NO_VALUE)
DBUG_RETURN(1);
}
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 320360b2587..de501b9089e 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -116,7 +116,7 @@ int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table)
if (field)
{
field->set_name(field_info->old_name,
- strlen(field_info->old_name),
+ (uint) strlen(field_info->old_name),
system_charset_info);
if (add_item_to_list(thd, field))
return 1;
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 14088961ea2..57319e4cda7 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -205,7 +205,7 @@ void adjust_linfo_offsets(my_off_t purge_offset)
bool log_in_use(const char* log_name)
{
- int log_name_len = strlen(log_name) + 1;
+ size_t log_name_len = strlen(log_name) + 1;
THD *tmp;
bool result = 0;
@@ -1366,8 +1366,8 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
const char* log_file_name2, ulonglong log_pos2)
{
int res;
- uint log_file_name1_len= strlen(log_file_name1);
- uint log_file_name2_len= strlen(log_file_name2);
+ size_t log_file_name1_len= strlen(log_file_name1);
+ size_t log_file_name2_len= strlen(log_file_name2);
// We assume that both log names match up to '.'
if (log_file_name1_len == log_file_name2_len)
@@ -1687,7 +1687,7 @@ int log_loaded_block(IO_CACHE* file)
lf_info->last_pos_in_file >= my_b_get_pos_in_file(file))
DBUG_RETURN(0);
- for (block_len= my_b_get_bytes_in_buffer(file); block_len > 0;
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
buffer += min(block_len, max_event_size),
block_len -= min(block_len, max_event_size))
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d7eed19d619..5cf6c9b1dbe 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7658,7 +7658,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
if (and_level)
{
/*
- Retrieve all conjucts of this level detecting the equality
+ Retrieve all conjuncts of this level detecting the equality
that are subject to substitution by multiple equality items and
removing each such predicate from the conjunction after having
found/created a multiple equality whose inference the predicate is.
@@ -7674,6 +7674,15 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
li.remove();
}
+ /*
+ Check if we eliminated all the predicates of the level, e.g.
+ (a=a AND b=b AND a=a).
+ */
+ if (!args->elements &&
+ !cond_equal.current_level.elements &&
+ !eq_list.elements)
+ return new Item_int((longlong) 1, 1);
+
List_iterator_fast<Item_equal> it(cond_equal.current_level);
while ((item_equal= it++))
{
@@ -9820,6 +9829,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->in_use= thd;
table->quick_keys.init();
table->covering_keys.init();
+ table->merge_keys.init();
table->keys_in_use_for_query.init();
table->s= share;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 43e26a6b4b2..5e97185a7b9 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -730,3 +730,9 @@ bool error_if_full_join(JOIN *join);
int report_error(TABLE *table, int error);
int safe_index_read(JOIN_TAB *tab);
COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value);
+
+inline bool optimizer_flag(THD *thd, uint flag)
+{
+ return (thd->variables.optimizer_switch & flag);
+}
+
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index 13bed8001a3..f8a8dea18ff 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -60,7 +60,7 @@ prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options);
/* drop functions */
static int delete_server_record(TABLE *table,
char *server_name,
- int server_name_length);
+ size_t server_name_length);
static int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options);
/* update functions */
@@ -301,7 +301,7 @@ get_server_from_table_to_cache(TABLE *table)
/* get each field into the server struct ptr */
server->server_name= get_field(&mem, table->field[0]);
- server->server_name_length= strlen(server->server_name);
+ server->server_name_length= (uint) strlen(server->server_name);
ptr= get_field(&mem, table->field[1]);
server->host= ptr ? ptr : blank;
ptr= get_field(&mem, table->field[2]);
@@ -911,7 +911,7 @@ end:
static int
delete_server_record(TABLE *table,
- char *server_name, int server_name_length)
+ char *server_name, size_t server_name_length)
{
int error;
DBUG_ENTER("delete_server_record");
@@ -1271,7 +1271,7 @@ static FOREIGN_SERVER *clone_server(MEM_ROOT *mem, const FOREIGN_SERVER *server,
FOREIGN_SERVER *get_server_by_name(MEM_ROOT *mem, const char *server_name,
FOREIGN_SERVER *buff)
{
- uint server_name_length;
+ size_t server_name_length;
FOREIGN_SERVER *server;
DBUG_ENTER("get_server_by_name");
DBUG_PRINT("info", ("server_name %s", server_name));
@@ -1290,8 +1290,8 @@ FOREIGN_SERVER *get_server_by_name(MEM_ROOT *mem, const char *server_name,
(uchar*) server_name,
server_name_length)))
{
- DBUG_PRINT("info", ("server_name %s length %d not found!",
- server_name, server_name_length));
+ DBUG_PRINT("info", ("server_name %s length %u not found!",
+ server_name, (unsigned) server_name_length));
server= (FOREIGN_SERVER *) NULL;
}
/* otherwise, make copy of server */
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 8deb564e02b..3687dc0751d 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1705,7 +1705,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
field->maybe_null=1;
field_list.push_back(new Item_empty_string("Command",16));
- field_list.push_back(new Item_return_int("Time",7, MYSQL_TYPE_LONG));
+ field_list.push_back(field= new Item_return_int("Time",7, MYSQL_TYPE_LONG));
+ field->unsigned_flag= 0;
field_list.push_back(field=new Item_empty_string("State",30));
field->maybe_null=1;
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
@@ -1798,7 +1799,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
else
protocol->store(command_name[thd_info->command].str, system_charset_info);
if (thd_info->start_time)
- protocol->store((uint32) (now - thd_info->start_time));
+ protocol->store_long ((longlong) (now - thd_info->start_time));
else
protocol->store_null();
protocol->store(thd_info->state_info, system_charset_info);
@@ -1873,8 +1874,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[4]->store(command_name[tmp->command].str,
command_name[tmp->command].length, cs);
/* MYSQL_TIME */
- table->field[5]->store((uint32)(tmp->start_time ?
- now - tmp->start_time : 0), TRUE);
+ table->field[5]->store((longlong)(tmp->start_time ?
+ now - tmp->start_time : 0), FALSE);
/* STATE */
#ifndef EMBEDDED_LIBRARY
val= (char*) (tmp->locked ? "Locked" :
@@ -6551,7 +6552,7 @@ ST_FIELD_INFO processlist_fields_info[]=
SKIP_OPEN_TABLE},
{"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE},
{"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE},
- {"TIME", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
+ {"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time", SKIP_OPEN_TABLE},
{"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
{"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
SKIP_OPEN_TABLE},
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index f2c5b2750ef..f0324da328f 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -455,7 +455,7 @@ bool String::append(const char *s,uint32 arg_length)
bool String::append(const char *s)
{
- return append(s, strlen(s));
+ return append(s, (uint) strlen(s));
}
@@ -1048,7 +1048,7 @@ outp:
}
}
*from_end_pos= from;
- res= to - to_start;
+ res= (uint) (to - to_start);
}
return (uint32) res;
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 7b76d9d6c56..7cee3a20fef 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -84,7 +84,7 @@ static void wait_for_kill_signal(THD *thd)
uint filename_to_tablename(const char *from, char *to, uint to_length)
{
uint errors;
- uint res;
+ size_t res;
DBUG_ENTER("filename_to_tablename");
DBUG_PRINT("enter", ("from '%s'", from));
@@ -224,7 +224,7 @@ uint build_table_filename(char *buff, size_t bufflen, const char *db,
char *end = buff + bufflen;
/* Don't add FN_ROOTDIR if mysql_data_home already includes it */
char *pos = strnmov(buff, mysql_data_home, bufflen);
- int rootdir_len= strlen(FN_ROOTDIR);
+ size_t rootdir_len= strlen(FN_ROOTDIR);
if (pos - rootdir_len >= buff &&
memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
pos= strnmov(pos, FN_ROOTDIR, end - pos);
@@ -273,7 +273,7 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
my_casedn_str(files_charset_info, p);
}
- uint length= unpack_filename(buff, buff);
+ size_t length= unpack_filename(buff, buff);
DBUG_PRINT("exit", ("buff: '%s'", buff));
DBUG_RETURN(length);
}
@@ -1991,7 +1991,7 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
for (pos= interval->type_names, len= interval->type_lengths;
*pos ; pos++, len++)
{
- uint length= cs->cset->numchars(cs, *pos, *pos + *len);
+ size_t length= cs->cset->numchars(cs, *pos, *pos + *len);
*tot_length+= length;
set_if_bigger(*max_length, (uint32)length);
}
@@ -2320,7 +2320,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_ASSERT(comma_length > 0);
for (uint i= 0; (tmp= int_it++); i++)
{
- uint lengthsp;
+ size_t lengthsp;
if (String::needs_conversion(tmp->length(), tmp->charset(),
cs, &dummy))
{
@@ -4245,7 +4245,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
(!(alter_info->flags & ALTER_ALL_PARTITION)))
{
char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
- uint length;
+ size_t length;
DBUG_PRINT("admin", ("sending non existent partition error"));
protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info);
@@ -4334,7 +4334,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
/* purecov: begin inspected */
char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
- uint length;
+ size_t length;
DBUG_PRINT("admin", ("sending error message"));
protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info);
@@ -4452,7 +4452,7 @@ send_result_message:
case HA_ADMIN_NOT_IMPLEMENTED:
{
char buf[MYSQL_ERRMSG_SIZE];
- uint length=my_snprintf(buf, sizeof(buf),
+ size_t length=my_snprintf(buf, sizeof(buf),
ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
protocol->store(STRING_WITH_LEN("note"), system_charset_info);
protocol->store(buf, length, system_charset_info);
@@ -4462,7 +4462,7 @@ send_result_message:
case HA_ADMIN_NOT_BASE_TABLE:
{
char buf[MYSQL_ERRMSG_SIZE];
- uint length= my_snprintf(buf, sizeof(buf),
+ size_t length= my_snprintf(buf, sizeof(buf),
ER(ER_BAD_TABLE_ERROR), table_name);
protocol->store(STRING_WITH_LEN("note"), system_charset_info);
protocol->store(buf, length, system_charset_info);
@@ -4590,7 +4590,7 @@ send_result_message:
case HA_ADMIN_NEEDS_ALTER:
{
char buf[MYSQL_ERRMSG_SIZE];
- uint length;
+ size_t length;
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
length=my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_UPGRADE),
@@ -4603,7 +4603,7 @@ send_result_message:
default: // Probably HA_ADMIN_INTERNAL_ERROR
{
char buf[MYSQL_ERRMSG_SIZE];
- uint length=my_snprintf(buf, sizeof(buf),
+ size_t length=my_snprintf(buf, sizeof(buf),
"Unknown - internal error %d during operation",
result_code);
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index bad8db56f02..c055268ecca 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1728,7 +1728,7 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
List_iterator_fast<LEX_STRING> it_def(definitions_list);
List_iterator_fast<LEX_STRING> it_on_table_name(on_table_names_list);
List_iterator_fast<ulonglong> it_mode(definition_modes_list);
- uint on_q_table_name_len, before_on_len;
+ size_t on_q_table_name_len, before_on_len;
String buff;
DBUG_ASSERT(definitions_list.elements == on_table_names_list.elements &&
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index ebd183c6803..c60dac42fb8 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -159,7 +159,7 @@ void udf_init()
DBUG_PRINT("info",("init udf record"));
LEX_STRING name;
name.str=get_field(&mem, table->field[0]);
- name.length = strlen(name.str);
+ name.length = (uint) strlen(name.str);
char *dl_name= get_field(&mem, table->field[2]);
bool new_dl=0;
Item_udftype udftype=UDFTYPE_FUNCTION;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 58448f82d82..07ab7df0d92 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -61,7 +61,8 @@ static void make_unique_view_field_name(Item *target,
char *name= (target->orig_name ?
target->orig_name :
target->name);
- uint name_len, attempt;
+ size_t name_len;
+ uint attempt;
char buff[NAME_LEN+1];
List_iterator_fast<Item> itc(item_list);
@@ -545,7 +546,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
}
while ((item= it++, name= nm++))
{
- item->set_name(name->str, name->length, system_charset_info);
+ item->set_name(name->str, (uint) name->length, system_charset_info);
item->is_autogenerated_name= FALSE;
}
}
@@ -1681,7 +1682,7 @@ frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
{
File file;
uchar header[10]; //"TYPE=VIEW\n" it is 10 characters
- int error;
+ size_t error;
DBUG_ENTER("mysql_frm_type");
*dbt= DB_TYPE_UNKNOWN;
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index d6f9784e4ad..5ff2efe2020 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -89,6 +89,208 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length,
}
+static const char *on_off_default_names[]=
+{
+ "off","on","default", NullS
+};
+
+static const unsigned int on_off_default_names_len[]=
+{
+ sizeof("off") - 1,
+ sizeof("on") - 1,
+ sizeof("default") - 1
+};
+
+static TYPELIB on_off_default_typelib= {array_elements(on_off_default_names)-1,
+ "", on_off_default_names,
+ (unsigned int *)on_off_default_names_len};
+
+
+/*
+ Parse a TYPELIB name from the buffer
+
+ SYNOPSIS
+ parse_name()
+ lib Set of names to scan for.
+ strpos INOUT Start of the buffer (updated to point to the next
+ character after the name)
+ end End of the buffer
+ cs Charset used in the buffer
+
+ DESCRIPTION
+ Parse a TYPELIB name from the buffer. The buffer is assumed to contain
+ one of the names specified in the TYPELIB, followed by comma, '=', or
+ end of the buffer.
+
+ RETURN
+ 0 No matching name
+ >0 Offset+1 in typelib for matched name
+*/
+
+static uint parse_name(TYPELIB *lib, const char **strpos, const char *end,
+ CHARSET_INFO *cs)
+{
+ const char *pos= *strpos;
+ const char *start= pos;
+
+ /* Find the length */
+ if (cs && cs->mbminlen > 1)
+ {
+ int mblen= 0;
+ for ( ; pos < end; pos+= mblen)
+ {
+ my_wc_t wc;
+ if ((mblen= cs->cset->mb_wc(cs, &wc, (const uchar *) pos,
+ (const uchar *) end)) < 1)
+ mblen= 1; // Not to hang on a wrong multibyte sequence
+ if (wc == (my_wc_t) '=' || wc == (my_wc_t) ',')
+ break;
+ }
+ }
+ else
+ for (; pos != end && *pos != '=' && *pos !=',' ; pos++);
+
+ uint var_len= (uint) (pos - start);
+ /* Determine which flag it is */
+ uint find= cs ? find_type2(lib, start, var_len, cs) :
+ find_type(lib, start, var_len, (bool) 0);
+ *strpos= pos;
+ return find;
+}
+
+
+/* Read next character from the buffer in a charset-aware way */
+
+static my_wc_t get_next_char(const char **pos, const char *end, CHARSET_INFO *cs)
+{
+ my_wc_t wc;
+ if (*pos == end)
+ return (my_wc_t)-1;
+
+ if (cs && cs->mbminlen > 1)
+ {
+ int mblen;
+ if ((mblen= cs->cset->mb_wc(cs, &wc, (const uchar *) *pos,
+ (const uchar *) end)) < 1)
+ mblen= 1; // Not to hang on a wrong multibyte sequence
+ *pos += mblen;
+ return wc;
+ }
+ else
+ return *((*pos)++);
+}
+
+
+/*
+ Parse and apply a set of flag assingments
+
+ SYNOPSIS
+ find_set_from_flags()
+ lib Flag names
+ default_name Number of "default" in the typelib
+ cur_set Current set of flags (start from this state)
+ default_set Default set of flags (use this for assign-default
+ keyword and flag=default assignments)
+ str String to be parsed
+ length Length of the string
+ cs String charset
+ err_pos OUT If error, set to point to start of wrong set string
+ NULL on success
+ err_len OUT If error, set to the length of wrong set string
+ set_warning OUT TRUE <=> Some string in set couldn't be used
+
+ DESCRIPTION
+ Parse a set of flag assignments, that is, parse a string in form:
+
+ param_name1=value1,param_name2=value2,...
+
+ where the names are specified in the TYPELIB, and each value can be
+ either 'on','off', or 'default'. Setting the same name twice is not
+ allowed.
+
+ Besides param=val assignments, we support the "default" keyword (keyword
+ #default_name in the typelib). It can be used one time, if specified it
+ causes us to build the new set over the default_set rather than cur_set
+ value.
+
+ RETURN
+ Parsed set value if (*errpos == NULL)
+ Otherwise undefined
+*/
+
+ulonglong find_set_from_flags(TYPELIB *lib, uint default_name,
+ ulonglong cur_set, ulonglong default_set,
+ const char *str, uint length, CHARSET_INFO *cs,
+ char **err_pos, uint *err_len, bool *set_warning)
+{
+ CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
+ const char *end= str + strip->cset->lengthsp(strip, str, length);
+ ulonglong flags_to_set= 0, flags_to_clear= 0;
+ bool set_defaults= 0;
+ *err_pos= 0; // No error yet
+ if (str != end)
+ {
+ const char *start= str;
+ for (;;)
+ {
+ const char *pos= start;
+ uint flag_no, value;
+
+ if (!(flag_no= parse_name(lib, &pos, end, cs)))
+ goto err;
+
+ if (flag_no == default_name)
+ {
+ /* Using 'default' twice isn't allowed. */
+ if (set_defaults)
+ goto err;
+ set_defaults= TRUE;
+ }
+ else
+ {
+ ulonglong bit= ((longlong) 1 << (flag_no - 1));
+ /* parse the '=on|off|default' */
+ if ((flags_to_clear | flags_to_set) & bit ||
+ get_next_char(&pos, end, cs) != '=' ||
+ !(value= parse_name(&on_off_default_typelib, &pos, end, cs)))
+ {
+ goto err;
+ }
+
+ if (value == 1) // this is '=off'
+ flags_to_clear|= bit;
+ else if (value == 2) // this is '=on'
+ flags_to_set|= bit;
+ else // this is '=default'
+ {
+ if (default_set & bit)
+ flags_to_set|= bit;
+ else
+ flags_to_clear|= bit;
+ }
+ }
+ if (pos >= end)
+ break;
+
+ if (get_next_char(&pos, end, cs) != ',')
+ goto err;
+
+ start=pos;
+ continue;
+ err:
+ *err_pos= (char*)start;
+ *err_len= end - start;
+ *set_warning= TRUE;
+ break;
+ }
+ }
+ ulonglong res= set_defaults? default_set : cur_set;
+ res|= flags_to_set;
+ res&= ~flags_to_clear;
+ return res;
+}
+
+
/*
Function to find a string in a TYPELIB
(Same format as mysys/typelib.c)
diff --git a/sql/table.cc b/sql/table.cc
index 7184f145339..787709e1f25 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1652,6 +1652,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
goto err;
outparam->quick_keys.init();
outparam->covering_keys.init();
+ outparam->merge_keys.init();
outparam->keys_in_use_for_query.init();
/* Allocate handler */
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 860a604b545..cd6e63be039 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1825,6 +1825,13 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
#ifdef ABBR_ARE_USED
char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
#endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+ allocate and keep the tz info and tz name in tz_storage.
+ */
+ TIME_ZONE_INFO tmp_tz_info;
+ memset(&tmp_tz_info, 0, sizeof(TIME_ZONE_INFO));
+
DBUG_ENTER("tz_load_from_open_tables");
/* Prepare tz_info for loading also let us make copy of time zone name */
@@ -1866,7 +1873,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
Most probably user has mistyped time zone name, so no need to bark here
unless we need it for debugging.
*/
- sql_print_error("Can't find description of time zone '%s'", tz_name_buff);
+ sql_print_error("Can't find description of time zone '%.*s'",
+ tz_name->length(), tz_name->ptr());
#endif
goto end;
}
@@ -1895,8 +1903,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
/* If Uses_leap_seconds == 'Y' */
if (table->field[1]->val_int() == 1)
{
- tz_info->leapcnt= tz_leapcnt;
- tz_info->lsis= tz_lsis;
+ tmp_tz_info.leapcnt= tz_leapcnt;
+ tmp_tz_info.lsis= tz_lsis;
}
(void)table->file->ha_index_end();
@@ -1932,18 +1940,18 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
#ifdef ABBR_ARE_USED
// FIXME should we do something with duplicates here ?
table->field[4]->val_str(&abbr, &abbr);
- if (tz_info->charcnt + abbr.length() + 1 > sizeof(chars))
+ if (tmp_tz_info.charcnt + abbr.length() + 1 > sizeof(chars))
{
sql_print_error("Error while loading time zone description from "
"mysql.time_zone_transition_type table: not enough "
"room for abbreviations");
goto end;
}
- ttis[ttid].tt_abbrind= tz_info->charcnt;
- memcpy(chars + tz_info->charcnt, abbr.ptr(), abbr.length());
- tz_info->charcnt+= abbr.length();
- chars[tz_info->charcnt]= 0;
- tz_info->charcnt++;
+ ttis[ttid].tt_abbrind= tmp_tz_info.charcnt;
+ memcpy(chars + tmp_tz_info.charcnt, abbr.ptr(), abbr.length());
+ tmp_tz_info.charcnt+= abbr.length();
+ chars[tmp_tz_info.charcnt]= 0;
+ tmp_tz_info.charcnt++;
DBUG_PRINT("info",
("time_zone_transition_type table: tz_id=%u tt_id=%u tt_gmtoff=%ld "
@@ -1956,9 +1964,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
#endif
/* ttid is increasing because we are reading using index */
- DBUG_ASSERT(ttid >= tz_info->typecnt);
+ DBUG_ASSERT(ttid >= tmp_tz_info.typecnt);
- tz_info->typecnt= ttid + 1;
+ tmp_tz_info.typecnt= ttid + 1;
res= table->file->index_next_same(table->record[0],
table->field[0]->ptr, 4);
@@ -1990,14 +1998,14 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
ttime= (my_time_t)table->field[1]->val_int();
ttid= (uint)table->field[2]->val_int();
- if (tz_info->timecnt + 1 > TZ_MAX_TIMES)
+ if (tmp_tz_info.timecnt + 1 > TZ_MAX_TIMES)
{
sql_print_error("Error while loading time zone description from "
"mysql.time_zone_transition table: "
"too much transitions");
goto end;
}
- if (ttid + 1 > tz_info->typecnt)
+ if (ttid + 1 > tmp_tz_info.typecnt)
{
sql_print_error("Error while loading time zone description from "
"mysql.time_zone_transition table: "
@@ -2005,9 +2013,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
goto end;
}
- ats[tz_info->timecnt]= ttime;
- types[tz_info->timecnt]= ttid;
- tz_info->timecnt++;
+ ats[tmp_tz_info.timecnt]= ttime;
+ types[tmp_tz_info.timecnt]= ttid;
+ tmp_tz_info.timecnt++;
DBUG_PRINT("info",
("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u",
@@ -2032,6 +2040,34 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
table= 0;
/*
+ Let us check how correct our time zone description is. We don't check for
+ tz->timecnt < 1 since it is ok for GMT.
+ */
+ if (tmp_tz_info.typecnt < 1)
+ {
+ sql_print_error("loading time zone without transition types");
+ goto end;
+ }
+
+ /* Allocate memory for the timezone info and timezone name in tz_storage. */
+ if (!(alloc_buff= (char*) alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) +
+ tz_name->length() + 1)))
+ {
+ sql_print_error("Out of memory while loading time zone description");
+ return 0;
+ }
+
+ /* Move the temporary tz_info into the allocated area */
+ tz_info= (TIME_ZONE_INFO *)alloc_buff;
+ memcpy(tz_info, &tmp_tz_info, sizeof(TIME_ZONE_INFO));
+ tz_name_buff= alloc_buff + sizeof(TIME_ZONE_INFO);
+ /*
+ By writing zero to the end we guarantee that we can call ptr()
+ instead of c_ptr() for time zone name.
+ */
+ strmake(tz_name_buff, tz_name->ptr(), tz_name->length());
+
+ /*
Now we will allocate memory and init TIME_ZONE_INFO structure.
*/
if (!(alloc_buff= (char*) alloc_root(&tz_storage,
@@ -2062,15 +2098,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
tz_info->ttis= (TRAN_TYPE_INFO *)alloc_buff;
memcpy(tz_info->ttis, ttis, tz_info->typecnt * sizeof(TRAN_TYPE_INFO));
- /*
- Let us check how correct our time zone description and build
- reversed map. We don't check for tz->timecnt < 1 since it ok for GMT.
- */
- if (tz_info->typecnt < 1)
- {
- sql_print_error("loading time zone without transition types");
- goto end;
- }
+ /* Build reversed map. */
if (prepare_tz_info(tz_info, &tz_storage))
{
sql_print_error("Unable to build mktime map for time zone");
diff --git a/sql/udf_example.c b/sql/udf_example.c
index a3d149f0971..30d85d95034 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -1099,7 +1099,7 @@ char * is_const(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)),
sprintf(result, "not const");
}
*is_null= 0;
- *length= strlen(result);
+ *length= (uint) strlen(result);
return result;
}
@@ -1133,7 +1133,7 @@ char * check_const_len(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)),
char *is_null, char *error __attribute__((unused)))
{
strmov(result, initid->ptr);
- *length= strlen(result);
+ *length= (uint) strlen(result);
*is_null= 0;
return result;
}
diff --git a/sql/uniques.cc b/sql/uniques.cc
index c2f16f2e05b..3d1ea9243b9 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -130,7 +130,7 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
total_buf_elems+= *pbuf;
*last= total_buf_elems;
- int n_buffers= last - first + 1;
+ size_t n_buffers= last - first + 1;
/* Using log2(n)=log(n)/log(2) formula */
return 2*((double)total_buf_elems*elem_size) / IO_SIZE +