diff options
author | unknown <knielsen@knielsen-hq.org> | 2012-08-24 15:29:01 +0200 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2012-08-24 15:29:01 +0200 |
commit | ced3907c02dfa3b237e14d79aa800b3a0769e94a (patch) | |
tree | 1189a55392ca290d6c9e8446250b7a9384feafb6 /sql | |
parent | caa535eb9fa97bd7c2190292bb4a3a3c1aaa71e3 (diff) | |
parent | fc666a0df6c69a620d3cffacd78e2569fb0ac410 (diff) | |
download | mariadb-git-ced3907c02dfa3b237e14d79aa800b3a0769e94a.tar.gz |
Merge from 5.3
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_ndbcluster_binlog.cc | 25 | ||||
-rw-r--r-- | sql/item.cc | 18 | ||||
-rw-r--r-- | sql/item.h | 1 | ||||
-rw-r--r-- | sql/item_func.cc | 4 | ||||
-rw-r--r-- | sql/item_func.h | 2 | ||||
-rw-r--r-- | sql/log.cc | 11 | ||||
-rw-r--r-- | sql/log_event.cc | 379 | ||||
-rw-r--r-- | sql/log_event.h | 47 | ||||
-rw-r--r-- | sql/log_event_old.cc | 2 | ||||
-rw-r--r-- | sql/log_event_old.h | 2 | ||||
-rw-r--r-- | sql/repl_failsafe.cc | 1 | ||||
-rw-r--r-- | sql/rpl_record.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 22 | ||||
-rw-r--r-- | sql/sql_db.cc | 41 | ||||
-rw-r--r-- | sql/sql_load.cc | 90 | ||||
-rw-r--r-- | sql/sql_repl.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 24 | ||||
-rw-r--r-- | sql/sql_show.h | 2 | ||||
-rw-r--r-- | sql/sql_string.cc | 28 | ||||
-rw-r--r-- | sql/sql_string.h | 1 | ||||
-rw-r--r-- | sql/sql_table.cc | 21 | ||||
-rw-r--r-- | sql/sql_truncate.cc | 41 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 |
24 files changed, 395 insertions, 375 deletions
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index f91e19df08e..59b9d6eab6b 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -1295,7 +1295,9 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share, DBUG_RETURN(0); } - char tmp_buf2[FN_REFLEN]; + char tmp_buf2_mem[FN_REFLEN]; + String tmp_buf2(tmp_buf2_mem, sizeof(tmp_buf2_mem), system_charset_info); + tmp_buf2.length(0); const char *type_str; switch (type) { @@ -1304,17 +1306,24 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share, if (thd->lex->sql_command == SQLCOM_DROP_DB) DBUG_RETURN(0); /* redo the drop table query as is may contain several tables */ - query= tmp_buf2; - query_length= (uint) (strxmov(tmp_buf2, "drop table `", - table_name, "`", NullS) - tmp_buf2); + tmp_buf2.append(STRING_WITH_LEN("drop table ")); + append_identifier(thd, &tmp_buf2, table_name, strlen(table_name)); + query= tmp_buf2.c_ptr_safe(); + query_length= tmp_buf2.length(); type_str= "drop table"; break; case SOT_RENAME_TABLE: /* redo the rename table query as is may contain several tables */ - query= tmp_buf2; - query_length= (uint) (strxmov(tmp_buf2, "rename table `", - db, ".", table_name, "` to `", - new_db, ".", new_table_name, "`", NullS) - tmp_buf2); + tmp_buf2.append(STRING_WITH_LEN("rename table ")); + append_identifier(thd, &tmp_buf2, db, strlen(db)); + tmp_buf2.append(STRING_WITH_LEN(".")); + append_identifier(thd, &tmp_buf2, table_name, strlen(table_name)); + tmp_buf2.append(STRING_WITH_LEN(" to ")); + append_identifier(thd, &tmp_buf2, new_db, strlen(new_db)); + tmp_buf2.append(STRING_WITH_LEN(".")); + append_identifier(thd, &tmp_buf2, new_table_name, strlen(new_table_name)); + query= tmp_buf2.c_ptr_safe(); + query_length= tmp_buf2.length(); type_str= "rename table"; break; case SOT_CREATE_TABLE: diff --git a/sql/item.cc b/sql/item.cc index eac33041797..ac54e1925b7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -992,15 +992,31 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) if (!my_charset_same(cs, system_charset_info)) { size_t res_length; - name= sql_strmake_with_convert(str, name_length= length, cs, + name= sql_strmake_with_convert(str, length, cs, MAX_ALIAS_NAME, system_charset_info, &res_length); + name_length= res_length; } else name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME))); } +void Item::set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs) +{ + if (!my_charset_same(cs, system_charset_info)) + { + size_t res_length; + name= sql_strmake_with_convert(str, length, cs, + UINT_MAX, system_charset_info, + &res_length); + name_length= res_length; + } + else + name= sql_strmake(str, (name_length= length)); +} + + void Item::set_name_for_rollback(THD *thd, const char *str, uint length, CHARSET_INFO *cs) { diff --git a/sql/item.h b/sql/item.h index f7f3edda384..8855996b76c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -656,6 +656,7 @@ public: #endif } /*lint -e1509 */ void set_name(const char *str, uint length, CHARSET_INFO *cs); + void set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs); void set_name_for_rollback(THD *thd, const char *str, uint length, CHARSET_INFO *cs); void rename(char *new_name); diff --git a/sql/item_func.cc b/sql/item_func.cc index d65f13931e2..7a7cdd4ba02 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5443,10 +5443,10 @@ my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer) } -void Item_user_var_as_out_param::print(String *str, enum_query_type query_type) +void Item_user_var_as_out_param::print_for_load(THD *thd, String *str) { str->append('@'); - str->append(name.str,name.length); + append_identifier(thd, str, name.str, name.length); } diff --git a/sql/item_func.h b/sql/item_func.h index cb9c1929d7d..111479c8e52 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1670,7 +1670,7 @@ public: my_decimal *val_decimal(my_decimal *decimal_buffer); /* fix_fields() binds variable name with its entry structure */ bool fix_fields(THD *thd, Item **ref); - virtual void print(String *str, enum_query_type query_type); + void print_for_load(THD *thd, String *str); void set_null_value(CHARSET_INFO* cs); void set_value(const char *str, uint length, CHARSET_INFO* cs); }; diff --git a/sql/log.cc b/sql/log.cc index 9cb85ab4b2b..56c07f81c9e 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -52,6 +52,7 @@ #include "sql_plugin.h" #include "rpl_handler.h" #include "debug_sync.h" +#include "sql_show.h" /* max size of the log message */ #define MAX_LOG_BUFFER_SIZE 1024 @@ -2073,9 +2074,8 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) String log_query; if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) || - log_query.append("`") || - log_query.append(thd->lex->ident.str, thd->lex->ident.length) || - log_query.append("`")) + append_identifier(thd, &log_query, + thd->lex->ident.str, thd->lex->ident.length)) DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == NOT_KILLED); Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), @@ -2097,9 +2097,8 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) { String log_query; if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) || - log_query.append("`") || - log_query.append(thd->lex->ident.str, thd->lex->ident.length) || - log_query.append("`")) + append_identifier(thd, &log_query, + thd->lex->ident.str, thd->lex->ident.length)) DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == NOT_KILLED); Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), diff --git a/sql/log_event.cc b/sql/log_event.cc index 4d834941215..dca9091e03d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -46,6 +46,7 @@ #include "rpl_record.h" #include "transaction.h" #include <my_dir.h> +#include "sql_show.h" #endif /* MYSQL_CLIENT */ @@ -471,29 +472,28 @@ inline bool unexpected_error_code(int unexpected_error) pretty_print_str() */ -static char *pretty_print_str(char *packet, const char *str, int len) +static void +pretty_print_str(String *packet, const char *str, int len) { const char *end= str + len; - char *pos= packet; - *pos++= '\''; + packet->append(STRING_WITH_LEN("'")); while (str < end) { char c; switch ((c=*str++)) { - case '\n': *pos++= '\\'; *pos++= 'n'; break; - case '\r': *pos++= '\\'; *pos++= 'r'; break; - case '\\': *pos++= '\\'; *pos++= '\\'; break; - case '\b': *pos++= '\\'; *pos++= 'b'; break; - case '\t': *pos++= '\\'; *pos++= 't'; break; - case '\'': *pos++= '\\'; *pos++= '\''; break; - case 0 : *pos++= '\\'; *pos++= '0'; break; + case '\n': packet->append(STRING_WITH_LEN("\\n")); break; + case '\r': packet->append(STRING_WITH_LEN("\\r")); break; + case '\\': packet->append(STRING_WITH_LEN("\\\\")); break; + case '\b': packet->append(STRING_WITH_LEN("\\b")); break; + case '\t': packet->append(STRING_WITH_LEN("\\t")); break; + case '\'': packet->append(STRING_WITH_LEN("\\'")); break; + case 0 : packet->append(STRING_WITH_LEN("\\0")); break; default: - *pos++= c; + packet->append(&c, 1); break; } } - *pos++= '\''; - return pos; + packet->append(STRING_WITH_LEN("'")); } #endif /* !MYSQL_CLIENT */ @@ -926,7 +926,7 @@ Log_event::do_shall_skip(Relay_log_info *rli) Log_event::pack_info() */ -void Log_event::pack_info(Protocol *protocol) +void Log_event::pack_info(THD *thd, Protocol *protocol) { protocol->store("", &my_charset_bin); } @@ -935,7 +935,8 @@ void Log_event::pack_info(Protocol *protocol) /** Only called by SHOW BINLOG EVENTS */ -int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos) +int Log_event::net_send(THD *thd, Protocol *protocol, const char* log_name, + my_off_t pos) { const char *p= strrchr(log_name, FN_LIBCHAR); const char *event_type; @@ -949,7 +950,7 @@ int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos) protocol->store(event_type, strlen(event_type), &my_charset_bin); protocol->store((uint32) server_id); protocol->store((ulonglong) log_pos); - pack_info(protocol); + pack_info(thd, protocol); return protocol->write(); } #endif /* HAVE_REPLICATION */ @@ -2448,27 +2449,22 @@ Log_event::continue_group(Relay_log_info *rli) show the catalog ?? */ -void Query_log_event::pack_info(Protocol *protocol) +void Query_log_event::pack_info(THD *thd, Protocol *protocol) { // TODO: show the catalog ?? - char *buf, *pos; - if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME)))) - return; - pos= buf; + char buf_mem[1024]; + String buf(buf_mem, sizeof(buf_mem), system_charset_info); + buf.real_alloc(9 + db_len + q_len); if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db && db_len) { - pos= strmov(buf, "use `"); - memcpy(pos, db, db_len); - pos= strmov(pos+db_len, "`; "); + buf.append(STRING_WITH_LEN("use ")); + append_identifier(thd, &buf, db, db_len); + buf.append("; "); } if (query && q_len) - { - memcpy(pos, query, q_len); - pos+= q_len; - } - protocol->store(buf, pos-buf, &my_charset_bin); - my_free(buf); + buf.append(query, q_len); + protocol->store(&buf); } #endif @@ -3334,11 +3330,17 @@ void Query_log_event::print_query_header(IO_CACHE* file, } else if (db) { + /* Room for expand ` to `` + initial/final ` + \0 */ + char buf[FN_REFLEN*2+3]; + different_db= memcmp(print_event_info->db, db, db_len + 1); if (different_db) memcpy(print_event_info->db, db, db_len + 1); if (db[0] && different_db) - my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter); + { + my_snprintf(buf, sizeof(buf), "%`s", db); + my_b_printf(file, "use %s%s\n", buf, print_event_info->delimiter); + } } end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10); @@ -4003,7 +4005,7 @@ Start_log_event_v3::Start_log_event_v3() */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Start_log_event_v3::pack_info(Protocol *protocol) +void Start_log_event_v3::pack_info(THD *thd, Protocol *protocol) { char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos; pos= strmov(buf, "Server ver: "); @@ -4779,131 +4781,113 @@ uint8 get_checksum_alg(const char* buf, ulong len) */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -uint Load_log_event::get_query_buffer_length() -{ - return - 5 + db_len + 3 + // "use DB; " - 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''" - 11 + // "CONCURRENT " - 7 + // LOCAL - 9 + // " REPLACE or IGNORE " - 13 + table_name_len*2 + // "INTO TABLE `table`" - 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'" - 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'" - 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'" - 21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'" - 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'" - 15 + 22 + // " IGNORE xxx LINES" - 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)" -} - - -void Load_log_event::print_query(bool need_db, const char *cs, char *buf, - char **end, char **fn_start, char **fn_end) +void Load_log_event::print_query(THD *thd, bool need_db, const char *cs, + String *buf, my_off_t *fn_start, + my_off_t *fn_end, const char *qualify_db) { - char *pos= buf; - if (need_db && db && db_len) { - pos= strmov(pos, "use `"); - memcpy(pos, db, db_len); - pos= strmov(pos+db_len, "`; "); + buf->append(STRING_WITH_LEN("use ")); + append_identifier(thd, buf, db, db_len); + buf->append(STRING_WITH_LEN("; ")); } - pos= strmov(pos, "LOAD DATA "); + buf->append(STRING_WITH_LEN("LOAD DATA ")); if (is_concurrent) - pos= strmov(pos, "CONCURRENT "); + buf->append(STRING_WITH_LEN("CONCURRENT ")); if (fn_start) - *fn_start= pos; + *fn_start= buf->length(); if (check_fname_outside_temp_buf()) - pos= strmov(pos, "LOCAL "); - pos= strmov(pos, "INFILE '"); - memcpy(pos, fname, fname_len); - pos= strmov(pos+fname_len, "' "); + buf->append(STRING_WITH_LEN("LOCAL ")); + buf->append(STRING_WITH_LEN("INFILE '")); + buf->append_for_single_quote(fname, fname_len); + buf->append(STRING_WITH_LEN("' ")); if (sql_ex.opt_flags & REPLACE_FLAG) - pos= strmov(pos, "REPLACE "); + buf->append(STRING_WITH_LEN("REPLACE ")); else if (sql_ex.opt_flags & IGNORE_FLAG) - pos= strmov(pos, "IGNORE "); + buf->append(STRING_WITH_LEN("IGNORE ")); - pos= strmov(pos ,"INTO"); + buf->append(STRING_WITH_LEN("INTO")); if (fn_end) - *fn_end= pos; + *fn_end= buf->length(); - pos= strmov(pos ," TABLE `"); - memcpy(pos, table_name, table_name_len); - pos+= table_name_len; + buf->append(STRING_WITH_LEN(" TABLE ")); + if (qualify_db) + { + append_identifier(thd, buf, qualify_db, strlen(qualify_db)); + buf->append(STRING_WITH_LEN(".")); + } + append_identifier(thd, buf, table_name, table_name_len); if (cs != NULL) { - pos= strmov(pos ,"` CHARACTER SET "); - pos= strmov(pos , cs); + buf->append(STRING_WITH_LEN(" CHARACTER SET ")); + buf->append(cs, strlen(cs)); } - else - pos= strmov(pos, "`"); /* We have to create all optional fields as the default is not empty */ - pos= strmov(pos, " FIELDS TERMINATED BY "); - pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len); + buf->append(STRING_WITH_LEN(" FIELDS TERMINATED BY ")); + pretty_print_str(buf, sql_ex.field_term, sql_ex.field_term_len); if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG) - pos= strmov(pos, " OPTIONALLY "); - pos= strmov(pos, " ENCLOSED BY "); - pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len); + buf->append(STRING_WITH_LEN(" OPTIONALLY ")); + buf->append(STRING_WITH_LEN(" ENCLOSED BY ")); + pretty_print_str(buf, sql_ex.enclosed, sql_ex.enclosed_len); - pos= strmov(pos, " ESCAPED BY "); - pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len); + buf->append(STRING_WITH_LEN(" ESCAPED BY ")); + pretty_print_str(buf, sql_ex.escaped, sql_ex.escaped_len); - pos= strmov(pos, " LINES TERMINATED BY "); - pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len); + buf->append(STRING_WITH_LEN(" LINES TERMINATED BY ")); + pretty_print_str(buf, sql_ex.line_term, sql_ex.line_term_len); if (sql_ex.line_start_len) { - pos= strmov(pos, " STARTING BY "); - pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len); + buf->append(STRING_WITH_LEN(" STARTING BY ")); + pretty_print_str(buf, sql_ex.line_start, sql_ex.line_start_len); } if ((long) skip_lines > 0) { - pos= strmov(pos, " IGNORE "); - pos= longlong10_to_str((longlong) skip_lines, pos, 10); - pos= strmov(pos," LINES "); + buf->append(STRING_WITH_LEN(" IGNORE ")); + buf->append_ulonglong(skip_lines); + buf->append(STRING_WITH_LEN(" LINES ")); } if (num_fields) { uint i; const char *field= fields; - pos= strmov(pos, " ("); + buf->append(STRING_WITH_LEN(" (")); for (i = 0; i < num_fields; i++) { if (i) { - *pos++= ' '; - *pos++= ','; + /* + Yes, the space and comma is reversed here. But this is mostly dead + code, at most used when reading really old binlogs from old servers, + so better just leave it as is... + */ + buf->append(STRING_WITH_LEN(" ,")); } - memcpy(pos, field, field_lens[i]); - pos+= field_lens[i]; + append_identifier(thd, buf, field, field_lens[i]); field+= field_lens[i] + 1; } - *pos++= ')'; + buf->append(STRING_WITH_LEN(")")); } - - *end= pos; } -void Load_log_event::pack_info(Protocol *protocol) +void Load_log_event::pack_info(THD *thd, Protocol *protocol) { - char *buf, *end; + char query_buffer[1024]; + String query_str(query_buffer, sizeof(query_buffer), system_charset_info); - if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME)))) - return; - print_query(TRUE, NULL, buf, &end, 0, 0); - protocol->store(buf, end-buf, &my_charset_bin); - my_free(buf); + query_str.length(0); + print_query(thd, TRUE, NULL, &query_str, 0, 0, NULL); + protocol->store(query_str.ptr(), query_str.length(), &my_charset_bin); } #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */ @@ -5361,16 +5345,20 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli, else { char llbuff[22]; - char *end; enum enum_duplicates handle_dup; bool ignore= 0; + char query_buffer[1024]; + String query_str(query_buffer, sizeof(query_buffer), system_charset_info); char *load_data_query; + query_str.length(0); /* Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST and written to slave's binlog if binlogging is on. */ - if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1))) + print_query(thd, FALSE, NULL, &query_str, NULL, NULL, NULL); + if (!(load_data_query= (char *)thd->strmake(query_str.ptr(), + query_str.length()))) { /* This will set thd->fatal_error in case of OOM. So we surely will notice @@ -5379,9 +5367,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli, goto error; } - print_query(FALSE, NULL, load_data_query, &end, NULL, NULL); - *end= 0; - thd->set_query(load_data_query, (uint) (end - load_data_query)); + thd->set_query(load_data_query, (uint) (query_str.length())); if (sql_ex.opt_flags & REPLACE_FLAG) handle_dup= DUP_REPLACE; @@ -5559,7 +5545,7 @@ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Rotate_log_event::pack_info(Protocol *protocol) +void Rotate_log_event::pack_info(THD *thd, Protocol *protocol) { char buf1[256], buf[22]; String tmp(buf1, sizeof(buf1), log_cs); @@ -5777,7 +5763,7 @@ Rotate_log_event::do_shall_skip(Relay_log_info *rli) */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Intvar_log_event::pack_info(Protocol *protocol) +void Intvar_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[256], *pos; pos= strmake(buf, get_var_type_name(), sizeof(buf)-23); @@ -5931,7 +5917,7 @@ Intvar_log_event::do_shall_skip(Relay_log_info *rli) **************************************************************************/ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Rand_log_event::pack_info(Protocol *protocol) +void Rand_log_event::pack_info(THD *thd, Protocol *protocol) { char buf1[256], *pos; pos= strmov(buf1,"rand_seed1="); @@ -6056,7 +6042,7 @@ bool slave_execute_deferred_events(THD *thd) **************************************************************************/ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Xid_log_event::pack_info(Protocol *protocol) +void Xid_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[128], *pos; pos= strmov(buf, "COMMIT /* xid="); @@ -6153,84 +6139,117 @@ Xid_log_event::do_shall_skip(Relay_log_info *rli) **************************************************************************/ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void User_var_log_event::pack_info(Protocol* protocol) +static bool +user_var_append_name_part(THD *thd, String *buf, + const char *name, size_t name_len) { - char *buf= 0; - uint val_offset= 4 + name_len; - uint event_len= val_offset; + return buf->append("@") || + append_identifier(thd, buf, name, name_len) || + buf->append("="); +} +void User_var_log_event::pack_info(THD *thd, Protocol* protocol) +{ if (is_null) { - if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME)))) + char buf_mem[FN_REFLEN+7]; + String buf(buf_mem, sizeof(buf_mem), system_charset_info); + buf.length(0); + if (user_var_append_name_part(thd, &buf, name, name_len) || + buf.append("NULL")) return; - strmov(buf + val_offset, "NULL"); - event_len= val_offset + 4; + protocol->store(buf.ptr(), buf.length(), &my_charset_bin); } else { switch (type) { case REAL_RESULT: + { double real_val; + char buf2[MY_GCVT_MAX_FIELD_WIDTH+1]; + char buf_mem[FN_REFLEN + MY_GCVT_MAX_FIELD_WIDTH + 1]; + String buf(buf_mem, sizeof(buf_mem), system_charset_info); float8get(real_val, val); - if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1, - MYF(MY_WME)))) + buf.length(0); + if (user_var_append_name_part(thd, &buf, name, name_len) || + buf.append(buf2, my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, + MY_GCVT_MAX_FIELD_WIDTH, buf2, NULL))) return; - event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH, - buf + val_offset, NULL); + protocol->store(buf.ptr(), buf.length(), &my_charset_bin); break; + } case INT_RESULT: - if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME)))) + { + char buf2[22]; + char buf_mem[FN_REFLEN + 22]; + String buf(buf_mem, sizeof(buf_mem), system_charset_info); + buf.length(0); + if (user_var_append_name_part(thd, &buf, name, name_len) || + buf.append(buf2, + longlong10_to_str(uint8korr(val), buf2, + ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10))-buf2)) return; - event_len= longlong10_to_str(uint8korr(val), buf + val_offset, - ((flags & User_var_log_event::UNSIGNED_F) ? - 10 : -10))-buf; + protocol->store(buf.ptr(), buf.length(), &my_charset_bin); break; + } case DECIMAL_RESULT: { - if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH, - MYF(MY_WME)))) - return; - String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin); + char buf_mem[FN_REFLEN + DECIMAL_MAX_STR_LENGTH]; + String buf(buf_mem, sizeof(buf_mem), system_charset_info); + char buf2[DECIMAL_MAX_STR_LENGTH+1]; + String str(buf2, sizeof(buf2), &my_charset_bin); my_decimal dec; + buf.length(0); binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0], val[1]); my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str); - event_len= str.length() + val_offset; + if (user_var_append_name_part(thd, &buf, name, name_len) || + buf.append(buf2)) + return; + protocol->store(buf.ptr(), buf.length(), &my_charset_bin); break; - } + } case STRING_RESULT: + { /* 15 is for 'COLLATE' and other chars */ - buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15, - MYF(MY_WME)); + char buf_mem[FN_REFLEN + 512 + 1 + 2*MY_CS_NAME_SIZE+15]; + String buf(buf_mem, sizeof(buf_mem), system_charset_info); CHARSET_INFO *cs; - if (!buf) - return; + buf.length(0); if (!(cs= get_charset(charset_number, MYF(0)))) { - strmov(buf+val_offset, "???"); - event_len+= 3; + if (buf.append("???")) + return; } else { - char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS); - p= str_to_hex(p, val, val_len); - p= strxmov(p, " COLLATE ", cs->name, NullS); - event_len= p-buf; + size_t old_len; + char *beg, *end; + if (user_var_append_name_part(thd, &buf, name, name_len) || + buf.append("_") || + buf.append(cs->csname) || + buf.append(" ")) + return; + old_len= buf.length(); + if (buf.reserve(old_len + val_len*2 + 2 + sizeof(" COLLATE ") + + MY_CS_NAME_SIZE)) + return; + beg= const_cast<char *>(buf.ptr()) + old_len; + end= str_to_hex(beg, val, val_len); + buf.length(old_len + (end - beg)); + if (buf.append(" COLLATE ") || + buf.append(cs->name)) + return; } + protocol->store(buf.ptr(), buf.length(), &my_charset_bin); break; + } case ROW_RESULT: default: DBUG_ASSERT(0); return; } } - buf[0]= '@'; - buf[1]= '`'; - memcpy(buf+2, name, name_len); - buf[2+name_len]= '`'; - buf[3+name_len]= '='; - protocol->store(buf, event_len, &my_charset_bin); - my_free(buf); } #endif /* !MYSQL_CLIENT */ @@ -6388,9 +6407,8 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) my_b_printf(&cache, "\tUser_var\n"); } - my_b_printf(&cache, "SET @`"); - my_b_write(&cache, (uchar*) name, (uint) (name_len)); - my_b_printf(&cache, "`"); + my_b_printf(&cache, "SET @"); + my_b_write_backtick_quote(&cache, name, name_len); if (is_null) { @@ -6613,7 +6631,7 @@ void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info #endif #ifndef MYSQL_CLIENT -void Slave_log_event::pack_info(Protocol *protocol) +void Slave_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[256+HOSTNAME_LENGTH], *pos; pos= strmov(buf, "host="); @@ -6995,7 +7013,7 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Create_file_log_event::pack_info(Protocol *protocol) +void Create_file_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos; pos= strmov(buf, "db="); @@ -7181,7 +7199,7 @@ void Append_block_log_event::print(FILE* file, */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Append_block_log_event::pack_info(Protocol *protocol) +void Append_block_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[256]; uint length; @@ -7338,7 +7356,7 @@ void Delete_file_log_event::print(FILE* file, */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Delete_file_log_event::pack_info(Protocol *protocol) +void Delete_file_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[64]; uint length; @@ -7437,7 +7455,7 @@ void Execute_load_log_event::print(FILE* file, */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Execute_load_log_event::pack_info(Protocol *protocol) +void Execute_load_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[64]; uint length; @@ -7699,27 +7717,24 @@ void Execute_load_query_log_event::print(FILE* file, #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Execute_load_query_log_event::pack_info(Protocol *protocol) +void Execute_load_query_log_event::pack_info(THD *thd, Protocol *protocol) { - char *buf, *pos; - if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME)))) - return; - pos= buf; + char buf_mem[1024]; + String buf(buf_mem, sizeof(buf_mem), system_charset_info); + buf.real_alloc(9 + db_len + q_len + 10 + 21); if (db && db_len) { - pos= strmov(buf, "use `"); - memcpy(pos, db, db_len); - pos= strmov(pos+db_len, "`; "); - } - if (query && q_len) - { - memcpy(pos, query, q_len); - pos+= q_len; + if (buf.append("use ") || + append_identifier(thd, &buf, db, db_len) || + buf.append("; ")) + return; } - pos= strmov(pos, " ;file_id="); - pos= int10_to_str((long) file_id, pos, 10); - protocol->store(buf, pos-buf, &my_charset_bin); - my_free(buf); + if (query && q_len && buf.append(query, q_len)) + return; + if (buf.append(" ;file_id=") || + buf.append_ulonglong(file_id)) + return; + protocol->store(buf.ptr(), buf.length(), &my_charset_bin); } @@ -8682,7 +8697,7 @@ bool Rows_log_event::write_data_body(IO_CACHE*file) #endif #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Rows_log_event::pack_info(Protocol *protocol) +void Rows_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[256]; char const *const flagstr= @@ -8786,7 +8801,7 @@ bool Annotate_rows_log_event::write_data_body(IO_CACHE *file) #endif #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) -void Annotate_rows_log_event::pack_info(Protocol* protocol) +void Annotate_rows_log_event::pack_info(THD *thd, Protocol* protocol) { if (m_query_txt && m_query_len) protocol->store(m_query_txt, m_query_len, &my_charset_bin); @@ -9530,7 +9545,7 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file) */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Table_map_log_event::pack_info(Protocol *protocol) +void Table_map_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[256]; size_t bytes= my_snprintf(buf, sizeof(buf), @@ -9551,7 +9566,7 @@ void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info) { print_header(&print_event_info->head_cache, print_event_info, TRUE); my_b_printf(&print_event_info->head_cache, - "\tTable_map: `%s`.`%s` mapped to number %lu\n", + "\tTable_map: %`s.%`s mapped to number %lu\n", m_dbnam, m_tblnam, m_table_id); print_base64(&print_event_info->body_cache, print_event_info, TRUE); } @@ -10884,7 +10899,7 @@ Incident_log_event::description() const #ifndef MYSQL_CLIENT -void Incident_log_event::pack_info(Protocol *protocol) +void Incident_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[256]; size_t bytes; diff --git a/sql/log_event.h b/sql/log_event.h index 19a77f03b84..00fddf1a821 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1065,14 +1065,15 @@ public: */ static void init_show_field_list(List<Item>* field_list); #ifdef HAVE_REPLICATION - int net_send(Protocol *protocol, const char* log_name, my_off_t pos); + int net_send(THD *thd, Protocol *protocol, const char* log_name, + my_off_t pos); /* pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends a string to display to the user, so it resembles print(). */ - virtual void pack_info(Protocol *protocol); + virtual void pack_info(THD *thd, Protocol *protocol); #endif /* HAVE_REPLICATION */ virtual const char* get_db() @@ -1809,7 +1810,7 @@ public: bool using_trans, bool direct, bool suppress_use, int error); const char* get_db() { return db; } #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info); @@ -1939,7 +1940,7 @@ public: #ifdef MYSQL_SERVER Slave_log_event(THD* thd_arg, Relay_log_info* rli); - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); #endif @@ -2172,9 +2173,9 @@ protected: const Format_description_log_event* description_event); public: - uint get_query_buffer_length(); - void print_query(bool need_db, const char *cs, char *buf, char **end, - char **fn_start, char **fn_end); + void print_query(THD *thd, bool need_db, const char *cs, String *buf, + my_off_t *fn_start, my_off_t *fn_end, + const char *qualify_db); ulong thread_id; ulong slave_proxy_id; uint32 table_name_len; @@ -2235,7 +2236,7 @@ public: Name_resolution_context *context); const char* get_db() { return db; } #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -2332,7 +2333,7 @@ public: #ifdef MYSQL_SERVER Start_log_event_v3(); #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else Start_log_event_v3() {} @@ -2496,7 +2497,7 @@ Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg, cache_type= Log_event::EVENT_NO_CACHE; } #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -2576,7 +2577,7 @@ class Rand_log_event: public Log_event cache_type= Log_event::EVENT_NO_CACHE; } #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -2625,7 +2626,7 @@ class Xid_log_event: public Log_event cache_type= Log_event::EVENT_NO_CACHE; } #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -2687,7 +2688,7 @@ public: if (direct) cache_type= Log_event::EVENT_NO_CACHE; } - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); #endif @@ -2825,7 +2826,7 @@ public: uint ident_len_arg, ulonglong pos_arg, uint flags); #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -2886,7 +2887,7 @@ public: uchar* block_arg, uint block_len_arg, bool using_trans); #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -2958,7 +2959,7 @@ public: Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg, uint block_len_arg, bool using_trans); #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); virtual int get_create_or_append() const; #endif /* HAVE_REPLICATION */ #else @@ -2999,7 +3000,7 @@ public: #ifdef MYSQL_SERVER Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans); #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -3040,7 +3041,7 @@ public: #ifdef MYSQL_SERVER Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans); #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -3136,7 +3137,7 @@ public: bool using_trans, bool direct, bool suppress_use, int errcode); #ifdef HAVE_REPLICATION - void pack_info(Protocol* protocol); + void pack_info(THD *thd, Protocol* protocol); #endif /* HAVE_REPLICATION */ #else void print(FILE* file, PRINT_EVENT_INFO* print_event_info); @@ -3222,7 +3223,7 @@ public: #endif #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) - virtual void pack_info(Protocol*); + virtual void pack_info(THD *thd, Protocol*); #endif #ifdef MYSQL_CLIENT @@ -3636,7 +3637,7 @@ public: #endif #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) - virtual void pack_info(Protocol *protocol); + virtual void pack_info(THD *thd, Protocol *protocol); #endif #ifdef MYSQL_CLIENT @@ -3748,7 +3749,7 @@ public: flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; } #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) - virtual void pack_info(Protocol *protocol); + virtual void pack_info(THD *thd, Protocol *protocol); #endif #ifdef MYSQL_CLIENT @@ -4195,7 +4196,7 @@ public: #endif #ifdef MYSQL_SERVER - void pack_info(Protocol*); + void pack_info(THD *thd, Protocol*); #endif Incident_log_event(const char *buf, uint event_len, diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 8f2c515e11c..d7c66af769a 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1935,7 +1935,7 @@ bool Old_rows_log_event::write_data_body(IO_CACHE*file) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Old_rows_log_event::pack_info(Protocol *protocol) +void Old_rows_log_event::pack_info(THD *thd, Protocol *protocol) { char buf[256]; char const *const flagstr= diff --git a/sql/log_event_old.h b/sql/log_event_old.h index 8fe2e9e0a75..3e1efd8e2c0 100644 --- a/sql/log_event_old.h +++ b/sql/log_event_old.h @@ -108,7 +108,7 @@ public: flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; } #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) - virtual void pack_info(Protocol *protocol); + virtual void pack_info(THD *thd, Protocol *protocol); #endif #ifdef MYSQL_CLIENT diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index abc22a00695..89fb1bb27de 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -35,7 +35,6 @@ #include "rpl_mi.h" #include "rpl_filter.h" #include "log_event.h" -#include "sql_db.h" // mysql_create_db #include <mysql.h> #define SLAVE_LIST_CHUNK 128 diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index a49f10db440..b883ec8df03 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -314,7 +314,7 @@ unpack_row(Relay_log_info const *rli, if (!pack_ptr) { rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT, - "Could not read field `%s` of table `%s`.`%s`", + "Could not read field %`s of table %`s.%`s", f->field_name, table->s->db.str, table->s->table_name.str); DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index acd330dd4d2..95b1843f5e1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3887,22 +3887,22 @@ static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry) entry->file->implicit_emptied= 0; if (mysql_bin_log.is_open()) { - char *query, *end; - uint query_buf_size= 20 + share->db.length + share->table_name.length +1; - if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME)))) + char query_buf[2*FN_REFLEN + 21]; + String query(query_buf, sizeof(query_buf), system_charset_info); + query.length(0); + if (query.ptr()) { /* this DELETE FROM is needed even with row-based binlogging */ - end = strxmov(strmov(query, "DELETE FROM `"), - share->db.str,"`.`",share->table_name.str,"`", NullS); + query.append("DELETE FROM "); + append_identifier(thd, &query, share->db.str, share->db.length); + query.append("."); + append_identifier(thd, &query, share->table_name.str, + share->table_name.length); int errcode= query_error_code(thd, TRUE); if (thd->binlog_query(THD::STMT_QUERY_TYPE, - query, (ulong)(end-query), + query.ptr(), query.length(), FALSE, FALSE, FALSE, errcode)) - { - my_free(query); return TRUE; - } - my_free(query); } else { @@ -3912,7 +3912,7 @@ static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry) because of MYF(MY_WME) in my_malloc() above). */ sql_print_error("When opening HEAP table, could not allocate memory " - "to write 'DELETE FROM `%s`.`%s`' to the binary log", + "to write 'DELETE FROM %`s.%`s' to the binary log", share->db.str, share->table_name.str); delete entry->triggers; return TRUE; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 052616f6965..5704b6d51b6 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -544,7 +544,6 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) { char path[FN_REFLEN+16]; - char tmp_query[FN_REFLEN+16]; long result= 1; int error= 0; MY_STAT stat_info; @@ -622,17 +621,9 @@ not_silent: char *query; uint query_length; - if (!thd->query()) // Only in replication - { - query= tmp_query; - query_length= (uint) (strxmov(tmp_query,"create database `", - db, "`", NullS) - tmp_query); - } - else - { - query= thd->query(); - query_length= thd->query_length(); - } + query= thd->query(); + query_length= thd->query_length(); + DBUG_ASSERT(query); ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB, query, query_length, @@ -885,18 +876,11 @@ update_binlog: { const char *query; ulong query_length; - if (!thd->query()) - { - /* The client used the old obsolete mysql_drop_db() call */ - query= path; - query_length= (uint) (strxmov(path, "drop database `", db, "`", - NullS) - path); - } - else - { - query= thd->query(); - query_length= thd->query_length(); - } + + query= thd->query(); + query_length= thd->query_length(); + DBUG_ASSERT(query); + if (mysql_bin_log.is_open()) { int errcode= query_error_code(thd, TRUE); @@ -940,6 +924,7 @@ update_binlog: { uint tbl_name_len; bool exists; + char quoted_name[FN_REFLEN+3]; // Only write drop table to the binlog for tables that no longer exist. if (check_if_table_exists(thd, tbl, &exists)) @@ -950,8 +935,8 @@ update_binlog: if (exists) continue; - /* 3 for the quotes and the comma*/ - tbl_name_len= strlen(tbl->table_name) + 3; + my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name); + tbl_name_len= strlen(quoted_name) + 1; /* +1 for the comma */ if (query_pos + tbl_name_len + 1 >= query_end) { /* @@ -966,9 +951,7 @@ update_binlog: query_pos= query_data_start; } - *query_pos++ = '`'; - query_pos= strmov(query_pos,tbl->table_name); - *query_pos++ = '`'; + query_pos= strmov(query_pos, quoted_name); *query_pos++ = ','; } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 33d1741b5ec..98031c96225 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -39,6 +39,7 @@ #include "sp_head.h" #include "sql_trigger.h" #include "sql_derived.h" +#include "sql_show.h" class XML_TAG { public: @@ -675,24 +676,28 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, bool transactional_table, int errcode) { - char *load_data_query, - *end, - *fname_start, - *fname_end, - *p= NULL; - size_t pl= 0; + char *load_data_query; + my_off_t fname_start, + fname_end; List<Item> fv; Item *item, *val; int n; - const char *tbl= table_name_arg; const char *tdb= (thd->db != NULL ? thd->db : db_arg); - char name_buffer[SAFE_NAME_LEN*2]; + const char *qualify_db= NULL; char command_buffer[1024]; - String string_buf(name_buffer, sizeof(name_buffer), - system_charset_info); - String pfields(command_buffer, sizeof(command_buffer), + String query_str(command_buffer, sizeof(command_buffer), system_charset_info); + Load_log_event lle(thd, ex, tdb, table_name_arg, fv, is_concurrent, + duplicates, ignore, transactional_table); + + /* + force in a LOCAL if there was one in the original. + */ + if (thd->lex->local_file) + lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name)); + + query_str.length(0); if (!thd->db || strcmp(db_arg, thd->db)) { /* @@ -700,49 +705,35 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, prefix table name with database name so that it becomes a FQ name. */ - string_buf.length(0); - string_buf.append(db_arg); - string_buf.append("`"); - string_buf.append("."); - string_buf.append("`"); - string_buf.append(table_name_arg); - tbl= string_buf.c_ptr_safe(); + qualify_db= db_arg; } - - Load_log_event lle(thd, ex, tdb, tbl, fv, is_concurrent, - duplicates, ignore, transactional_table); - - /* - force in a LOCAL if there was one in the original. - */ - if (thd->lex->local_file) - lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name)); + lle.print_query(thd, FALSE, (const char *) ex->cs?ex->cs->csname:NULL, + &query_str, &fname_start, &fname_end, qualify_db); /* prepare fields-list and SET if needed; print_query won't do that for us. */ - pfields.length(0); if (!thd->lex->field_list.is_empty()) { List_iterator<Item> li(thd->lex->field_list); - pfields.append(" ("); + query_str.append(" ("); n= 0; while ((item= li++)) { if (n++) - pfields.append(", "); + query_str.append(", "); if (item->type() == Item::FIELD_ITEM) + append_identifier(thd, &query_str, item->name, strlen(item->name)); + else { - pfields.append("`"); - pfields.append(item->name); - pfields.append("`"); + /* Actually Item_user_var_as_out_param despite claiming STRING_ITEM. */ + DBUG_ASSERT(item->type() == Item::STRING_ITEM); + ((Item_user_var_as_out_param *)item)->print_for_load(thd, &query_str); } - else - item->print(&pfields, QT_ORDINARY); } - pfields.append(")"); + query_str.append(")"); } if (!thd->lex->update_list.is_empty()) @@ -750,38 +741,25 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, List_iterator<Item> lu(thd->lex->update_list); List_iterator<Item> lv(thd->lex->value_list); - pfields.append(" SET "); + query_str.append(" SET "); n= 0; while ((item= lu++)) { val= lv++; if (n++) - pfields.append(", "); - pfields.append("`"); - pfields.append(item->name); - pfields.append("`"); - pfields.append(val->name); + query_str.append(", "); + append_identifier(thd, &query_str, item->name, strlen(item->name)); + query_str.append(val->name); } } - p= pfields.c_ptr_safe(); - pl= pfields.length(); - - if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl))) + if (!(load_data_query= (char *)thd->strmake(query_str.ptr(), query_str.length()))) return TRUE; - lle.print_query(FALSE, (const char *) ex->cs?ex->cs->csname:NULL, - load_data_query, &end, - (char **)&fname_start, (char **)&fname_end); - - strcpy(end, p); - end += pl; - Execute_load_query_log_event - e(thd, load_data_query, end-load_data_query, - (uint) ((char*) fname_start - load_data_query - 1), - (uint) ((char*) fname_end - load_data_query), + e(thd, load_data_query, query_str.length(), + (uint) (fname_start - 1), (uint) fname_end, (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE : (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR), transactional_table, FALSE, FALSE, errcode); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 751c0d6ada5..268a68c3202 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2000,7 +2000,7 @@ bool mysql_show_binlog_events(THD* thd) description_event->checksum_alg= ev->checksum_alg; if (event_count >= limit_start && - ev->net_send(protocol, linfo.log_file_name, pos)) + ev->net_send(thd, protocol, linfo.log_file_name, pos)) { errmsg = "Net error"; delete ev; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index dc09488632c..8dc00ee710a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -16481,7 +16481,7 @@ int report_error(TABLE *table, int error) && !table->in_use->killed) { push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, error, - "Got error %d when reading table `%s`.`%s`", + "Got error %d when reading table %`s.%`s", error, table->s->db.str, table->s->table_name.str); sql_print_error("Got error %d when reading table '%s'", error, table->s->path.str); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 009ced7810a..5e3095181ee 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -992,9 +992,13 @@ static const char *require_quotes(const char *name, uint name_length) packet target string name the identifier to be appended name_length length of the appending identifier + + RETURN VALUES + true Error + false Ok */ -void +bool append_identifier(THD *thd, String *packet, const char *name, uint length) { const char *name_end; @@ -1002,10 +1006,7 @@ append_identifier(THD *thd, String *packet, const char *name, uint length) int q= get_quote_char_for_identifier(thd, name, length); if (q == EOF) - { - packet->append(name, length, packet->charset()); - return; - } + return packet->append(name, length, packet->charset()); /* The identifier must be quoted as it includes a quote character or @@ -1014,7 +1015,8 @@ append_identifier(THD *thd, String *packet, const char *name, uint length) (void) packet->reserve(length*2 + 2); quote_char= (char) q; - packet->append("e_char, 1, system_charset_info); + if (packet->append("e_char, 1, system_charset_info)) + return true; for (name_end= name+length ; name < name_end ; name+= length) { @@ -1029,11 +1031,13 @@ append_identifier(THD *thd, String *packet, const char *name, uint length) */ if (!length) length= 1; - if (length == 1 && chr == (uchar) quote_char) - packet->append("e_char, 1, system_charset_info); - packet->append(name, length, system_charset_info); + if (length == 1 && chr == (uchar) quote_char && + packet->append("e_char, 1, system_charset_info)) + return true; + if (packet->append(name, length, system_charset_info)) + return true; } - packet->append("e_char, 1, system_charset_info); + return packet->append("e_char, 1, system_charset_info); } diff --git a/sql/sql_show.h b/sql/sql_show.h index 8ad9327c08c..611e3a64c73 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -90,7 +90,7 @@ int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff); int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table); -void append_identifier(THD *thd, String *packet, const char *name, +bool append_identifier(THD *thd, String *packet, const char *name, uint length); void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild); int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd); diff --git a/sql/sql_string.cc b/sql/sql_string.cc index c4f5f315b08..75029a03790 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -1121,39 +1121,47 @@ outp: - -void String::print(String *str) +/* + Append characters to a single-quoted string '...', escaping special + characters as necessary. + Does not add the enclosing quotes, this is left up to caller. +*/ +void String::append_for_single_quote(const char *st, uint len) { - char *st= (char*)Ptr, *end= st+str_length; + const char *end= st+len; for (; st < end; st++) { uchar c= *st; switch (c) { case '\\': - str->append(STRING_WITH_LEN("\\\\")); + append(STRING_WITH_LEN("\\\\")); break; case '\0': - str->append(STRING_WITH_LEN("\\0")); + append(STRING_WITH_LEN("\\0")); break; case '\'': - str->append(STRING_WITH_LEN("\\'")); + append(STRING_WITH_LEN("\\'")); break; case '\n': - str->append(STRING_WITH_LEN("\\n")); + append(STRING_WITH_LEN("\\n")); break; case '\r': - str->append(STRING_WITH_LEN("\\r")); + append(STRING_WITH_LEN("\\r")); break; case '\032': // Ctrl-Z - str->append(STRING_WITH_LEN("\\Z")); + append(STRING_WITH_LEN("\\Z")); break; default: - str->append(c); + append(c); } } } +void String::print(String *str) +{ + str->append_for_single_quote(Ptr, str_length); +} /* Exchange state of this object and argument. diff --git a/sql/sql_string.h b/sql/sql_string.h index 86af507918c..2f0cd9103dc 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -459,6 +459,7 @@ public: return FALSE; } void print(String *print); + void append_for_single_quote(const char *st, uint len); /* Swap two string objects. Efficient way to exchange data without memcpy. */ void swap(String &s); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index db5435b9b27..f01c367fd55 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2104,6 +2104,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, { bool is_trans; char *db=table->db; + size_t db_length= table->db_length; handlerton *table_type; enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN; @@ -2165,14 +2166,14 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, Don't write the database name if it is the current one (or if thd->db is NULL). */ - built_ptr_query->append("`"); if (thd->db == NULL || strcmp(db,thd->db) != 0) { - built_ptr_query->append(db); - built_ptr_query->append("`.`"); + append_identifier(thd, built_ptr_query, db, db_length); + built_ptr_query->append("."); } - built_ptr_query->append(table->table_name); - built_ptr_query->append("`,"); + append_identifier(thd, built_ptr_query, table->table_name, + table->table_name_length); + built_ptr_query->append(","); } /* This means that a temporary table was droped and as such there @@ -2228,15 +2229,15 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, Don't write the database name if it is the current one (or if thd->db is NULL). */ - built_query.append("`"); if (thd->db == NULL || strcmp(db,thd->db) != 0) { - built_query.append(db); - built_query.append("`.`"); + append_identifier(thd, &built_query, db, db_length); + built_query.append("."); } - built_query.append(table->table_name); - built_query.append("`,"); + append_identifier(thd, &built_query, table->table_name, + table->table_name_length); + built_query.append(","); } } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 3c1b231d3f2..9d4ca5e1373 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -24,6 +24,7 @@ #include "sql_acl.h" // DROP_ACL #include "sql_parse.h" // check_one_table_access() #include "sql_truncate.h" +#include "sql_show.h" /** @@ -35,7 +36,8 @@ @return TRUE on failure, FALSE otherwise. */ -static bool fk_info_append_fields(String *str, List<LEX_STRING> *fields) +static bool fk_info_append_fields(THD *thd, String *str, + List<LEX_STRING> *fields) { bool res= FALSE; LEX_STRING *field; @@ -43,9 +45,8 @@ static bool fk_info_append_fields(String *str, List<LEX_STRING> *fields) while ((field= it++)) { - res|= str->append("`"); - res|= str->append(field); - res|= str->append("`, "); + res|= append_identifier(thd, str, field->str, field->length); + res|= str->append(", "); } str->chop(); @@ -76,20 +77,24 @@ static const char *fk_info_str(THD *thd, FOREIGN_KEY_INFO *fk_info) `db`.`tbl`, CONSTRAINT `id` FOREIGN KEY (`fk`) REFERENCES `db`.`tbl` (`fk`) */ - res|= str.append('`'); - res|= str.append(fk_info->foreign_db); - res|= str.append("`.`"); - res|= str.append(fk_info->foreign_table); - res|= str.append("`, CONSTRAINT `"); - res|= str.append(fk_info->foreign_id); - res|= str.append("` FOREIGN KEY ("); - res|= fk_info_append_fields(&str, &fk_info->foreign_fields); - res|= str.append(") REFERENCES `"); - res|= str.append(fk_info->referenced_db); - res|= str.append("`.`"); - res|= str.append(fk_info->referenced_table); - res|= str.append("` ("); - res|= fk_info_append_fields(&str, &fk_info->referenced_fields); + res|= append_identifier(thd, &str, fk_info->foreign_db->str, + fk_info->foreign_db->length); + res|= str.append("."); + res|= append_identifier(thd, &str, fk_info->foreign_table->str, + fk_info->foreign_table->length); + res|= str.append(", CONSTRAINT "); + res|= append_identifier(thd, &str, fk_info->foreign_id->str, + fk_info->foreign_id->length); + res|= str.append(" FOREIGN KEY ("); + res|= fk_info_append_fields(thd, &str, &fk_info->foreign_fields); + res|= str.append(") REFERENCES "); + res|= append_identifier(thd, &str, fk_info->referenced_db->str, + fk_info->referenced_db->length); + res|= str.append("."); + res|= append_identifier(thd, &str, fk_info->referenced_table->str, + fk_info->referenced_table->length); + res|= str.append(" ("); + res|= fk_info_append_fields(thd, &str, &fk_info->referenced_fields); res|= str.append(')'); return res ? NULL : thd->strmake(str.ptr(), str.length()); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1b5f741d44a..8ef59fafb98 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -12144,7 +12144,7 @@ load_data_set_elem: if (lex->update_list.push_back($1) || lex->value_list.push_back($4)) MYSQL_YYABORT; - $4->set_name($3, (uint) ($5 - $3), YYTHD->charset()); + $4->set_name_no_truncate($3, (uint) ($5 - $3), YYTHD->charset()); } ; |