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.cc198
1 files changed, 125 insertions, 73 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index d93845603fd..d65b20f4b72 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -372,7 +372,7 @@ append_query_string(CHARSET_INFO *csinfo,
else
{
*ptr++= '\'';
- ptr+= escape_string_for_mysql(from->charset(), ptr, 0,
+ ptr+= escape_string_for_mysql(csinfo, ptr, 0,
from->ptr(), from->length());
*ptr++='\'';
}
@@ -993,7 +993,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
case FORMAT_DESCRIPTION_EVENT:
ev = new Format_description_log_event(buf, event_len, description_event);
break;
-#if defined(HAVE_REPLICATION) && defined(HAVE_ROW_BASED_REPLICATION)
+#if defined(HAVE_REPLICATION)
case WRITE_ROWS_EVENT:
ev = new Write_rows_log_event(buf, event_len, description_event);
break;
@@ -1182,7 +1182,7 @@ void Log_event::print_base64(IO_CACHE* file,
my_b_printf(file, "%s\n", tmp_str);
if (!more)
- my_b_printf(file, "';\n");
+ my_b_printf(file, "'%s\n", print_event_info->delimiter);
my_free(tmp_str, MYF(0));
DBUG_VOID_RETURN;
@@ -1288,7 +1288,8 @@ bool Query_log_event::write(IO_CACHE* file)
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+1+MAX_TIME_ZONE_NAME_LENGTH // code of tz and tz length and tz name
+ 1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name
+ 1+2 // code of lc_time_names and lc_time_names_number
], *start, *start_of_status;
ulong event_length;
@@ -1400,6 +1401,13 @@ bool Query_log_event::write(IO_CACHE* file)
memcpy(start, time_zone_str, time_zone_len);
start+= time_zone_len;
}
+ if (lc_time_names_number)
+ {
+ DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
+ *start++= Q_LC_TIME_NAMES_CODE;
+ int2store(start, lc_time_names_number);
+ start+= 2;
+ }
/*
Here there could be code like
if (command-line-option-which-says-"log_this_variable" && inited)
@@ -1464,7 +1472,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
flags2_inited(1), sql_mode_inited(1), charset_inited(1),
sql_mode(thd_arg->variables.sql_mode),
auto_increment_increment(thd_arg->variables.auto_increment_increment),
- auto_increment_offset(thd_arg->variables.auto_increment_offset)
+ auto_increment_offset(thd_arg->variables.auto_increment_offset),
+ lc_time_names_number(thd_arg->variables.lc_time_names->number)
{
time_t end_time;
time(&end_time);
@@ -1506,18 +1515,27 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
/* 2 utility functions for the next method */
-static void get_str_len_and_pointer(const char **dst, const char **src, uint *len)
+
+/*
+ Get the pointer for a string (src) that contains the length in
+ the first byte. Set the output string (dst) to the string value
+ and place the length of the string in the byte after the string.
+*/
+static void get_str_len_and_pointer(const Log_event::Byte **src,
+ const char **dst,
+ uint *len)
{
if ((*len= **src))
- *dst= *src + 1; // Will be copied later
- (*src)+= *len+1;
+ *dst= (char *)*src + 1; // Will be copied later
+ (*src)+= *len + 1;
}
-
-static void copy_str_and_move(char **dst, const char **src, uint len)
+static void copy_str_and_move(const char **src,
+ Log_event::Byte **dst,
+ uint len)
{
memcpy(*dst, *src, len);
- *src= *dst;
+ *src= (const char *)*dst;
(*dst)+= len;
*(*dst)++= 0;
}
@@ -1535,13 +1553,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
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),
- time_zone_len(0)
+ time_zone_len(0), lc_time_names_number(0)
{
ulong data_len;
uint32 tmp;
uint8 common_header_len, post_header_len;
- char *start;
- const char *end;
+ Log_event::Byte *start;
+ const Log_event::Byte *end;
bool catalog_nz= 1;
DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
@@ -1587,9 +1605,9 @@ 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= (const char*) (start+status_vars_len);
- for (const uchar* pos= (const uchar*) start; pos < (const uchar*) end;)
+ start= (Log_event::Byte*) (buf+post_header_len);
+ end= (const Log_event::Byte*) (start+status_vars_len);
+ for (const Log_event::Byte* pos= start; pos < end;)
{
switch (*pos++) {
case Q_FLAGS2_CODE:
@@ -1611,7 +1629,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
break;
}
case Q_CATALOG_NZ_CODE:
- get_str_len_and_pointer(&catalog, (const char **)(&pos), &catalog_len);
+ get_str_len_and_pointer(&pos, &catalog, &catalog_len);
break;
case Q_AUTO_INCREMENT:
auto_increment_increment= uint2korr(pos);
@@ -1627,7 +1645,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
}
case Q_TIME_ZONE_CODE:
{
- get_str_len_and_pointer(&time_zone_str, (const char **)(&pos), &time_zone_len);
+ get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len);
break;
}
case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
@@ -1636,6 +1654,10 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
pos+= catalog_len+2; // leap over end 0
catalog_nz= 0; // catalog has end 0 in event
break;
+ case Q_LC_TIME_NAMES_CODE:
+ lc_time_names_number= uint2korr(pos);
+ pos+= 2;
+ 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\
@@ -1645,38 +1667,38 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
}
#if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
- if (!(start= data_buf = (char*) my_malloc(catalog_len + 1 +
- time_zone_len + 1 +
- data_len + 1 +
- QUERY_CACHE_FLAGS_SIZE +
- db_len + 1,
- MYF(MY_WME))))
+ if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 +
+ time_zone_len + 1 +
+ data_len + 1 +
+ QUERY_CACHE_FLAGS_SIZE +
+ db_len + 1,
+ MYF(MY_WME))))
#else
- if (!(start= data_buf = (char*) my_malloc(catalog_len + 1 +
- time_zone_len + 1 +
- data_len + 1,
- MYF(MY_WME))))
+ if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 +
+ time_zone_len + 1 +
+ data_len + 1,
+ MYF(MY_WME))))
#endif
DBUG_VOID_RETURN;
if (catalog_len) // If catalog is given
{
if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
- copy_str_and_move(&start, &catalog, catalog_len);
+ copy_str_and_move(&catalog, &start, catalog_len);
else
{
memcpy(start, catalog, catalog_len+1); // copy end 0
- catalog= start;
+ catalog= (const char *)start;
start+= catalog_len+1;
}
}
if (time_zone_len)
- copy_str_and_move(&start, &time_zone_str, time_zone_len);
+ copy_str_and_move(&time_zone_str, &start, time_zone_len);
/* A 2nd variable part; this is common to all versions */
memcpy((char*) start, end, data_len); // Copy db and query
start[data_len]= '\0'; // End query with \0 (For safetly)
- db= start;
- query= start + db_len + 1;
+ db= (char *)start;
+ query= (char *)(start + db_len + 1);
q_len= data_len - db_len -1;
DBUG_VOID_RETURN;
}
@@ -1708,15 +1730,16 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (different_db= memcmp(print_event_info->db, db, db_len + 1))
memcpy(print_event_info->db, db, db_len + 1);
if (db[0] && different_db)
- my_b_printf(file, "use %s;\n", db);
+ my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
}
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
- *end++=';';
+ end= strmov(end, print_event_info->delimiter);
*end++='\n';
my_b_write(file, (byte*) buff, (uint) (end-buff));
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
- my_b_printf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id);
+ my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
+ (ulong)thread_id, print_event_info->delimiter);
/*
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
@@ -1745,7 +1768,7 @@ void Query_log_event::print_query_header(IO_CACHE* file,
"@@session.sql_auto_is_null", &need_comma);
print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
"@@session.unique_checks", &need_comma);
- my_b_printf(file,";\n");
+ my_b_printf(file,"%s\n", print_event_info->delimiter);
print_event_info->flags2= flags2;
}
}
@@ -1773,15 +1796,17 @@ void Query_log_event::print_query_header(IO_CACHE* file,
}
if (unlikely(print_event_info->sql_mode != sql_mode))
{
- my_b_printf(file,"SET @@session.sql_mode=%lu;\n",(ulong)sql_mode);
+ my_b_printf(file,"SET @@session.sql_mode=%lu%s\n",
+ (ulong)sql_mode, print_event_info->delimiter);
print_event_info->sql_mode= sql_mode;
}
}
if (print_event_info->auto_increment_increment != auto_increment_increment ||
print_event_info->auto_increment_offset != auto_increment_offset)
{
- my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;\n",
- auto_increment_increment,auto_increment_offset);
+ my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
+ auto_increment_increment,auto_increment_offset,
+ print_event_info->delimiter);
print_event_info->auto_increment_increment= auto_increment_increment;
print_event_info->auto_increment_offset= auto_increment_offset;
}
@@ -1801,16 +1826,18 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (cs_info)
{
/* for mysql client */
- my_b_printf(file, "/*!\\C %s */;\n", cs_info->csname);
+ my_b_printf(file, "/*!\\C %s */%s\n",
+ cs_info->csname, print_event_info->delimiter);
}
my_b_printf(file,"SET "
"@@session.character_set_client=%d,"
"@@session.collation_connection=%d,"
"@@session.collation_server=%d"
- ";\n",
+ "%s\n",
uint2korr(charset),
uint2korr(charset+2),
- uint2korr(charset+4));
+ uint2korr(charset+4),
+ print_event_info->delimiter);
memcpy(print_event_info->charset, charset, 6);
}
}
@@ -1818,10 +1845,17 @@ void Query_log_event::print_query_header(IO_CACHE* file,
{
if (bcmp(print_event_info->time_zone_str, time_zone_str, time_zone_len+1))
{
- my_b_printf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
+ my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
+ time_zone_str, print_event_info->delimiter);
memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
}
}
+ if (lc_time_names_number != print_event_info->lc_time_names_number)
+ {
+ my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
+ lc_time_names_number, print_event_info->delimiter);
+ print_event_info->lc_time_names_number= lc_time_names_number;
+ }
}
@@ -1831,7 +1865,7 @@ void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
print_query_header(&cache, print_event_info);
my_b_write(&cache, (byte*) query, q_len);
- my_b_printf(&cache, ";\n");
+ my_b_printf(&cache, "%s\n", print_event_info->delimiter);
}
#endif /* MYSQL_CLIENT */
@@ -1964,6 +1998,19 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli,
goto compare_errors;
}
}
+ if (lc_time_names_number)
+ {
+ if (!(thd->variables.lc_time_names=
+ my_locale_by_number(lc_time_names_number)))
+ {
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "Unknown locale: '%d'", MYF(0), lc_time_names_number);
+ thd->variables.lc_time_names= &my_locale_en_US;
+ goto compare_errors;
+ }
+ }
+ else
+ thd->variables.lc_time_names= &my_locale_en_US;
/* Execute the query (note that we bypass dispatch_command()) */
mysql_parse(thd, thd->query, thd->query_length);
@@ -2188,9 +2235,9 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
and rollback unfinished transaction.
Probably this can be done with RESET CONNECTION (syntax to be defined).
*/
- my_b_printf(&cache,"RESET CONNECTION;\n");
+ my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
#else
- my_b_printf(&cache,"ROLLBACK;\n");
+ my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
#endif
}
DBUG_VOID_RETURN;
@@ -2945,15 +2992,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;\n",
+ my_b_printf(&cache, "%suse %s%s\n",
commented ? "# " : "",
- db);
+ db, print_event_info->delimiter);
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
- my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu;\n",
- commented ? "# " : "", (ulong)thread_id);
+ my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
+ commented ? "# " : "", (ulong)thread_id,
+ print_event_info->delimiter);
my_b_printf(&cache, "%sLOAD DATA ",
- commented ? "# " : "");
+ commented ? "# " : "");
if (check_fname_outside_temp_buf())
my_b_printf(&cache, "LOCAL ");
my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
@@ -3003,7 +3051,7 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
my_b_printf(&cache, ")");
}
- my_b_printf(&cache, ";\n");
+ my_b_printf(&cache, "%s\n", print_event_info->delimiter);
DBUG_VOID_RETURN;
}
#endif /* MYSQL_CLIENT */
@@ -3582,7 +3630,8 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
msg="INVALID_INT";
break;
}
- my_b_printf(&cache, "%s=%s;\n", msg, llstr(val,llbuff));
+ my_b_printf(&cache, "%s=%s%s\n",
+ msg, llstr(val,llbuff), print_event_info->delimiter);
}
#endif
@@ -3660,8 +3709,9 @@ void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
print_header(&cache, print_event_info, FALSE);
my_b_printf(&cache, "\tRand\n");
}
- my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
- llstr(seed1, llbuff),llstr(seed2, llbuff2));
+ my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
+ llstr(seed1, llbuff),llstr(seed2, llbuff2),
+ print_event_info->delimiter);
}
#endif /* MYSQL_CLIENT */
@@ -3734,7 +3784,7 @@ void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
print_header(&cache, print_event_info, FALSE);
my_b_printf(&cache, "\tXid = %s\n", buf);
}
- my_b_printf(&cache, "COMMIT;\n");
+ my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
}
#endif /* MYSQL_CLIENT */
@@ -3939,7 +3989,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
if (is_null)
{
- my_b_printf(&cache, ":=NULL;\n");
+ my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
}
else
{
@@ -3947,12 +3997,12 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
case REAL_RESULT:
double real_val;
float8get(real_val, val);
- my_b_printf(&cache, ":=%.14g;\n", real_val);
+ my_b_printf(&cache, ":=%.14g%s\n", real_val, print_event_info->delimiter);
break;
case INT_RESULT:
char int_buf[22];
longlong10_to_str(uint8korr(val), int_buf, -10);
- my_b_printf(&cache, ":=%s;\n", int_buf);
+ my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
break;
case DECIMAL_RESULT:
{
@@ -3968,7 +4018,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
bin2decimal(val+2, &dec, precision, scale);
decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
str_buf[str_len]= 0;
- my_b_printf(&cache, ":=%s;\n",str_buf);
+ my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
break;
}
case STRING_RESULT:
@@ -4004,9 +4054,11 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
Generate an unusable command (=> syntax error) is probably the best
thing we can do here.
*/
- my_b_printf(&cache, ":=???;\n");
+ my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
else
- my_b_printf(&cache, ":=_%s %s COLLATE `%s`;\n", cs->csname, hex_str, cs->name);
+ my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
+ cs->csname, hex_str, cs->name,
+ print_event_info->delimiter);
my_afree(hex_str);
}
break;
@@ -5108,12 +5160,12 @@ void Execute_load_query_log_event::print(FILE* file,
my_b_printf(&cache, " REPLACE");
my_b_printf(&cache, " INTO");
my_b_write(&cache, (byte*) query + fn_pos_end, q_len-fn_pos_end);
- my_b_printf(&cache, ";\n");
+ my_b_printf(&cache, "%s\n", print_event_info->delimiter);
}
else
{
my_b_write(&cache, (byte*) query, q_len);
- my_b_printf(&cache, ";\n");
+ my_b_printf(&cache, "%s\n", print_event_info->delimiter);
}
if (!print_event_info->short_form)
@@ -5287,8 +5339,6 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
}
-#ifdef HAVE_ROW_BASED_REPLICATION
-
/**************************************************************************
Rows_log_event member functions
**************************************************************************/
@@ -6582,10 +6632,13 @@ copy_extra_record_fields(TABLE *table,
case MYSQL_TYPE_BIT:
Field_bit *f= static_cast<Field_bit*>(*field_ptr);
- my_ptrdiff_t const offset= table->record[1] - table->record[0];
- uchar const bits=
- get_rec_bits(f->bit_ptr + offset, f->bit_ofs, f->bit_len);
- set_rec_bits(bits, f->bit_ptr, f->bit_ofs, f->bit_len);
+ if (f->bit_len > 0)
+ {
+ my_ptrdiff_t const offset= table->record[1] - table->record[0];
+ uchar const bits=
+ get_rec_bits(f->bit_ptr + offset, f->bit_ofs, f->bit_len);
+ set_rec_bits(bits, f->bit_ptr, f->bit_ofs, f->bit_len);
+ }
break;
}
}
@@ -7286,4 +7339,3 @@ void Update_rows_log_event::print(FILE *file,
}
#endif
-#endif /* defined(HAVE_ROW_BASED_REPLICATION) */