diff options
author | unknown <serg@serg.mylan> | 2005-03-22 16:11:43 +0100 |
---|---|---|
committer | unknown <serg@serg.mylan> | 2005-03-22 16:11:43 +0100 |
commit | e31642727b405e83ed0512a6c3318869f2a31e0c (patch) | |
tree | cb3fd62572918eb80e7c2add26636565c33ecace /sql | |
parent | 82182de38722242c3ec5c6b7d77bdbfe271b4bc5 (diff) | |
parent | 6ed02debff53e895e6c526fbbeac7c791e1f269f (diff) | |
download | mariadb-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.cc | 4 | ||||
-rw-r--r-- | sql/handler.cc | 14 | ||||
-rw-r--r-- | sql/item.cc | 14 | ||||
-rw-r--r-- | sql/item_sum.cc | 20 | ||||
-rw-r--r-- | sql/log.cc | 51 | ||||
-rw-r--r-- | sql/log_event.cc | 171 | ||||
-rw-r--r-- | sql/log_event.h | 45 | ||||
-rw-r--r-- | sql/my_decimal.cc | 4 | ||||
-rw-r--r-- | sql/my_decimal.h | 46 | ||||
-rw-r--r-- | sql/mysql_priv.h | 6 | ||||
-rw-r--r-- | sql/mysqld.cc | 7 | ||||
-rw-r--r-- | sql/set_var.cc | 56 | ||||
-rw-r--r-- | sql/set_var.h | 6 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 | ||||
-rw-r--r-- | sql/slave.cc | 19 | ||||
-rw-r--r-- | sql/slave.h | 1 | ||||
-rw-r--r-- | sql/sql_acl.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 16 | ||||
-rw-r--r-- | sql/sql_string.h | 5 | ||||
-rw-r--r-- | sql/sql_table.cc | 9 | ||||
-rw-r--r-- | sql/table.cc | 10 | ||||
-rw-r--r-- | sql/tztime.cc | 56 | ||||
-rw-r--r-- | sql/tztime.h | 7 |
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, ×tamps, ×tamps_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) */ |