summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMats Kindahl <mats@sun.com>2009-02-09 23:51:59 +0100
committerMats Kindahl <mats@sun.com>2009-02-09 23:51:59 +0100
commit8a98664d3b825f7d98d7acd8372079fc6224dfcb (patch)
tree82b5d2468e08a43e31587af5f72ab6d52e5aff5c /sql
parentbd53d21417e2d340758abfeb29f7057221e0da03 (diff)
parent86a11e6a39593db66b56013841adb5059c8d1455 (diff)
downloadmariadb-git-8a98664d3b825f7d98d7acd8372079fc6224dfcb.tar.gz
Merging with 5.1-bugteam.
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_ndbcluster.cc10
-rw-r--r--sql/ha_ndbcluster_binlog.cc19
-rw-r--r--sql/handler.cc4
-rw-r--r--sql/item.cc29
-rw-r--r--sql/item_cmpfunc.cc4
-rw-r--r--sql/item_func.cc7
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_timefunc.h1
-rw-r--r--sql/item_xmlfunc.cc8
-rw-r--r--sql/log.cc7
-rw-r--r--sql/log.h4
-rw-r--r--sql/log_event.cc142
-rw-r--r--sql/log_event.h34
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/mysqld.cc12
-rw-r--r--sql/parse_file.cc5
-rw-r--r--sql/rpl_rli.cc1
-rw-r--r--sql/set_var.cc5
-rw-r--r--sql/share/errmsg.txt48
-rw-r--r--sql/sql_cache.cc3
-rw-r--r--sql/sql_class.cc9
-rw-r--r--sql/sql_class.h9
-rw-r--r--sql/sql_db.cc1
-rw-r--r--sql/sql_delete.cc3
-rw-r--r--sql/sql_error.cc2
-rw-r--r--sql/sql_insert.cc5
-rw-r--r--sql/sql_parse.cc7
-rw-r--r--sql/sql_plugin.cc3
-rw-r--r--sql/sql_repl.cc2
-rw-r--r--sql/sql_select.cc78
-rw-r--r--sql/sql_select.h9
-rw-r--r--sql/sql_table.cc18
-rw-r--r--sql/sql_test.cc2
-rw-r--r--sql/sql_update.cc8
-rw-r--r--sql/unireg.cc4
35 files changed, 337 insertions, 168 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index f7d52d3834e..3454f3558e8 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -5209,6 +5209,7 @@ int ha_ndbcluster::create(const char *name,
strcmp(m_tabname, NDB_SCHEMA_TABLE) == 0))
{
DBUG_PRINT("info", ("Schema distribution table not setup"));
+ DBUG_ASSERT(ndb_schema_share);
DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
single_user_mode = NdbDictionary::Table::SingleUserModeReadWrite;
@@ -6036,6 +6037,7 @@ ha_ndbcluster::delete_table(ha_ndbcluster *h, Ndb *ndb,
if (!ndb_schema_share)
{
DBUG_PRINT("info", ("Schema distribution table not setup"));
+ DBUG_ASSERT(ndb_schema_share);
DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
/* ndb_share reference temporary */
@@ -6217,6 +6219,7 @@ int ha_ndbcluster::delete_table(const char *name)
if (!ndb_schema_share)
{
DBUG_PRINT("info", ("Schema distribution table not setup"));
+ DBUG_ASSERT(ndb_schema_share);
DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
#endif
@@ -6503,8 +6506,11 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(res);
}
#ifdef HAVE_NDB_BINLOG
- if (!ndb_binlog_tables_inited && ndb_binlog_running)
+ if (!ndb_binlog_tables_inited)
+ {
table->db_stat|= HA_READ_ONLY;
+ sql_print_information("table '%s' opened read only", name);
+ }
#endif
DBUG_RETURN(0);
}
@@ -6868,8 +6874,8 @@ static void ndbcluster_drop_database(handlerton *hton, char *path)
if (!ndb_schema_share)
{
DBUG_PRINT("info", ("Schema distribution table not setup"));
+ DBUG_ASSERT(ndb_schema_share);
DBUG_VOID_RETURN;
- //DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
#endif
ndbcluster_drop_database_impl(path);
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 4fd5ee1b402..baf86d739eb 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -815,9 +815,10 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd)
" end_pos BIGINT UNSIGNED NOT NULL, "
" PRIMARY KEY USING HASH (server_id) ) ENGINE=NDB CHARACTER SET latin1");
- const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR,
+ const int no_print_error[6]= {ER_TABLE_EXISTS_ERROR,
701,
702,
+ 721, // Table already exist
4009,
0}; // do not print error 701 etc
run_query(thd, buf, end, no_print_error, TRUE);
@@ -876,9 +877,10 @@ static int ndbcluster_create_schema_table(THD *thd)
" type INT UNSIGNED NOT NULL,"
" PRIMARY KEY USING HASH (db,name) ) ENGINE=NDB CHARACTER SET latin1");
- const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR,
+ const int no_print_error[6]= {ER_TABLE_EXISTS_ERROR,
701,
702,
+ 721, // Table already exist
4009,
0}; // do not print error 701 etc
run_query(thd, buf, end, no_print_error, TRUE);
@@ -919,12 +921,9 @@ int ndbcluster_setup_binlog_table_shares(THD *thd)
{
pthread_mutex_lock(&LOCK_open);
ndb_binlog_tables_inited= TRUE;
- if (ndb_binlog_running)
- {
- if (ndb_extra_logging)
- sql_print_information("NDB Binlog: ndb tables writable");
- close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE);
- }
+ if (ndb_extra_logging)
+ sql_print_information("NDB Binlog: ndb tables writable");
+ close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE);
pthread_mutex_unlock(&LOCK_open);
/* Signal injector thread that all is setup */
pthread_cond_signal(&injector_cond);
@@ -2069,6 +2068,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
ndb_schema_share->use_count));
free_share(&ndb_schema_share);
ndb_schema_share= 0;
+ ndb_binlog_tables_inited= 0;
pthread_mutex_unlock(&ndb_schema_share_mutex);
/* end protect ndb_schema_share */
@@ -3269,6 +3269,7 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
share->key, share->use_count));
free_share(&ndb_apply_status_share);
ndb_apply_status_share= 0;
+ ndb_binlog_tables_inited= 0;
}
DBUG_PRINT("error", ("CLUSTER FAILURE EVENT: "
"%s received share: 0x%lx op: 0x%lx share op: 0x%lx "
@@ -3288,6 +3289,7 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
share->key, share->use_count));
free_share(&ndb_apply_status_share);
ndb_apply_status_share= 0;
+ ndb_binlog_tables_inited= 0;
}
/* ToDo: remove printout */
if (ndb_extra_logging)
@@ -4311,6 +4313,7 @@ err:
ndb_schema_share->use_count));
free_share(&ndb_schema_share);
ndb_schema_share= 0;
+ ndb_binlog_tables_inited= 0;
pthread_mutex_unlock(&ndb_schema_share_mutex);
/* end protect ndb_schema_share */
}
diff --git a/sql/handler.cc b/sql/handler.cc
index 938fb9a63ba..948cb08b13f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2655,8 +2655,12 @@ void handler::print_error(int error, myf errflag)
break;
case HA_ERR_RECORD_FILE_FULL:
case HA_ERR_INDEX_FILE_FULL:
+ {
textno=ER_RECORD_FILE_FULL;
+ /* Write the error message to error log */
+ errflag|= ME_NOREFRESH;
break;
+ }
case HA_ERR_LOCK_WAIT_TIMEOUT:
textno=ER_LOCK_WAIT_TIMEOUT;
break;
diff --git a/sql/item.cc b/sql/item.cc
index 2ee6de97ad0..8356dee0560 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -327,7 +327,7 @@ int Item::save_time_in_field(Field *field)
{
MYSQL_TIME ltime;
if (get_time(&ltime))
- return set_field_to_null(field);
+ return set_field_to_null_with_conversions(field, 0);
field->set_notnull();
return field->store_time(&ltime, MYSQL_TIMESTAMP_TIME);
}
@@ -337,7 +337,7 @@ int Item::save_date_in_field(Field *field)
{
MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
- return set_field_to_null(field);
+ return set_field_to_null_with_conversions(field, 0);
field->set_notnull();
return field->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
}
@@ -1274,13 +1274,26 @@ Item::Type Item_name_const::type() const
valid_args guarantees value_item->basic_const_item(); if type is
FUNC_ITEM, then we have a fudged item_func_neg() on our hands
and return the underlying type.
+ For Item_func_set_collation()
+ e.g. NAME_CONST('name', 'value' COLLATE collation) we return its
+ 'value' argument type.
*/
- return valid_args ?
- (((value_item->type() == FUNC_ITEM) &&
- (((Item_func *) value_item)->functype() == Item_func::NEG_FUNC)) ?
- ((Item_func *) value_item)->key_item()->type() :
- value_item->type()) :
- NULL_ITEM;
+ if (!valid_args)
+ return NULL_ITEM;
+ Item::Type value_type= value_item->type();
+ if (value_type == FUNC_ITEM)
+ {
+ /*
+ The second argument of NAME_CONST('name', 'value') must be
+ a simple constant item or a NEG_FUNC/COLLATE_FUNC.
+ */
+ DBUG_ASSERT(((Item_func *) value_item)->functype() ==
+ Item_func::NEG_FUNC ||
+ ((Item_func *) value_item)->functype() ==
+ Item_func::COLLATE_FUNC);
+ return ((Item_func *) value_item)->key_item()->type();
+ }
+ return value_type;
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 813e50e0693..bd90dd81365 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1623,8 +1623,8 @@ void Item_in_optimizer::cleanup()
bool Item_in_optimizer::is_null()
{
- cache->store(args[0]);
- return (null_value= (cache->null_value || args[1]->is_null()));
+ val_int();
+ return null_value;
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index ff0c22ecfa9..34cb50ee7fa 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3808,6 +3808,13 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
}
+void Item_func_set_user_var::cleanup()
+{
+ Item_func::cleanup();
+ entry= NULL;
+}
+
+
bool Item_func_set_user_var::set_entry(THD *thd, bool create_if_not_exists)
{
if (entry && thd->thread_id == entry_thread_id)
diff --git a/sql/item_func.h b/sql/item_func.h
index e2937a4daf8..d23d821baf6 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1357,6 +1357,7 @@ public:
void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
bool register_field_in_read_map(uchar *arg);
bool set_entry(THD *thd, bool create_if_not_exists);
+ void cleanup();
};
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 94b02d1eaf6..9e3c2e8c89f 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -419,6 +419,7 @@ public:
{
return save_time_in_field(field);
}
+ longlong val_int() { return val_int_from_decimal(); }
bool result_as_longlong() { return TRUE; }
};
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 68d85418324..5601a2b18c6 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -1969,6 +1969,13 @@ my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath)
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH))
return 1;
+ if (xpath->item->type() != Item::XPATH_NODESET)
+ {
+ xpath->lasttok= xpath->prevtok;
+ xpath->error= 1;
+ return 0;
+ }
+
my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH);
return my_xpath_parse_RelativeLocationPath(xpath);
}
@@ -1976,7 +1983,6 @@ static int my_xpath_parse_PathExpr(MY_XPATH *xpath)
{
return my_xpath_parse_LocationPath(xpath) ||
my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(xpath);
-
}
diff --git a/sql/log.cc b/sql/log.cc
index add0c3ff1f2..74dc75702ae 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1450,8 +1450,6 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all)
return 0;
}
-#define YESNO(X) ((X) ? "yes" : "no")
-
/**
This function is called once after each statement.
@@ -2304,6 +2302,7 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
MYSQL_BIN_LOG::MYSQL_BIN_LOG()
:bytes_written(0), prepared_xids(0), file_id(1), open_count(1),
need_start_event(TRUE), m_table_map_version(0),
+ is_relay_log(0),
description_event_for_exec(0), description_event_for_queue(0)
{
/*
@@ -2502,7 +2501,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
*/
description_event_for_queue->created= 0;
/* Don't set log_pos in event header */
- description_event_for_queue->artificial_event=1;
+ description_event_for_queue->set_artificial_event();
if (description_event_for_queue->write(&log_file))
goto err;
@@ -3474,7 +3473,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
to change base names at some point.
*/
Rotate_log_event r(new_name+dirname_length(new_name),
- 0, LOG_EVENT_OFFSET, 0);
+ 0, LOG_EVENT_OFFSET, is_relay_log ? Rotate_log_event::RELAY_LOG : 0);
r.write(&log_file);
bytes_written += r.data_written;
}
diff --git a/sql/log.h b/sql/log.h
index 6346f38a279..d54df8add3b 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -281,6 +281,10 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
public:
MYSQL_LOG::generate_name;
MYSQL_LOG::is_open;
+
+ /* This is relay log */
+ bool is_relay_log;
+
/*
These describe the log's format. This is used only for relay logs.
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 3a3350a4eb8..0e400ac2705 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -53,6 +53,8 @@
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
+
static const char *HA_ERR(int i)
{
switch (i) {
@@ -810,9 +812,8 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
if (is_artificial_event())
{
/*
- We should not do any cleanup on slave when reading this. We
- mark this by setting log_pos to 0. Start_log_event_v3() will
- detect this on reading and set artificial_event=1 for the event.
+ Artificial events are automatically generated and do not exist
+ in master's binary log, so log_pos should be set to 0.
*/
log_pos= 0;
}
@@ -2724,11 +2725,13 @@ void Query_log_event::print_query_header(IO_CACHE* file,
bool need_comma= 0;
my_b_printf(file, "SET ");
print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
- "@@session.foreign_key_checks", &need_comma);
+ "@@session.foreign_key_checks", &need_comma);
print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
- "@@session.sql_auto_is_null", &need_comma);
+ "@@session.sql_auto_is_null", &need_comma);
print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
- "@@session.unique_checks", &need_comma);
+ "@@session.unique_checks", &need_comma);
+ print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
+ "@@session.autocommit", &need_comma);
my_b_printf(file,"%s\n", print_event_info->delimiter);
print_event_info->flags2= flags2;
}
@@ -2893,7 +2896,37 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
- const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
+ if (strcmp("COMMIT", query) == 0 && rli->tables_to_lock)
+ {
+ /*
+ Cleaning-up the last statement context:
+ the terminal event of the current statement flagged with
+ STMT_END_F got filtered out in ndb circular replication.
+ */
+ int error;
+ char llbuff[22];
+ if ((error= rows_event_stmt_cleanup(const_cast<Relay_log_info*>(rli), thd)))
+ {
+ const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
+ "Error in cleaning up after an event preceeding the commit; "
+ "the group log file/position: %s %s",
+ const_cast<Relay_log_info*>(rli)->group_master_log_name,
+ llstr(const_cast<Relay_log_info*>(rli)->group_master_log_pos,
+ llbuff));
+ }
+ /*
+ Executing a part of rli->stmt_done() logics that does not deal
+ with group position change. The part is redundant now but is
+ future-change-proof addon, e.g if COMMIT handling will start checking
+ invariants like IN_STMT flag must be off at committing the transaction.
+ */
+ const_cast<Relay_log_info*>(rli)->inc_event_relay_log_pos();
+ const_cast<Relay_log_info*>(rli)->clear_flag(Relay_log_info::IN_STMT);
+ }
+ else
+ {
+ const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
+ }
/*
Note: We do not need to execute reset_one_shot_variables() if this
@@ -3196,7 +3229,7 @@ Query_log_event::do_shall_skip(Relay_log_info *rli)
#ifndef MYSQL_CLIENT
Start_log_event_v3::Start_log_event_v3()
:Log_event(), created(0), binlog_version(BINLOG_VERSION),
- artificial_event(0), dont_set_created(0)
+ dont_set_created(0)
{
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
}
@@ -3244,7 +3277,7 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
"Most probably mysqld crashed writing it.\n");
}
- if (!artificial_event && created)
+ if (!is_artificial_event() && created)
{
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
/*
@@ -3287,8 +3320,6 @@ Start_log_event_v3::Start_log_event_v3(const char* buf,
// prevent overrun if log is corrupted on disk
server_version[ST_SERVER_VER_LEN-1]= 0;
created= uint4korr(buf+ST_CREATED_OFFSET);
- /* We use log_pos to mark if this was an artificial event or not */
- artificial_event= (log_pos == 0);
dont_set_created= 1;
}
@@ -3730,7 +3761,7 @@ int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
original place when it comes to us; we'll know this by checking
log_pos ("artificial" events have log_pos == 0).
*/
- if (!artificial_event && created && thd->transaction.all.ha_list)
+ if (!is_artificial_event() && created && thd->transaction.all.ha_list)
{
/* This is not an error (XA is safe), just an information */
rli->report(INFORMATION_LEVEL, 0,
@@ -4667,6 +4698,8 @@ Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
#endif
if (flags & DUP_NAME)
new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
+ if (flags & RELAY_LOG)
+ set_relay_log_event();
DBUG_VOID_RETURN;
}
#endif
@@ -4738,8 +4771,6 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli)
DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
- pthread_mutex_lock(&rli->data_lock);
- rli->event_relay_log_pos= my_b_tell(rli->cur_log);
/*
If we are in a transaction or in a group: the only normal case is
when the I/O thread was copying a big transaction, then it was
@@ -4757,23 +4788,24 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli)
relay log, which shall not change the group positions.
*/
if ((server_id != ::server_id || rli->replicate_same_server_id) &&
+ !is_relay_log_event() &&
!rli->is_in_group())
{
+ pthread_mutex_lock(&rli->data_lock);
DBUG_PRINT("info", ("old group_master_log_name: '%s' "
"old group_master_log_pos: %lu",
rli->group_master_log_name,
(ulong) rli->group_master_log_pos));
memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
rli->notify_group_master_log_name_update();
- rli->group_master_log_pos= pos;
- strmake(rli->group_relay_log_name, rli->event_relay_log_name,
- sizeof(rli->group_relay_log_name) - 1);
- rli->notify_group_relay_log_name_update();
- rli->group_relay_log_pos= rli->event_relay_log_pos;
+ rli->inc_group_relay_log_pos(pos, TRUE /* skip_lock */);
DBUG_PRINT("info", ("new group_master_log_name: '%s' "
"new group_master_log_pos: %lu",
rli->group_master_log_name,
(ulong) rli->group_master_log_pos));
+ pthread_mutex_unlock(&rli->data_lock);
+ flush_relay_log_info(rli);
+
/*
Reset thd->options and sql_mode etc, because this could be the signal of
a master's downgrade from 5.0 to 4.0.
@@ -4787,9 +4819,9 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli)
thd->variables.auto_increment_increment=
thd->variables.auto_increment_offset= 1;
}
- pthread_mutex_unlock(&rli->data_lock);
- pthread_cond_broadcast(&rli->data_cond);
- flush_relay_log_info(rli);
+ else
+ rli->inc_event_relay_log_pos();
+
DBUG_RETURN(0);
}
@@ -5945,8 +5977,15 @@ void Create_file_log_event::pack_info(Protocol *protocol)
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
-/*
+/**
Create_file_log_event::do_apply_event()
+ Constructor for Create_file_log_event to intantiate an event
+ from the relay log on the slave.
+
+ @retval
+ 0 Success
+ @retval
+ 1 Failure
*/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
@@ -6015,7 +6054,7 @@ err:
if (fd >= 0)
my_close(fd, MYF(0));
thd_proc_info(thd, 0);
- return error == 0;
+ return error != 0;
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -7396,16 +7435,20 @@ Rows_log_event::do_shall_skip(Relay_log_info *rli)
return Log_event::do_shall_skip(rli);
}
-int
-Rows_log_event::do_update_pos(Relay_log_info *rli)
-{
- DBUG_ENTER("Rows_log_event::do_update_pos");
- int error= 0;
-
- DBUG_PRINT("info", ("flags: %s",
- get_flags(STMT_END_F) ? "STMT_END_F " : ""));
+/**
+ The function is called at Rows_log_event statement commit time,
+ normally from Rows_log_event::do_update_pos() and possibly from
+ Query_log_event::do_apply_event() of the COMMIT.
+ The function commits the last statement for engines, binlog and
+ releases resources have been allocated for the statement.
+
+ @retval 0 Ok.
+ @retval non-zero Error at the commit.
+ */
- if (get_flags(STMT_END_F))
+static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
+{
+ int error;
{
/*
This is the end of a statement or transaction, so close (and
@@ -7447,14 +7490,39 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
thd->reset_current_stmt_binlog_row_based();
- rli->cleanup_context(thd, 0);
- if (error == 0)
+ const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
+ }
+ return error;
+}
+
+/**
+ The method either increments the relay log position or
+ commits the current statement and increments the master group
+ possition if the event is STMT_END_F flagged and
+ the statement corresponds to the autocommit query (i.e replicated
+ without wrapping in BEGIN/COMMIT)
+
+ @retval 0 Success
+ @retval non-zero Error in the statement commit
+ */
+int
+Rows_log_event::do_update_pos(Relay_log_info *rli)
+{
+ DBUG_ENTER("Rows_log_event::do_update_pos");
+ int error= 0;
+
+ DBUG_PRINT("info", ("flags: %s",
+ get_flags(STMT_END_F) ? "STMT_END_F " : ""));
+
+ if (get_flags(STMT_END_F))
+ {
+ if ((error= rows_event_stmt_cleanup(rli, thd)) == 0)
{
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
- */
+ */
rli->stmt_done(log_pos, when);
/*
@@ -7468,11 +7536,13 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
thd->clear_error();
}
else
+ {
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
get_type_str(), m_table->s->db.str,
m_table->s->table_name.str);
+ }
}
else
{
diff --git a/sql/log_event.h b/sql/log_event.h
index e546cff8b7b..1d11d7e2d5f 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -462,6 +462,25 @@ struct sql_ex_info
#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x10
/**
+ @def LOG_EVENT_ARTIFICIAL_F
+
+ Artificial events are created arbitarily and not written to binary
+ log
+
+ These events should not update the master log position when slave
+ SQL thread executes them.
+*/
+#define LOG_EVENT_ARTIFICIAL_F 0x20
+
+/**
+ @def LOG_EVENT_RELAY_LOG_F
+
+ Events with this flag set are created by slave IO thread and written
+ to relay log
+*/
+#define LOG_EVENT_RELAY_LOG_F 0x40
+
+/**
@def OPTIONS_WRITTEN_TO_BIN_LOG
OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must
@@ -984,7 +1003,10 @@ public:
#endif
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
- virtual bool is_artificial_event() { return 0; }
+ void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; }
+ void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; }
+ bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
+ bool is_relay_log_event() const { return flags & LOG_EVENT_RELAY_LOG_F; }
inline bool get_cache_stmt() const { return cache_stmt; }
Log_event(const char* buf, const Format_description_log_event
*description_event);
@@ -2083,12 +2105,6 @@ public:
uint16 binlog_version;
char server_version[ST_SERVER_VER_LEN];
/*
- artifical_event is 1 in the case where this is a generated event that
- should not case any cleanup actions. We handle this in the log by
- setting log_event == 0 (for now).
- */
- bool artificial_event;
- /*
We set this to 1 if we don't want to have the created time in the log,
which is the case when we rollover to a new log.
*/
@@ -2116,7 +2132,6 @@ public:
{
return START_V3_HEADER_LEN; //no variable-sized part
}
- virtual bool is_artificial_event() { return artificial_event; }
protected:
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
@@ -2538,7 +2553,8 @@ class Rotate_log_event: public Log_event
{
public:
enum {
- DUP_NAME= 2 // if constructor should dup the string argument
+ DUP_NAME= 2, // if constructor should dup the string argument
+ RELAY_LOG=4 // rotate event for relay log
};
const char* new_log_ident;
ulonglong pos;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 9ce8077249c..015128cda1f 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1953,6 +1953,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_ignore_builtin_innodb;
extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop, shutdown_in_progress;
extern uint volatile thread_count, thread_running, global_read_lock;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a2ccbc42e77..0213eea889b 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -378,7 +378,7 @@ static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
/* Global variables */
-bool opt_update_log, opt_bin_log;
+bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0;
my_bool opt_log, opt_slow_log;
ulong log_output_options;
my_bool opt_log_queries_not_using_indexes= 0;
@@ -5585,7 +5585,8 @@ enum options_mysqld
OPT_OLD_MODE,
OPT_SLAVE_EXEC_MODE,
OPT_GENERAL_LOG_FILE,
- OPT_SLOW_QUERY_LOG_FILE
+ OPT_SLOW_QUERY_LOG_FILE,
+ OPT_IGNORE_BUILTIN_INNODB
};
@@ -5791,6 +5792,9 @@ Disable with --skip-large-pages.",
(uchar**) &opt_large_pages, (uchar**) &opt_large_pages, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
#endif
+ {"ignore-builtin-innodb", OPT_IGNORE_BUILTIN_INNODB ,
+ "Disable initialization of builtin InnoDB plugin",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection",
(uchar**) &opt_init_connect, (uchar**) &opt_init_connect, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -7484,6 +7488,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_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 !
opt_secure_auth= 0;
@@ -7781,6 +7786,9 @@ mysqld_get_one_option(int optid,
case (int) OPT_BIG_TABLES:
thd_startup_options|=OPTION_BIG_TABLES;
break;
+ case (int) OPT_IGNORE_BUILTIN_INNODB:
+ opt_ignore_builtin_innodb= 1;
+ break;
case (int) OPT_ISAM_LOG:
opt_myisam_log=1;
break;
diff --git a/sql/parse_file.cc b/sql/parse_file.cc
index d3ece194dcd..07ea434e8e0 100644
--- a/sql/parse_file.cc
+++ b/sql/parse_file.cc
@@ -266,6 +266,11 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
if (end_io_cache(&file))
goto err_w_file;
+ if (opt_sync_frm) {
+ if (my_sync(handler, MYF(MY_WME)))
+ goto err_w_file;
+ }
+
if (my_close(handler, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index b6dfd1a1dc8..3a0f784d195 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -155,6 +155,7 @@ int init_relay_log_info(Relay_log_info* rli,
sql_print_error("Failed in open_log() called from init_relay_log_info()");
DBUG_RETURN(1);
}
+ rli->relay_log.is_relay_log= TRUE;
}
/* if file does not exist */
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 07e1528d483..f14068fcfcb 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -275,6 +275,11 @@ static sys_var_const sys_ft_query_expansion_limit(&vars,
static sys_var_const sys_ft_stopword_file(&vars, "ft_stopword_file",
OPT_GLOBAL, SHOW_CHAR_PTR,
(uchar*) &ft_stopword_file);
+
+static sys_var_const sys_ignore_builtin_innodb(&vars, "ignore_builtin_innodb",
+ OPT_GLOBAL, SHOW_BOOL,
+ (uchar*) &opt_ignore_builtin_innodb);
+
sys_var_str sys_init_connect(&vars, "init_connect", 0,
sys_update_init_connect,
sys_default_init_connect,0);
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index fd75fee9737..befd064e3e3 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -571,30 +571,30 @@ ER_ERROR_ON_READ
swe "Fick fel vid läsning av '%-.200s' (Felkod %d)"
ukr "îÅ ÍÏÖÕ ÐÒÏÞÉÔÁÔÉ ÆÁÊÌ '%-.200s' (ÐÏÍÉÌËÁ: %d)"
ER_ERROR_ON_RENAME
- cze "Chyba p-Bøi pøejmenování '%-.150s' na '%-.150s' (chybový kód: %d)"
- dan "Fejl ved omdøbning af '%-.150s' til '%-.150s' (Fejlkode: %d)"
- nla "Fout bij het hernoemen van '%-.150s' naar '%-.150s' (Errcode: %d)"
- eng "Error on rename of '%-.150s' to '%-.150s' (errno: %d)"
- jps "'%-.150s' ‚ð '%-.150s' ‚É rename ‚Å‚«‚Ü‚¹‚ñ (errno: %d)",
- est "Viga faili '%-.150s' ümbernimetamisel '%-.150s'-ks (veakood: %d)"
- fre "Erreur en renommant '%-.150s' en '%-.150s' (Errcode: %d)"
- ger "Fehler beim Umbenennen von '%-.150s' in '%-.150s' (Fehler: %d)"
- greek "Ðñüâëçìá êáôÜ ôçí ìåôïíïìáóßá ôïõ áñ÷åßïõ '%-.150s' to '%-.150s' (êùäéêüò ëÜèïõò: %d)"
- hun "Hiba a '%-.150s' file atnevezesekor '%-.150s'. (hibakod: %d)"
- ita "Errore durante la rinominazione da '%-.150s' a '%-.150s' (errno: %d)"
- jpn "'%-.150s' ¤ò '%-.150s' ¤Ë rename ¤Ç¤­¤Þ¤»¤ó (errno: %d)"
- kor "'%-.150s'¸¦ '%-.150s'·Î À̸§ º¯°æÁß ¿¡·¯ (¿¡·¯¹øÈ£: %d)"
- nor "Feil ved omdøping av '%-.150s' til '%-.150s' (Feilkode: %d)"
- norwegian-ny "Feil ved omdøyping av '%-.150s' til '%-.150s' (Feilkode: %d)"
- pol "B³?d podczas zmieniania nazwy '%-.150s' na '%-.150s' (Kod b³êdu: %d)"
- por "Erro ao renomear '%-.150s' para '%-.150s' (erro no. %d)"
- rum "Eroare incercind sa renumesc '%-.150s' in '%-.150s' (errno: %d)"
- rus "ïÛÉÂËÁ ÐÒÉ ÐÅÒÅÉÍÅÎÏ×ÁÎÉÉ '%-.150s' × '%-.150s' (ÏÛÉÂËÁ: %d)"
- serbian "Greška pri promeni imena '%-.150s' na '%-.150s' (errno: %d)"
- slo "Chyba pri premenovávaní '%-.150s' na '%-.150s' (chybový kód: %d)"
- spa "Error en el renombrado de '%-.150s' a '%-.150s' (Error: %d)"
- swe "Kan inte byta namn från '%-.150s' till '%-.150s' (Felkod: %d)"
- ukr "îÅ ÍÏÖÕ ÐÅÒÅÊÍÅÎÕ×ÁÔÉ '%-.150s' Õ '%-.150s' (ÐÏÍÉÌËÁ: %d)"
+ cze "Chyba p-Bøi pøejmenování '%-.210s' na '%-.210s' (chybový kód: %d)"
+ dan "Fejl ved omdøbning af '%-.210s' til '%-.210s' (Fejlkode: %d)"
+ nla "Fout bij het hernoemen van '%-.210s' naar '%-.210s' (Errcode: %d)"
+ eng "Error on rename of '%-.210s' to '%-.210s' (errno: %d)"
+ jps "'%-.210s' ‚ð '%-.210s' ‚É rename ‚Å‚«‚Ü‚¹‚ñ (errno: %d)",
+ est "Viga faili '%-.210s' ümbernimetamisel '%-.210s'-ks (veakood: %d)"
+ fre "Erreur en renommant '%-.210s' en '%-.210s' (Errcode: %d)"
+ ger "Fehler beim Umbenennen von '%-.210s' in '%-.210s' (Fehler: %d)"
+ greek "Ðñüâëçìá êáôÜ ôçí ìåôïíïìáóßá ôïõ áñ÷åßïõ '%-.210s' to '%-.210s' (êùäéêüò ëÜèïõò: %d)"
+ hun "Hiba a '%-.210s' file atnevezesekor '%-.210s'. (hibakod: %d)"
+ ita "Errore durante la rinominazione da '%-.210s' a '%-.210s' (errno: %d)"
+ jpn "'%-.210s' ¤ò '%-.210s' ¤Ë rename ¤Ç¤­¤Þ¤»¤ó (errno: %d)"
+ kor "'%-.210s'¸¦ '%-.210s'·Î À̸§ º¯°æÁß ¿¡·¯ (¿¡·¯¹øÈ£: %d)"
+ nor "Feil ved omdøping av '%-.210s' til '%-.210s' (Feilkode: %d)"
+ norwegian-ny "Feil ved omdøyping av '%-.210s' til '%-.210s' (Feilkode: %d)"
+ pol "B³?d podczas zmieniania nazwy '%-.210s' na '%-.210s' (Kod b³êdu: %d)"
+ por "Erro ao renomear '%-.210s' para '%-.210s' (erro no. %d)"
+ rum "Eroare incercind sa renumesc '%-.210s' in '%-.210s' (errno: %d)"
+ rus "ïÛÉÂËÁ ÐÒÉ ÐÅÒÅÉÍÅÎÏ×ÁÎÉÉ '%-.210s' × '%-.210s' (ÏÛÉÂËÁ: %d)"
+ serbian "Greška pri promeni imena '%-.210s' na '%-.210s' (errno: %d)"
+ slo "Chyba pri premenovávaní '%-.210s' na '%-.210s' (chybový kód: %d)"
+ spa "Error en el renombrado de '%-.210s' a '%-.210s' (Error: %d)"
+ swe "Kan inte byta namn från '%-.210s' till '%-.210s' (Felkod: %d)"
+ ukr "îÅ ÍÏÖÕ ÐÅÒÅÊÍÅÎÕ×ÁÔÉ '%-.210s' Õ '%-.210s' (ÐÏÍÉÌËÁ: %d)"
ER_ERROR_ON_WRITE
cze "Chyba p-Bøi zápisu do souboru '%-.200s' (chybový kód: %d)"
dan "Fejl ved skriving av filen '%-.200s' (Fejlkode: %d)"
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 5e098edbd7f..7c97ee4cf32 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -781,6 +781,9 @@ void query_cache_end_of_result(THD *thd)
if (thd->net.query_cache_query == 0)
DBUG_VOID_RETURN;
+ /* Ensure that only complete results are cached. */
+ DBUG_ASSERT(thd->main_da.is_eof());
+
if (thd->killed)
{
query_cache_abort(&thd->net);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index ecda2b33d5b..118dc5af68f 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3601,7 +3601,6 @@ show_query_type(THD::enum_binlog_query_type qtype)
default:
DBUG_ASSERT(0 <= qtype && qtype < THD::QUERY_TYPE_COUNT);
}
-
static char buf[64];
sprintf(buf, "UNKNOWN#%d", qtype);
return buf;
@@ -3661,16 +3660,14 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
if (lex->is_stmt_unsafe() &&
variables.binlog_format == BINLOG_FORMAT_STMT)
{
- DBUG_ASSERT(this->query != NULL);
push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BINLOG_UNSAFE_STATEMENT,
ER(ER_BINLOG_UNSAFE_STATEMENT));
if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
{
- char warn_buf[MYSQL_ERRMSG_SIZE];
- my_snprintf(warn_buf, MYSQL_ERRMSG_SIZE, "%s Statement: %s",
- ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
- sql_print_warning(warn_buf);
+ sql_print_warning("%s Statement: %.*s",
+ ER(ER_BINLOG_UNSAFE_STATEMENT),
+ MYSQL_ERRMSG_SIZE, query_arg);
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
}
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 7ee4fe84f4d..3439e5b4f74 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1010,6 +1010,7 @@ show_system_thread(enum_thread_type thread)
{
#define RETURN_NAME_AS_STRING(NAME) case (NAME): return #NAME
switch (thread) {
+ static char buf[64];
RETURN_NAME_AS_STRING(NON_SYSTEM_THREAD);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_DELAYED_INSERT);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_SLAVE_IO);
@@ -1017,9 +1018,11 @@ show_system_thread(enum_thread_type thread)
RETURN_NAME_AS_STRING(SYSTEM_THREAD_NDBCLUSTER_BINLOG);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_SCHEDULER);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_WORKER);
+ default:
+ sprintf(buf, "<UNKNOWN SYSTEM THREAD: %d>", thread);
+ return buf;
}
#undef RETURN_NAME_AS_STRING
- return "UNKNOWN"; /* keep gcc happy */
}
/**
@@ -2118,8 +2121,8 @@ public:
Don't reset binlog format for NDB binlog injector thread.
*/
DBUG_PRINT("debug",
- ("temporary_tables: %p, in_sub_stmt: %d, system_thread: %s",
- temporary_tables, in_sub_stmt,
+ ("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
+ YESNO(temporary_tables), YESNO(in_sub_stmt),
show_system_thread(system_thread)));
if ((temporary_tables == NULL) && (in_sub_stmt == 0) &&
(system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG))
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index c538dfb08bc..72ae664bba1 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -907,7 +907,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
remove_db_from_cache(db);
pthread_mutex_unlock(&LOCK_open);
-
error= -1;
/*
We temporarily disable the binary log while dropping the objects
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index b37e2a24895..d87eafa3e0c 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -1028,6 +1028,9 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
share->db.str,
share->table_name.str, 1))))
(void) rm_temporary_table(table_type, path);
+ else
+ thd->thread_specific_used= TRUE;
+
free_table_share(share);
my_free((char*) table,MYF(0));
/*
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 79da1936eb9..bd8f9469571 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -177,7 +177,7 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
uint code, const char *format, ...)
{
va_list args;
- char warning[ERRMSGSIZE+20];
+ char warning[MYSQL_ERRMSG_SIZE];
DBUG_ENTER("push_warning_printf");
DBUG_PRINT("enter",("warning: %u", code));
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index fb437bed3fa..fcf86edeaa9 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1690,6 +1690,7 @@ public:
class Delayed_insert :public ilink {
uint locks_in_memory;
+ thr_lock_type delayed_lock;
public:
THD thd;
TABLE *table;
@@ -1731,6 +1732,8 @@ public:
pthread_cond_init(&cond_client,NULL);
VOID(pthread_mutex_lock(&LOCK_thread_count));
delayed_insert_threads++;
+ delayed_lock= global_system_variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY : TL_WRITE;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
}
~Delayed_insert()
@@ -2540,7 +2543,7 @@ bool Delayed_insert::handle_inserts(void)
table->use_all_columns();
thd_proc_info(&thd, "upgrading lock");
- if (thr_upgrade_write_delay_lock(*thd.lock->locks))
+ if (thr_upgrade_write_delay_lock(*thd.lock->locks, delayed_lock))
{
/*
This can happen if thread is killed either by a shutdown
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 99b131c3aef..592dbe9f43b 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5454,9 +5454,10 @@ bool check_stack_overrun(THD *thd, long margin,
if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
(long) (my_thread_stack_size - margin))
{
- sprintf(errbuff[0],ER(ER_STACK_OVERRUN_NEED_MORE),
- stack_used,my_thread_stack_size,margin);
- my_message(ER_STACK_OVERRUN_NEED_MORE,errbuff[0],MYF(0));
+ char ebuff[MYSQL_ERRMSG_SIZE];
+ my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
+ stack_used, my_thread_stack_size, margin);
+ my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
thd->fatal_error();
return 1;
}
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 0df1631294b..60f205ec8e8 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1138,6 +1138,9 @@ int plugin_init(int *argc, char **argv, int flags)
{
for (plugin= *builtins; plugin->info; plugin++)
{
+ if (opt_ignore_builtin_innodb &&
+ !my_strcasecmp(&my_charset_latin1, plugin->name, "InnoDB"))
+ continue;
/* by default, ndbcluster and federated are disabled */
def_enabled=
my_strcasecmp(&my_charset_latin1, plugin->name, "NDBCLUSTER") != 0 &&
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 646bfdaefe8..81db5469891 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -63,7 +63,7 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
ulong event_len = ident_len + LOG_EVENT_HEADER_LEN + ROTATE_HEADER_LEN;
int4store(header + SERVER_ID_OFFSET, server_id);
int4store(header + EVENT_LEN_OFFSET, event_len);
- int2store(header + FLAGS_OFFSET, 0);
+ int2store(header + FLAGS_OFFSET, LOG_EVENT_ARTIFICIAL_F);
// TODO: check what problems this may cause and fix them
int4store(header + LOG_POS_OFFSET, 0);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 49cacbe9272..75c11c2ac64 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -87,7 +87,6 @@ static store_key *get_store_key(THD *thd,
KEYUSE *keyuse, table_map used_tables,
KEY_PART_INFO *key_part, uchar *key_buff,
uint maybe_null);
-static bool make_simple_join(JOIN *join,TABLE *tmp_table);
static void make_outerjoin_info(JOIN *join);
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
static void make_join_readinfo(JOIN *join, ulonglong options);
@@ -1676,8 +1675,13 @@ JOIN::exec()
We have to test for 'conds' here as the WHERE may not be constant
even if we don't have any tables for prepared statements or if
conds uses something like 'rand()'.
+ If the HAVING clause is either impossible or always true, then
+ JOIN::having is set to NULL by optimize_cond.
+ In this case JOIN::exec must check for JOIN::having_value, in the
+ same way it checks for JOIN::cond_value.
*/
if (cond_value != Item::COND_FALSE &&
+ having_value != Item::COND_FALSE &&
(!conds || conds->val_int()) &&
(!having || having->val_int()))
{
@@ -1874,7 +1878,7 @@ JOIN::exec()
/* Free first data from old join */
curr_join->join_free();
- if (make_simple_join(curr_join, curr_tmp_table))
+ if (curr_join->make_simple_join(this, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, group_list);
count_field_types(select_lex, &curr_join->tmp_table_param,
@@ -1997,7 +2001,7 @@ JOIN::exec()
curr_join->select_distinct=0;
}
curr_tmp_table->reginfo.lock_type= TL_UNLOCK;
- if (make_simple_join(curr_join, curr_tmp_table))
+ if (curr_join->make_simple_join(this, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, curr_join->group_list);
count_field_types(select_lex, &curr_join->tmp_table_param,
@@ -5681,48 +5685,42 @@ store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
}
-static bool
-make_simple_join(JOIN *join,TABLE *tmp_table)
+/**
+ @details Initialize a JOIN as a query execution plan
+ that accesses a single table via a table scan.
+
+ @param parent contains JOIN_TAB and TABLE object buffers for this join
+ @param tmp_table temporary table
+
+ @retval FALSE success
+ @retval TRUE error occurred
+*/
+bool
+JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table)
{
- TABLE **tableptr;
- JOIN_TAB *join_tab;
- DBUG_ENTER("make_simple_join");
+ DBUG_ENTER("JOIN::make_simple_join");
/*
Reuse TABLE * and JOIN_TAB if already allocated by a previous call
to this function through JOIN::exec (may happen for sub-queries).
*/
- if (!join->table_reexec)
- {
- if (!(join->table_reexec= (TABLE**) join->thd->alloc(sizeof(TABLE*))))
- DBUG_RETURN(TRUE); /* purecov: inspected */
- if (join->tmp_join)
- join->tmp_join->table_reexec= join->table_reexec;
- }
- if (!join->join_tab_reexec)
- {
- if (!(join->join_tab_reexec=
- (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
- DBUG_RETURN(TRUE); /* purecov: inspected */
- if (join->tmp_join)
- join->tmp_join->join_tab_reexec= join->join_tab_reexec;
- }
- tableptr= join->table_reexec;
- join_tab= join->join_tab_reexec;
-
- join->join_tab=join_tab;
- join->table=tableptr; tableptr[0]=tmp_table;
- join->tables=1;
- join->const_tables=0;
- join->const_table_map=0;
- join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count=
- join->tmp_table_param.func_count=0;
- join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0;
- join->first_record=join->sort_and_group=0;
- join->send_records=(ha_rows) 0;
- join->group=0;
- join->row_limit=join->unit->select_limit_cnt;
- join->do_send_rows = (join->row_limit) ? 1 : 0;
+ if (!parent->join_tab_reexec &&
+ !(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+
+ join_tab= parent->join_tab_reexec;
+ table= &parent->table_reexec[0]; parent->table_reexec[0]= tmp_table;
+ tables= 1;
+ const_tables= 0;
+ const_table_map= 0;
+ tmp_table_param.field_count= tmp_table_param.sum_func_count=
+ tmp_table_param.func_count= 0;
+ tmp_table_param.copy_field= tmp_table_param.copy_field_end=0;
+ first_record= sort_and_group=0;
+ send_records= (ha_rows) 0;
+ group= 0;
+ row_limit= unit->select_limit_cnt;
+ do_send_rows= row_limit ? 1 : 0;
join_tab->cache.buff=0; /* No caching */
join_tab->table=tmp_table;
@@ -5739,7 +5737,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
join_tab->ref.key = -1;
join_tab->not_used_in_distinct=0;
join_tab->read_first_record= join_init_read_record;
- join_tab->join=join;
+ join_tab->join= this;
join_tab->ref.key_parts= 0;
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
tmp_table->status=0;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index c5961f097c2..7d794b71f4d 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -402,9 +402,12 @@ public:
cleared only at the end of the execution of the whole query and not caching
allocations that occur in repetition at execution time will result in
excessive memory usage.
+ Note: make_simple_join always creates an execution plan that accesses
+ a single table, thus it is sufficient to have a one-element array for
+ table_reexec.
*/
SORT_FIELD *sortorder; // make_unireg_sortorder()
- TABLE **table_reexec; // make_simple_join()
+ TABLE *table_reexec[1]; // make_simple_join()
JOIN_TAB *join_tab_reexec; // make_simple_join()
/* end of allocation caching storage */
@@ -434,7 +437,7 @@ public:
exec_tmp_table1= 0;
exec_tmp_table2= 0;
sortorder= 0;
- table_reexec= 0;
+ table_reexec[0]= 0;
join_tab_reexec= 0;
thd= thd_arg;
sum_funcs= sum_funcs2= 0;
@@ -526,6 +529,8 @@ public:
return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 ||
select_lex == unit->fake_select_lex));
}
+private:
+ bool make_simple_join(JOIN *join, TABLE *tmp_table);
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 3ec03be72a5..aa2a5739f17 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4435,8 +4435,8 @@ send_result_message:
switch (result_code) {
case HA_ADMIN_NOT_IMPLEMENTED:
{
- char buf[ERRMSGSIZE+20];
- uint length=my_snprintf(buf, ERRMSGSIZE,
+ char buf[MYSQL_ERRMSG_SIZE];
+ uint length=my_snprintf(buf, sizeof(buf),
ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
protocol->store(STRING_WITH_LEN("note"), system_charset_info);
protocol->store(buf, length, system_charset_info);
@@ -4445,8 +4445,8 @@ send_result_message:
case HA_ADMIN_NOT_BASE_TABLE:
{
- char buf[ERRMSGSIZE+20];
- uint length= my_snprintf(buf, ERRMSGSIZE,
+ char buf[MYSQL_ERRMSG_SIZE];
+ uint length= my_snprintf(buf, sizeof(buf),
ER(ER_BAD_TABLE_ERROR), table_name);
protocol->store(STRING_WITH_LEN("note"), system_charset_info);
protocol->store(buf, length, system_charset_info);
@@ -4573,11 +4573,12 @@ send_result_message:
case HA_ADMIN_NEEDS_UPGRADE:
case HA_ADMIN_NEEDS_ALTER:
{
- char buf[ERRMSGSIZE];
+ char buf[MYSQL_ERRMSG_SIZE];
uint length;
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
- length=my_snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
+ length=my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_UPGRADE),
+ table->table_name);
protocol->store(buf, length, system_charset_info);
fatal_error=1;
break;
@@ -4585,8 +4586,8 @@ send_result_message:
default: // Probably HA_ADMIN_INTERNAL_ERROR
{
- char buf[ERRMSGSIZE+20];
- uint length=my_snprintf(buf, ERRMSGSIZE,
+ char buf[MYSQL_ERRMSG_SIZE];
+ uint length=my_snprintf(buf, sizeof(buf),
"Unknown - internal error %d during operation",
result_code);
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
@@ -4983,6 +4984,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
dst_path); /* purecov: inspected */
goto err; /* purecov: inspected */
}
+ thd->thread_specific_used= TRUE;
}
else if (err)
{
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 01363714484..78932396efe 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -513,7 +513,7 @@ Next alarm time: %lu\n",
fprintf(stdout,"\nBegin safemalloc memory dump:\n"); // tag needed for test suite
TERMINATE(stdout, 1); // Write malloc information
fprintf(stdout,"\nEnd safemalloc memory dump.\n");
-
+ fflush(stdout);
#ifdef HAVE_MALLINFO
struct mallinfo info= mallinfo();
printf("\nMemory status:\n\
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index f448fb7ab50..b3bd5d0bc57 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -526,9 +526,11 @@ int mysql_update(THD *thd,
init_read_record(&info, thd, table, select, 0, 1, FALSE);
updated= found= 0;
- /* Generate an error when trying to set a NOT NULL field to NULL. */
- thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
- : CHECK_FIELD_ERROR_FOR_NULL;
+ /*
+ Generate an error (in TRADITIONAL mode) or warning
+ when trying to set a NOT NULL field to NULL.
+ */
+ thd->count_cuted_fields= CHECK_FIELD_WARN;
thd->cuted_fields=0L;
thd_proc_info(thd, "Updating");
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 7b770ab733e..da018ebec3d 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -92,8 +92,8 @@ handle_error(uint sql_errno,
db_file Handler to use. May be zero, in which case we use
create_info->db_type
RETURN
- 0 ok
- 1 error
+ false ok
+ true error
*/
bool mysql_create_frm(THD *thd, const char *file_name,