summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rwxr-xr-xsql/CMakeLists.txt4
-rw-r--r--sql/field.cc12
-rw-r--r--sql/ha_ndbcluster.cc11
-rw-r--r--sql/handler.cc12
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item.cc13
-rw-r--r--sql/item_cmpfunc.h14
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/item_subselect.cc15
-rw-r--r--sql/item_subselect.h1
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/mysqld.cc24
-rw-r--r--sql/net_serv.cc4
-rw-r--r--sql/set_var.cc4
-rw-r--r--sql/sp_head.cc34
-rw-r--r--sql/sp_head.h4
-rw-r--r--sql/sql_acl.cc10
-rw-r--r--sql/sql_class.cc31
-rw-r--r--sql/sql_class.h6
-rw-r--r--sql/sql_connect.cc7
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_load.cc4
-rw-r--r--sql/sql_parse.cc10
-rw-r--r--sql/sql_plugin.cc30
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/sql_update.cc10
28 files changed, 210 insertions, 75 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 7f6074c903c..1f4c4034e8c 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -49,7 +49,7 @@ SET (SQL_SOURCE
hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc
item_create.cc item_func.cc item_geofunc.cc item_row.cc
item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc
- key.cc log.cc lock.cc message.rc
+ key.cc log.cc lock.cc
log_event.cc rpl_record.cc rpl_reporting.cc
log_event_old.cc rpl_record_old.cc
message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c
@@ -89,7 +89,7 @@ ADD_LIBRARY(sql ${SQL_SOURCE})
IF (NOT EXISTS cmake_dummy.cc)
FILE (WRITE cmake_dummy.cc "")
ENDIF (NOT EXISTS cmake_dummy.cc)
-ADD_EXECUTABLE(mysqld cmake_dummy.cc)
+ADD_EXECUTABLE(mysqld cmake_dummy.cc message.rc)
SET_TARGET_PROPERTIES(mysqld PROPERTIES OUTPUT_NAME mysqld${MYSQLD_EXE_SUFFIX})
SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
diff --git a/sql/field.cc b/sql/field.cc
index b6323d7b839..b203a42a918 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8878,14 +8878,20 @@ bool Field_num::eq_def(Field *field)
}
+/**
+ Check whether two numeric fields can be considered 'equal' for table
+ alteration purposes. Fields are equal if they are of the same type
+ and retain the same pack length.
+*/
+
uint Field_num::is_equal(Create_field *new_field)
{
return ((new_field->sql_type == real_type()) &&
- ((new_field->flags & UNSIGNED_FLAG) == (uint) (flags &
- UNSIGNED_FLAG)) &&
+ ((new_field->flags & UNSIGNED_FLAG) ==
+ (uint) (flags & UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) ==
(uint) (flags & AUTO_INCREMENT_FLAG)) &&
- (new_field->length <= max_display_length()));
+ (new_field->pack_length == pack_length()));
}
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 9fdb8b628ca..9c26105546d 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -7316,13 +7316,6 @@ static int ndbcluster_init(void *p)
if (ndbcluster_inited)
DBUG_RETURN(FALSE);
- /*
- Below we create new THD's. They'll need LOCK_plugin, but it's taken now by
- plugin initialization code. Release it to avoid deadlocks. It's safe, as
- there're no threads that may concurrently access plugin control structures.
- */
- pthread_mutex_unlock(&LOCK_plugin);
-
pthread_mutex_init(&ndbcluster_mutex,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&LOCK_ndb_util_thread, MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_ndb_util_thread, NULL);
@@ -7463,8 +7456,6 @@ static int ndbcluster_init(void *p)
goto ndbcluster_init_error;
}
- pthread_mutex_lock(&LOCK_plugin);
-
ndbcluster_inited= 1;
DBUG_RETURN(FALSE);
@@ -7477,8 +7468,6 @@ ndbcluster_init_error:
g_ndb_cluster_connection= NULL;
ndbcluster_hton->state= SHOW_OPTION_DISABLED; // If we couldn't use handler
- pthread_mutex_lock(&LOCK_plugin);
-
DBUG_RETURN(TRUE);
}
diff --git a/sql/handler.cc b/sql/handler.cc
index 216228ed509..19f397ef09f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -159,7 +159,7 @@ redo:
}
-plugin_ref ha_lock_engine(THD *thd, handlerton *hton)
+plugin_ref ha_lock_engine(THD *thd, const handlerton *hton)
{
if (hton)
{
@@ -601,9 +601,13 @@ static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
there's no need to rollback here as all transactions must
be rolled back already
*/
- if (hton->state == SHOW_OPTION_YES && hton->close_connection &&
- thd_get_ha_data(thd, hton))
- hton->close_connection(hton, thd);
+ if (hton->state == SHOW_OPTION_YES && thd_get_ha_data(thd, hton))
+ {
+ if (hton->close_connection)
+ hton->close_connection(hton, thd);
+ /* make sure ha_data is reset and ha_data_lock is released */
+ thd_set_ha_data(thd, hton, NULL);
+ }
return FALSE;
}
diff --git a/sql/handler.h b/sql/handler.h
index 7fc2bf2fece..d9dfd4f0707 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1956,7 +1956,7 @@ extern ulong total_ha, total_ha_2pc;
/* lookups */
handlerton *ha_default_handlerton(THD *thd);
plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
-plugin_ref ha_lock_engine(THD *thd, handlerton *hton);
+plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
handlerton *db_type);
diff --git a/sql/item.cc b/sql/item.cc
index 809377e80b3..3407d2fecd4 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1713,7 +1713,16 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname,
if (!(conv= (*arg)->safe_charset_converter(coll.collation)) &&
((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII))
- conv= new Item_func_conv_charset(*arg, coll.collation, 1);
+ {
+ /*
+ We should disable const subselect item evaluation because
+ subselect transformation does not happen in view_prepare_mode
+ and thus val_...() methods can not be called for const items.
+ */
+ bool resolve_const= ((*arg)->type() == Item::SUBSELECT_ITEM &&
+ thd->lex->view_prepare_mode) ? FALSE : TRUE;
+ conv= new Item_func_conv_charset(*arg, coll.collation, resolve_const);
+ }
if (!conv)
{
@@ -3515,7 +3524,7 @@ void Item_copy_decimal::copy()
{
my_decimal *nr= item->val_decimal(&cached_value);
if (nr && nr != &cached_value)
- memcpy (&cached_value, nr, sizeof (my_decimal));
+ my_decimal2decimal (nr, &cached_value);
null_value= item->null_value;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index f7d222a47d1..4eb27988984 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -54,9 +54,9 @@ public:
/* Allow owner function to use string buffers. */
String value1, value2;
- Arg_comparator(): thd(0), a_cache(0), b_cache(0), set_null(TRUE),
+ Arg_comparator(): comparators(0), thd(0), a_cache(0), b_cache(0), set_null(TRUE),
get_value_a_func(0), get_value_b_func(0) {};
- Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
+ Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), comparators(0), thd(0),
a_cache(0), b_cache(0), set_null(TRUE),
get_value_a_func(0), get_value_b_func(0) {};
@@ -112,6 +112,11 @@ public:
return (owner->type() == Item::FUNC_ITEM &&
((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
}
+ void cleanup()
+ {
+ delete [] comparators;
+ comparators= 0;
+ }
friend class Item_func;
};
@@ -365,6 +370,11 @@ public:
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
uint decimal_precision() const { return 1; }
void top_level_item() { abort_on_null= TRUE; }
+ void cleanup()
+ {
+ Item_int_func::cleanup();
+ cmp.cleanup();
+ }
friend class Arg_comparator;
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 66308215d0b..b53172d631a 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -324,7 +324,7 @@ String *Item_func_concat::val_str(String *str)
}
else if (str->alloced_length() >= res->length()+res2->length())
{
- if (str == res2)
+ if (str->ptr() == res2->ptr())
str->replace(0,0,*res);
else
{
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index f89ca2d7955..f3fcbc4db68 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -122,6 +122,21 @@ void Item_subselect::cleanup()
DBUG_VOID_RETURN;
}
+
+/*
+ We cannot use generic Item::safe_charset_converter() because
+ Subselect transformation does not happen in view_prepare_mode
+ and thus we can not evaluate val_...() for const items.
+*/
+
+Item *Item_subselect::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ Item_func_conv_charset *conv=
+ new Item_func_conv_charset(this, tocs, thd->lex->view_prepare_mode ? 0 : 1);
+ return conv->safe ? conv : NULL;
+}
+
+
void Item_singlerow_subselect::cleanup()
{
DBUG_ENTER("Item_singlerow_subselect::cleanup");
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 467e9b22637..3806e68e377 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -126,6 +126,7 @@ public:
virtual void reset_value_registration() {}
enum_parsing_place place() { return parsing_place; }
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
+ Item *safe_charset_converter(CHARSET_INFO *tocs);
/**
Get the SELECT_LEX structure associated with this Item.
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index c36fb8b8d64..8c1e5501a1b 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3420,7 +3420,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type)
{
if (i)
str->append(',');
- (*order[i]->item)->print(str, query_type);
+ pargs[i + arg_count_field]->print(str, query_type);
if (order[i]->asc)
str->append(STRING_WITH_LEN(" ASC"));
else
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 098ea514cb6..56175d069c5 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1990,6 +1990,7 @@ extern my_bool opt_log, opt_slow_log;
extern ulong log_output_options;
extern my_bool opt_log_queries_not_using_indexes;
extern bool opt_disable_networking, opt_skip_show_db;
+extern bool opt_skip_name_resolve;
extern bool opt_ignore_builtin_innodb;
extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop, shutdown_in_progress;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index bb685ba42e3..0d62c5953fc 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -410,6 +410,7 @@ ulong log_output_options;
my_bool opt_log_queries_not_using_indexes= 0;
bool opt_error_log= IF_WIN(1,0);
bool opt_disable_networking=0, opt_skip_show_db=0;
+bool opt_skip_name_resolve=0;
my_bool opt_character_set_client_handshake= 1;
bool server_id_supplied = 0;
bool opt_endinfo, using_udf_functions;
@@ -7715,6 +7716,7 @@ static int mysql_init_variables(void)
log_output_options= find_bit_type(log_output_str, &log_output_typelib);
opt_bin_log= 0;
opt_disable_networking= opt_skip_show_db=0;
+ opt_skip_name_resolve= 0;
opt_ignore_builtin_innodb= 0;
opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name !
@@ -8241,6 +8243,7 @@ mysqld_get_one_option(int optid,
opt_specialflag|= SPECIAL_NO_HOST_CACHE;
break;
case (int) OPT_SKIP_RESOLVE:
+ opt_skip_name_resolve= 1;
opt_specialflag|=SPECIAL_NO_RESOLVE;
break;
case (int) OPT_SKIP_NETWORKING:
@@ -8834,10 +8837,25 @@ static int fix_paths(void)
*/
if (opt_secure_file_priv)
{
- convert_dirname(buff, opt_secure_file_priv, NullS);
- my_free(opt_secure_file_priv, MYF(0));
- opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE));
+ if (*opt_secure_file_priv == 0)
+ {
+ opt_secure_file_priv= 0;
+ }
+ else
+ {
+ convert_dirname(buff, opt_secure_file_priv, NullS);
+ char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
+ if (secure_file_real_path == 0 ||
+ my_realpath(secure_file_real_path, buff, 0))
+ {
+ sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
+ return 1;
+ }
+ my_free(opt_secure_file_priv, MYF(0));
+ opt_secure_file_priv= secure_file_real_path;
+ }
}
+
return 0;
}
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 73892f31ccf..15c0c581108 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -136,6 +136,9 @@ my_bool my_net_init(NET *net, Vio* vio)
#else
net->query_cache_query= 0;
#endif
+#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+ net->skip_big_packet= FALSE;
+#endif
if (vio != 0) /* If real connection */
{
@@ -949,6 +952,7 @@ my_real_read(NET *net, size_t *complen)
{
#if defined(MYSQL_SERVER) && !defined(NO_ALARM)
if (!net->compress &&
+ net->skip_big_packet &&
!my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
net->error= 3; /* Successfully skiped packet */
#endif
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 0a9541b9f2c..f7d9d9df42e 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -533,6 +533,10 @@ static sys_var_const sys_skip_show_database(&vars, "skip_show_database",
OPT_GLOBAL, SHOW_BOOL,
(uchar*) &opt_skip_show_db);
+static sys_var_const sys_skip_name_resolve(&vars, "skip_name_resolve",
+ OPT_GLOBAL, SHOW_BOOL,
+ (uchar*) &opt_skip_name_resolve);
+
static sys_var_const sys_socket(&vars, "socket",
OPT_GLOBAL, SHOW_CHAR_PTR,
(uchar*) &mysqld_unix_port);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 11d5e5f830b..cadda38053c 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -745,21 +745,12 @@ sp_head::create(THD *thd)
sp_head::~sp_head()
{
+ LEX *lex;
+ sp_instr *i;
DBUG_ENTER("sp_head::~sp_head");
- destroy();
- delete m_next_cached_sp;
- if (m_thd)
- restore_thd_mem_root(m_thd);
- DBUG_VOID_RETURN;
-}
-void
-sp_head::destroy()
-{
- sp_instr *i;
- LEX *lex;
- DBUG_ENTER("sp_head::destroy");
- DBUG_PRINT("info", ("name: %s", m_name.str));
+ /* sp_head::restore_thd_mem_root() must already have been called. */
+ DBUG_ASSERT(m_thd == NULL);
for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
delete i;
@@ -770,21 +761,22 @@ sp_head::destroy()
/*
If we have non-empty LEX stack then we just came out of parser with
error. Now we should delete all auxilary LEXes and restore original
- THD::lex (In this case sp_head::restore_thd_mem_root() was not called
- too, so m_thd points to the current thread context).
- It is safe to not update LEX::ptr because further query string parsing
- and execution will be stopped anyway.
+ THD::lex. It is safe to not update LEX::ptr because further query
+ string parsing and execution will be stopped anyway.
*/
- DBUG_ASSERT(m_lex.is_empty() || m_thd);
while ((lex= (LEX *)m_lex.pop()))
{
- lex_end(m_thd->lex);
- delete m_thd->lex;
- m_thd->lex= lex;
+ THD *thd= lex->thd;
+ lex_end(thd->lex);
+ delete thd->lex;
+ thd->lex= lex;
}
hash_free(&m_sptabs);
hash_free(&m_sroutines);
+
+ delete m_next_cached_sp;
+
DBUG_VOID_RETURN;
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 00c96d44f70..d422adc8927 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -289,10 +289,6 @@ public:
virtual ~sp_head();
- /// Free memory
- void
- destroy();
-
bool
execute_trigger(THD *thd,
const LEX_STRING *db_name,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index a8828d15cae..dd256c70ecb 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -6117,19 +6117,19 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
VOID(pthread_mutex_unlock(&acl_cache->lock));
- int binlog_error=
+ if (result)
+ my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
+
+ result= result |
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- /* error for writing binary log has already been reported */
- if (result && !binlog_error)
- my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
- DBUG_RETURN(result || binlog_error);
+ DBUG_RETURN(result);
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 266064f9f08..bf5af7141c0 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -284,6 +284,37 @@ void **thd_ha_data(const THD *thd, const struct handlerton *hton)
return (void **) &thd->ha_data[hton->slot].ha_ptr;
}
+
+/**
+ Provide a handler data getter to simplify coding
+*/
+extern "C"
+void *thd_get_ha_data(const THD *thd, const struct handlerton *hton)
+{
+ return *thd_ha_data(thd, hton);
+}
+
+
+/**
+ Provide a handler data setter to simplify coding
+ @see thd_set_ha_data() definition in plugin.h
+*/
+extern "C"
+void thd_set_ha_data(THD *thd, const struct handlerton *hton,
+ const void *ha_data)
+{
+ plugin_ref *lock= &thd->ha_data[hton->slot].lock;
+ if (ha_data && !*lock)
+ *lock= ha_lock_engine(NULL, (handlerton*) hton);
+ else if (!ha_data && *lock)
+ {
+ plugin_unlock(NULL, *lock);
+ *lock= NULL;
+ }
+ *thd_ha_data(thd, hton)= (void*) ha_data;
+}
+
+
extern "C"
long long thd_test_options(const THD *thd, long long test_options)
{
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2ddd9358382..4d0552c5b9d 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1264,7 +1264,11 @@ struct Ha_data
@sa trans_register_ha()
*/
Ha_trx_info ha_info[2];
-
+ /**
+ NULL: engine is not bound to this thread
+ non-NULL: engine is bound to this thread, engine shutdown forbidden
+ */
+ plugin_ref lock;
Ha_data() :ha_ptr(NULL) {}
};
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 16f11fe22c4..2039c7f7449 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -471,6 +471,13 @@ check_user(THD *thd, enum enum_server_command command,
}
my_ok(thd);
thd->password= test(passwd_len); // remember for error messages
+ /*
+ Allow the network layer to skip big packets. Although a malicious
+ authenticated session might use this to trick the server to read
+ big packets indefinitely, this is a previously established behavior
+ that needs to be preserved as to not break backwards compatibility.
+ */
+ thd->net.skip_big_packet= TRUE;
/* Ready to handle queries */
DBUG_RETURN(0);
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 5097ca2ad5b..a3776f59241 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2106,6 +2106,7 @@ void st_lex::cleanup_lex_after_parse_error(THD *thd)
*/
if (thd->lex->sphead)
{
+ thd->lex->sphead->restore_thd_mem_root(thd);
delete thd->lex->sphead;
thd->lex->sphead= NULL;
}
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 3fb1b07cf6c..71cf118f577 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -350,9 +350,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
}
else if (opt_secure_file_priv)
{
- char secure_file_real_path[FN_REFLEN];
- (void) my_realpath(secure_file_real_path, opt_secure_file_priv, 0);
- if (strncmp(secure_file_real_path, name, strlen(secure_file_real_path)))
+ if (strncmp(opt_secure_file_priv, name, strlen(opt_secure_file_priv)))
{
/* Read only allowed from within dir specified by secure_file_priv */
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 5228a37f490..11481933c8a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1300,8 +1300,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
We have name + wildcard in packet, separated by endzero
*/
arg_end= strend(packet);
+ uint arg_length= arg_end - packet;
+
+ /* Check given table name length. */
+ if (arg_length >= packet_length || arg_length > NAME_LEN)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ break;
+ }
thd->convert_string(&conv_name, system_charset_info,
- packet, (uint) (arg_end - packet), thd->charset());
+ packet, arg_length, thd->charset());
table_list.alias= table_list.table_name= conv_name.str;
packet= arg_end + 1;
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 0706ef24881..94a2b506207 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1006,9 +1006,14 @@ void plugin_unlock_list(THD *thd, plugin_ref *list, uint count)
static int plugin_initialize(struct st_plugin_int *plugin)
{
+ int ret= 1;
DBUG_ENTER("plugin_initialize");
safe_mutex_assert_owner(&LOCK_plugin);
+ uint state= plugin->state;
+ DBUG_ASSERT(state == PLUGIN_IS_UNINITIALIZED);
+
+ pthread_mutex_unlock(&LOCK_plugin);
if (plugin_type_initialize[plugin->plugin->type])
{
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
@@ -1027,8 +1032,7 @@ static int plugin_initialize(struct st_plugin_int *plugin)
goto err;
}
}
-
- plugin->state= PLUGIN_IS_READY;
+ state= PLUGIN_IS_READY; // plugin->init() succeeded
if (plugin->plugin->status_vars)
{
@@ -1047,7 +1051,8 @@ static int plugin_initialize(struct st_plugin_int *plugin)
if (add_status_vars(array)) // add_status_vars makes a copy
goto err;
#else
- add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
+ if (add_status_vars(plugin->plugin->status_vars))
+ goto err;
#endif /* FIX_LATER */
}
@@ -1067,9 +1072,12 @@ static int plugin_initialize(struct st_plugin_int *plugin)
}
}
- DBUG_RETURN(0);
+ ret= 0;
+
err:
- DBUG_RETURN(1);
+ pthread_mutex_lock(&LOCK_plugin);
+ plugin->state= state;
+ DBUG_RETURN(ret);
}
@@ -1657,6 +1665,12 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
struct st_plugin_int *tmp;
DBUG_ENTER("mysql_install_plugin");
+ if (opt_noacl)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
+ DBUG_RETURN(TRUE);
+ }
+
bzero(&tables, sizeof(tables));
tables.db= (char *)"mysql";
tables.table_name= tables.alias= (char *)"plugin";
@@ -1733,6 +1747,12 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
struct st_plugin_int *plugin;
DBUG_ENTER("mysql_uninstall_plugin");
+ if (opt_noacl)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
+ DBUG_RETURN(TRUE);
+ }
+
bzero(&tables, sizeof(tables));
tables.db= (char *)"mysql";
tables.table_name= tables.alias= (char *)"plugin";
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c8c23e9a602..291432c2bb6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1124,13 +1124,13 @@ JOIN::optimize()
elements may be lost during further having
condition transformation in JOIN::exec.
*/
- if (having && !having->with_sum_func)
+ if (having && const_table_map)
{
- COND *const_cond= make_cond_for_table(having, const_table_map, 0);
- DBUG_EXECUTE("where", print_where(const_cond, "const_having_cond",
- QT_ORDINARY););
- if (const_cond && !const_cond->val_int())
+ having->update_used_tables();
+ having= remove_eq_conds(thd, having, &having_value);
+ if (having_value == Item::COND_FALSE)
{
+ having= new Item_int((longlong) 0,1);
zero_result_cause= "Impossible HAVING noticed after reading const tables";
DBUG_RETURN(0);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index ad72cab664e..1101be67d5e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -6922,6 +6922,13 @@ view_err:
&candidate_key_count))
goto err;
+ DBUG_EXECUTE_IF("alter_table_only_metadata_change", {
+ if (need_copy_table_res != ALTER_TABLE_METADATA_ONLY)
+ goto err; });
+ DBUG_EXECUTE_IF("alter_table_only_index_change", {
+ if (need_copy_table_res != ALTER_TABLE_INDEX_CHANGED)
+ goto err; });
+
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
need_copy_table= need_copy_table_res;
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 63af275cef3..d8141deba63 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1379,6 +1379,16 @@ int multi_update::prepare(List<Item> &not_used_values,
{
table->read_set= &table->def_read_set;
bitmap_union(table->read_set, &table->tmp_set);
+ /*
+ If a timestamp field settable on UPDATE is present then to avoid wrong
+ update force the table handler to retrieve write-only fields to be able
+ to compare records and detect data change.
+ */
+ if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
+ table->timestamp_field &&
+ (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
+ table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
+ bitmap_union(table->read_set, table->write_set);
}
}