summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <serg@serg.mylan>2005-03-22 16:11:43 +0100
committerunknown <serg@serg.mylan>2005-03-22 16:11:43 +0100
commite31642727b405e83ed0512a6c3318869f2a31e0c (patch)
treecb3fd62572918eb80e7c2add26636565c33ecace /sql
parent82182de38722242c3ec5c6b7d77bdbfe271b4bc5 (diff)
parent6ed02debff53e895e6c526fbbeac7c791e1f269f (diff)
downloadmariadb-git-e31642727b405e83ed0512a6c3318869f2a31e0c.tar.gz
Merge bk-internal:/home/bk/mysql-5.0
into serg.mylan:/usr/home/serg/Abk/mysql-5.0 innobase/include/trx0trx.h: Auto merged sql/ha_innodb.cc: Auto merged sql/handler.cc: Auto merged sql/item.cc: Auto merged sql/log_event.cc: Auto merged sql/mysql_priv.h: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_innodb.cc4
-rw-r--r--sql/handler.cc14
-rw-r--r--sql/item.cc14
-rw-r--r--sql/item_sum.cc20
-rw-r--r--sql/log.cc51
-rw-r--r--sql/log_event.cc171
-rw-r--r--sql/log_event.h45
-rw-r--r--sql/my_decimal.cc4
-rw-r--r--sql/my_decimal.h46
-rw-r--r--sql/mysql_priv.h6
-rw-r--r--sql/mysqld.cc7
-rw-r--r--sql/set_var.cc56
-rw-r--r--sql/set_var.h6
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/slave.cc19
-rw-r--r--sql/slave.h1
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_select.cc16
-rw-r--r--sql/sql_string.h5
-rw-r--r--sql/sql_table.cc9
-rw-r--r--sql/table.cc10
-rw-r--r--sql/tztime.cc56
-rw-r--r--sql/tztime.h7
23 files changed, 323 insertions, 248 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 072f6866d7a..349a69e5a80 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -1309,6 +1309,9 @@ innobase_end(void)
}
#endif
if (innodb_inited) {
+
+#ifndef __NETWARE__ /* NetWare can't close unclosed files, kill remaining
+ threads, etc, so we disable the very fast shutdown */
if (innobase_very_fast_shutdown) {
srv_very_fast_shutdown = TRUE;
fprintf(stderr,
@@ -1316,6 +1319,7 @@ innobase_end(void)
"InnoDB: the InnoDB buffer pool to data files. At the next mysqld startup\n"
"InnoDB: InnoDB will do a crash recovery!\n");
}
+#endif
innodb_inited = 0;
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
diff --git a/sql/handler.cc b/sql/handler.cc
index 78f9ce61d57..d23553014ef 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -764,14 +764,13 @@ static char* xid_to_str(char *buf, XID *xid)
for (i=0; i < xid->gtrid_length+xid->bqual_length; i++)
{
uchar c=(uchar)xid->data[i];
- bool is_next_dig;
+ /* is_next_dig is set if next character is a number */
+ bool is_next_dig= FALSE;
if (i < XIDDATASIZE)
{
- char ch=xid->data[i+1];
- is_next_dig=(c >= '0' && c <='9');
+ char ch= xid->data[i+1];
+ is_next_dig= (ch >= '0' && ch <='9');
}
- else
- is_next_dig=FALSE;
if (i == xid->gtrid_length)
{
*s++='\'';
@@ -784,6 +783,11 @@ static char* xid_to_str(char *buf, XID *xid)
if (c < 32 || c > 126)
{
*s++='\\';
+ /*
+ If next character is a number, write current character with
+ 3 octal numbers to ensure that the next number is not seen
+ as part of the octal number
+ */
if (c > 077 || is_next_dig)
*s++=_dig_vec_lower[c >> 6];
if (c > 007 || is_next_dig)
diff --git a/sql/item.cc b/sql/item.cc
index 69aaec44f55..457aa774352 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -586,18 +586,8 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
return NULL;
}
conv->str_value.copy();
- /*
- The above line executes str_value.realloc() internally,
- which alligns Alloced_length using ALLIGN_SIZE.
- In the case of Item_string::str_value we don't want
- Alloced_length to be longer than str_length.
- Otherwise, some functions like Item_func_concat::val_str()
- try to reuse str_value as a buffer for concatenation result
- for optimization purposes, so our string constant become
- corrupted. See bug#8785 for more details.
- Let's shrink Alloced_length to str_length to avoid this problem.
- */
- conv->str_value.shrink_to_length();
+ /* Ensure that no one is going to change the result string */
+ conv->str_value.mark_as_const();
return conv;
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 9fc68931ef6..49f32cb0245 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2158,7 +2158,7 @@ int composite_key_cmp(void* arg, byte* key1, byte* key2)
}
-static int count_distinct_walk(void *elem, unsigned int count, void *arg)
+static int count_distinct_walk(void *elem, element_count count, void *arg)
{
(*((ulonglong*)arg))++;
return 0;
@@ -2667,11 +2667,11 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
TABLE *table= item->table;
char *record= (char*) table->record[0] + table->s->null_bytes;
String tmp(table->record[1], table->s->reclength, default_charset_info), tmp2;
- String &result= item->result;
+ String *result= &item->result;
Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
- if (result.length())
- result.append(*item->separator);
+ if (result->length())
+ result->append(*item->separator);
tmp.length(0);
@@ -2698,14 +2698,14 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
else
res= (*arg)->val_str(&tmp);
if (res)
- result.append(*res);
+ result->append(*res);
}
/* stop if length of result more than max_length */
- if (result.length() > item->max_length)
+ if (result->length() > item->max_length)
{
item->count_cut_values++;
- result.length(item->max_length);
+ result->length(item->max_length);
item->warning_for_row= TRUE;
return 1;
}
@@ -2906,8 +2906,6 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
MYF(0));
return TRUE;
}
- if (!args) /* allocation in constructor may fail */
- return TRUE;
thd->allow_sum_func= 0;
maybe_null= 0;
@@ -2968,12 +2966,10 @@ bool Item_func_group_concat::setup(THD *thd)
if (item->null_value)
{
always_null= 1;
- break;
+ DBUG_RETURN(FALSE);
}
}
}
- if (always_null)
- DBUG_RETURN(FALSE);
List<Item> all_fields(list);
/*
diff --git a/sql/log.cc b/sql/log.cc
index af1e59df255..9af70a4d527 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1638,57 +1638,6 @@ bool MYSQL_LOG::write(Log_event *event_info)
if (thd)
{
-#if MYSQL_VERSION_ID < 50003
- /*
- To make replication of charsets working in 4.1 we are writing values
- of charset related variables before every statement in the binlog,
- if values of those variables differ from global server-wide defaults.
- We are using SET ONE_SHOT command so that the charset vars get reset
- to default after the first non-SET statement.
- In the next 5.0 this won't be needed as we will use the new binlog
- format to store charset info.
- */
- if ((thd->variables.character_set_client->number !=
- global_system_variables.collation_server->number) ||
- (thd->variables.character_set_client->number !=
- thd->variables.collation_connection->number) ||
- (thd->variables.collation_server->number !=
- thd->variables.collation_connection->number))
- {
- char buf[200];
- int written= my_snprintf(buf, sizeof(buf)-1,
- "SET ONE_SHOT CHARACTER_SET_CLIENT=%u,\
-COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
- (uint) thd->variables.character_set_client->number,
- (uint) thd->variables.collation_connection->number,
- (uint) thd->variables.collation_database->number,
- (uint) thd->variables.collation_server->number);
- Query_log_event e(thd, buf, written, 0, FALSE);
- if (e.write(file))
- goto err;
- }
-#endif
- /*
- We use the same ONE_SHOT trick for making replication of time zones
- working in 4.1. Again in 5.0 we have better means for doing this.
-
- TODO: we should do like we now do with charsets (no more ONE_SHOT;
- logging in each event in a compact format). Dmitri says we can do:
- if (time_zone_used) write the timezone to binlog (in a format to be
- defined).
- */
- if (thd->time_zone_used &&
- thd->variables.time_zone != global_system_variables.time_zone)
- {
- char buf[MAX_TIME_ZONE_NAME_LENGTH + 26];
- char *buf_end= strxmov(buf, "SET ONE_SHOT TIME_ZONE='",
- thd->variables.time_zone->get_name()->ptr(),
- "'", NullS);
- Query_log_event e(thd, buf, buf_end - buf, 0, FALSE);
- if (e.write(file))
- goto err;
- }
-
if (thd->last_insert_id_used)
{
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 500408f34a7..27c30cadd11 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -506,8 +506,6 @@ void Log_event::init_show_field_list(List<Item>* field_list)
field_list->push_back(new Item_empty_string("Info", 20));
}
-#endif /* !MYSQL_CLIENT */
-
/*
Log_event::write()
@@ -592,7 +590,6 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
*/
-#ifndef MYSQL_CLIENT
int Log_event::read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock)
{
@@ -956,6 +953,7 @@ void Query_log_event::pack_info(Protocol *protocol)
}
#endif
+#ifndef MYSQL_CLIENT
/*
Query_log_event::write()
@@ -973,7 +971,8 @@ bool Query_log_event::write(IO_CACHE* file)
1+8+ // code of sql_mode and sql_mode
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1+4+ // code of autoinc and the 2 autoinc variables
- 1+6 // code of charset and charset
+ 1+6+ // code of charset and charset
+ 1+1+MAX_TIME_ZONE_NAME_LENGTH // code of tz and tz length and tz name
], *start, *start_of_status;
ulong event_length;
@@ -1030,20 +1029,20 @@ bool Query_log_event::write(IO_CACHE* file)
start_of_status= start= buf+QUERY_HEADER_LEN;
if (flags2_inited)
{
- *(start++)= Q_FLAGS2_CODE;
+ *start++= Q_FLAGS2_CODE;
int4store(start, flags2);
start+= 4;
}
if (sql_mode_inited)
{
- *(start++)= Q_SQL_MODE_CODE;
+ *start++= Q_SQL_MODE_CODE;
int8store(start, (ulonglong)sql_mode);
start+= 8;
}
- if (catalog_len >= 0) // i.e. "catalog inited" (false for 4.0 events)
+ if (catalog_len) // i.e. "catalog inited" (false for 4.0 events)
{
- *(start++)= Q_CATALOG_CODE;
- *(start++)= (uchar) catalog_len;
+ *start++= Q_CATALOG_CODE;
+ *start++= (uchar) catalog_len;
bmove(start, catalog, catalog_len);
start+= catalog_len;
/*
@@ -1071,15 +1070,24 @@ bool Query_log_event::write(IO_CACHE* file)
}
if (charset_inited)
{
- *(start++)= Q_CHARSET_CODE;
+ *start++= Q_CHARSET_CODE;
memcpy(start, charset, 6);
start+= 6;
}
+ if (time_zone_len)
+ {
+ /* In the TZ sys table, column Name is of length 64 so this should be ok */
+ DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
+ *start++= Q_TIME_ZONE_CODE;
+ *start++= time_zone_len;
+ memcpy(start, time_zone_str, time_zone_len);
+ start+= time_zone_len;
+ }
/*
Here there could be code like
if (command-line-option-which-says-"log_this_variable" && inited)
{
- *(start++)= Q_THIS_VARIABLE_CODE;
+ *start++= Q_THIS_VARIABLE_CODE;
int4store(start, this_variable);
start+= 4;
}
@@ -1108,8 +1116,6 @@ bool Query_log_event::write(IO_CACHE* file)
/*
Query_log_event::Query_log_event()
*/
-
-#ifndef MYSQL_CLIENT
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
ulong query_length, bool using_trans,
bool suppress_use)
@@ -1150,6 +1156,18 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
int2store(charset, thd_arg->variables.character_set_client->number);
int2store(charset+2, thd_arg->variables.collation_connection->number);
int2store(charset+4, thd_arg->variables.collation_server->number);
+ if (thd_arg->time_zone_used)
+ {
+ /*
+ Note that our event becomes dependent on the Time_zone object
+ representing the time zone. Fortunately such objects are never deleted
+ or changed during mysqld's lifetime.
+ */
+ time_zone_len= thd_arg->variables.time_zone->get_name()->length();
+ time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
+ }
+ else
+ time_zone_len= 0;
DBUG_PRINT("info",("Query_log_event has flags2=%lu sql_mode=%lu",flags2,sql_mode));
}
#endif /* MYSQL_CLIENT */
@@ -1163,15 +1181,17 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
Query_log_event::Query_log_event(const char* buf, uint event_len,
const Format_description_log_event *description_event,
Log_event_type event_type)
- :Log_event(buf, description_event), data_buf(0), query(NullS), catalog(NullS),
+ :Log_event(buf, description_event), data_buf(0), query(NullS),
db(NullS), catalog_len(0), status_vars_len(0),
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
- auto_increment_increment(1), auto_increment_offset(1)
+ auto_increment_increment(1), auto_increment_offset(1),
+ time_zone_len(0)
{
ulong data_len;
uint32 tmp;
uint8 common_header_len, post_header_len;
- const char *start, *end;
+ char *start;
+ const char *end;
DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
common_header_len= description_event->common_header_len;
@@ -1191,7 +1211,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
- db_len = (uint)buf[Q_DB_LEN_OFFSET];
+ db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
/*
@@ -1217,7 +1237,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
/* variable-part: the status vars; only in MySQL 5.0 */
start= (char*) (buf+post_header_len);
- end= (char*) (start+status_vars_len);
+ end= (const char*) (start+status_vars_len);
for (const uchar* pos= (const uchar*) start; pos < (const uchar*) end;)
{
switch (*pos++) {
@@ -1240,8 +1260,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
break;
}
case Q_CATALOG_CODE:
- catalog_len= *pos;
- if (catalog_len)
+ if ((catalog_len= *pos))
catalog= (char*) pos+1; // Will be copied later
pos+= catalog_len+2;
break;
@@ -1257,6 +1276,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
pos+= 6;
break;
}
+ case Q_TIME_ZONE_CODE:
+ {
+ if ((time_zone_len= *pos))
+ time_zone_str= (char *)(pos+1);
+ pos+= time_zone_len+1;
+ break;
+ }
default:
/* That's why you must write status vars in growing order of code */
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
@@ -1265,24 +1291,29 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
}
}
- /* A 2nd variable part; this is common to all versions */
-
- if (!(start= data_buf = (char*) my_malloc(catalog_len + data_len +2, MYF(MY_WME))))
+ if (!(start= data_buf = (char*) my_malloc(catalog_len + 1 +
+ time_zone_len + 1 +
+ data_len + 1, MYF(MY_WME))))
DBUG_VOID_RETURN;
- if (catalog) // If catalog is given
+ if (catalog_len) // If catalog is given
{
- memcpy((char*) start, catalog, catalog_len+1); // Copy name and end \0
+ memcpy(start, catalog, catalog_len+1); // Copy name and end \0
catalog= start;
start+= catalog_len+1;
}
+ if (time_zone_len)
+ {
+ memcpy(start, time_zone_str, time_zone_len);
+ time_zone_str= start;
+ start+= time_zone_len;
+ *start++= 0;
+ }
+ /* A 2nd variable part; this is common to all versions */
memcpy((char*) start, end, data_len); // Copy db and query
- ((char*) start)[data_len]= '\0'; // End query with \0 (For safetly)
+ start[data_len]= '\0'; // End query with \0 (For safetly)
db= start;
query= start + db_len + 1;
q_len= data_len - db_len -1;
- /* This is used to detect wrong parsing. Could be removed in the future. */
- DBUG_PRINT("info", ("catalog: '%s' len: %u db: '%s' len: %u q_len: %lu",
- catalog, (uint) catalog_len, db, (uint) db_len,q_len));
DBUG_VOID_RETURN;
}
@@ -1390,6 +1421,8 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
last_event_info->auto_increment_offset= auto_increment_offset;
}
+ /* TODO: print the catalog when we feature SET CATALOG */
+
if (likely(charset_inited))
{
if (unlikely(!last_event_info->charset_inited)) /* first Query event */
@@ -1410,6 +1443,14 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
memcpy(last_event_info->charset, charset, 6);
}
}
+ if (time_zone_len)
+ {
+ if (bcmp(last_event_info->time_zone_str, time_zone_str, time_zone_len+1))
+ {
+ fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
+ memcpy(last_event_info->time_zone_str, time_zone_str, time_zone_len+1);
+ }
+ }
}
@@ -1443,7 +1484,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
alloced block (see Query_log_event::exec_event()). Same for thd->db.
Thank you.
*/
- thd->catalog= (char*) catalog;
+ thd->catalog= catalog_len ? (char *) catalog : (char *)"";
thd->db_length= db_len;
thd->db= (char*) rewrite_db(db, &thd->db_length);
thd->variables.auto_increment_increment= auto_increment_increment;
@@ -1513,20 +1554,28 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
get_charset(uint2korr(charset+4), MYF(MY_WME))))
{
/*
- We updated the thd->variables with nonsensical values (0), and the
- thread is not guaranteed to terminate now (as it may be configured
- to ignore EE_UNKNOWN_CHARSET);if we're going to execute a next
- statement we'll have a new charset info with it, so no problem to
- have stored 0 in thd->variables. But we invalidate cached
- charset to force a check next time (otherwise if next time
- charset is unknown again we won't detect it).
+ We updated the thd->variables with nonsensical values (0). Let's
+ set them to something safe (i.e. which avoids crash), and we'll
+ stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
+ ignore this error).
*/
- rli->cached_charset_invalidate();
+ set_slave_thread_default_charset(thd, rli);
goto compare_errors;
}
thd->update_charset(); // for the charset change to take effect
}
}
+ if (time_zone_len)
+ {
+ String tmp(time_zone_str, time_zone_len, &my_charset_bin);
+ if (!(thd->variables.time_zone=
+ my_tz_find_with_opening_tz_tables(thd, &tmp)))
+ {
+ my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
+ thd->variables.time_zone= global_system_variables.time_zone;
+ goto compare_errors;
+ }
+ }
/* Execute the query (note that we bypass dispatch_command()) */
mysql_parse(thd, thd->query, thd->query_length);
@@ -1751,6 +1800,7 @@ Start_log_event_v3::Start_log_event_v3(const char* buf,
Start_log_event_v3::write()
*/
+#ifndef MYSQL_CLIENT
bool Start_log_event_v3::write(IO_CACHE* file)
{
char buff[START_V3_HEADER_LEN];
@@ -1760,6 +1810,7 @@ bool Start_log_event_v3::write(IO_CACHE* file)
return (write_header(file, sizeof(buff)) ||
my_b_safe_write(file, (byte*) buff, sizeof(buff)));
}
+#endif
/*
@@ -1975,7 +2026,7 @@ Format_description_log_event(const char* buf,
DBUG_VOID_RETURN;
}
-
+#ifndef MYSQL_CLIENT
bool Format_description_log_event::write(IO_CACHE* file)
{
/*
@@ -1992,6 +2043,7 @@ bool Format_description_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buff)) ||
my_b_safe_write(file, buff, sizeof(buff)));
}
+#endif
/*
SYNOPSIS
@@ -2210,6 +2262,8 @@ void Load_log_event::pack_info(Protocol *protocol)
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
+#ifndef MYSQL_CLIENT
+
/*
Load_log_event::write_data_header()
*/
@@ -2251,7 +2305,6 @@ bool Load_log_event::write_data_body(IO_CACHE* file)
Load_log_event::Load_log_event()
*/
-#ifndef MYSQL_CLIENT
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
const char *db_arg, const char *table_name_arg,
List<Item> &fields_arg,
@@ -2865,6 +2918,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
Rotate_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Rotate_log_event::write(IO_CACHE* file)
{
char buf[ROTATE_HEADER_LEN];
@@ -2873,7 +2927,7 @@ bool Rotate_log_event::write(IO_CACHE* file)
my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
}
-
+#endif
/*
Rotate_log_event::exec_event()
@@ -2931,17 +2985,10 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
master is 4.0 then the events are in the slave's format (conversion).
*/
set_slave_thread_options(thd);
+ set_slave_thread_default_charset(thd, rli);
thd->variables.sql_mode= global_system_variables.sql_mode;
thd->variables.auto_increment_increment=
thd->variables.auto_increment_offset= 1;
- thd->variables.character_set_client=
- global_system_variables.character_set_client;
- thd->variables.collation_connection=
- global_system_variables.collation_connection;
- thd->variables.collation_server=
- global_system_variables.collation_server;
- thd->update_charset();
- rli->cached_charset_invalidate();
}
pthread_mutex_unlock(&rli->data_lock);
pthread_cond_broadcast(&rli->data_cond);
@@ -3003,6 +3050,7 @@ const char* Intvar_log_event::get_var_type_name()
Intvar_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Intvar_log_event::write(IO_CACHE* file)
{
byte buf[9];
@@ -3011,6 +3059,7 @@ bool Intvar_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
+#endif
/*
@@ -3095,6 +3144,7 @@ Rand_log_event::Rand_log_event(const char* buf,
}
+#ifndef MYSQL_CLIENT
bool Rand_log_event::write(IO_CACHE* file)
{
byte buf[16];
@@ -3103,6 +3153,7 @@ bool Rand_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
+#endif
#ifdef MYSQL_CLIENT
@@ -3166,11 +3217,13 @@ Xid_log_event(const char* buf,
}
+#ifndef MYSQL_CLIENT
bool Xid_log_event::write(IO_CACHE* file)
{
return write_header(file, sizeof(xid)) ||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
}
+#endif
#ifdef MYSQL_CLIENT
@@ -3304,6 +3357,7 @@ User_var_log_event(const char* buf,
}
+#ifndef MYSQL_CLIENT
bool User_var_log_event::write(IO_CACHE* file)
{
char buf[UV_NAME_LEN_SIZE];
@@ -3338,7 +3392,7 @@ bool User_var_log_event::write(IO_CACHE* file)
dec->fix_buffer_pointer();
buf2[0]= (char)(dec->intg + dec->frac);
buf2[1]= (char)dec->frac;
- decimal2bin((decimal*)val, buf2+2, buf2[0], buf2[1]);
+ decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
break;
}
@@ -3363,6 +3417,7 @@ bool User_var_log_event::write(IO_CACHE* file)
my_b_safe_write(file, (byte*) buf1, buf1_length) ||
my_b_safe_write(file, (byte*) pos, val_len));
}
+#endif
/*
@@ -3405,8 +3460,8 @@ void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* las
int str_len= sizeof(str_buf) - 1;
int precision= (int)val[0];
int scale= (int)val[1];
- decimal_digit dec_buf[10];
- decimal dec;
+ decimal_digit_t dec_buf[10];
+ decimal_t dec;
dec.len= 10;
dec.buf= dec_buf;
@@ -3636,6 +3691,7 @@ int Slave_log_event::get_data_size()
}
+#ifndef MYSQL_CLIENT
bool Slave_log_event::write(IO_CACHE* file)
{
ulong event_length= get_data_size();
@@ -3646,6 +3702,7 @@ bool Slave_log_event::write(IO_CACHE* file)
return (write_header(file, event_length) ||
my_b_safe_write(file, (byte*) mem_pool, event_length));
}
+#endif
void Slave_log_event::init_from_mem_pool(int data_size)
@@ -3772,7 +3829,6 @@ Create_file_log_event(THD* thd_arg, sql_exchange* ex,
sql_ex.force_new_format();
DBUG_VOID_RETURN;
}
-#endif /* !MYSQL_CLIENT */
/*
@@ -3817,6 +3873,7 @@ bool Create_file_log_event::write_base(IO_CACHE* file)
return res;
}
+#endif /* !MYSQL_CLIENT */
/*
Create_file_log_event ctor
@@ -4044,6 +4101,7 @@ Append_block_log_event::Append_block_log_event(const char* buf, uint len,
Append_block_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Append_block_log_event::write(IO_CACHE* file)
{
byte buf[APPEND_BLOCK_HEADER_LEN];
@@ -4052,6 +4110,7 @@ bool Append_block_log_event::write(IO_CACHE* file)
my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
my_b_safe_write(file, (byte*) block, block_len));
}
+#endif
/*
@@ -4173,6 +4232,7 @@ Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
Delete_file_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Delete_file_log_event::write(IO_CACHE* file)
{
byte buf[DELETE_FILE_HEADER_LEN];
@@ -4180,6 +4240,7 @@ bool Delete_file_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
+#endif
/*
@@ -4267,6 +4328,7 @@ Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
Execute_load_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Execute_load_log_event::write(IO_CACHE* file)
{
byte buf[EXEC_LOAD_HEADER_LEN];
@@ -4274,6 +4336,7 @@ bool Execute_load_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
+#endif
/*
@@ -4477,6 +4540,7 @@ ulong Execute_load_query_log_event::get_post_header_size_for_derived()
}
+#ifndef MYSQL_CLIENT
bool
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
{
@@ -4487,6 +4551,7 @@ Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
*(buf + 4 + 4 + 4)= (char)dup_handling;
return my_b_safe_write(file, (byte*) buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
}
+#endif
#ifdef MYSQL_CLIENT
diff --git a/sql/log_event.h b/sql/log_event.h
index 43a801da851..72142db0aa7 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -237,6 +237,7 @@ struct sql_ex_info
#define Q_CATALOG_CODE 2
#define Q_AUTO_INCREMENT 3
#define Q_CHARSET_CODE 4
+#define Q_TIME_ZONE_CODE 5
/* Intvar event post-header */
@@ -448,6 +449,7 @@ typedef struct st_last_event_info
ulong auto_increment_increment, auto_increment_offset;
bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes
+ char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
st_last_event_info()
:flags2_inited(0), sql_mode_inited(0),
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0)
@@ -459,6 +461,7 @@ typedef struct st_last_event_info
*/
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
+ bzero(time_zone_str, sizeof(time_zone_str));
}
} LAST_EVENT_INFO;
#endif
@@ -583,6 +586,7 @@ public:
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
+#ifndef MYSQL_CLIENT
bool write_header(IO_CACHE* file, ulong data_length);
virtual bool write(IO_CACHE* file)
{
@@ -590,13 +594,14 @@ public:
write_data_header(file) ||
write_data_body(file));
}
- virtual bool is_artificial_event() { return 0; }
virtual bool write_data_header(IO_CACHE* file)
{ return 0; }
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
+#endif
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
+ virtual bool is_artificial_event() { return 0; }
inline bool get_cache_stmt() { return cache_stmt; }
Log_event(const char* buf, const Format_description_log_event* description_event);
virtual ~Log_event() { free_temp_buf();}
@@ -672,7 +677,7 @@ public:
concerned) from here.
*/
- int catalog_len; // <= 255 char; -1 means uninited
+ uint catalog_len; // <= 255 char; 0 means uninited
/*
We want to be able to store a variable number of N-bit status vars:
@@ -714,6 +719,8 @@ public:
ulong sql_mode;
ulong auto_increment_increment, auto_increment_offset;
char charset[6];
+ uint time_zone_len; /* 0 means uninited */
+ const char *time_zone_str;
#ifndef MYSQL_CLIENT
@@ -737,12 +744,13 @@ public:
~Query_log_event()
{
if (data_buf)
- {
my_free((gptr) data_buf, MYF(0));
- }
}
Log_event_type get_type_code() { return QUERY_EVENT; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+ virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
+#endif
bool is_valid() const { return query != 0; }
/*
@@ -751,7 +759,6 @@ public:
*/
virtual ulong get_post_header_size_for_derived() { return 0; }
/* Writes derived event-specific part of post header. */
- virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
};
#ifdef HAVE_REPLICATION
@@ -790,7 +797,9 @@ public:
int get_data_size();
bool is_valid() const { return master_host != 0; }
Log_event_type get_type_code() { return SLAVE_EVENT; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
};
#endif /* HAVE_REPLICATION */
@@ -885,8 +894,10 @@ public:
{
return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
}
+#ifndef MYSQL_CLIENT
bool write_data_header(IO_CACHE* file);
bool write_data_body(IO_CACHE* file);
+#endif
bool is_valid() const { return table_name != 0; }
int get_data_size()
{
@@ -962,7 +973,9 @@ public:
const Format_description_log_event* description_event);
~Start_log_event_v3() {}
Log_event_type get_type_code() { return START_EVENT_V3;}
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
int get_data_size()
{
@@ -1004,7 +1017,9 @@ public:
const Format_description_log_event* description_event);
~Format_description_log_event() { my_free((gptr)post_header_len, MYF(0)); }
Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const
{
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
@@ -1054,7 +1069,9 @@ public:
Log_event_type get_type_code() { return INTVAR_EVENT;}
const char* get_var_type_name();
int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;}
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
};
@@ -1092,7 +1109,9 @@ class Rand_log_event: public Log_event
~Rand_log_event() {}
Log_event_type get_type_code() { return RAND_EVENT;}
int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
};
@@ -1127,7 +1146,9 @@ class Xid_log_event: public Log_event
~Xid_log_event() {}
Log_event_type get_type_code() { return XID_EVENT;}
int get_data_size() { return sizeof(xid); }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
};
@@ -1169,7 +1190,9 @@ public:
User_var_log_event(const char* buf, const Format_description_log_event* description_event);
~User_var_log_event() {}
Log_event_type get_type_code() { return USER_VAR_EVENT;}
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
};
@@ -1239,7 +1262,9 @@ public:
Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
bool is_valid() const { return new_log_ident != 0; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
};
@@ -1299,6 +1324,7 @@ public:
4 + 1 + block_len);
}
bool is_valid() const { return inited_from_old || block != 0; }
+#ifndef MYSQL_CLIENT
bool write_data_header(IO_CACHE* file);
bool write_data_body(IO_CACHE* file);
/*
@@ -1306,6 +1332,7 @@ public:
write it as Load event - used on the slave
*/
bool write_base(IO_CACHE* file);
+#endif
};
@@ -1352,7 +1379,9 @@ public:
Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
bool is_valid() const { return block != 0; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
const char* get_db() { return db; }
};
@@ -1386,7 +1415,9 @@ public:
Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
const char* get_db() { return db; }
};
@@ -1419,7 +1450,9 @@ public:
Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
const char* get_db() { return db; }
};
@@ -1507,7 +1540,9 @@ public:
bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; }
ulong get_post_header_size_for_derived();
+#ifndef MYSQL_CLIENT
bool write_post_header_for_derived(IO_CACHE* file);
+#endif
};
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 334c40c0f70..19b6abd7243 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -88,7 +88,7 @@ int my_decimal2string(uint mask, const my_decimal *d,
int result;
if (str->alloc(length))
return check_result(mask, E_DEC_OOM);
- result= decimal2string((decimal*) d, (char*) str->ptr(),
+ result= decimal2string((decimal_t*) d, (char*) str->ptr(),
&length, fixed_prec, fixed_dec,
filler);
str->length(length);
@@ -172,7 +172,7 @@ int str2my_decimal(uint mask, const char *from, uint length,
charset= &my_charset_bin;
}
from_end= end= (char*) from+length;
- err= string2decimal((char *)from, (decimal *)decimal_value, &end);
+ err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
if (end != from_end && !err)
{
/* Give warining if there is something other than end space */
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index 44530acd0cc..03801390d82 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -69,15 +69,15 @@ inline uint my_decimal_size(uint precision, uint scale)
/*
- my_decimal class limits 'decimal' type to what we need in MySQL
+ my_decimal class limits 'decimal_t' type to what we need in MySQL
It contains internally all necessary space needed by the instance so
no extra memory is needed. One should call fix_buffer_pointer() function
when he moves my_decimal objects in memory
*/
-class my_decimal :public decimal
+class my_decimal :public decimal_t
{
- decimal_digit buffer[DECIMAL_BUFF_LENGTH];
+ decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
public:
@@ -97,8 +97,8 @@ public:
}
void fix_buffer_pointer() { buf= buffer; }
- bool sign() const { return decimal::sign; }
- void sign(bool s) { decimal::sign= s; }
+ bool sign() const { return decimal_t::sign; }
+ void sign(bool s) { decimal_t::sign= s; }
};
@@ -165,7 +165,7 @@ inline
int binary2my_decimal(uint mask, const char *bin, my_decimal *d, int prec,
int scale)
{
- return check_result(mask, bin2decimal((char *)bin, (decimal*) d, prec,
+ return check_result(mask, bin2decimal((char *)bin, (decimal_t*) d, prec,
scale));
}
@@ -173,7 +173,7 @@ int binary2my_decimal(uint mask, const char *bin, my_decimal *d, int prec,
inline
int my_decimal_set_zero(my_decimal *d)
{
- decimal_make_zero(((decimal*) d));
+ decimal_make_zero(((decimal_t*) d));
return 0;
}
@@ -181,7 +181,7 @@ int my_decimal_set_zero(my_decimal *d)
inline
bool my_decimal_is_zero(const my_decimal *decimal_value)
{
- return decimal_is_zero((decimal*) decimal_value);
+ return decimal_is_zero((decimal_t*) decimal_value);
}
@@ -189,7 +189,7 @@ inline
int my_decimal_round(uint mask, const my_decimal *from, int scale,
bool truncate, my_decimal *to)
{
- return check_result(mask, decimal_round((decimal*) from, to, scale,
+ return check_result(mask, decimal_round((decimal_t*) from, to, scale,
(truncate ? TRUNCATE : HALF_UP)));
}
@@ -197,14 +197,14 @@ int my_decimal_round(uint mask, const my_decimal *from, int scale,
inline
int my_decimal_floor(uint mask, const my_decimal *from, my_decimal *to)
{
- return check_result(mask, decimal_round((decimal*) from, to, 0, FLOOR));
+ return check_result(mask, decimal_round((decimal_t*) from, to, 0, FLOOR));
}
inline
int my_decimal_ceiling(uint mask, const my_decimal *from, my_decimal *to)
{
- return check_result(mask, decimal_round((decimal*) from, to, 0, CEILING));
+ return check_result(mask, decimal_round((decimal_t*) from, to, 0, CEILING));
}
@@ -219,7 +219,7 @@ int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag,
{
my_decimal rounded;
/* decimal_round can return only E_DEC_TRUNCATED */
- decimal_round((decimal*)d, &rounded, 0, HALF_UP);
+ decimal_round((decimal_t*)d, &rounded, 0, HALF_UP);
return check_result(mask, (unsigned_flag ?
decimal2ulonglong(&rounded, (ulonglong *)l) :
decimal2longlong(&rounded, l)));
@@ -230,14 +230,14 @@ inline
int my_decimal2double(uint mask, const my_decimal *d, double *result)
{
/* No need to call check_result as this will always succeed */
- return decimal2double((decimal*) d, result);
+ return decimal2double((decimal_t*) d, result);
}
inline
int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end)
{
- return check_result(mask, string2decimal(str, (decimal*) d, end));
+ return check_result(mask, string2decimal(str, (decimal_t*) d, end));
}
@@ -255,7 +255,7 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d)
inline
int double2my_decimal(uint mask, double val, my_decimal *d)
{
- return check_result(mask, double2decimal(val, (decimal*) d));
+ return check_result(mask, double2decimal(val, (decimal_t*) d));
}
@@ -269,7 +269,7 @@ int int2my_decimal(uint mask, longlong i, my_bool unsigned_flag, my_decimal *d)
inline
-void my_decimal_neg(st_decimal *arg)
+void my_decimal_neg(decimal_t *arg)
{
decimal_neg(arg);
}
@@ -279,7 +279,7 @@ inline
int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b)
{
- return check_result(mask, decimal_add((decimal*) a, (decimal*) b, res));
+ return check_result(mask, decimal_add((decimal_t*) a, (decimal_t*) b, res));
}
@@ -287,7 +287,7 @@ inline
int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b)
{
- return check_result(mask, decimal_sub((decimal*) a, (decimal*) b, res));
+ return check_result(mask, decimal_sub((decimal_t*) a, (decimal_t*) b, res));
}
@@ -295,7 +295,7 @@ inline
int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b)
{
- return check_result(mask, decimal_mul((decimal*) a, (decimal*) b, res));
+ return check_result(mask, decimal_mul((decimal_t*) a, (decimal_t*) b, res));
}
@@ -303,7 +303,7 @@ inline
int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b, int div_scale_inc)
{
- return check_result(mask, decimal_div((decimal*) a, (decimal*) b, res,
+ return check_result(mask, decimal_div((decimal_t*) a, (decimal_t*) b, res,
div_scale_inc));
}
@@ -312,7 +312,7 @@ inline
int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b)
{
- return check_result(mask, decimal_mod((decimal*) a, (decimal*) b, res));
+ return check_result(mask, decimal_mod((decimal_t*) a, (decimal_t*) b, res));
}
@@ -320,14 +320,14 @@ int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
inline
int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
{
- return decimal_cmp((decimal*) a, (decimal*) b);
+ return decimal_cmp((decimal_t*) a, (decimal_t*) b);
}
inline
void max_my_decimal(my_decimal *to, int precision, int frac)
{
DBUG_ASSERT(precision <= DECIMAL_MAX_LENGTH);
- max_decimal(precision, frac, (decimal*) to);
+ max_decimal(precision, frac, (decimal_t*) to);
}
#endif /*my_decimal_h*/
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index dfa945c3fd3..1ee53e5ed64 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -264,6 +264,12 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
/* Flag set if setup_tables already done */
#define OPTION_SETUP_TABLES_DONE (1L << 30)
+/*
+ Maximum length of time zone name that we support
+ (Time zone name is char(64) in db). mysqlbinlog needs it.
+*/
+#define MAX_TIME_ZONE_NAME_LENGTH 72
+
/* The rest of the file is included in the server only */
#ifndef MYSQL_CLIENT
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 6747b79703b..ecaa7ace841 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3310,9 +3310,10 @@ default_service_handling(char **argv,
int main(int argc, char **argv)
{
- /* When several instances are running on the same machine, we
- need to have an unique named hEventShudown through the
- application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
+ /*
+ When several instances are running on the same machine, we
+ need to have an unique named hEventShudown through the
+ application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
*/
int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
"MySQLShutdown"), 10);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 0c9483b2783..f5df4dfbd2c 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -2095,27 +2095,6 @@ void sys_var_character_set_server::set_default(THD *thd, enum_var_type type)
}
}
-#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
-bool sys_var_character_set_server::check(THD *thd, set_var *var)
-{
- /*
- To be perfect we should fail even if we are a 5.0.3 slave, a 4.1 master,
- and user wants to change our global character set variables. Because
- replicating a 4.1 assumes those are not changed. But that's not easy to
- do.
- */
- if ((var->type == OPT_GLOBAL) &&
- (mysql_bin_log.is_open() ||
- active_mi->slave_running || active_mi->rli.slave_running))
- {
- my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0),
- "character set, collation");
- return 1;
- }
- return sys_var_character_set::check(thd,var);
-}
-#endif
-
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
enum_var_type type)
{
@@ -2208,20 +2187,6 @@ void sys_var_collation_database::set_default(THD *thd, enum_var_type type)
}
}
-#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
-bool sys_var_collation_server::check(THD *thd, set_var *var)
-{
- if ((var->type == OPT_GLOBAL) &&
- (mysql_bin_log.is_open() ||
- active_mi->slave_running || active_mi->rli.slave_running))
- {
- my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0),
- "character set, collation");
- return 1;
- }
- return sys_var_collation::check(thd,var);
-}
-#endif
bool sys_var_collation_server::update(THD *thd, set_var *var)
{
@@ -2560,16 +2525,6 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
String str(buff, sizeof(buff), &my_charset_latin1);
String *res= var->value->val_str(&str);
-#if defined(HAVE_REPLICATION)
- if ((var->type == OPT_GLOBAL) &&
- (mysql_bin_log.is_open() ||
- active_mi->slave_running || active_mi->rli.slave_running))
- {
- my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0), "time zone");
- return 1;
- }
-#endif
-
if (!(var->save_result.time_zone=
my_tz_find(res, thd->lex->time_zone_tables_used)))
{
@@ -2605,7 +2560,18 @@ byte *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
if (type == OPT_GLOBAL)
return (byte *)(global_system_variables.time_zone->get_name()->ptr());
else
+ {
+ /*
+ This is an ugly fix for replication: we don't replicate properly queries
+ invoking system variables' values to update tables; but
+ CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
+ replicable (i.e. we tell the binlog code to store the session
+ timezone). If it's the global value which was used we can't replicate
+ (binlog code stores session value only).
+ */
+ thd->time_zone_used= 1;
return (byte *)(thd->variables.time_zone->get_name()->ptr());
+ }
}
diff --git a/sql/set_var.h b/sql/set_var.h
index d78c228c142..585f6df3547 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -565,9 +565,6 @@ class sys_var_character_set_server :public sys_var_character_set
public:
sys_var_character_set_server(const char *name_arg) :
sys_var_character_set(name_arg) {}
-#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
- bool check(THD *thd, set_var *var);
-#endif
void set_default(THD *thd, enum_var_type type);
CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
};
@@ -603,9 +600,6 @@ class sys_var_collation_server :public sys_var_collation
{
public:
sys_var_collation_server(const char *name_arg) :sys_var_collation(name_arg) {}
-#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
- bool check(THD *thd, set_var *var);
-#endif
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index d4caeebb70c..886c37b7061 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5332,3 +5332,5 @@ ER_STARTUP
eng "%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d %s"
ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR
eng "Can't load value from file with fixed size rows to variable"
+ER_CANT_CREATE_USER_WITH_GRANT
+ eng "You are not allowed to create a user with GRANT"
diff --git a/sql/slave.cc b/sql/slave.cc
index 73dd0fd13c3..c92350f4a2f 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1456,11 +1456,10 @@ be equal for replication to work";
such check will broke everything for them. (And now everything will
work for them because by default both their master and slave will have
'SYSTEM' time zone).
-
- TODO: when the new replication of timezones is sorted out with Dmitri,
- change >= '4' to == '4'.
+ This check is only necessary for 4.x masters (and < 5.0.4 masters but
+ those were alpha).
*/
- if ((*mysql->server_version >= '4') &&
+ if ((*mysql->server_version == '4') &&
!mysql_real_query(mysql, "SELECT @@GLOBAL.TIME_ZONE", 25) &&
(master_res= mysql_store_result(mysql)))
{
@@ -2770,6 +2769,18 @@ void set_slave_thread_options(THD* thd)
thd->variables.completion_type= 0;
}
+void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli)
+{
+ thd->variables.character_set_client=
+ global_system_variables.character_set_client;
+ thd->variables.collation_connection=
+ global_system_variables.collation_connection;
+ thd->variables.collation_server=
+ global_system_variables.collation_server;
+ thd->update_charset();
+ rli->cached_charset_invalidate();
+}
+
/*
init_slave_thread()
*/
diff --git a/sql/slave.h b/sql/slave.h
index ee5541ffe08..bc41cd4deca 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -562,6 +562,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos,
int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
const char** errmsg);
void set_slave_thread_options(THD* thd);
+void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli);
void rotate_relay_log(MASTER_INFO* mi);
extern "C" pthread_handler_decl(handle_slave_io,arg);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index c51e5e00aa1..de5df4559db 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1627,7 +1627,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
else if (((thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER) &&
!password_len) || !create_user)
{
- my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0),
+ my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0),
thd->user, thd->host_or_ip);
goto end;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b6cda4f8d85..856fb937b6e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -10144,20 +10144,18 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->sum_funcs_end[send_group_parts]);
if (join->having && join->having->val_int() == 0)
error= -1;
- else if ((error=table->file->write_row(table->record[0])))
+ else if ((error= table->file->write_row(table->record[0])))
{
if (create_myisam_from_heap(join->thd, table,
&join->tmp_table_param,
error, 0))
DBUG_RETURN(-1);
}
- if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
+ if (join->rollup.state != ROLLUP::STATE_NONE)
{
if (join->rollup_write_data((uint) (idx+1), table))
- error= 1;
+ DBUG_RETURN(-1);
}
- if (error > 0)
- DBUG_RETURN(-1);
if (end_of_records)
DBUG_RETURN(0);
}
@@ -12684,17 +12682,21 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
{
/* Check if this is something that is part of this group by */
ORDER *group_tmp;
- for (group_tmp= start_group, i-- ;
+ for (group_tmp= start_group, i= pos ;
group_tmp ; group_tmp= group_tmp->next, i++)
{
if (*group_tmp->item == item)
{
+ Item_null_result *null_item;
/*
This is an element that is used by the GROUP BY and should be
set to NULL in this level
*/
item->maybe_null= 1; // Value will be null sometimes
- Item_null_result *null_item= rollup.null_items[i];
+ null_item= rollup.null_items[i];
+ DBUG_ASSERT(null_item->result_field == 0 ||
+ null_item->result_field ==
+ ((Item_field *) item)->result_field);
null_item->result_field= ((Item_field *) item)->result_field;
item= null_item;
break;
diff --git a/sql/sql_string.h b/sql/sql_string.h
index fc1e9f171b6..7ece9885040 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -84,6 +84,7 @@ public:
inline char& operator [] (uint32 i) const { return Ptr[i]; }
inline void length(uint32 len) { str_length=len ; }
inline bool is_empty() { return (str_length == 0); }
+ inline void mark_as_const() { Alloced_length= 0;}
inline const char *ptr() const { return Ptr; }
inline char *c_ptr()
{
@@ -205,10 +206,6 @@ public:
}
}
}
- inline void shrink_to_length()
- {
- Alloced_length= str_length;
- }
bool is_alloced() { return alloced; }
inline String& operator = (const String &s)
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 82d887891cf..b125eeaf03a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -613,7 +613,7 @@ int prepare_create_field(create_field *sql_field,
Prepares the table and key structures for table creation.
NOTES
- sets create_info->varchar if the table has a varchar or blob.
+ sets create_info->varchar if the table has a varchar
RETURN VALUES
0 ok
@@ -862,12 +862,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
&timestamps, &timestamps_with_niladic,
file->table_flags()))
DBUG_RETURN(-1);
- if (sql_field->sql_type == FIELD_TYPE_BLOB ||
- sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB ||
- sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
- sql_field->sql_type == FIELD_TYPE_LONG_BLOB ||
- sql_field->sql_type == FIELD_TYPE_GEOMETRY ||
- sql_field->sql_type == MYSQL_TYPE_VARCHAR)
+ if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
create_info->varchar= 1;
sql_field->offset= pos;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
diff --git a/sql/table.cc b/sql/table.cc
index 939690395d4..9238d8aa68e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -149,6 +149,15 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
*fn_ext(index_file)='\0'; // Remove .frm extension
share->frm_version= head[2];
+ /*
+ Check if .frm file created by MySQL 5.0. In this case we want to
+ display CHAR fields as CHAR and not as VARCHAR.
+ We do it this way as we want to keep the old frm version to enable
+ MySQL 4.1 to read these files.
+ */
+ if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
+ share->frm_version= FRM_VER_TRUE_VARCHAR;
+
share->db_type= ha_checktype((enum db_type) (uint) *(head+3));
share->db_create_options= db_create_options=uint2korr(head+30);
share->db_options_in_use= share->db_create_options;
@@ -1317,6 +1326,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo,
create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
int2store(fileinfo+30,create_info->table_options);
fileinfo[32]=0; // No filename anymore
+ fileinfo[33]=5; // Mark for 5.0 frm file
int4store(fileinfo+34,create_info->avg_row_length);
fileinfo[38]= (create_info->default_table_charset ?
create_info->default_table_charset->number : 0);
diff --git a/sql/tztime.cc b/sql/tztime.cc
index bd9d49f0ab0..983c630071e 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -2178,7 +2178,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
DBUG_PRINT("enter", ("time zone name='%s'",
name ? ((String *)name)->c_ptr() : "NULL"));
- DBUG_ASSERT(!time_zone_tables_exist || tz_tables);
+ DBUG_ASSERT(!time_zone_tables_exist || tz_tables || current_thd->slave_thread);
if (!name)
DBUG_RETURN(0);
@@ -2210,7 +2210,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
(const byte *)name->ptr(),
name->length())))
result_tz= tmp_tzname->tz;
- else if (time_zone_tables_exist)
+ else if (time_zone_tables_exist && tz_tables)
result_tz= tz_load_from_open_tables(name, tz_tables);
}
@@ -2219,6 +2219,58 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
DBUG_RETURN(result_tz);
}
+
+/*
+ A more standalone version of my_tz_find(): will open tz tables if needed.
+ This is so far only used by replication, where time zone setting does not
+ happen in the usual query context.
+
+ SYNOPSIS
+ my_tz_find_with_opening_tz_tables()
+ thd - pointer to thread's THD structure
+ name - time zone specification
+
+ DESCRIPTION
+ This function tries to find a time zone which matches the named passed in
+ argument. If it fails, it will open time zone tables and re-try the
+ search.
+ This function is needed for the slave SQL thread, which does not do the
+ addition of time zone tables which is usually done during query parsing
+ (as time zone setting by slave does not happen in mysql_parse() but
+ before). So it needs to open tz tables by itself if needed.
+ See notes of my_tz_find() as they also apply here.
+
+ RETURN VALUE
+ Pointer to corresponding Time_zone object. 0 - in case of bad time zone
+ specification or other error.
+
+*/
+Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name)
+{
+ Time_zone *tz;
+ DBUG_ENTER("my_tz_find_with_opening_tables");
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(thd->slave_thread); // intended for use with slave thread only
+ if (!(tz= my_tz_find(name, 0)) && time_zone_tables_exist)
+ {
+ /*
+ Probably we have not loaded this time zone yet so let us look it up in
+ our time zone tables. Note that if we don't have tz tables on this
+ slave, we don't even try.
+ */
+ TABLE_LIST tables[4];
+ TABLE_LIST *dummy;
+ TABLE_LIST **dummyp= &dummy;
+ tz_init_table_list(tables, &dummyp);
+ if (simple_open_n_lock_tables(thd, tables))
+ DBUG_RETURN(0);
+ tz= my_tz_find(name, tables);
+ /* We need to close tables _now_ to not pollute coming query */
+ close_thread_tables(thd);
+ }
+ DBUG_RETURN(tz);
+}
+
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
diff --git a/sql/tztime.h b/sql/tztime.h
index caf663fc8cb..777e521d761 100644
--- a/sql/tztime.h
+++ b/sql/tztime.h
@@ -61,6 +61,7 @@ extern Time_zone * my_tz_UTC;
extern Time_zone * my_tz_SYSTEM;
extern TABLE_LIST * my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr);
extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables);
+extern Time_zone * my_tz_find_with_opening_tz_tables(THD *thd, const String *name);
extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
extern void my_tz_free();
@@ -96,10 +97,4 @@ inline bool my_tz_check_n_skip_implicit_tables(TABLE_LIST **table,
return FALSE;
}
-/*
- Maximum length of time zone name that we support
- (Time zone name is char(64) in db)
-*/
-#define MAX_TIME_ZONE_NAME_LENGTH 72
-
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */