summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/event_db_repository.cc15
-rw-r--r--sql/field.cc22
-rw-r--r--sql/filesort.cc2
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item.cc50
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_cmpfunc.cc22
-rw-r--r--sql/item_cmpfunc.h11
-rw-r--r--sql/item_func.cc5
-rw-r--r--sql/item_func.h12
-rw-r--r--sql/item_subselect.cc19
-rw-r--r--sql/item_timefunc.cc9
-rw-r--r--sql/log_event.cc1
-rw-r--r--sql/my_json_writer.cc8
-rw-r--r--sql/mysqld.cc128
-rw-r--r--sql/signal_handler.cc2
-rw-r--r--sql/sp_head.cc22
-rw-r--r--sql/sql_acl.cc9
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_class.cc9
-rw-r--r--sql/sql_class.h21
-rw-r--r--sql/sql_connect.cc10
-rw-r--r--sql/sql_delete.cc3
-rw-r--r--sql/sql_insert.cc121
-rw-r--r--sql/sql_insert.h3
-rw-r--r--sql/sql_lex.cc6
-rw-r--r--sql/sql_load.cc4
-rw-r--r--sql/sql_parse.cc17
-rw-r--r--sql/sql_parse.h1
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc32
-rw-r--r--sql/sql_select.h6
-rw-r--r--sql/sql_table.cc12
-rw-r--r--sql/sql_trigger.cc3
-rw-r--r--sql/sql_udf.cc6
-rw-r--r--sql/sql_yacc.yy8
-rw-r--r--sql/sys_vars.cc10
-rw-r--r--sql/sys_vars.ic2
-rw-r--r--sql/table.cc21
39 files changed, 337 insertions, 303 deletions
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index c96060cd5df..ca4d93eb240 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -18,6 +18,7 @@
#include "sql_priv.h"
#include "unireg.h"
#include "sql_base.h" // close_thread_tables
+#include "sql_parse.h"
#include "event_db_repository.h"
#include "key.h" // key_copy
#include "sql_db.h" // get_default_db_collation
@@ -702,19 +703,17 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
restore_record(table, s->default_values); // Get default values for fields
- if (system_charset_info->cset->
- numchars(system_charset_info, parse_data->dbname.str,
- parse_data->dbname.str + parse_data->dbname.length) >
- table->field[ET_FIELD_DB]->char_length())
+ if (check_string_char_length(&parse_data->dbname, 0,
+ table->field[ET_FIELD_DB]->char_length(),
+ system_charset_info, 1))
{
my_error(ER_TOO_LONG_IDENT, MYF(0), parse_data->dbname.str);
goto end;
}
- if (system_charset_info->cset->
- numchars(system_charset_info, parse_data->name.str,
- parse_data->name.str + parse_data->name.length) >
- table->field[ET_FIELD_NAME]->char_length())
+ if (check_string_char_length(&parse_data->name, 0,
+ table->field[ET_FIELD_NAME]->char_length(),
+ system_charset_info, 1))
{
my_error(ER_TOO_LONG_IDENT, MYF(0), parse_data->name.str);
goto end;
diff --git a/sql/field.cc b/sql/field.cc
index ff8b948ef62..23a8ecd965d 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1371,12 +1371,15 @@ void Field_num::prepend_zeros(String *value) const
int diff;
if ((diff= (int) (field_length - value->length())) > 0)
{
- bmove_upp((uchar*) value->ptr()+field_length,
- (uchar*) value->ptr()+value->length(),
- value->length());
- bfill((uchar*) value->ptr(),diff,'0');
- value->length(field_length);
- (void) value->c_ptr_quick(); // Avoid warnings in purify
+ const bool error= value->realloc(field_length);
+ if (!error)
+ {
+ bmove_upp((uchar*) value->ptr()+field_length,
+ (uchar*) value->ptr()+value->length(),
+ value->length());
+ bfill((uchar*) value->ptr(),diff,'0');
+ value->length(field_length);
+ }
}
}
@@ -2309,9 +2312,10 @@ void Field::set_default()
{
if (default_value)
{
- table->in_use->reset_arena_for_cached_items(table->expr_arena);
+ Query_arena backup_arena;
+ table->in_use->set_n_backup_active_arena(table->expr_arena, &backup_arena);
(void) default_value->expr->save_in_field(this, 0);
- table->in_use->reset_arena_for_cached_items(0);
+ table->in_use->restore_active_arena(table->expr_arena, &backup_arena);
return;
}
/* Copy constant value stored in s->default_values */
@@ -10509,7 +10513,7 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
if (length != 4)
{
char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
- my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length);
+ my_snprintf(buff, sizeof(buff), "YEAR(%llu)", length);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_WARN_DEPRECATED_SYNTAX,
ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX),
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 6046693cba1..2283e6e3d0a 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1672,7 +1672,7 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file,
if (!(error= (int) read_to_buffer(from_file, buffpek,
rec_length)))
{
- queue_remove(&queue,0);
+ (void) queue_remove_top(&queue);
reuse_freed_buff(&queue, buffpek, rec_length);
}
else if (error == -1)
diff --git a/sql/handler.cc b/sql/handler.cc
index f06c5d71a5e..9b1bf820f0c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4549,7 +4549,7 @@ void handler::get_dynamic_partition_info(PARTITION_STATS *stat_info,
stat_info->update_time= stats.update_time;
stat_info->check_time= stats.check_time;
stat_info->check_sum= 0;
- if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_OLD_CHECKSUM))
+ if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
stat_info->check_sum= checksum();
return;
}
diff --git a/sql/item.cc b/sql/item.cc
index 682f88317f1..7b657aeadc6 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -544,7 +544,14 @@ uint Item::decimal_precision() const
unsigned_flag);
return MY_MIN(prec, DECIMAL_MAX_PRECISION);
}
- return MY_MIN(max_char_length(), DECIMAL_MAX_PRECISION);
+ uint res= max_char_length();
+ /*
+ Return at least one decimal digit, even if Item::max_char_length()
+ returned 0. This is important to avoid attempts to create fields of types
+ INT(0) or DECIMAL(0,0) when converting NULL or empty strings to INT/DECIMAL:
+ CREATE TABLE t1 AS SELECT CONVERT(NULL,SIGNED) AS a;
+ */
+ return res ? MY_MIN(res, DECIMAL_MAX_PRECISION) : 1;
}
@@ -1182,7 +1189,8 @@ Item *Item_cache::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
if (conv == example)
return this;
Item_cache *cache;
- if (!conv || !(cache= new (thd->mem_root) Item_cache_str(thd, conv)))
+ if (!conv || conv->fix_fields(thd, (Item **) NULL) ||
+ !(cache= new (thd->mem_root) Item_cache_str(thd, conv)))
return NULL; // Safe conversion is not possible, or OEM
cache->setup(thd, conv);
cache->fixed= false; // Make Item::fix_fields() happy
@@ -2878,6 +2886,44 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
depended_from= NULL;
if (context)
{
+ bool need_change= false;
+ /*
+ Suppose there are nested selects:
+
+ select_id=1
+ select_id=2
+ select_id=3 <----+
+ select_id=4 -+
+ select_id=5 --+
+
+ Suppose, pullout operation has moved anything that had select_id=4 or 5
+ in to select_id=3.
+
+ If this Item_field had a name resolution context pointing into select_lex
+ with id=4 or id=5, it needs a new name resolution context.
+
+ However, it could also be that this object is a part of outer reference:
+ Item_ref(Item_field(field in select with select_id=1))).
+ - The Item_ref object has a context with select_id=5, and so needs a new
+ name resolution context.
+ - The Item_field object has a context with select_id=1, and doesn't need
+ a new name resolution context.
+
+ So, the following loop walks from Item_field's current context upwards.
+ If we find that the select we've been pulled out to is up there, we
+ create the new name resolution context. Otherwise, we don't.
+ */
+ for (Name_resolution_context *ct= context; ct; ct= ct->outer_context)
+ {
+ if (new_parent == ct->select_lex)
+ {
+ need_change= true;
+ break;
+ }
+ }
+ if (!need_change)
+ return;
+
Name_resolution_context *ctx= new Name_resolution_context();
if (context->select_lex == new_parent)
{
diff --git a/sql/item.h b/sql/item.h
index 1f3e0f02971..b6ece6dae69 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -3413,7 +3413,7 @@ class Item_blob :public Item_partition_func_safe_string
{
public:
Item_blob(THD *thd, const char *name_arg, uint length):
- Item_partition_func_safe_string(thd, name_arg, length, &my_charset_bin)
+ Item_partition_func_safe_string(thd, name_arg, strlen(name_arg), &my_charset_bin)
{ max_length= length; }
enum Type type() const { return TYPE_HOLDER; }
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2856cea0697..a3b9041aed4 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -610,7 +610,7 @@ int Arg_comparator::set_compare_func(Item_func_or_sum *item, Item_result type)
int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
Item **a1, Item **a2)
{
- thd= current_thd;
+ THD *thd= current_thd;
owner= owner_arg;
set_null= set_null && owner_arg;
a= a1;
@@ -742,12 +742,10 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
if (cache_arg && item->const_item() &&
!(item->type() == Item::CACHE_ITEM && item->cmp_type() == TIME_RESULT))
{
- Query_arena backup;
- Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup);
- Item_cache_temporal *cache= new (thd->mem_root) Item_cache_temporal(thd, f_type);
- if (save_arena)
- thd->set_query_arena(save_arena);
+ if (!thd)
+ thd= current_thd;
+ Item_cache_temporal *cache= new (thd->mem_root) Item_cache_temporal(thd, f_type);
cache->store_packed(value, item);
*cache_arg= cache;
*item_arg= cache_arg;
@@ -782,12 +780,12 @@ int Arg_comparator::compare_temporal(enum_field_types type)
owner->null_value= 1;
/* Get DATE/DATETIME/TIME value of the 'a' item. */
- a_value= get_datetime_value(thd, &a, &a_cache, type, &a_is_null);
+ a_value= get_datetime_value(0, &a, &a_cache, type, &a_is_null);
if (a_is_null)
return -1;
/* Get DATE/DATETIME/TIME value of the 'b' item. */
- b_value= get_datetime_value(thd, &b, &b_cache, type, &b_is_null);
+ b_value= get_datetime_value(0, &b, &b_cache, type, &b_is_null);
if (b_is_null)
return -1;
@@ -805,10 +803,10 @@ int Arg_comparator::compare_e_temporal(enum_field_types type)
longlong a_value, b_value;
/* Get DATE/DATETIME/TIME value of the 'a' item. */
- a_value= get_datetime_value(thd, &a, &a_cache, type, &a_is_null);
+ a_value= get_datetime_value(0, &a, &a_cache, type, &a_is_null);
/* Get DATE/DATETIME/TIME value of the 'b' item. */
- b_value= get_datetime_value(thd, &b, &b_cache, type, &b_is_null);
+ b_value= get_datetime_value(0, &b, &b_cache, type, &b_is_null);
return a_is_null || b_is_null ? a_is_null == b_is_null
: a_value == b_value;
}
@@ -3742,7 +3740,7 @@ uchar *in_datetime::get_value(Item *item)
Item **tmp_item= lval_cache ? &lval_cache : &item;
enum_field_types f_type=
tmp_item[0]->field_type_for_temporal_comparison(warn_item);
- tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, f_type, &is_null);
+ tmp.val= get_datetime_value(0, &tmp_item, &lval_cache, f_type, &is_null);
if (item->null_value)
return 0;
tmp.unsigned_flag= 1L;
@@ -4007,7 +4005,7 @@ void cmp_item_datetime::store_value(Item *item)
Item **tmp_item= lval_cache ? &lval_cache : &item;
enum_field_types f_type=
tmp_item[0]->field_type_for_temporal_comparison(warn_item);
- value= get_datetime_value(thd, &tmp_item, &lval_cache, f_type, &is_null);
+ value= get_datetime_value(0, &tmp_item, &lval_cache, f_type, &is_null);
m_null_value= item->null_value;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 7774663bd57..b1d25ba69fd 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -55,7 +55,6 @@ class Arg_comparator: public Sql_alloc
Arg_comparator *comparators; // used only for compare_row()
double precision;
/* Fields used in DATE/DATETIME comparison. */
- THD *thd;
Item *a_cache, *b_cache; // Cached values of a and b items
// when one of arguments is NULL.
int set_compare_func(Item_func_or_sum *owner, Item_result type);
@@ -70,12 +69,12 @@ public:
Arg_comparator(): m_compare_type(STRING_RESULT),
m_compare_collation(&my_charset_bin),
- set_null(TRUE), comparators(0), thd(0),
+ set_null(TRUE), comparators(0),
a_cache(0), b_cache(0) {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2),
m_compare_type(STRING_RESULT),
m_compare_collation(&my_charset_bin),
- set_null(TRUE), comparators(0), thd(0),
+ set_null(TRUE), comparators(0),
a_cache(0), b_cache(0) {};
public:
@@ -1268,14 +1267,13 @@ public:
class in_datetime :public in_longlong
{
public:
- THD *thd;
/* An item used to issue warnings. */
Item *warn_item;
/* Cache for the left item. */
Item *lval_cache;
in_datetime(THD *thd, Item *warn_item_arg, uint elements)
- :in_longlong(thd, elements), thd(current_thd), warn_item(warn_item_arg),
+ :in_longlong(thd, elements), warn_item(warn_item_arg),
lval_cache(0) {};
void set(uint pos,Item *item);
uchar *get_value(Item *item);
@@ -1445,14 +1443,13 @@ class cmp_item_datetime : public cmp_item_scalar
{
longlong value;
public:
- THD *thd;
/* Item used for issuing warnings. */
Item *warn_item;
/* Cache for the left item. */
Item *lval_cache;
cmp_item_datetime(Item *warn_item_arg)
- :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
+ : warn_item(warn_item_arg), lval_cache(0) {}
void store_value(Item *item);
int cmp(Item *arg);
int compare(cmp_item *ci);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index f6162b54806..2e0596da2d1 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2725,7 +2725,6 @@ void Item_func_min_max::fix_length_and_dec()
decimals=0;
max_length=0;
maybe_null=0;
- thd= current_thd;
Item_result tmp_cmp_type= args[0]->cmp_type();
uint string_type_count= 0;
uint temporal_type_count= 0;
@@ -2867,10 +2866,8 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
longlong res= args[i]->val_temporal_packed(Item_func_min_max::field_type());
/* Check if we need to stop (because of error or KILL) and stop the loop */
- if (thd->is_error() || args[i]->null_value)
- {
+ if (args[i]->null_value)
return (null_value= 1);
- }
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
min_max= res;
diff --git a/sql/item_func.h b/sql/item_func.h
index d4314f7bd6a..08b1421cb1d 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -636,8 +636,15 @@ public:
}
void fix_length_and_dec()
{
- fix_char_length(MY_MIN(args[0]->max_char_length(),
- MY_INT64_NUM_DECIMAL_DIGITS));
+ uint32 char_length= MY_MIN(args[0]->max_char_length(),
+ MY_INT64_NUM_DECIMAL_DIGITS);
+ /*
+ args[0]->max_char_length() can return 0.
+ Reserve max_length to fit at least one character for one digit,
+ plus one character for the sign (if signed).
+ */
+ set_if_bigger(char_length, 1 + (unsigned_flag ? 0 : 1));
+ fix_char_length(char_length);
}
virtual void print(String *str, enum_query_type query_type);
uint decimal_precision() const { return args[0]->decimal_precision(); }
@@ -1156,7 +1163,6 @@ class Item_func_min_max :public Item_hybrid_func
{
String tmp_value;
int cmp_sign;
- THD *thd;
public:
Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg):
Item_hybrid_func(thd, list), cmp_sign(cmp_sign_arg)
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 89c663b5f16..94bc71ca889 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
- Copyright (c) 2010, 2015, MariaDB
+/* Copyright (c) 2002, 2016, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2016, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3520,9 +3520,14 @@ bool subselect_union_engine::is_executed() const
bool subselect_union_engine::no_rows()
{
/* Check if we got any rows when reading UNION result from temp. table: */
- return MY_TEST(!(unit->fake_select_lex ?
- unit->fake_select_lex->join->send_records :
- ((select_union_direct *)(unit->get_union_result()))
+ if (unit->fake_select_lex)
+ {
+ JOIN *join= unit->fake_select_lex->join;
+ if (join)
+ return MY_TEST(!join->send_records);
+ return false;
+ }
+ return MY_TEST(!(((select_union_direct *)(unit->get_union_result()))
->send_records));
}
@@ -4897,9 +4902,9 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
result= result_sink;
/*
- If the subquery has blobs, or the total key lenght is bigger than
+ If the subquery has blobs, or the total key length is bigger than
some length, or the total number of key parts is more than the
- allowed maximum (currently MAX_REF_PARTS == 16), then the created
+ allowed maximum (currently MAX_REF_PARTS == 32), then the created
index cannot be used for lookups and we can't use hash semi
join. If this is the case, delete the temporary table since it
will not be used, and tell the caller we failed to initialize the
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 27ce83f3f2b..300ab0deb9e 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2009, 2017, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -426,7 +426,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
{
if (!my_isspace(&my_charset_latin1,*val))
{
- make_truncated_value_warning(current_thd,
+ make_truncated_value_warning(current_thd,
Sql_condition::WARN_LEVEL_WARN,
val_begin, length,
cached_timestamp_type, NullS);
@@ -711,7 +711,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
{
longlong value;
const char *start= str;
- for (value=0; str != end && my_isdigit(cs, *str) ; str++)
+ for (value= 0; str != end && my_isdigit(cs, *str); str++)
value= value*10 + *str - '0';
msec_length= 6 - (str - start);
values[i]= value;
@@ -1464,8 +1464,9 @@ void Item_temporal_func::fix_length_and_dec()
/*
We set maybe_null to 1 as default as any bad argument with date or
time can get us to return NULL.
- */
+ */
maybe_null= (arg_count > 0);
+
if (decimals)
{
if (decimals == NOT_FIXED_DEC)
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 0af348ab453..e1a37a8bccf 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -7605,6 +7605,7 @@ Gtid_list_log_event::do_apply_event(rpl_group_info *rgi)
rli->abort_slave= true;
rli->stop_for_until= true;
}
+ free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
return ret;
}
diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc
index d36fdd1192a..135ce353552 100644
--- a/sql/my_json_writer.cc
+++ b/sql/my_json_writer.cc
@@ -125,7 +125,7 @@ void Json_writer::start_element()
void Json_writer::add_ll(longlong val)
{
char buf[64];
- my_snprintf(buf, sizeof(buf), "%ld", val);
+ my_snprintf(buf, sizeof(buf), "%lld", val);
add_unquoted_str(buf);
}
@@ -135,16 +135,16 @@ void Json_writer::add_size(longlong val)
{
char buf[64];
if (val < 1024)
- my_snprintf(buf, sizeof(buf), "%ld", val);
+ my_snprintf(buf, sizeof(buf), "%lld", val);
else if (val < 1024*1024*16)
{
/* Values less than 16MB are specified in KB for precision */
- size_t len= my_snprintf(buf, sizeof(buf), "%ld", val/1024);
+ size_t len= my_snprintf(buf, sizeof(buf), "%lld", val/1024);
strcpy(buf + len, "Kb");
}
else
{
- size_t len= my_snprintf(buf, sizeof(buf), "%ld", val/(1024*1024));
+ size_t len= my_snprintf(buf, sizeof(buf), "%lld", val/(1024*1024));
strcpy(buf + len, "Mb");
}
add_str(buf);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4b79ea43c7c..d30fa3e25c7 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+ Copyright (c) 2008, 2017, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -130,10 +130,7 @@ extern "C" { // Because of SCO 3.2V4.2
#include <sysent.h>
#endif
#ifdef HAVE_PWD_H
-#include <pwd.h> // For getpwent
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
+#include <pwd.h> // For struct passwd
#endif
#include <my_net.h>
@@ -485,9 +482,7 @@ ulong opt_binlog_rows_event_max_size;
my_bool opt_master_verify_checksum= 0;
my_bool opt_slave_sql_verify_checksum= 1;
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
-#ifdef HAVE_INITGROUPS
volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
-#endif
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
uint mysqld_extra_port;
uint mysqld_port_timeout;
@@ -2421,59 +2416,18 @@ static void set_ports()
static struct passwd *check_user(const char *user)
{
-#if !defined(__WIN__)
- struct passwd *tmp_user_info;
- uid_t user_id= geteuid();
+ myf flags= 0;
+ if (global_system_variables.log_warnings)
+ flags|= MY_WME;
+ if (!opt_bootstrap && !opt_help)
+ flags|= MY_FAE;
- // Don't bother if we aren't superuser
- if (user_id)
- {
- if (user)
- {
- /* Don't give a warning, if real user is same as given with --user */
- /* purecov: begin tested */
- tmp_user_info= getpwnam(user);
- if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
- global_system_variables.log_warnings)
- sql_print_warning(
- "One can only use the --user switch if running as root\n");
- /* purecov: end */
- }
- return NULL;
- }
- if (!user)
- {
- if (!opt_bootstrap && !opt_help)
- {
- sql_print_error("Fatal error: Please consult the Knowledge Base "
- "to find out how to run mysqld as root!\n");
- unireg_abort(1);
- }
- return NULL;
- }
- /* purecov: begin tested */
- if (!strcmp(user,"root"))
- return NULL; // Avoid problem with dynamic libraries
+ struct passwd *tmp_user_info= my_check_user(user, MYF(flags));
- if (!(tmp_user_info= getpwnam(user)))
- {
- // Allow a numeric uid to be used
- const char *pos;
- for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
- if (*pos) // Not numeric id
- goto err;
- if (!(tmp_user_info= getpwuid(atoi(user))))
- goto err;
- }
+ if (!tmp_user_info && my_errno==EINVAL && (flags & MY_FAE))
+ unireg_abort(1);
return tmp_user_info;
- /* purecov: end */
-
-err:
- sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
- unireg_abort(1);
-#endif
- return NULL;
}
static inline void allow_coredumps()
@@ -2490,10 +2444,6 @@ static inline void allow_coredumps()
static void set_user(const char *user, struct passwd *user_info_arg)
{
- /* purecov: begin tested */
-#if !defined(__WIN__)
- DBUG_ASSERT(user_info_arg != 0);
-#ifdef HAVE_INITGROUPS
/*
We can get a SIGSEGV when calling initgroups() on some systems when NSS
is configured to use LDAP and the server is statically linked. We set
@@ -2501,22 +2451,11 @@ static void set_user(const char *user, struct passwd *user_info_arg)
output a specific message to help the user resolve this problem.
*/
calling_initgroups= 1;
- initgroups((char*) user, user_info_arg->pw_gid);
+ int res= my_set_user(user, user_info_arg, MYF(MY_WME));
calling_initgroups= 0;
-#endif
- if (setgid(user_info_arg->pw_gid) == -1)
- {
- sql_perror("setgid");
+ if (res)
unireg_abort(1);
- }
- if (setuid(user_info_arg->pw_uid) == -1)
- {
- sql_perror("setuid");
- unireg_abort(1);
- }
allow_coredumps();
-#endif
- /* purecov: end */
}
@@ -4087,8 +4026,8 @@ extern "C" {
static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
{
THD *thd= current_thd;
-
- if (likely(is_thread_specific)) /* If thread specific memory */
+
+ if (is_thread_specific) /* If thread specific memory */
{
/*
When thread specfic is set, both mysqld_server_initialized and thd
@@ -4100,14 +4039,22 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
(longlong) thd->status_var.local_memory_used,
size));
thd->status_var.local_memory_used+= size;
+ if (thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used &&
+ !thd->killed)
+ {
+ char buf[1024];
+ thd->killed= KILL_QUERY;
+ my_snprintf(buf, sizeof(buf), "--max-thread-mem-used=%llu",
+ thd->variables.max_mem_used);
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf);
+ }
DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 ||
!debug_assert_on_not_freed_memory);
}
else if (likely(thd))
{
DBUG_PRINT("info", ("global thd memory_used: %lld size: %lld",
- (longlong) thd->status_var.global_memory_used,
- size));
+ (longlong) thd->status_var.global_memory_used, size));
thd->status_var.global_memory_used+= size;
}
else
@@ -4580,19 +4527,24 @@ static int init_common_variables()
default_charset_info= default_collation;
}
/* Set collactions that depends on the default collation */
- global_system_variables.collation_server= default_charset_info;
- global_system_variables.collation_database= default_charset_info;
- global_system_variables.collation_connection= default_charset_info;
- global_system_variables.character_set_results= default_charset_info;
- if (default_charset_info->mbminlen > 1)
- {
- global_system_variables.character_set_client= &my_charset_latin1;
- sql_print_warning("Cannot use %s as character_set_client, %s will be used instead",
- default_charset_info->csname,
- global_system_variables.character_set_client->csname);
+ global_system_variables.collation_server= default_charset_info;
+ global_system_variables.collation_database= default_charset_info;
+ if (is_supported_parser_charset(default_charset_info))
+ {
+ global_system_variables.collation_connection= default_charset_info;
+ global_system_variables.character_set_results= default_charset_info;
+ global_system_variables.character_set_client= default_charset_info;
}
else
- global_system_variables.character_set_client= default_charset_info;
+ {
+ sql_print_warning("'%s' can not be used as client character set. "
+ "'%s' will be used as default client character set.",
+ default_charset_info->csname,
+ my_charset_latin1.csname);
+ global_system_variables.collation_connection= &my_charset_latin1;
+ global_system_variables.character_set_results= &my_charset_latin1;
+ global_system_variables.character_set_client= &my_charset_latin1;
+ }
if (!(character_set_filesystem=
get_charset_by_csname(character_set_filesystem_name,
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index ad7fb873c68..dc90fcae576 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -156,7 +156,7 @@ extern "C" sig_handler handle_fatal_signal(int sig)
if (opt_stack_trace)
{
- my_safe_printf_stderr("Thread pointer: 0x%p\n", thd);
+ my_safe_printf_stderr("Thread pointer: %p\n", thd);
my_safe_printf_stderr("%s",
"Attempting backtrace. You can use the following "
"information to find out\n"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 0b9b503aef3..251b829fb1d 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -523,12 +523,8 @@ check_routine_name(LEX_STRING *ident)
my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
return TRUE;
}
- if (check_string_char_length(ident, 0, NAME_CHAR_LEN,
- system_charset_info, 1))
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), ident->str);
+ if (check_ident_length(ident))
return TRUE;
- }
return FALSE;
}
@@ -3152,23 +3148,23 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
thd->query_length()) <= 0)
{
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
+ bool log_slow= !res && thd->enable_slow_log;
- if (thd->get_stmt_da()->is_eof())
- {
- /* Finalize server status flags after executing a statement. */
+ /* Finalize server status flags after executing a statement. */
+ if (log_slow || thd->get_stmt_da()->is_eof())
thd->update_server_status();
+ if (thd->get_stmt_da()->is_eof())
thd->protocol->end_statement();
- }
query_cache_end_of_result(thd);
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
- thd->get_stmt_da()->is_error() ?
- thd->get_stmt_da()->sql_errno() : 0,
- command_name[COM_QUERY].str);
+ thd->get_stmt_da()->is_error() ?
+ thd->get_stmt_da()->sql_errno() : 0,
+ command_name[COM_QUERY].str);
- if (!res && unlikely(thd->enable_slow_log))
+ if (log_slow)
log_slow_statement(thd);
}
else
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 4a3c9ae75e7..ada5ab1cd28 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -892,7 +892,7 @@ static my_bool do_validate(THD *, plugin_ref plugin, void *arg)
}
-static bool validate_password(LEX_USER *user)
+static bool validate_password(LEX_USER *user, THD *thd)
{
if (user->pwtext.length || !user->pwhash.length)
{
@@ -908,7 +908,8 @@ static bool validate_password(LEX_USER *user)
}
else
{
- if (strict_password_validation && has_validation_plugins())
+ if (!thd->slave_thread &&
+ strict_password_validation && has_validation_plugins())
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--strict-password-validation");
return true;
@@ -2748,7 +2749,7 @@ bool check_change_password(THD *thd, LEX_USER *user)
LEX_USER *real_user= get_current_user(thd, user);
if (fix_and_copy_user(real_user, user, thd) ||
- validate_password(real_user))
+ validate_password(real_user, thd))
return true;
*user= *real_user;
@@ -3463,7 +3464,7 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
}
if (!old_row_exists || combo.pwtext.length || combo.pwhash.length)
- if (!handle_as_role && validate_password(&combo))
+ if (!handle_as_role && validate_password(&combo, thd))
goto end;
/* Update table columns with new privileges */
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ac4b8a45107..ff16e46a631 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5c7cfdce657..f63ba4ed657 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+ Copyright (c) 2008, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -742,8 +742,8 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
#endif
{
ulong tmp;
+ bzero(&variables, sizeof(variables));
- mdl_context.init(this);
/*
We set THR_THD to temporally point to this THD to register all the
variables that allocates memory for this THD
@@ -753,8 +753,11 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
status_var.local_memory_used= sizeof(THD);
status_var.global_memory_used= 0;
variables.pseudo_thread_id= thread_id;
+ variables.max_mem_used= global_system_variables.max_mem_used;
main_da.init();
+ mdl_context.init(this);
+
/*
Pass nominal parameters to init_alloc_root only to ensure that
the destructor works OK in case of an error. The main_mem_root
@@ -800,7 +803,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
connection_name.str= 0;
connection_name.length= 0;
- bzero(&variables, sizeof(variables));
file_id = 0;
query_id= 0;
query_name_consts= 0;
@@ -916,7 +918,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
m_internal_handler= NULL;
m_binlog_invoker= INVOKER_NONE;
- arena_for_cached_items= 0;
memset(&invoker_user, 0, sizeof(invoker_user));
memset(&invoker_host, 0, sizeof(invoker_host));
prepare_derived_at_open= FALSE;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3a7454e0a89..f68d75ef935 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -546,6 +546,7 @@ typedef struct system_variables
ulonglong sortbuff_size;
ulonglong group_concat_max_len;
ulonglong default_regex_flags;
+ ulonglong max_mem_used;
/**
Place holders to store Multi-source variables in sys_var.cc during
@@ -3991,27 +3992,7 @@ public:
}
}
-private:
- /*
- This reference points to the table arena when the expression
- for a virtual column is being evaluated
- */
- Query_arena *arena_for_cached_items;
-
public:
- void reset_arena_for_cached_items(Query_arena *new_arena)
- {
- arena_for_cached_items= new_arena;
- }
- Query_arena *switch_to_arena_for_cached_items(Query_arena *backup)
- {
- if (!arena_for_cached_items)
- return 0;
- set_n_backup_active_arena(arena_for_cached_items, backup);
- return backup;
- }
-
-
void clear_wakeup_ready() { wakeup_ready= false; }
/*
Sleep waiting for others to wake us up with signal_wakeup_ready().
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index fe6a101f999..e277a81624e 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2007, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2014, SkySQL Ab.
+ Copyright (c) 2008, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -789,6 +789,7 @@ void update_global_user_stats(THD *thd, bool create_user, time_t now)
bool thd_init_client_charset(THD *thd, uint cs_number)
{
+ SV *gv=&global_system_variables;
CHARSET_INFO *cs;
/*
Use server character set and collation if
@@ -799,9 +800,10 @@ bool thd_init_client_charset(THD *thd, uint cs_number)
if (!opt_character_set_client_handshake ||
!(cs= get_charset(cs_number, MYF(0))))
{
- thd->update_charset(global_system_variables.character_set_client,
- global_system_variables.collation_connection,
- global_system_variables.character_set_results);
+ DBUG_ASSERT(is_supported_parser_charset(gv->character_set_client));
+ thd->update_charset(gv->character_set_client,
+ gv->collation_connection,
+ gv->character_set_results);
}
else
{
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 2f4c2d9a6f8..07066c4c504 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2010, Oracle and/or its affiliates.
- Copyright (c) 2010, 2015, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1346,4 +1346,3 @@ bool multi_delete::send_eof()
}
return 0;
}
-
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index b9c1dcebee9..b9cc836e164 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -309,6 +309,32 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(0);
}
+static bool has_no_default_value(THD *thd, Field *field, TABLE_LIST *table_list)
+{
+ if ((field->flags & NO_DEFAULT_VALUE_FLAG) && field->real_type() != MYSQL_TYPE_ENUM)
+ {
+ bool view= false;
+ if (table_list)
+ {
+ table_list= table_list->top_table();
+ view= table_list->view != NULL;
+ }
+ if (view)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_DEFAULT_FOR_VIEW_FIELD,
+ ER_THD(thd, ER_NO_DEFAULT_FOR_VIEW_FIELD),
+ table_list->view_db.str, table_list->view_name.str);
+ }
+ else
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_DEFAULT_FOR_FIELD,
+ ER_THD(thd, ER_NO_DEFAULT_FOR_FIELD), field->field_name);
+ }
+ return true;
+ }
+ return false;
+}
+
/**
Check if update fields are correct.
@@ -744,13 +770,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
DBUG_ASSERT(bulk_iterations > 0);
if (mysql_prepare_insert(thd, table_list, table, fields, values,
update_fields, update_values, duplic, &unused_conds,
- FALSE,
- (fields.elements || !value_count ||
- table_list->view != 0),
- !ignore && thd->is_strict_mode()))
+ FALSE))
goto abort;
- /* mysql_prepare_insert set table_list->table if it was not set */
+ /* mysql_prepare_insert sets table_list->table if it was not set */
table= table_list->table;
context= &thd->lex->select_lex.context;
@@ -879,6 +902,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table->prepare_triggers_for_insert_stmt_or_event();
table->mark_columns_needed_for_insert();
+ if (fields.elements || !value_count || table_list->view != 0)
+ {
+ if (check_that_all_fields_are_given_values(thd, table, table_list))
+ {
+ error= 1;
+ goto values_loop_end;
+ }
+ }
+
if (table_list->prepare_where(thd, 0, TRUE) ||
table_list->prepare_check_option(thd))
error= 1;
@@ -973,6 +1005,23 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
}
}
+ /*
+ with triggers a field can get a value *conditionally*, so we have to repeat
+ has_no_default_value() check for every row
+ */
+ if (table->triggers &&
+ table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE))
+ {
+ for (Field **f=table->field ; *f ; f++)
+ {
+ if (!(*f)->has_explicit_value() && has_no_default_value(thd, *f, table_list))
+ {
+ error= 1;
+ goto values_loop_end;
+ }
+ }
+ }
+
if ((res= table_list->view_check_option(thd,
(values_list.elements == 1 ?
0 :
@@ -1384,10 +1433,6 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
be taken from table_list->table)
where Where clause (for insert ... select)
select_insert TRUE if INSERT ... SELECT statement
- check_fields TRUE if need to check that all INSERT fields are
- given values.
- abort_on_warning whether to report if some INSERT field is not
- assigned as an error (TRUE) or as a warning (FALSE).
TODO (in far future)
In cases of:
@@ -1407,9 +1452,8 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
TABLE *table, List<Item> &fields, List_item *values,
List<Item> &update_fields, List<Item> &update_values,
- enum_duplicates duplic,
- COND **where, bool select_insert,
- bool check_fields, bool abort_on_warning)
+ enum_duplicates duplic, COND **where,
+ bool select_insert)
{
SELECT_LEX *select_lex= &thd->lex->select_lex;
Name_resolution_context *context= &select_lex->context;
@@ -1481,17 +1525,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
check_insert_fields(thd, context->table_list, fields, *values,
!insert_into_view, 0, &map));
- if (!res && check_fields)
- {
- bool saved_abort_on_warning= thd->abort_on_warning;
- thd->abort_on_warning= abort_on_warning;
- res= check_that_all_fields_are_given_values(thd,
- table ? table :
- context->table_list->table,
- context->table_list);
- thd->abort_on_warning= saved_abort_on_warning;
- }
-
if (!res)
res= setup_fields(thd, Ref_ptr_array(),
update_values, MARK_COLUMNS_READ, 0, 0);
@@ -1927,8 +1960,8 @@ before_trg_err:
Check that all fields with arn't null_fields are used
******************************************************************************/
-int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
- TABLE_LIST *table_list)
+
+int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, TABLE_LIST *table_list)
{
int err= 0;
MY_BITMAP *write_set= entry->write_set;
@@ -1936,32 +1969,8 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
for (Field **field=entry->field ; *field ; field++)
{
if (!bitmap_is_set(write_set, (*field)->field_index) &&
- ((*field)->flags & NO_DEFAULT_VALUE_FLAG) &&
- ((*field)->real_type() != MYSQL_TYPE_ENUM))
- {
- bool view= FALSE;
- if (table_list)
- {
- table_list= table_list->top_table();
- view= MY_TEST(table_list->view);
- }
- if (view)
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_NO_DEFAULT_FOR_VIEW_FIELD,
- ER_THD(thd, ER_NO_DEFAULT_FOR_VIEW_FIELD),
- table_list->view_db.str,
- table_list->view_name.str);
- }
- else
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_NO_DEFAULT_FOR_FIELD,
- ER_THD(thd, ER_NO_DEFAULT_FOR_FIELD),
- (*field)->field_name);
- }
- err= 1;
- }
+ has_no_default_value(thd, *field, table_list))
+ err=1;
}
return thd->abort_on_warning ? err : 0;
}
@@ -3430,9 +3439,8 @@ bool mysql_insert_select_prepare(THD *thd)
if (mysql_prepare_insert(thd, lex->query_tables,
lex->query_tables->table, lex->field_list, 0,
- lex->update_list, lex->value_list,
- lex->duplicates,
- &select_lex->where, TRUE, FALSE, FALSE))
+ lex->update_list, lex->value_list, lex->duplicates,
+ &select_lex->where, TRUE))
DBUG_RETURN(TRUE);
DBUG_ASSERT(select_lex->leaf_tables.elements != 0);
@@ -3519,8 +3527,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
bool saved_abort_on_warning= thd->abort_on_warning;
thd->abort_on_warning= !info.ignore && thd->is_strict_mode();
- res= check_that_all_fields_are_given_values(thd, table_list->table,
- table_list);
+ res= check_that_all_fields_are_given_values(thd, table_list->table, table_list);
thd->abort_on_warning= saved_abort_on_warning;
}
diff --git a/sql/sql_insert.h b/sql/sql_insert.h
index cbfc1ea9dcd..aea0dac6b0d 100644
--- a/sql/sql_insert.h
+++ b/sql/sql_insert.h
@@ -27,8 +27,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
List<Item> &fields, List_item *values,
List<Item> &update_fields,
List<Item> &update_values, enum_duplicates duplic,
- COND **where, bool select_insert,
- bool check_fields, bool abort_on_warning);
+ COND **where, bool select_insert);
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag,
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index c028d49d620..491ed37e63a 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4590,6 +4590,12 @@ bool st_select_lex::is_merged_child_of(st_select_lex *ancestor)
{
continue;
}
+
+ if (sl->master_unit()->derived &&
+ sl->master_unit()->derived->is_merged_derived())
+ {
+ continue;
+ }
all_merged= FALSE;
break;
}
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 6f0e97a61c9..138f5de11e9 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1463,7 +1463,7 @@ READ_INFO::READ_INFO(THD *thd, File file_par, uint tot_length, CHARSET_INFO *cs,
stack= stack_pos= (int*) thd->alloc(sizeof(int) * length);
if (data.reserve(tot_length))
- error=1; /* purecov: inspected */
+ error= 1; /* purecov: inspected */
else
{
if (init_io_cache(&cache,(get_it_from_net) ? -1 : file, 0,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 53482454491..11faaaef129 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5964,11 +5964,8 @@ end_with_restore_list:
}
case SQLCOM_SHOW_CREATE_TRIGGER:
{
- if (lex->spname->m_name.length > NAME_LEN)
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
+ if (check_ident_length(&lex->spname->m_name))
goto error;
- }
#ifdef WITH_WSREP
if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd)) goto error;
@@ -9668,6 +9665,18 @@ bool check_string_char_length(LEX_STRING *str, uint err_msg,
return TRUE;
}
+
+bool check_ident_length(LEX_STRING *ident)
+{
+ if (check_string_char_length(ident, 0, NAME_CHAR_LEN, system_charset_info, 1))
+ {
+ my_error(ER_TOO_LONG_IDENT, MYF(0), ident->str);
+ return 1;
+ }
+ return 0;
+}
+
+
C_MODE_START
/*
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index ad29bb2cdd3..d669f36acef 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -77,6 +77,7 @@ bool check_string_byte_length(LEX_STRING *str, uint err_msg,
bool check_string_char_length(LEX_STRING *str, uint err_msg,
uint max_char_length, CHARSET_INFO *cs,
bool no_error);
+bool check_ident_length(LEX_STRING *ident);
CHARSET_INFO* merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl);
CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs);
bool check_host_name(LEX_STRING *str);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index d7a23a41002..853079dd36a 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1358,7 +1358,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
if (mysql_prepare_insert(thd, table_list, table_list->table,
fields, values, update_fields, update_values,
- duplic, &unused_conds, FALSE, FALSE, FALSE))
+ duplic, &unused_conds, FALSE))
goto error;
value_count= values->elements;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2889e1e1549..899cd05f712 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016 Oracle and/or its affiliates.
- Copyright (c) 2009, 2016 MariaDB
+ Copyright (c) 2009, 2017 MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -788,10 +788,15 @@ JOIN::prepare(TABLE_LIST *tables_init,
if (mixed_implicit_grouping && tbl->table)
tbl->table->maybe_null= 1;
}
+
+ uint real_og_num= og_num;
+ if (skip_order_by &&
+ select_lex != select_lex->master_unit()->global_parameters())
+ real_og_num+= select_lex->order_list.elements;
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num))
DBUG_RETURN(-1);
- if (select_lex->setup_ref_array(thd, og_num))
+ if (select_lex->setup_ref_array(thd, real_og_num))
DBUG_RETURN(-1);
ref_ptrs= ref_ptr_array_slice(0);
@@ -13010,9 +13015,12 @@ COND *Item_cond_and::build_equal_items(THD *thd,
COND_EQUAL cond_equal;
cond_equal.upper_levels= inherited;
+ if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
+ return this; // Fatal error flag is set!
+
List<Item> eq_list;
List<Item> *cond_args= argument_list();
-
+
List_iterator<Item> li(*cond_args);
Item *item;
@@ -13022,7 +13030,7 @@ COND *Item_cond_and::build_equal_items(THD *thd,
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.
- */
+ */
while ((item= li++))
{
/*
@@ -17826,7 +17834,7 @@ do_select(JOIN *join, Procedure *procedure)
}
join->procedure= procedure;
- join->send_records=0;
+ join->duplicate_rows= join->send_records= 0;
if (join->only_const_tables() && !join->need_tmp)
{
Next_select_func end_select= setup_end_select_func(join, NULL);
@@ -17889,7 +17897,7 @@ do_select(JOIN *join, Procedure *procedure)
error= join->first_select(join,join_tab,1);
}
- join->thd->limit_found_rows= join->send_records;
+ join->thd->limit_found_rows= join->send_records - join->duplicate_rows;
if (error == NESTED_LOOP_NO_MORE_ROWS || join->thd->killed == ABORT_QUERY)
error= NESTED_LOOP_OK;
@@ -19503,10 +19511,14 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
if (join->do_send_rows)
{
- int error;
/* result < 0 if row was not accepted and should not be counted */
- if ((error= join->result->send_data(*fields)))
- DBUG_RETURN(error < 0 ? NESTED_LOOP_OK : NESTED_LOOP_ERROR);
+ if (int error= join->result->send_data(*fields))
+ {
+ if (error > 0)
+ DBUG_RETURN(NESTED_LOOP_ERROR);
+ // error < 0 => duplicate row
+ join->duplicate_rows++;
+ }
}
++join->send_records;
@@ -19652,7 +19664,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (error < 0)
{
/* Duplicate row, don't count */
- join->send_records--;
+ join->duplicate_rows++;
error= 0;
}
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index f3b59e5d20c..d043e3559f7 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1149,6 +1149,10 @@ public:
(if sql_calc_found_rows is used, LIMIT is ignored)
*/
ha_rows select_limit;
+ /*
+ Number of duplicate rows found in UNION.
+ */
+ ha_rows duplicate_rows;
/**
Used to fetch no more than given amount of rows per one
fetch operation of server side cursor.
@@ -1420,7 +1424,7 @@ public:
sort_and_group= 0;
first_record= 0;
do_send_rows= 1;
- send_records= 0;
+ duplicate_rows= send_records= 0;
found_records= 0;
fetch_limit= HA_POS_ERROR;
thd= thd_arg;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2df3f4ef34a..eb66bc85549 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3475,7 +3475,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->pack_length= dup_field->pack_length;
sql_field->key_length= dup_field->key_length;
sql_field->decimals= dup_field->decimals;
- sql_field->create_length_to_internal_length();
sql_field->unireg_check= dup_field->unireg_check;
/*
We're making one field from two, the result field will have
@@ -3485,6 +3484,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (!(sql_field->flags & NOT_NULL_FLAG))
null_fields--;
sql_field->flags= dup_field->flags;
+ sql_field->create_length_to_internal_length();
sql_field->interval= dup_field->interval;
sql_field->vcol_info= dup_field->vcol_info;
it2.remove(); // Remove first (create) definition
@@ -3610,12 +3610,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
DBUG_RETURN(TRUE);
}
- if (check_string_char_length(&key->name, 0, NAME_CHAR_LEN,
- system_charset_info, 1))
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), key->name.str);
+ if (check_ident_length(&key->name))
DBUG_RETURN(TRUE);
- }
key_iterator2.rewind ();
if (key->type != Key::FOREIGN_KEY)
{
@@ -4130,7 +4126,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
- !sql_field->default_value &&
+ !sql_field->default_value && !sql_field->vcol_info &&
is_timestamp_type(sql_field->sql_type) &&
(sql_field->flags & NOT_NULL_FLAG) &&
(type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index bd02289b135..f2ad2b3dc0a 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2004, 2012, Oracle and/or its affiliates.
+ Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1206,7 +1207,7 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table)
(table->s->stored_fields != table->s->null_fields))
{
- int null_bytes= (table->s->stored_fields - table->s->null_fields + 7)/8;
+ int null_bytes= (table->s->fields - table->s->null_fields + 7)/8;
if (!(extra_null_bitmap= (uchar*)alloc_root(&table->mem_root, null_bytes)))
return 1;
if (!(record0_field= (Field **)alloc_root(&table->mem_root,
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index db2ef93204c..394fa713445 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -501,12 +501,8 @@ int mysql_create_function(THD *thd,udf_func *udf)
my_message(ER_UDF_NO_PATHS, ER_THD(thd, ER_UDF_NO_PATHS), MYF(0));
DBUG_RETURN(1);
}
- if (check_string_char_length(&udf->name, 0, NAME_CHAR_LEN,
- system_charset_info, 1))
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), udf->name.str);
+ if (check_ident_length(&udf->name))
DBUG_RETURN(1);
- }
tables.init_one_table(STRING_WITH_LEN("mysql"), STRING_WITH_LEN("func"),
"func", TL_WRITE);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ff4a5e12e56..7a5fb1c4fbf 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5195,6 +5195,8 @@ part_name:
{
partition_info *part_info= Lex->part_info;
partition_element *p_elem= part_info->curr_part_elem;
+ if (check_ident_length(&$1))
+ MYSQL_YYABORT;
p_elem->partition_name= $1.str;
}
;
@@ -5499,7 +5501,11 @@ sub_part_definition:
sub_name:
ident_or_text
- { Lex->part_info->curr_part_elem->partition_name= $1.str; }
+ {
+ if (check_ident_length(&$1))
+ MYSQL_YYABORT;
+ Lex->part_info->curr_part_elem->partition_name= $1.str;
+ }
;
opt_part_options:
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index bdfedc30d46..17b1aedd4f1 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
- Copyright (c) 2012, 2016, MariaDB Corporation
+ Copyright (c) 2012, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -641,6 +641,7 @@ static bool check_cs_client(sys_var *self, THD *thd, set_var *var)
if (check_charset_not_null(self, thd, var))
return true;
+ // Currently, UCS-2 cannot be used as a client character set
if (!is_supported_parser_charset((CHARSET_INFO *)(var->save_result.ptr)))
return true;
@@ -5468,6 +5469,13 @@ static Sys_var_ulong Sys_log_tc_size(
BLOCK_SIZE(my_getpagesize()));
#endif
+static Sys_var_ulonglong Sys_max_thread_mem(
+ "max_session_mem_used", "Amount of memory a single user session "
+ "is allowed to allocate. This limits the value of the "
+ "session variable MEM_USED", SESSION_VAR(max_mem_used),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(8192, ULONGLONG_MAX),
+ DEFAULT(LONGLONG_MAX), BLOCK_SIZE(1));
+
#ifndef EMBEDDED_LIBRARY
static Sys_var_sesvartrack Sys_track_session_sys_vars(
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index c7f148afd39..780450b484b 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -1347,7 +1347,7 @@ public:
if (var->value->result_type() == STRING_RESULT)
{
- if (!(res=var->value->val_str(&str)))
+ if (!(res=var->value->val_str_ascii(&str)))
return true;
else
{
diff --git a/sql/table.cc b/sql/table.cc
index 4242b870d55..04f827646a3 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+ Copyright (c) 2008, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -7347,12 +7347,12 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode)
DBUG_PRINT("enter", ("update_mode: %d", update_mode));
Field **vfield_ptr, *vf;
Turn_errors_to_warnings_handler Suppress_errors;
- int error;
+ Query_arena backup_arena;
+ int error= 0;
bool handler_pushed= 0;
DBUG_ASSERT(vfield);
- error= 0;
- in_use->reset_arena_for_cached_items(expr_arena);
+ in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
/* When reading or deleting row, ignore errors from virtual columns */
if (update_mode == VCOL_UPDATE_FOR_READ ||
@@ -7362,6 +7362,7 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode)
in_use->push_internal_handler(&Suppress_errors);
handler_pushed= 1;
}
+
/* Iterate over virtual fields in the table */
for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
{
@@ -7435,7 +7436,7 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode)
}
if (handler_pushed)
in_use->pop_internal_handler();
- in_use->reset_arena_for_cached_items(0);
+ in_use->restore_active_arena(expr_arena, &backup_arena);
/* Return 1 only of we got a fatal error, not a warning */
DBUG_RETURN(in_use->is_error());
@@ -7443,13 +7444,14 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode)
int TABLE::update_virtual_field(Field *vf)
{
+ Query_arena backup_arena;
DBUG_ENTER("TABLE::update_virtual_field");
- in_use->reset_arena_for_cached_items(expr_arena);
+ in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
bitmap_clear_all(&tmp_set);
vf->vcol_info->expr->walk(&Item::update_vcol_processor, 0, &tmp_set);
vf->vcol_info->expr->save_in_field(vf, 0);
- in_use->reset_arena_for_cached_items(0);
+ in_use->restore_active_arena(expr_arena, &backup_arena);
DBUG_RETURN(0);
}
@@ -7478,10 +7480,11 @@ int TABLE::update_default_fields(bool update_command, bool ignore_errors)
{
DBUG_ENTER("TABLE::update_default_fields");
Field **field_ptr;
+ Query_arena backup_arena;
int res= 0;
DBUG_ASSERT(default_field);
- in_use->reset_arena_for_cached_items(expr_arena);
+ in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
/* Iterate over fields with default functions in the table */
for (field_ptr= default_field; *field_ptr ; field_ptr++)
@@ -7509,7 +7512,7 @@ int TABLE::update_default_fields(bool update_command, bool ignore_errors)
res= 0;
}
}
- in_use->reset_arena_for_cached_items(0);
+ in_use->restore_active_arena(expr_arena, &backup_arena);
DBUG_RETURN(res);
}