summaryrefslogtreecommitdiff
path: root/sql/log_event.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r--sql/log_event.cc209
1 files changed, 164 insertions, 45 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 2f27efa8b4e..829ee06d20e 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -34,6 +34,7 @@
#include "rpl_utility.h"
#include "rpl_record.h"
#include <my_dir.h>
+#include "sql_show.h" // append_identifier
#endif /* MYSQL_CLIENT */
@@ -1946,6 +1947,10 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
void Rows_log_event::print_verbose(IO_CACHE *file,
PRINT_EVENT_INFO *print_event_info)
{
+ // Quoted length of the identifier can be twice the original length
+ char quoted_db[1 + NAME_LEN * 2 + 2];
+ char quoted_table[1 + NAME_LEN * 2 + 2];
+ int quoted_db_len, quoted_table_len;
Table_map_log_event *map;
table_def *td;
const char *sql_command, *sql_clause1, *sql_clause2;
@@ -1982,9 +1987,23 @@ void Rows_log_event::print_verbose(IO_CACHE *file,
for (const uchar *value= m_rows_buf; value < m_rows_end; )
{
size_t length;
+#ifdef MYSQL_SERVER
+ quoted_db_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_db,
+ map->get_db_name(), 0);
+ quoted_table_len= my_strmov_quoted_identifier(this->thd,
+ (char *) quoted_table,
+ map->get_table_name(), 0);
+#else
+ quoted_db_len= my_strmov_quoted_identifier((char *) quoted_db,
+ map->get_db_name());
+ quoted_table_len= my_strmov_quoted_identifier((char *) quoted_table,
+ map->get_table_name());
+#endif
+ quoted_db[quoted_db_len]= '\0';
+ quoted_table[quoted_table_len]= '\0';
my_b_printf(file, "### %s %s.%s\n",
sql_command,
- map->get_db_name(), map->get_table_name());
+ quoted_db, quoted_table);
/* Print the first image */
if (!(length= print_verbose_one_row(file, td, print_event_info,
&m_cols, value,
@@ -2143,24 +2162,20 @@ Log_event::continue_group(Relay_log_info *rli)
void Query_log_event::pack_info(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;
+ String temp_buf;
+ // Add use `DB` to the string if required
if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
&& db && db_len)
{
- pos= strmov(buf, "use `");
- memcpy(pos, db, db_len);
- pos= strmov(pos+db_len, "`; ");
+ temp_buf.append("use ");
+ append_identifier(this->thd, &temp_buf, db, db_len);
+ temp_buf.append("; ");
}
+ // Add the query to the string
if (query && q_len)
- {
- memcpy(pos, query, q_len);
- pos+= q_len;
- }
- protocol->store(buf, pos-buf, &my_charset_bin);
- my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
+ temp_buf.append(query);
+ // persist the buffer in protocol
+ protocol->store(temp_buf.ptr(), temp_buf.length(), &my_charset_bin);
}
#endif
@@ -2932,6 +2947,8 @@ void Query_log_event::print_query_header(IO_CACHE* file,
{
// TODO: print the catalog ??
char buff[40],*end; // Enough for SET TIMESTAMP
+ char quoted_id[1+ 2*FN_REFLEN+ 2];
+ int quoted_len= 0;
bool different_db= 1;
uint32 tmp;
@@ -2950,11 +2967,17 @@ void Query_log_event::print_query_header(IO_CACHE* file,
}
else if (db)
{
+#ifdef MYSQL_SERVER
+ quoted_len= my_strmov_quoted_identifier(this->thd, (char*)quoted_id, db, 0);
+#else
+ quoted_len= my_strmov_quoted_identifier((char*)quoted_id, db);
+#endif
+ quoted_id[quoted_len]= '\0';
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_b_printf(file, "use %s%s\n", quoted_id, print_event_info->delimiter);
}
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
@@ -4216,7 +4239,8 @@ void Format_description_log_event::calc_server_version_split()
uint Load_log_event::get_query_buffer_length()
{
return
- 5 + db_len + 3 + // "use DB; "
+ //the DB name may double if we escape the quote character
+ 5 + 2*db_len + 3 +
18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
11 + // "CONCURRENT "
7 + // LOCAL
@@ -4235,13 +4259,21 @@ uint Load_log_event::get_query_buffer_length()
void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
char **end, char **fn_start, char **fn_end)
{
+ char quoted_id[1 + NAME_LEN * 2 + 2];//quoted length
+ int quoted_id_len= 0;
char *pos= buf;
if (need_db && db && db_len)
{
- pos= strmov(pos, "use `");
- memcpy(pos, db, db_len);
- pos= strmov(pos+db_len, "`; ");
+ pos= strmov(pos, "use ");
+#ifdef MYSQL_SERVER
+ quoted_id_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_id,
+ db, 0);
+#else
+ quoted_id_len= my_strmov_quoted_identifier((char *) quoted_id, db);
+#endif
+ pos+= quoted_id_len;
+ pos= strmov(pos, "; ");
}
pos= strmov(pos, "LOAD DATA ");
@@ -4268,17 +4300,15 @@ void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
if (fn_end)
*fn_end= pos;
- pos= strmov(pos ," TABLE `");
+ pos= strmov(pos ," TABLE ");
memcpy(pos, table_name, table_name_len);
pos+= table_name_len;
if (cs != NULL)
{
- pos= strmov(pos ,"` CHARACTER SET ");
+ pos= strmov(pos ," CHARACTER SET ");
pos= strmov(pos , cs);
}
- else
- pos= strmov(pos, "`");
/* We have to create all optional fields as the default is not empty */
pos= strmov(pos, " FIELDS TERMINATED BY ");
@@ -4318,9 +4348,9 @@ void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
*pos++= ' ';
*pos++= ',';
}
- memcpy(pos, field, field_lens[i]);
- pos+= field_lens[i];
- field+= field_lens[i] + 1;
+ quoted_id_len= my_strmov_quoted_identifier(this->thd, quoted_id, field,
+ 0);
+ memcpy(pos, quoted_id, quoted_id_len);
}
*pos++= ')';
}
@@ -4560,6 +4590,8 @@ void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
bool commented)
{
+ size_t id_len= 0;
+ char temp_buf[1 + 2*FN_REFLEN + 2];
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
DBUG_ENTER("Load_log_event::print");
@@ -4585,10 +4617,16 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
}
if (db && db[0] && different_db)
- my_b_printf(&cache, "%suse %s%s\n",
- commented ? "# " : "",
- db, print_event_info->delimiter);
-
+ {
+#ifdef MYSQL_SERVER
+ id_len= my_strmov_quoted_identifier(this->thd, temp_buf, db, 0);
+#else
+ id_len= my_strmov_quoted_identifier(temp_buf, db);
+#endif
+ temp_buf[id_len]= '\0';
+ my_b_printf(&cache, "%suse %s%s\n",
+ commented ? "# " : "", temp_buf, print_event_info->delimiter);
+ }
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
commented ? "# " : "", (ulong)thread_id,
@@ -4603,8 +4641,14 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
my_b_printf(&cache,"REPLACE ");
else if (sql_ex.opt_flags & IGNORE_FLAG)
my_b_printf(&cache,"IGNORE ");
-
- my_b_printf(&cache, "INTO TABLE `%s`", table_name);
+
+#ifdef MYSQL_SERVER
+ id_len= my_strmov_quoted_identifier(this->thd, temp_buf, table_name, 0);
+#else
+ id_len= my_strmov_quoted_identifier(temp_buf, table_name);
+#endif
+ temp_buf[id_len]= '\0';
+ my_b_printf(&cache, "INTO TABLE %s", temp_buf);
my_b_printf(&cache, " FIELDS TERMINATED BY ");
pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
@@ -4637,7 +4681,9 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
{
if (i)
my_b_printf(&cache, ",");
- my_b_printf(&cache, "%s", field);
+ id_len= my_strmov_quoted_identifier((char *) temp_buf, field);
+ temp_buf[id_len]= '\0';
+ my_b_printf(&cache, "%s", temp_buf);
field += field_lens[i] + 1;
}
@@ -5560,7 +5606,10 @@ Xid_log_event::do_shall_skip(Relay_log_info *rli)
void User_var_log_event::pack_info(Protocol* protocol)
{
char *buf= 0;
- uint val_offset= 4 + name_len;
+ char quoted_id[1 + FN_REFLEN * 2 + 2];// quoted identifier
+ int id_len= my_strmov_quoted_identifier(this->thd, quoted_id, name, 0);
+ quoted_id[id_len]= '\0';
+ uint val_offset= 2 + id_len;
uint event_len= val_offset;
if (is_null)
@@ -5626,10 +5675,8 @@ void User_var_log_event::pack_info(Protocol* protocol)
}
}
buf[0]= '@';
- buf[1]= '`';
- memcpy(buf+2, name, name_len);
- buf[2+name_len]= '`';
- buf[3+name_len]= '=';
+ memcpy(buf + 1, quoted_id, id_len);
+ buf[1 + id_len]= '=';
protocol->store(buf, event_len, &my_charset_bin);
my_free(buf, MYF(0));
}
@@ -5740,6 +5787,8 @@ bool User_var_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ char quoted_id[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
+ int quoted_len= 0;
Write_on_release_cache cache(&print_event_info->head_cache, file,
Write_on_release_cache::FLUSH_F);
@@ -5749,9 +5798,11 @@ 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 @");
+ quoted_len= my_strmov_quoted_identifier((char *) quoted_id,
+ (const char *) name);
+ quoted_id[quoted_len]= '\0';
+ my_b_write(&cache, (uchar*) quoted_id, (uint) quoted_len);
if (is_null)
{
@@ -7043,14 +7094,23 @@ void Execute_load_query_log_event::print(FILE* file,
void Execute_load_query_log_event::pack_info(Protocol *protocol)
{
char *buf, *pos;
- if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
+ if (!(buf= (char*) my_malloc(9 + (db_len * 2) + 2 + q_len + 10 + 21,
+ MYF(MY_WME))))
return;
pos= buf;
if (db && db_len)
{
- pos= strmov(buf, "use `");
- memcpy(pos, db, db_len);
- pos= strmov(pos+db_len, "`; ");
+ /*
+ Statically allocates room to store '\0' and an identifier
+ that may have NAME_LEN * 2 due to quoting and there are
+ two quoting characters that wrap them.
+ */
+ char quoted_db[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
+ size_t size= 0;
+ size= my_strmov_quoted_identifier(this->thd, quoted_db, db, 0);
+ pos= strmov(buf, "use ");
+ memcpy(pos, quoted_db, size);
+ pos= strmov(pos + size, "; ");
}
if (query && q_len)
{
@@ -9907,3 +9967,62 @@ st_print_event_info::st_print_event_info()
open_cached_file(&body_cache, NULL, NULL, 0, flags);
}
#endif
+
+#ifdef MYSQL_SERVER
+/*
+ This is a utility function that adds a quoted identifier into the a buffer.
+ This also escapes any existance of the quote string inside the identifier.
+
+ SYNOPSIS
+ my_strmov_quoted_identifier
+ thd thread handler
+ buffer target buffer
+ identifier the identifier to be quoted
+ length length of the identifier
+*/
+size_t my_strmov_quoted_identifier(THD* thd, char *buffer,
+ const char* identifier,
+ uint length)
+{
+ int q= thd ? get_quote_char_for_identifier(thd, identifier, length) : '`';
+ return my_strmov_quoted_identifier_helper(q, buffer, identifier, length);
+}
+#else
+size_t my_strmov_quoted_identifier(char *buffer, const char* identifier)
+{
+ int q= '`';
+ return my_strmov_quoted_identifier_helper(q, buffer, identifier, 0);
+}
+
+#endif
+
+size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
+ const char* identifier,
+ uint length)
+{
+ size_t written= 0;
+ char quote_char;
+ uint id_length= (length) ? length : strlen(identifier);
+
+ if (q == EOF)
+ {
+ (void *) strncpy(buffer, identifier, id_length);
+ return id_length;
+ }
+ quote_char= (char) q;
+ *buffer++= quote_char;
+ written++;
+ while (id_length--)
+ {
+ if (*identifier == quote_char)
+ {
+ *buffer++= quote_char;
+ written++;
+ }
+ *buffer++= *identifier++;
+ written++;
+ }
+ *buffer++= quote_char;
+ return ++written;
+}
+