summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2017-01-12 03:37:35 +0200
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2017-01-12 03:37:35 +0200
commit4f5338467807f099b67f07d0bfb415358222a2b1 (patch)
tree9be13fd51713f08b9f5952e73f673cda824377d6 /sql
parent833fda8f1a0c415ced1f2b8c1851809383bcc639 (diff)
parent1c5ca7c1837b9db071cb2e791d6605f8806af0c1 (diff)
downloadmariadb-git-4f5338467807f099b67f07d0bfb415358222a2b1.tar.gz
Merge branch 'bb-10.0-vicentiu' into 10.0mariadb-10.0.29
Extra merge commit due to intermediate commits pushed to 10.0 while merge was done.
Diffstat (limited to 'sql')
-rw-r--r--sql/event_db_repository.cc15
-rw-r--r--sql/field.cc15
-rw-r--r--sql/filesort.cc2
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item.cc41
-rw-r--r--sql/item_subselect.cc15
-rw-r--r--sql/item_timefunc.cc5
-rw-r--r--sql/mysqld.cc110
-rw-r--r--sql/signal_handler.cc2
-rw-r--r--sql/sp_head.cc22
-rw-r--r--sql/sql_connect.cc13
-rw-r--r--sql/sql_lex.cc6
-rw-r--r--sql/sql_load.cc14
-rw-r--r--sql/sql_parse.cc24
-rw-r--r--sql/sql_parse.h1
-rw-r--r--sql/sql_select.cc23
-rw-r--r--sql/sql_select.h5
-rw-r--r--sql/sql_table.cc8
-rw-r--r--sql/sql_udf.cc6
-rw-r--r--sql/sql_yacc.yy8
-rw-r--r--sql/sys_vars.cc3
-rw-r--r--sql/sys_vars.h2
22 files changed, 172 insertions, 170 deletions
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 6785b46d0da..66606b18c49 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
@@ -704,19 +705,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 49989a4a4ed..dec89e16674 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1269,12 +1269,15 @@ void Field_num::prepend_zeros(String *value)
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);
+ }
}
}
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 6ad7bee48c6..73a6c89e53f 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1629,7 +1629,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 8298d286259..b261983ea0d 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4524,7 +4524,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 ecdb3a94f7f..86f1795a4da 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1206,7 +1206,8 @@ Item *Item_cache::safe_charset_converter(CHARSET_INFO *tocs)
if (conv == example)
return this;
Item_cache *cache;
- if (!conv || !(cache= new Item_cache_str(conv)))
+ if (!conv || conv->fix_fields(current_thd, (Item **) NULL) ||
+ !(cache= new Item_cache_str(conv)))
return NULL; // Safe conversion is not possible, or OEM
cache->setup(conv);
cache->fixed= false; // Make Item::fix_fields() happy
@@ -2742,6 +2743,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_subselect.cc b/sql/item_subselect.cc
index cf09b1801cf..f3a98785a0b 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
@@ -3424,8 +3424,12 @@ bool subselect_union_engine::is_executed() const
bool subselect_union_engine::no_rows()
{
+ bool rows_present= false;
+
/* Check if we got any rows when reading UNION result from temp. table: */
- return MY_TEST(!unit->fake_select_lex->join->send_records);
+ if (unit->fake_select_lex->join)
+ rows_present= MY_TEST(!unit->fake_select_lex->join->send_records);
+ return rows_present;
}
@@ -4808,9 +4812,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
@@ -6564,4 +6568,3 @@ end:
void subselect_table_scan_engine::cleanup()
{
}
-
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 866dbe65ecc..fa1c3d0da90 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -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, Sql_condition::WARN_LEVEL_WARN,
+ make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
val_begin, length,
cached_timestamp_type, NullS);
break;
@@ -708,7 +708,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;
@@ -1460,6 +1460,7 @@ void Item_temporal_func::fix_length_and_dec()
time can get us to return NULL.
*/
maybe_null= 1;
+
if (decimals)
{
if (decimals == NOT_FIXED_DEC)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index fda4fab9d26..6e40168990f 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -123,10 +123,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>
@@ -465,9 +462,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;
@@ -2223,59 +2218,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()
@@ -2292,10 +2246,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
@@ -2303,22 +2253,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 */
}
@@ -4265,19 +4204,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 c3f25848e8a..2029c52d17d 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -149,7 +149,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 b90108ed944..fb0f3132816 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -522,12 +522,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, "", 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;
}
@@ -3120,23 +3116,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_connect.cc b/sql/sql_connect.cc
index c5a0d1464e7..63f9bfae47a 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, 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
@@ -831,6 +831,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
@@ -841,12 +842,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->variables.character_set_client=
- global_system_variables.character_set_client;
- thd->variables.collation_connection=
- global_system_variables.collation_connection;
- thd->variables.character_set_results=
- global_system_variables.character_set_results;
+ DBUG_ASSERT(is_supported_parser_charset(gv->character_set_client));
+ thd->variables.character_set_client= gv->character_set_client;
+ thd->variables.collation_connection= gv->collation_connection;
+ thd->variables.character_set_results= gv->character_set_results;
}
else
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 22489913ded..de450b8ede8 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4274,6 +4274,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 51a284964e1..6d803961621 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1482,7 +1482,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
stack=stack_pos=(int*) sql_alloc(sizeof(int)*length);
if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(MY_WME | MY_THREAD_SPECIFIC))))
- error=1; /* purecov: inspected */
+ error= 1; /* purecov: inspected */
else
{
end_of_buff=buffer+buff_length;
@@ -1748,7 +1748,7 @@ int READ_INFO::read_field()
** We come here if buffer is too small. Enlarge it and continue
*/
if (!(new_buffer=(uchar*) my_realloc((char*) buffer,buff_length+1+IO_SIZE,
- MYF(MY_WME | MY_THREAD_SPECIFIC))))
+ MYF(MY_WME | MY_THREAD_SPECIFIC))))
return (error=1);
to=new_buffer + (to-buffer);
buffer=new_buffer;
@@ -1984,15 +1984,7 @@ int READ_INFO::read_value(int delim, String *val)
for (chr= GET; my_tospace(chr) != delim && chr != my_b_EOF;)
{
#ifdef USE_MB
- uint ml= my_mbcharlen(read_charset, chr);
- if (ml == 0)
- {
- chr= my_b_EOF;
- val->length(0);
- return chr;
- }
-
- if (ml > 1)
+ if (my_mbcharlen(read_charset, chr) > 1)
{
DBUG_PRINT("read_xml",("multi byte"));
int i, ml= my_mbcharlen(read_charset, chr);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 70511fcd849..03bad46ae0e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4921,11 +4921,8 @@ create_sp_error:
}
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;
- }
if (show_create_trigger(thd, lex->spname))
goto error; /* Error has been already logged. */
@@ -6663,12 +6660,9 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
uint8 datetime_precision= length ? atoi(length) : 0;
DBUG_ENTER("add_field_to_list");
- if (check_string_char_length(field_name, "", NAME_CHAR_LEN,
- system_charset_info, 1))
- {
- my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
+ if (check_ident_length(field_name))
DBUG_RETURN(1); /* purecov: inspected */
- }
+
if (type_modifier & PRI_KEY_FLAG)
{
Key *key;
@@ -8443,6 +8437,18 @@ bool check_string_char_length(LEX_STRING *str, const char *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 7a55d8ac4a4..3d11d842259 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -76,6 +76,7 @@ bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
bool check_string_char_length(LEX_STRING *str, const char *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);
bool check_host_name(LEX_STRING *str);
bool check_identifier_name(LEX_STRING *str, uint max_char_length,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 09ceb16fcba..7850c7a0dcf 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -777,10 +777,15 @@ JOIN::prepare(Item ***rref_pointer_array,
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 ((wild_num && setup_wild(thd, tables_list, fields_list, &all_fields,
wild_num)) ||
- select_lex->setup_ref_array(thd, og_num) ||
+ select_lex->setup_ref_array(thd, real_og_num) ||
setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
&all_fields, 1) ||
setup_without_group(thd, (*rref_pointer_array), tables_list,
@@ -3082,7 +3087,7 @@ void JOIN::exec_inner()
*curr_fields_list),
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
error= do_select(curr_join, curr_fields_list, NULL, procedure);
- thd->limit_found_rows= curr_join->send_records;
+ thd->limit_found_rows= curr_join->send_records - curr_join->duplicate_rows;
if (curr_join->order && curr_join->sortorder &&
curr_join->filesort_found_rows)
{
@@ -12765,6 +12770,9 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
COND_EQUAL cond_equal;
cond_equal.upper_levels= inherited;
+ if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
+ return cond; // Fatal error flag is set!
+
if (cond->type() == Item::COND_ITEM)
{
List<Item> eq_list;
@@ -17453,7 +17461,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
join->join_tab[join->top_join_tab_count - 1].next_select= end_select;
join_tab=join->join_tab+join->const_tables;
}
- join->send_records=0;
+ join->duplicate_rows= join->send_records=0;
if (join->table_count == join->const_tables)
{
/*
@@ -18978,7 +18986,12 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
int error;
/* result < 0 if row was not accepted and should not be counted */
if ((error= join->result->send_data(*join->fields)))
- DBUG_RETURN(error < 0 ? NESTED_LOOP_OK : NESTED_LOOP_ERROR);
+ {
+ if (error > 0)
+ DBUG_RETURN(NESTED_LOOP_ERROR);
+ // error < 0 => duplicate row
+ join->duplicate_rows++;
+ }
}
++join->send_records;
@@ -19112,7 +19125,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 cbad287c5e5..d51bca785a5 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1015,7 +1015,8 @@ public:
table_map outer_join;
/* Bitmap of tables used in the select list items */
table_map select_list_used_tables;
- ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
+ ha_rows send_records, found_records, examined_rows,
+ row_limit, select_limit, duplicate_rows;
/**
Used to fetch no more than given amount of rows per one
fetch operation of server side cursor.
@@ -1281,7 +1282,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;
examined_rows= 0;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 31f61301c37..5b5fa27ac7e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3516,7 +3516,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
@@ -3526,6 +3525,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;
sql_field->stored_in_db= dup_field->stored_in_db;
@@ -3652,12 +3652,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, "", 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)
{
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 74d2f6bc252..456a6bd4058 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -453,12 +453,8 @@ int mysql_create_function(THD *thd,udf_func *udf)
my_message(ER_UDF_NO_PATHS, ER(ER_UDF_NO_PATHS), MYF(0));
DBUG_RETURN(1);
}
- if (check_string_char_length(&udf->name, "", 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 bf354496433..aca579f0a98 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5117,6 +5117,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;
}
;
@@ -5411,7 +5413,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 089b6cd9c7e..4adc19231bc 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -34,6 +34,7 @@
#include "sql_plugin.h" // Includes my_global.h
#include "sql_priv.h"
#include "sql_class.h" // set_var.h: THD
+#include "sql_parse.h"
#include "sys_vars.h"
#include "events.h"
@@ -613,7 +614,7 @@ static bool check_cs_client(sys_var *self, THD *thd, set_var *var)
return true;
// Currently, UCS-2 cannot be used as a client character set
- if (((CHARSET_INFO *)(var->save_result.ptr))->mbminlen > 1)
+ if (!is_supported_parser_charset((CHARSET_INFO *)(var->save_result.ptr)))
return true;
return false;
diff --git a/sql/sys_vars.h b/sql/sys_vars.h
index 79b67d3b45c..957c38749ba 100644
--- a/sql/sys_vars.h
+++ b/sql/sys_vars.h
@@ -1235,7 +1235,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
{