Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
d4d26ba7
Commit
d4d26ba7
authored
Oct 06, 2006
by
mats@romeo.(none)
Browse files
Options
Browse Files
Download
Plain Diff
Merge romeo.(none):/home/bkroot/mysql-5.1-new-rpl
into romeo.(none):/home/bk/b19459-mysql-5.1-new
parents
cb1fdf51
e762328b
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
619 additions
and
277 deletions
+619
-277
client/mysqlbinlog.cc
client/mysqlbinlog.cc
+29
-6
include/base64.h
include/base64.h
+2
-1
include/my_sys.h
include/my_sys.h
+1
-0
mysys/base64.c
mysys/base64.c
+47
-18
mysys/mf_iocache2.c
mysys/mf_iocache2.c
+47
-0
sql/log_event.cc
sql/log_event.cc
+370
-205
sql/log_event.h
sql/log_event.h
+26
-4
sql/share/errmsg.txt
sql/share/errmsg.txt
+3
-0
sql/sql_binlog.cc
sql/sql_binlog.cc
+92
-41
storage/ndb/src/mgmapi/mgmapi.cpp
storage/ndb/src/mgmapi/mgmapi.cpp
+1
-1
unittest/mysys/base64-t.c
unittest/mysys/base64-t.c
+1
-1
No files found.
client/mysqlbinlog.cc
View file @
d4d26ba7
...
@@ -476,6 +476,30 @@ static bool check_database(const char *log_dbname)
...
@@ -476,6 +476,30 @@ static bool check_database(const char *log_dbname)
}
}
static
int
write_event_header_and_base64
(
Log_event
*
ev
,
FILE
*
result_file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
DBUG_ENTER
(
"write_event_header_and_base64"
);
/* Write header and base64 output to cache */
IO_CACHE
result_cache
;
if
(
init_io_cache
(
&
result_cache
,
-
1
,
0
,
WRITE_CACHE
,
0L
,
FALSE
,
MYF
(
MY_WME
|
MY_NABP
)))
{
return
1
;
}
ev
->
print_header
(
&
result_cache
,
print_event_info
,
FALSE
);
ev
->
print_base64
(
&
result_cache
,
print_event_info
,
FALSE
);
/* Read data from cache and write to result file */
my_b_copy_to_file
(
&
result_cache
,
result_file
);
end_io_cache
(
&
result_cache
);
DBUG_RETURN
(
0
);
}
/*
/*
Process an event
Process an event
...
@@ -538,18 +562,18 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
...
@@ -538,18 +562,18 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print_event_info
->
base64_output
=
opt_base64_output
;
print_event_info
->
base64_output
=
opt_base64_output
;
DBUG_PRINT
(
"debug"
,
(
"event_type: %s"
,
ev
->
get_type_str
()));
switch
(
ev_type
)
{
switch
(
ev_type
)
{
case
QUERY_EVENT
:
case
QUERY_EVENT
:
if
(
check_database
(((
Query_log_event
*
)
ev
)
->
db
))
if
(
check_database
(((
Query_log_event
*
)
ev
)
->
db
))
goto
end
;
goto
end
;
if
(
opt_base64_output
)
if
(
opt_base64_output
)
{
write_event_header_and_base64
(
ev
,
result_file
,
print_event_info
);
ev
->
print_header
(
result_file
,
print_event_info
);
ev
->
print_base64
(
result_file
,
print_event_info
);
}
else
else
ev
->
print
(
result_file
,
print_event_info
);
ev
->
print
(
result_file
,
print_event_info
);
break
;
break
;
case
CREATE_FILE_EVENT
:
case
CREATE_FILE_EVENT
:
{
{
Create_file_log_event
*
ce
=
(
Create_file_log_event
*
)
ev
;
Create_file_log_event
*
ce
=
(
Create_file_log_event
*
)
ev
;
...
@@ -570,8 +594,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
...
@@ -570,8 +594,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
*/
if
(
opt_base64_output
)
if
(
opt_base64_output
)
{
{
ce
->
print_header
(
result_file
,
print_event_info
);
write_event_header_and_base64
(
ce
,
result_file
,
print_event_info
);
ce
->
print_base64
(
result_file
,
print_event_info
);
}
}
else
else
ce
->
print
(
result_file
,
print_event_info
,
TRUE
);
ce
->
print
(
result_file
,
print_event_info
,
TRUE
);
...
...
include/base64.h
View file @
d4d26ba7
...
@@ -39,7 +39,8 @@ int base64_encode(const void *src, size_t src_len, char *dst);
...
@@ -39,7 +39,8 @@ int base64_encode(const void *src, size_t src_len, char *dst);
/*
/*
Decode a base64 string into data
Decode a base64 string into data
*/
*/
int
base64_decode
(
const
char
*
src
,
size_t
src_len
,
void
*
dst
);
int
base64_decode
(
const
char
*
src
,
size_t
src_len
,
void
*
dst
,
const
char
**
end_ptr
);
#ifdef __cplusplus
#ifdef __cplusplus
...
...
include/my_sys.h
View file @
d4d26ba7
...
@@ -517,6 +517,7 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
...
@@ -517,6 +517,7 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
(uint) (*(info)->current_pos - (info)->request_pos))
(uint) (*(info)->current_pos - (info)->request_pos))
/* tell write offset in the SEQ_APPEND cache */
/* tell write offset in the SEQ_APPEND cache */
int
my_b_copy_to_file
(
IO_CACHE
*
cache
,
FILE
*
file
);
my_off_t
my_b_append_tell
(
IO_CACHE
*
info
);
my_off_t
my_b_append_tell
(
IO_CACHE
*
info
);
my_off_t
my_b_safe_tell
(
IO_CACHE
*
info
);
/* picks the correct tell() */
my_off_t
my_b_safe_tell
(
IO_CACHE
*
info
);
/* picks the correct tell() */
...
...
mysys/base64.c
View file @
d4d26ba7
...
@@ -125,44 +125,69 @@ pos(unsigned char c)
...
@@ -125,44 +125,69 @@ pos(unsigned char c)
/*
/*
Decode a base64 string
Decode a base64 string
Note: We require that dst is pre-allocated to correct size.
SYNOPSIS
See base64_needed_decoded_length().
base64_decode()
src Pointer to base64-encoded string
RETURN Number of bytes produced in dst or -1 in case of failure
len Length of string at 'src'
dst Pointer to location where decoded data will be stored
end_ptr Pointer to variable that will refer to the character
after the end of the encoded data that were decoded. Can
be NULL.
DESCRIPTION
The base64-encoded data in the range ['src','*end_ptr') will be
decoded and stored starting at 'dst'. The decoding will stop
after 'len' characters have been read from 'src', or when padding
occurs in the base64-encoded data. In either case: if 'end_ptr' is
non-null, '*end_ptr' will be set to point to the character after
the last read character, even in the presence of error.
NOTE
We require that 'dst' is pre-allocated to correct size.
SEE ALSO
base64_needed_decoded_length().
RETURN VALUE
Number of bytes written at 'dst' or -1 in case of failure
*/
*/
int
int
base64_decode
(
const
char
*
src
,
size_t
size
,
void
*
dst
)
base64_decode
(
const
char
*
const
src_base
,
size_t
const
len
,
void
*
dst
,
const
char
**
end_ptr
)
{
{
char
b
[
3
];
char
b
[
3
];
size_t
i
=
0
;
size_t
i
=
0
;
char
*
dst_base
=
(
char
*
)
dst
;
char
*
dst_base
=
(
char
*
)
dst
;
char
const
*
src
=
src_base
;
char
*
d
=
dst_base
;
char
*
d
=
dst_base
;
size_t
j
;
size_t
j
;
while
(
i
<
size
)
while
(
i
<
len
)
{
{
unsigned
c
=
0
;
unsigned
c
=
0
;
size_t
mark
=
0
;
size_t
mark
=
0
;
SKIP_SPACE
(
src
,
i
,
size
);
SKIP_SPACE
(
src
,
i
,
len
);
c
+=
pos
(
*
src
++
);
c
+=
pos
(
*
src
++
);
c
<<=
6
;
c
<<=
6
;
i
++
;
i
++
;
SKIP_SPACE
(
src
,
i
,
size
);
SKIP_SPACE
(
src
,
i
,
len
);
c
+=
pos
(
*
src
++
);
c
+=
pos
(
*
src
++
);
c
<<=
6
;
c
<<=
6
;
i
++
;
i
++
;
SKIP_SPACE
(
src
,
i
,
size
);
SKIP_SPACE
(
src
,
i
,
len
);
if
(
*
src
!=
'='
)
if
(
*
src
!=
'='
)
c
+=
pos
(
*
src
++
);
c
+=
pos
(
*
src
++
);
else
else
{
{
i
=
size
;
src
+=
2
;
/* There should be two bytes padding */
i
=
len
;
mark
=
2
;
mark
=
2
;
c
<<=
6
;
c
<<=
6
;
goto
end
;
goto
end
;
...
@@ -170,13 +195,14 @@ base64_decode(const char *src, size_t size, void *dst)
...
@@ -170,13 +195,14 @@ base64_decode(const char *src, size_t size, void *dst)
c
<<=
6
;
c
<<=
6
;
i
++
;
i
++
;
SKIP_SPACE
(
src
,
i
,
size
);
SKIP_SPACE
(
src
,
i
,
len
);
if
(
*
src
!=
'='
)
if
(
*
src
!=
'='
)
c
+=
pos
(
*
src
++
);
c
+=
pos
(
*
src
++
);
else
else
{
{
i
=
size
;
src
+=
1
;
/* There should be one byte padding */
i
=
len
;
mark
=
1
;
mark
=
1
;
goto
end
;
goto
end
;
}
}
...
@@ -191,11 +217,14 @@ base64_decode(const char *src, size_t size, void *dst)
...
@@ -191,11 +217,14 @@ base64_decode(const char *src, size_t size, void *dst)
*
d
++=
b
[
j
];
*
d
++=
b
[
j
];
}
}
if
(
i
!=
size
)
if
(
end_ptr
!=
NULL
)
{
*
end_ptr
=
src
;
return
-
1
;
}
/*
return
d
-
dst_base
;
The variable 'i' is set to 'len' when padding has been read, so it
does not actually reflect the number of bytes read from 'src'.
*/
return
i
!=
len
?
-
1
:
d
-
dst_base
;
}
}
...
...
mysys/mf_iocache2.c
View file @
d4d26ba7
...
@@ -24,6 +24,53 @@
...
@@ -24,6 +24,53 @@
#include <stdarg.h>
#include <stdarg.h>
#include <m_ctype.h>
#include <m_ctype.h>
/*
Copy contents of an IO_CACHE to a file.
SYNOPSIS
my_b_copy_to_file()
cache IO_CACHE to copy from
file File to copy to
DESCRIPTION
Copy the contents of the cache to the file. The cache will be
re-inited to a read cache and will read from the beginning of the
cache.
If a failure to write fully occurs, the cache is only copied
partially.
TODO
Make this function solid by handling partial reads from the cache
in a correct manner: it should be atomic.
RETURN VALUE
0 All OK
1 An error occured
*/
int
my_b_copy_to_file
(
IO_CACHE
*
cache
,
FILE
*
file
)
{
byte
buf
[
IO_SIZE
];
DBUG_ENTER
(
"my_b_copy_to_file"
);
/* Reinit the cache to read from the beginning of the cache */
if
(
reinit_io_cache
(
cache
,
READ_CACHE
,
0L
,
FALSE
,
FALSE
))
DBUG_RETURN
(
1
);
uint
bytes_in_cache
=
my_b_bytes_in_cache
(
cache
);
while
(
bytes_in_cache
>
0
)
{
uint
const
read_bytes
=
min
(
bytes_in_cache
,
sizeof
(
buf
));
DBUG_PRINT
(
"debug"
,
(
"Remaining %u bytes - Reading %u bytes"
,
bytes_in_cache
,
read_bytes
));
if
(
my_b_read
(
cache
,
buf
,
read_bytes
))
DBUG_RETURN
(
1
);
if
(
my_fwrite
(
file
,
buf
,
read_bytes
,
MYF
(
MY_WME
|
MY_NABP
))
==
(
uint
)
-
1
)
DBUG_RETURN
(
1
);
bytes_in_cache
-=
read_bytes
;
}
DBUG_RETURN
(
0
);
}
my_off_t
my_b_append_tell
(
IO_CACHE
*
info
)
my_off_t
my_b_append_tell
(
IO_CACHE
*
info
)
{
{
/*
/*
...
...
sql/log_event.cc
View file @
d4d26ba7
...
@@ -32,32 +32,111 @@
...
@@ -32,32 +32,111 @@
#define log_cs &my_charset_latin1
#define log_cs &my_charset_latin1
/*
Cache that will automatically be written to a dedicated file on
destruction.
DESCRIPTION
*/
class
Write_on_release_cache
{
public:
enum
flag
{
FLUSH_F
};
typedef
unsigned
short
flag_set
;
/*
Constructor.
SYNOPSIS
Write_on_release_cache
cache Pointer to cache to use
file File to write cache to upon destruction
flags Flags for the cache
DESCRIPTION
Class used to guarantee copy of cache to file before exiting the
current block. On successful copy of the cache, the cache will
be reinited as a WRITE_CACHE.
Currently, a pointer to the cache is provided in the
constructor, but it would be possible to create a subclass
holding the IO_CACHE itself.
*/
Write_on_release_cache
(
IO_CACHE
*
cache
,
FILE
*
file
,
flag_set
flags
=
0
)
:
m_cache
(
cache
),
m_file
(
file
),
m_flags
(
flags
)
{
reinit_io_cache
(
m_cache
,
WRITE_CACHE
,
0L
,
FALSE
,
TRUE
);
}
~
Write_on_release_cache
()
{
if
(
!
my_b_copy_to_file
(
m_cache
,
m_file
))
reinit_io_cache
(
m_cache
,
WRITE_CACHE
,
0L
,
FALSE
,
TRUE
);
if
(
m_flags
|
FLUSH_F
)
fflush
(
m_file
);
}
/*
Return a pointer to the internal IO_CACHE.
SYNOPSIS
operator&()
DESCRIPTION
Function to return a pointer to the internal, so that the object
can be treated as a IO_CACHE and used with the my_b_* IO_CACHE
functions
RETURN VALUE
A pointer to the internal IO_CACHE.
*/
IO_CACHE
*
operator
&
()
{
return
m_cache
;
}
private:
// Hidden, to prevent usage.
Write_on_release_cache
(
Write_on_release_cache
const
&
);
IO_CACHE
*
m_cache
;
FILE
*
m_file
;
flag_set
m_flags
;
};
/*
/*
pretty_print_str()
pretty_print_str()
*/
*/
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
static
void
pretty_print_str
(
FILE
*
fil
e
,
char
*
str
,
int
len
)
static
void
pretty_print_str
(
IO_CACHE
*
cach
e
,
char
*
str
,
int
len
)
{
{
char
*
end
=
str
+
len
;
char
*
end
=
str
+
len
;
fputc
(
'\''
,
file
);
my_b_printf
(
cache
,
"
\'
"
);
while
(
str
<
end
)
while
(
str
<
end
)
{
{
char
c
;
char
c
;
switch
((
c
=*
str
++
))
{
switch
((
c
=*
str
++
))
{
case
'\n'
:
fprintf
(
fil
e
,
"
\\
n"
);
break
;
case
'\n'
:
my_b_printf
(
cach
e
,
"
\\
n"
);
break
;
case
'\r'
:
fprintf
(
fil
e
,
"
\\
r"
);
break
;
case
'\r'
:
my_b_printf
(
cach
e
,
"
\\
r"
);
break
;
case
'\\'
:
fprintf
(
fil
e
,
"
\\\\
"
);
break
;
case
'\\'
:
my_b_printf
(
cach
e
,
"
\\\\
"
);
break
;
case
'\b'
:
fprintf
(
fil
e
,
"
\\
b"
);
break
;
case
'\b'
:
my_b_printf
(
cach
e
,
"
\\
b"
);
break
;
case
'\t'
:
fprintf
(
fil
e
,
"
\\
t"
);
break
;
case
'\t'
:
my_b_printf
(
cach
e
,
"
\\
t"
);
break
;
case
'\''
:
fprintf
(
fil
e
,
"
\\
'"
);
break
;
case
'\''
:
my_b_printf
(
cach
e
,
"
\\
'"
);
break
;
case
0
:
fprintf
(
fil
e
,
"
\\
0"
);
break
;
case
0
:
my_b_printf
(
cach
e
,
"
\\
0"
);
break
;
default:
default:
fputc
(
c
,
file
);
my_b_printf
(
cache
,
"%c"
,
c
);
break
;
break
;
}
}
}
}
fputc
(
'\''
,
file
);
my_b_printf
(
cache
,
"
\'
"
);
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -294,14 +373,15 @@ append_query_string(CHARSET_INFO *csinfo,
...
@@ -294,14 +373,15 @@ append_query_string(CHARSET_INFO *csinfo,
*/
*/
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
static
void
print_set_option
(
FILE
*
file
,
uint32
bits_changed
,
uint32
option
,
static
void
print_set_option
(
IO_CACHE
*
file
,
uint32
bits_changed
,
uint32
flags
,
const
char
*
name
,
bool
*
need_comma
)
uint32
option
,
uint32
flags
,
const
char
*
name
,
bool
*
need_comma
)
{
{
if
(
bits_changed
&
option
)
if
(
bits_changed
&
option
)
{
{
if
(
*
need_comma
)
if
(
*
need_comma
)
f
printf
(
file
,
", "
);
my_b_
printf
(
file
,
", "
);
f
printf
(
file
,
"%s=%d"
,
name
,
test
(
flags
&
option
));
my_b_
printf
(
file
,
"%s=%d"
,
name
,
test
(
flags
&
option
));
*
need_comma
=
1
;
*
need_comma
=
1
;
}
}
}
}
...
@@ -960,20 +1040,23 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
...
@@ -960,20 +1040,23 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
Log_event::print_header()
Log_event::print_header()
*/
*/
void
Log_event
::
print_header
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Log_event
::
print_header
(
IO_CACHE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
,
bool
is_more
__attribute__
((
unused
)))
{
{
char
llbuff
[
22
];
char
llbuff
[
22
];
my_off_t
hexdump_from
=
print_event_info
->
hexdump_from
;
my_off_t
hexdump_from
=
print_event_info
->
hexdump_from
;
DBUG_ENTER
(
"Log_event::print_header"
);
fputc
(
'#'
,
file
);
my_b_printf
(
file
,
"#"
);
print_timestamp
(
file
);
print_timestamp
(
file
);
f
printf
(
file
,
" server id %d end_log_pos %s "
,
server_id
,
my_b_
printf
(
file
,
" server id %d end_log_pos %s "
,
server_id
,
llstr
(
log_pos
,
llbuff
));
llstr
(
log_pos
,
llbuff
));
/* mysqlbinlog --hexdump */
/* mysqlbinlog --hexdump */
if
(
print_event_info
->
hexdump_from
)
if
(
print_event_info
->
hexdump_from
)
{
{
f
printf
(
file
,
"
\n
"
);
my_b_
printf
(
file
,
"
\n
"
);
uchar
*
ptr
=
(
uchar
*
)
temp_buf
;
uchar
*
ptr
=
(
uchar
*
)
temp_buf
;
my_off_t
size
=
my_off_t
size
=
uint4korr
(
ptr
+
EVENT_LEN_OFFSET
)
-
LOG_EVENT_MINIMAL_HEADER_LEN
;
uint4korr
(
ptr
+
EVENT_LEN_OFFSET
)
-
LOG_EVENT_MINIMAL_HEADER_LEN
;
...
@@ -986,15 +1069,21 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -986,15 +1069,21 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
/* Pretty-print event common header if header is exactly 19 bytes */
/* Pretty-print event common header if header is exactly 19 bytes */
if
(
print_event_info
->
common_header_len
==
LOG_EVENT_MINIMAL_HEADER_LEN
)
if
(
print_event_info
->
common_header_len
==
LOG_EVENT_MINIMAL_HEADER_LEN
)
{
{
fprintf
(
file
,
"# Position Timestamp Type Master ID "
char
emit_buf
[
256
];
// Enough for storing one line
my_b_printf
(
file
,
"# Position Timestamp Type Master ID "
"Size Master Pos Flags
\n
"
);
"Size Master Pos Flags
\n
"
);
fprintf
(
file
,
"# %8.8lx %02x %02x %02x %02x %02x "
int
const
bytes_written
=
my_snprintf
(
emit_buf
,
sizeof
(
emit_buf
),
"# %8.8lx %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x
\n
"
,
"%02x %02x %02x %02x %02x %02x
\n
"
,
(
unsigned
long
)
hexdump_from
,
(
unsigned
long
)
hexdump_from
,
ptr
[
0
],
ptr
[
1
],
ptr
[
2
],
ptr
[
3
],
ptr
[
4
],
ptr
[
5
],
ptr
[
6
],
ptr
[
0
],
ptr
[
1
],
ptr
[
2
],
ptr
[
3
],
ptr
[
4
],
ptr
[
5
],
ptr
[
6
],
ptr
[
7
],
ptr
[
8
],
ptr
[
9
],
ptr
[
10
],
ptr
[
11
],
ptr
[
12
],
ptr
[
13
],
ptr
[
7
],
ptr
[
8
],
ptr
[
9
],
ptr
[
10
],
ptr
[
11
],
ptr
[
12
],
ptr
[
13
],
ptr
[
14
],
ptr
[
15
],
ptr
[
16
],
ptr
[
17
],
ptr
[
18
]);
ptr
[
14
],
ptr
[
15
],
ptr
[
16
],
ptr
[
17
],
ptr
[
18
]);
DBUG_ASSERT
(
bytes_written
>=
0
);
DBUG_ASSERT
(
static_cast
<
my_size_t
>
(
bytes_written
)
<
sizeof
(
emit_buf
));
my_b_write
(
file
,
emit_buf
,
bytes_written
);
ptr
+=
LOG_EVENT_MINIMAL_HEADER_LEN
;
ptr
+=
LOG_EVENT_MINIMAL_HEADER_LEN
;
hexdump_from
+=
LOG_EVENT_MINIMAL_HEADER_LEN
;
hexdump_from
+=
LOG_EVENT_MINIMAL_HEADER_LEN
;
}
}
...
@@ -1011,9 +1100,21 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -1011,9 +1100,21 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
if
(
i
%
16
==
15
)
if
(
i
%
16
==
15
)
{
{
fprintf
(
file
,
"# %8.8lx %-48.48s |%16s|
\n
"
,
/*
my_b_printf() does not support full printf() formats, so we
have to do it this way.
TODO: Rewrite my_b_printf() to support full printf() syntax.
*/
char
emit_buf
[
256
];
int
const
bytes_written
=
my_snprintf
(
emit_buf
,
sizeof
(
emit_buf
),
"# %8.8lx %-48.48s |%16s|
\n
"
,
(
unsigned
long
)
(
hexdump_from
+
(
i
&
0xfffffff0
)),
(
unsigned
long
)
(
hexdump_from
+
(
i
&
0xfffffff0
)),
hex_string
,
char_string
);
hex_string
,
char_string
);
DBUG_ASSERT
(
bytes_written
>=
0
);
DBUG_ASSERT
(
static_cast
<
my_size_t
>
(
bytes_written
)
<
sizeof
(
emit_buf
));
my_b_write
(
file
,
emit_buf
,
bytes_written
);
hex_string
[
0
]
=
0
;
hex_string
[
0
]
=
0
;
char_string
[
0
]
=
0
;
char_string
[
0
]
=
0
;
c
=
char_string
;
c
=
char_string
;
...
@@ -1025,28 +1126,52 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -1025,28 +1126,52 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
/* Non-full last line */
/* Non-full last line */
if
(
hex_string
[
0
])
if
(
hex_string
[
0
])
fprintf
(
file
,
"# %8.8lx %-48.48s |%s|
\n
# "
,
{
char
emit_buf
[
256
];
int
const
bytes_written
=
my_snprintf
(
emit_buf
,
sizeof
(
emit_buf
),
"# %8.8lx %-48.48s |%s|
\n
# "
,
(
unsigned
long
)
(
hexdump_from
+
(
i
&
0xfffffff0
)),
(
unsigned
long
)
(
hexdump_from
+
(
i
&
0xfffffff0
)),
hex_string
,
char_string
);
hex_string
,
char_string
);
DBUG_ASSERT
(
bytes_written
>=
0
);
DBUG_ASSERT
(
static_cast
<
my_size_t
>
(
bytes_written
)
<
sizeof
(
emit_buf
));
my_b_write
(
file
,
emit_buf
,
bytes_written
);
}
}
}
DBUG_VOID_RETURN
;
}
}
void
Log_event
::
print_base64
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Log_event
::
print_base64
(
IO_CACHE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
,
bool
more
)
{
{
uchar
*
ptr
=
(
uchar
*
)
temp_buf
;
const
uchar
*
ptr
=
(
const
uchar
*
)
temp_buf
;
my_off_t
size
=
uint4korr
(
ptr
+
EVENT_LEN_OFFSET
);
my_off_t
size
=
uint4korr
(
ptr
+
EVENT_LEN_OFFSET
);
char
*
tmp_str
=
DBUG_ENTER
(
"Log_event::print_base64"
);
(
char
*
)
my_malloc
(
base64_needed_encoded_length
(
size
),
MYF
(
MY_WME
));
size_t
const
tmp_str_sz
=
base64_needed_encoded_length
(
size
);
char
*
const
tmp_str
=
(
char
*
)
my_malloc
(
tmp_str_sz
,
MYF
(
MY_WME
));
if
(
!
tmp_str
)
{
if
(
!
tmp_str
)
{
fprintf
(
stderr
,
"
\n
Error: Out of memory. "
fprintf
(
stderr
,
"
\n
Error: Out of memory. "
"Could not print correct binlog event.
\n
"
);
"Could not print correct binlog event.
\n
"
);
return
;
DBUG_VOID_RETURN
;
}
}
int
res
=
base64_encode
(
ptr
,
size
,
tmp_str
);
fprintf
(
file
,
"
\n
BINLOG '
\n
%s
\n
';
\n
"
,
tmp_str
);
int
const
res
=
base64_encode
(
ptr
,
size
,
tmp_str
);
DBUG_ASSERT
(
res
==
0
);
if
(
my_b_tell
(
file
)
==
0
)
my_b_printf
(
file
,
"
\n
BINLOG '
\n
"
);
my_b_printf
(
file
,
"%s
\n
"
,
tmp_str
);
if
(
!
more
)
my_b_printf
(
file
,
"';
\n
"
);
my_free
(
tmp_str
,
MYF
(
0
));
my_free
(
tmp_str
,
MYF
(
0
));
DBUG_VOID_RETURN
;
}
}
...
@@ -1054,9 +1179,10 @@ void Log_event::print_base64(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -1054,9 +1179,10 @@ void Log_event::print_base64(FILE* file, PRINT_EVENT_INFO* print_event_info)
Log_event::print_timestamp()
Log_event::print_timestamp()
*/
*/
void
Log_event
::
print_timestamp
(
FIL
E
*
file
,
time_t
*
ts
)
void
Log_event
::
print_timestamp
(
IO_CACH
E
*
file
,
time_t
*
ts
)
{
{
struct
tm
*
res
;
struct
tm
*
res
;
DBUG_ENTER
(
"Log_event::print_timestamp"
);
if
(
!
ts
)
if
(
!
ts
)
ts
=
&
when
;
ts
=
&
when
;
#ifdef MYSQL_SERVER // This is always false
#ifdef MYSQL_SERVER // This is always false
...
@@ -1066,13 +1192,14 @@ void Log_event::print_timestamp(FILE* file, time_t* ts)
...
@@ -1066,13 +1192,14 @@ void Log_event::print_timestamp(FILE* file, time_t* ts)
res
=
localtime
(
ts
);
res
=
localtime
(
ts
);
#endif
#endif
f
printf
(
file
,
"%02d%02d%02d %2d:%02d:%02d"
,
my_b_
printf
(
file
,
"%02d%02d%02d %2d:%02d:%02d"
,
res
->
tm_year
%
100
,
res
->
tm_year
%
100
,
res
->
tm_mon
+
1
,
res
->
tm_mon
+
1
,
res
->
tm_mday
,
res
->
tm_mday
,
res
->
tm_hour
,
res
->
tm_hour
,
res
->
tm_min
,
res
->
tm_min
,
res
->
tm_sec
);
res
->
tm_sec
);
DBUG_VOID_RETURN
;
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -1544,7 +1671,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
...
@@ -1544,7 +1671,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
*/
*/
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
Query_log_event
::
print_query_header
(
FIL
E
*
file
,
void
Query_log_event
::
print_query_header
(
IO_CACH
E
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
PRINT_EVENT_INFO
*
print_event_info
)
{
{
// TODO: print the catalog ??
// TODO: print the catalog ??
...
@@ -1554,9 +1681,10 @@ void Query_log_event::print_query_header(FILE* file,
...
@@ -1554,9 +1681,10 @@ void Query_log_event::print_query_header(FILE* file,
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
{
{
print_header
(
file
,
print_event_info
);
print_header
(
file
,
print_event_info
,
FALSE
);
fprintf
(
file
,
"
\t
%s
\t
thread_id=%lu
\t
exec_time=%lu
\t
error_code=%d
\n
"
,
my_b_printf
(
file
,
"
\t
%s
\t
thread_id=%lu
\t
exec_time=%lu
\t
error_code=%d
\n
"
,
get_type_str
(),
(
ulong
)
thread_id
,
(
ulong
)
exec_time
,
error_code
);
get_type_str
(),
(
ulong
)
thread_id
,
(
ulong
)
exec_time
,
error_code
);
}
}
if
(
!
(
flags
&
LOG_EVENT_SUPPRESS_USE_F
)
&&
db
)
if
(
!
(
flags
&
LOG_EVENT_SUPPRESS_USE_F
)
&&
db
)
...
@@ -1564,15 +1692,15 @@ void Query_log_event::print_query_header(FILE* file,
...
@@ -1564,15 +1692,15 @@ void Query_log_event::print_query_header(FILE* file,
if
(
different_db
=
memcmp
(
print_event_info
->
db
,
db
,
db_len
+
1
))
if
(
different_db
=
memcmp
(
print_event_info
->
db
,
db
,
db_len
+
1
))
memcpy
(
print_event_info
->
db
,
db
,
db_len
+
1
);
memcpy
(
print_event_info
->
db
,
db
,
db_len
+
1
);
if
(
db
[
0
]
&&
different_db
)
if
(
db
[
0
]
&&
different_db
)
f
printf
(
file
,
"use %s;
\n
"
,
db
);
my_b_
printf
(
file
,
"use %s;
\n
"
,
db
);
}
}
end
=
int10_to_str
((
long
)
when
,
strmov
(
buff
,
"SET TIMESTAMP="
),
10
);
end
=
int10_to_str
((
long
)
when
,
strmov
(
buff
,
"SET TIMESTAMP="
),
10
);
*
end
++=
';'
;
*
end
++=
';'
;
*
end
++=
'\n'
;
*
end
++=
'\n'
;
my_
fwrite
(
file
,
(
byte
*
)
buff
,
(
uint
)
(
end
-
buff
),
MYF
(
MY_NABP
|
MY_WME
));
my_
b_write
(
file
,
(
byte
*
)
buff
,
(
uint
)
(
end
-
buff
));
if
(
flags
&
LOG_EVENT_THREAD_SPECIFIC_F
)
if
(
flags
&
LOG_EVENT_THREAD_SPECIFIC_F
)
f
printf
(
file
,
"SET @@session.pseudo_thread_id=%lu;
\n
"
,(
ulong
)
thread_id
);
my_b_
printf
(
file
,
"SET @@session.pseudo_thread_id=%lu;
\n
"
,(
ulong
)
thread_id
);
/*
/*
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
...
@@ -1594,14 +1722,14 @@ void Query_log_event::print_query_header(FILE* file,
...
@@ -1594,14 +1722,14 @@ void Query_log_event::print_query_header(FILE* file,
if
(
unlikely
(
tmp
))
/* some bits have changed */
if
(
unlikely
(
tmp
))
/* some bits have changed */
{
{
bool
need_comma
=
0
;
bool
need_comma
=
0
;
f
printf
(
file
,
"SET "
);
my_b_
printf
(
file
,
"SET "
);
print_set_option
(
file
,
tmp
,
OPTION_NO_FOREIGN_KEY_CHECKS
,
~
flags2
,
print_set_option
(
file
,
tmp
,
OPTION_NO_FOREIGN_KEY_CHECKS
,
~
flags2
,
"@@session.foreign_key_checks"
,
&
need_comma
);
"@@session.foreign_key_checks"
,
&
need_comma
);
print_set_option
(
file
,
tmp
,
OPTION_AUTO_IS_NULL
,
flags2
,
print_set_option
(
file
,
tmp
,
OPTION_AUTO_IS_NULL
,
flags2
,
"@@session.sql_auto_is_null"
,
&
need_comma
);
"@@session.sql_auto_is_null"
,
&
need_comma
);
print_set_option
(
file
,
tmp
,
OPTION_RELAXED_UNIQUE_CHECKS
,
~
flags2
,
print_set_option
(
file
,
tmp
,
OPTION_RELAXED_UNIQUE_CHECKS
,
~
flags2
,
"@@session.unique_checks"
,
&
need_comma
);
"@@session.unique_checks"
,
&
need_comma
);
f
printf
(
file
,
";
\n
"
);
my_b_
printf
(
file
,
";
\n
"
);
print_event_info
->
flags2
=
flags2
;
print_event_info
->
flags2
=
flags2
;
}
}
}
}
...
@@ -1629,14 +1757,14 @@ void Query_log_event::print_query_header(FILE* file,
...
@@ -1629,14 +1757,14 @@ void Query_log_event::print_query_header(FILE* file,
}
}
if
(
unlikely
(
print_event_info
->
sql_mode
!=
sql_mode
))
if
(
unlikely
(
print_event_info
->
sql_mode
!=
sql_mode
))
{
{
f
printf
(
file
,
"SET @@session.sql_mode=%lu;
\n
"
,(
ulong
)
sql_mode
);
my_b_
printf
(
file
,
"SET @@session.sql_mode=%lu;
\n
"
,(
ulong
)
sql_mode
);
print_event_info
->
sql_mode
=
sql_mode
;
print_event_info
->
sql_mode
=
sql_mode
;
}
}
}
}
if
(
print_event_info
->
auto_increment_increment
!=
auto_increment_increment
||
if
(
print_event_info
->
auto_increment_increment
!=
auto_increment_increment
||
print_event_info
->
auto_increment_offset
!=
auto_increment_offset
)
print_event_info
->
auto_increment_offset
!=
auto_increment_offset
)
{
{
f
printf
(
file
,
"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;
\n
"
,
my_b_
printf
(
file
,
"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;
\n
"
,
auto_increment_increment
,
auto_increment_offset
);
auto_increment_increment
,
auto_increment_offset
);
print_event_info
->
auto_increment_increment
=
auto_increment_increment
;
print_event_info
->
auto_increment_increment
=
auto_increment_increment
;
print_event_info
->
auto_increment_offset
=
auto_increment_offset
;
print_event_info
->
auto_increment_offset
=
auto_increment_offset
;
...
@@ -1656,9 +1784,10 @@ void Query_log_event::print_query_header(FILE* file,
...
@@ -1656,9 +1784,10 @@ void Query_log_event::print_query_header(FILE* file,
CHARSET_INFO
*
cs_info
=
get_charset
(
uint2korr
(
charset
),
MYF
(
MY_WME
));
CHARSET_INFO
*
cs_info
=
get_charset
(
uint2korr
(
charset
),
MYF
(
MY_WME
));
if
(
cs_info
)
if
(
cs_info
)
{
{
fprintf
(
file
,
"/*!
\\
C %s */;
\n
"
,
cs_info
->
csname
);
/* for mysql client */
/* for mysql client */
my_b_printf
(
file
,
"/*!
\\
C %s */;
\n
"
,
cs_info
->
csname
);
}
}
f
printf
(
file
,
"SET "
my_b_
printf
(
file
,
"SET "
"@@session.character_set_client=%d,"
"@@session.character_set_client=%d,"
"@@session.collation_connection=%d,"
"@@session.collation_connection=%d,"
"@@session.collation_server=%d"
"@@session.collation_server=%d"
...
@@ -1673,7 +1802,7 @@ void Query_log_event::print_query_header(FILE* file,
...
@@ -1673,7 +1802,7 @@ void Query_log_event::print_query_header(FILE* file,
{
{
if
(
bcmp
(
print_event_info
->
time_zone_str
,
time_zone_str
,
time_zone_len
+
1
))
if
(
bcmp
(
print_event_info
->
time_zone_str
,
time_zone_str
,
time_zone_len
+
1
))
{
{
f
printf
(
file
,
"SET @@session.time_zone='%s';
\n
"
,
time_zone_str
);
my_b_
printf
(
file
,
"SET @@session.time_zone='%s';
\n
"
,
time_zone_str
);
memcpy
(
print_event_info
->
time_zone_str
,
time_zone_str
,
time_zone_len
+
1
);
memcpy
(
print_event_info
->
time_zone_str
,
time_zone_str
,
time_zone_len
+
1
);
}
}
}
}
...
@@ -1682,9 +1811,11 @@ void Query_log_event::print_query_header(FILE* file,
...
@@ -1682,9 +1811,11 @@ void Query_log_event::print_query_header(FILE* file,
void
Query_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Query_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
print_query_header
(
file
,
print_event_info
);
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
);
my_fwrite
(
file
,
(
byte
*
)
query
,
q_len
,
MYF
(
MY_NABP
|
MY_WME
));
fputs
(
";
\n
"
,
file
);
print_query_header
(
&
cache
,
print_event_info
);
my_b_write
(
&
cache
,
(
byte
*
)
query
,
q_len
);
my_b_printf
(
&
cache
,
";
\n
"
);
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -2014,17 +2145,22 @@ void Start_log_event_v3::pack_info(Protocol *protocol)
...
@@ -2014,17 +2145,22 @@ void Start_log_event_v3::pack_info(Protocol *protocol)
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
Start_log_event_v3
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Start_log_event_v3
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
DBUG_ENTER
(
"Start_log_event_v3::print"
);
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
,
Write_on_release_cache
::
FLUSH_F
);
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
{
{
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fprintf
(
file
,
"
\t
Start: binlog v %d, server v %s created "
,
binlog_version
,
my_b_printf
(
&
cache
,
"
\t
Start: binlog v %d, server v %s created "
,
server_version
);
binlog_version
,
server_version
);
print_timestamp
(
fil
e
);
print_timestamp
(
&
cach
e
);
if
(
created
)
if
(
created
)
fprintf
(
fil
e
,
" at startup"
);
my_b_printf
(
&
cach
e
,
" at startup"
);
fputc
(
'\n'
,
file
);
my_b_printf
(
&
cache
,
"
\n
"
);
if
(
flags
&
LOG_EVENT_BINLOG_IN_USE_F
)
if
(
flags
&
LOG_EVENT_BINLOG_IN_USE_F
)
fprintf
(
fil
e
,
"# Warning: this binlog was not closed properly. "
my_b_printf
(
&
cach
e
,
"# Warning: this binlog was not closed properly. "
"Most probably mysqld crashed writing it.
\n
"
);
"Most probably mysqld crashed writing it.
\n
"
);
}
}
if
(
!
artificial_event
&&
created
)
if
(
!
artificial_event
&&
created
)
...
@@ -2036,12 +2172,12 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -2036,12 +2172,12 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
and rollback unfinished transaction.
and rollback unfinished transaction.
Probably this can be done with RESET CONNECTION (syntax to be defined).
Probably this can be done with RESET CONNECTION (syntax to be defined).
*/
*/
fprintf
(
fil
e
,
"RESET CONNECTION;
\n
"
);
my_b_printf
(
&
cach
e
,
"RESET CONNECTION;
\n
"
);
#else
#else
fprintf
(
fil
e
,
"ROLLBACK;
\n
"
);
my_b_printf
(
&
cach
e
,
"ROLLBACK;
\n
"
);
#endif
#endif
}
}
fflush
(
file
)
;
DBUG_VOID_RETURN
;
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -2765,14 +2901,16 @@ void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -2765,14 +2901,16 @@ void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
}
}
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
)
bool
commented
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file_arg
);
DBUG_ENTER
(
"Load_log_event::print"
);
DBUG_ENTER
(
"Load_log_event::print"
);
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
{
{
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fprintf
(
fil
e
,
"
\t
Query
\t
thread_id=%ld
\t
exec_time=%ld
\n
"
,
my_b_printf
(
&
cach
e
,
"
\t
Query
\t
thread_id=%ld
\t
exec_time=%ld
\n
"
,
thread_id
,
exec_time
);
thread_id
,
exec_time
);
}
}
...
@@ -2791,65 +2929,65 @@ void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
...
@@ -2791,65 +2929,65 @@ void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
}
}
if
(
db
&&
db
[
0
]
&&
different_db
)
if
(
db
&&
db
[
0
]
&&
different_db
)
fprintf
(
fil
e
,
"%suse %s;
\n
"
,
my_b_printf
(
&
cach
e
,
"%suse %s;
\n
"
,
commented
?
"# "
:
""
,
commented
?
"# "
:
""
,
db
);
db
);
if
(
flags
&
LOG_EVENT_THREAD_SPECIFIC_F
)
if
(
flags
&
LOG_EVENT_THREAD_SPECIFIC_F
)
fprintf
(
fil
e
,
"%sSET @@session.pseudo_thread_id=%lu;
\n
"
,
my_b_printf
(
&
cach
e
,
"%sSET @@session.pseudo_thread_id=%lu;
\n
"
,
commented
?
"# "
:
""
,
(
ulong
)
thread_id
);
commented
?
"# "
:
""
,
(
ulong
)
thread_id
);
fprintf
(
fil
e
,
"%sLOAD DATA "
,
my_b_printf
(
&
cach
e
,
"%sLOAD DATA "
,
commented
?
"# "
:
""
);
commented
?
"# "
:
""
);
if
(
check_fname_outside_temp_buf
())
if
(
check_fname_outside_temp_buf
())
fprintf
(
fil
e
,
"LOCAL "
);
my_b_printf
(
&
cach
e
,
"LOCAL "
);
fprintf
(
fil
e
,
"INFILE '%-*s' "
,
fname_len
,
fname
);
my_b_printf
(
&
cach
e
,
"INFILE '%-*s' "
,
fname_len
,
fname
);
if
(
sql_ex
.
opt_flags
&
REPLACE_FLAG
)
if
(
sql_ex
.
opt_flags
&
REPLACE_FLAG
)
fprintf
(
fil
e
,
" REPLACE "
);
my_b_printf
(
&
cach
e
,
" REPLACE "
);
else
if
(
sql_ex
.
opt_flags
&
IGNORE_FLAG
)
else
if
(
sql_ex
.
opt_flags
&
IGNORE_FLAG
)
fprintf
(
fil
e
,
" IGNORE "
);
my_b_printf
(
&
cach
e
,
" IGNORE "
);
fprintf
(
fil
e
,
"INTO TABLE `%s`"
,
table_name
);
my_b_printf
(
&
cach
e
,
"INTO TABLE `%s`"
,
table_name
);
fprintf
(
fil
e
,
" FIELDS TERMINATED BY "
);
my_b_printf
(
&
cach
e
,
" FIELDS TERMINATED BY "
);
pretty_print_str
(
fil
e
,
sql_ex
.
field_term
,
sql_ex
.
field_term_len
);
pretty_print_str
(
&
cach
e
,
sql_ex
.
field_term
,
sql_ex
.
field_term_len
);
if
(
sql_ex
.
opt_flags
&
OPT_ENCLOSED_FLAG
)
if
(
sql_ex
.
opt_flags
&
OPT_ENCLOSED_FLAG
)
fprintf
(
fil
e
,
" OPTIONALLY "
);
my_b_printf
(
&
cach
e
,
" OPTIONALLY "
);
fprintf
(
fil
e
,
" ENCLOSED BY "
);
my_b_printf
(
&
cach
e
,
" ENCLOSED BY "
);
pretty_print_str
(
fil
e
,
sql_ex
.
enclosed
,
sql_ex
.
enclosed_len
);
pretty_print_str
(
&
cach
e
,
sql_ex
.
enclosed
,
sql_ex
.
enclosed_len
);
fprintf
(
fil
e
,
" ESCAPED BY "
);
my_b_printf
(
&
cach
e
,
" ESCAPED BY "
);
pretty_print_str
(
fil
e
,
sql_ex
.
escaped
,
sql_ex
.
escaped_len
);
pretty_print_str
(
&
cach
e
,
sql_ex
.
escaped
,
sql_ex
.
escaped_len
);
fprintf
(
fil
e
,
" LINES TERMINATED BY "
);
my_b_printf
(
&
cach
e
,
" LINES TERMINATED BY "
);
pretty_print_str
(
fil
e
,
sql_ex
.
line_term
,
sql_ex
.
line_term_len
);
pretty_print_str
(
&
cach
e
,
sql_ex
.
line_term
,
sql_ex
.
line_term_len
);
if
(
sql_ex
.
line_start
)
if
(
sql_ex
.
line_start
)
{
{
fprintf
(
fil
e
,
" STARTING BY "
);
my_b_printf
(
&
cach
e
,
" STARTING BY "
);
pretty_print_str
(
fil
e
,
sql_ex
.
line_start
,
sql_ex
.
line_start_len
);
pretty_print_str
(
&
cach
e
,
sql_ex
.
line_start
,
sql_ex
.
line_start_len
);
}
}
if
((
long
)
skip_lines
>
0
)
if
((
long
)
skip_lines
>
0
)
fprintf
(
fil
e
,
" IGNORE %ld LINES"
,
(
long
)
skip_lines
);
my_b_printf
(
&
cach
e
,
" IGNORE %ld LINES"
,
(
long
)
skip_lines
);
if
(
num_fields
)
if
(
num_fields
)
{
{
uint
i
;
uint
i
;
const
char
*
field
=
fields
;
const
char
*
field
=
fields
;
fprintf
(
fil
e
,
" ("
);
my_b_printf
(
&
cach
e
,
" ("
);
for
(
i
=
0
;
i
<
num_fields
;
i
++
)
for
(
i
=
0
;
i
<
num_fields
;
i
++
)
{
{
if
(
i
)
if
(
i
)
fputc
(
','
,
file
);
my_b_printf
(
&
cache
,
","
);
fprintf
(
fil
e
,
field
);
my_b_printf
(
&
cach
e
,
field
);
field
+=
field_lens
[
i
]
+
1
;
field
+=
field_lens
[
i
]
+
1
;
}
}
fputc
(
')'
,
file
);
my_b_printf
(
&
cache
,
")"
);
}
}
fprintf
(
fil
e
,
";
\n
"
);
my_b_printf
(
&
cach
e
,
";
\n
"
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -3185,17 +3323,16 @@ void Rotate_log_event::pack_info(Protocol *protocol)
...
@@ -3185,17 +3323,16 @@ void Rotate_log_event::pack_info(Protocol *protocol)
void
Rotate_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Rotate_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
char
buf
[
22
];
char
buf
[
22
];
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
,
Write_on_release_cache
::
FLUSH_F
);
if
(
print_event_info
->
short_form
)
if
(
print_event_info
->
short_form
)
return
;
return
;
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fprintf
(
fil
e
,
"
\t
Rotate to "
);
my_b_printf
(
&
cach
e
,
"
\t
Rotate to "
);
if
(
new_log_ident
)
if
(
new_log_ident
)
my_fwrite
(
file
,
(
byte
*
)
new_log_ident
,
(
uint
)
ident_len
,
my_b_write
(
&
cache
,
(
byte
*
)
new_log_ident
,
(
uint
)
ident_len
);
MYF
(
MY_NABP
|
MY_WME
));
my_b_printf
(
&
cache
,
" pos: %s
\n
"
,
llstr
(
pos
,
buf
));
fprintf
(
file
,
" pos: %s"
,
llstr
(
pos
,
buf
));
fputc
(
'\n'
,
file
);
fflush
(
file
);
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -3407,14 +3544,16 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -3407,14 +3544,16 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
char
llbuff
[
22
];
char
llbuff
[
22
];
const
char
*
msg
;
const
char
*
msg
;
LINT_INIT
(
msg
);
LINT_INIT
(
msg
);
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
,
Write_on_release_cache
::
FLUSH_F
);
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
{
{
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fprintf
(
fil
e
,
"
\t
Intvar
\n
"
);
my_b_printf
(
&
cach
e
,
"
\t
Intvar
\n
"
);
}
}
fprintf
(
fil
e
,
"SET "
);
my_b_printf
(
&
cach
e
,
"SET "
);
switch
(
type
)
{
switch
(
type
)
{
case
LAST_INSERT_ID_EVENT
:
case
LAST_INSERT_ID_EVENT
:
msg
=
"LAST_INSERT_ID"
;
msg
=
"LAST_INSERT_ID"
;
...
@@ -3427,8 +3566,7 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -3427,8 +3566,7 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
msg
=
"INVALID_INT"
;
msg
=
"INVALID_INT"
;
break
;
break
;
}
}
fprintf
(
file
,
"%s=%s;
\n
"
,
msg
,
llstr
(
val
,
llbuff
));
my_b_printf
(
&
cache
,
"%s=%s;
\n
"
,
msg
,
llstr
(
val
,
llbuff
));
fflush
(
file
);
}
}
#endif
#endif
...
@@ -3497,15 +3635,17 @@ bool Rand_log_event::write(IO_CACHE* file)
...
@@ -3497,15 +3635,17 @@ bool Rand_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
Rand_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Rand_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
,
Write_on_release_cache
::
FLUSH_F
);
char
llbuff
[
22
],
llbuff2
[
22
];
char
llbuff
[
22
],
llbuff2
[
22
];
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
{
{
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fprintf
(
fil
e
,
"
\t
Rand
\n
"
);
my_b_printf
(
&
cach
e
,
"
\t
Rand
\n
"
);
}
}
fprintf
(
fil
e
,
"SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;
\n
"
,
my_b_printf
(
&
cach
e
,
"SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;
\n
"
,
llstr
(
seed1
,
llbuff
),
llstr
(
seed2
,
llbuff2
));
llstr
(
seed1
,
llbuff
),
llstr
(
seed2
,
llbuff2
));
fflush
(
file
);
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -3567,16 +3707,18 @@ bool Xid_log_event::write(IO_CACHE* file)
...
@@ -3567,16 +3707,18 @@ bool Xid_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
Xid_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Xid_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
,
Write_on_release_cache
::
FLUSH_F
);
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
{
{
char
buf
[
64
];
char
buf
[
64
];
longlong10_to_str
(
xid
,
buf
,
10
);
longlong10_to_str
(
xid
,
buf
,
10
);
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fprintf
(
file
,
"
\t
Xid = %s
\n
"
,
buf
);
my_b_printf
(
&
cache
,
"
\t
Xid = %s
\n
"
,
buf
);
fflush
(
file
);
}
}
fprintf
(
fil
e
,
"COMMIT;
\n
"
);
my_b_printf
(
&
cach
e
,
"COMMIT;
\n
"
);
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -3766,19 +3908,22 @@ bool User_var_log_event::write(IO_CACHE* file)
...
@@ -3766,19 +3908,22 @@ bool User_var_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
User_var_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
User_var_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
,
Write_on_release_cache
::
FLUSH_F
);
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
{
{
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fprintf
(
fil
e
,
"
\t
User_var
\n
"
);
my_b_printf
(
&
cach
e
,
"
\t
User_var
\n
"
);
}
}
fprintf
(
fil
e
,
"SET @`"
);
my_b_printf
(
&
cach
e
,
"SET @`"
);
my_
fwrite
(
file
,
(
byte
*
)
name
,
(
uint
)
(
name_len
),
MYF
(
MY_NABP
|
MY_WME
));
my_
b_write
(
&
cache
,
(
byte
*
)
name
,
(
uint
)
(
name_len
));
fprintf
(
fil
e
,
"`"
);
my_b_printf
(
&
cach
e
,
"`"
);
if
(
is_null
)
if
(
is_null
)
{
{
fprintf
(
fil
e
,
":=NULL;
\n
"
);
my_b_printf
(
&
cach
e
,
":=NULL;
\n
"
);
}
}
else
else
{
{
...
@@ -3786,12 +3931,12 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -3786,12 +3931,12 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
case
REAL_RESULT
:
case
REAL_RESULT
:
double
real_val
;
double
real_val
;
float8get
(
real_val
,
val
);
float8get
(
real_val
,
val
);
fprintf
(
fil
e
,
":=%.14g;
\n
"
,
real_val
);
my_b_printf
(
&
cach
e
,
":=%.14g;
\n
"
,
real_val
);
break
;
break
;
case
INT_RESULT
:
case
INT_RESULT
:
char
int_buf
[
22
];
char
int_buf
[
22
];
longlong10_to_str
(
uint8korr
(
val
),
int_buf
,
-
10
);
longlong10_to_str
(
uint8korr
(
val
),
int_buf
,
-
10
);
fprintf
(
fil
e
,
":=%s;
\n
"
,
int_buf
);
my_b_printf
(
&
cach
e
,
":=%s;
\n
"
,
int_buf
);
break
;
break
;
case
DECIMAL_RESULT
:
case
DECIMAL_RESULT
:
{
{
...
@@ -3807,7 +3952,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -3807,7 +3952,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
bin2decimal
(
val
+
2
,
&
dec
,
precision
,
scale
);
bin2decimal
(
val
+
2
,
&
dec
,
precision
,
scale
);
decimal2string
(
&
dec
,
str_buf
,
&
str_len
,
0
,
0
,
0
);
decimal2string
(
&
dec
,
str_buf
,
&
str_len
,
0
,
0
,
0
);
str_buf
[
str_len
]
=
0
;
str_buf
[
str_len
]
=
0
;
fprintf
(
fil
e
,
":=%s;
\n
"
,
str_buf
);
my_b_printf
(
&
cach
e
,
":=%s;
\n
"
,
str_buf
);
break
;
break
;
}
}
case
STRING_RESULT
:
case
STRING_RESULT
:
...
@@ -3843,9 +3988,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -3843,9 +3988,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
Generate an unusable command (=> syntax error) is probably the best
Generate an unusable command (=> syntax error) is probably the best
thing we can do here.
thing we can do here.
*/
*/
fprintf
(
fil
e
,
":=???;
\n
"
);
my_b_printf
(
&
cach
e
,
":=???;
\n
"
);
else
else
fprintf
(
fil
e
,
":=_%s %s COLLATE `%s`;
\n
"
,
cs
->
csname
,
hex_str
,
cs
->
name
);
my_b_printf
(
&
cach
e
,
":=_%s %s COLLATE `%s`;
\n
"
,
cs
->
csname
,
hex_str
,
cs
->
name
);
my_afree
(
hex_str
);
my_afree
(
hex_str
);
}
}
break
;
break
;
...
@@ -3855,7 +4000,6 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -3855,7 +4000,6 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
return
;
return
;
}
}
}
}
fflush
(
file
);
}
}
#endif
#endif
...
@@ -3939,13 +4083,14 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
...
@@ -3939,13 +4083,14 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
#ifdef HAVE_REPLICATION
#ifdef HAVE_REPLICATION
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
Unknown_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Unknown_log_event
::
print
(
FILE
*
file
_arg
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file_arg
);
if
(
print_event_info
->
short_form
)
if
(
print_event_info
->
short_form
)
return
;
return
;
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fputc
(
'\n'
,
file
);
my_b_printf
(
&
cache
,
"
\n
# %s"
,
"Unknown event
\n
"
);
fprintf
(
file
,
"# %s"
,
"Unknown event
\n
"
);
}
}
#endif
#endif
...
@@ -4012,12 +4157,13 @@ Slave_log_event::~Slave_log_event()
...
@@ -4012,12 +4157,13 @@ Slave_log_event::~Slave_log_event()
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
Slave_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Slave_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
);
char
llbuff
[
22
];
char
llbuff
[
22
];
if
(
print_event_info
->
short_form
)
if
(
print_event_info
->
short_form
)
return
;
return
;
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fputc
(
'\n'
,
file
);
my_b_printf
(
&
cache
,
"
\n
\
fprintf
(
file
,
"\
Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s
\n
"
,
Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s
\n
"
,
master_host
,
master_port
,
master_log
,
llstr
(
master_pos
,
llbuff
));
master_host
,
master_port
,
master_log
,
llstr
(
master_pos
,
llbuff
));
}
}
...
@@ -4097,12 +4243,14 @@ int Slave_log_event::exec_event(struct st_relay_log_info* rli)
...
@@ -4097,12 +4243,14 @@ int Slave_log_event::exec_event(struct st_relay_log_info* rli)
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
Stop_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Stop_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
,
Write_on_release_cache
::
FLUSH_F
);
if
(
print_event_info
->
short_form
)
if
(
print_event_info
->
short_form
)
return
;
return
;
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fprintf
(
file
,
"
\t
Stop
\n
"
);
my_b_printf
(
&
cache
,
"
\t
Stop
\n
"
);
fflush
(
file
);
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -4277,6 +4425,8 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len,
...
@@ -4277,6 +4425,8 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len,
void
Create_file_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
,
void
Create_file_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
,
bool
enable_local
)
bool
enable_local
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
);
if
(
print_event_info
->
short_form
)
if
(
print_event_info
->
short_form
)
{
{
if
(
enable_local
&&
check_fname_outside_temp_buf
())
if
(
enable_local
&&
check_fname_outside_temp_buf
())
...
@@ -4292,10 +4442,10 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info
...
@@ -4292,10 +4442,10 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
SHOW BINLOG EVENTS we don't.
SHOW BINLOG EVENTS we don't.
*/
*/
fprintf
(
fil
e
,
"#"
);
my_b_printf
(
&
cach
e
,
"#"
);
}
}
fprintf
(
fil
e
,
" file_id: %d block_len: %d
\n
"
,
file_id
,
block_len
);
my_b_printf
(
&
cach
e
,
" file_id: %d block_len: %d
\n
"
,
file_id
,
block_len
);
}
}
...
@@ -4465,11 +4615,12 @@ bool Append_block_log_event::write(IO_CACHE* file)
...
@@ -4465,11 +4615,12 @@ bool Append_block_log_event::write(IO_CACHE* file)
void
Append_block_log_event
::
print
(
FILE
*
file
,
void
Append_block_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
);
if
(
print_event_info
->
short_form
)
if
(
print_event_info
->
short_form
)
return
;
return
;
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fputc
(
'\n'
,
file
);
my_b_printf
(
&
cache
,
"
\n
#%s: file_id: %d block_len: %d
\n
"
,
fprintf
(
file
,
"#%s: file_id: %d block_len: %d
\n
"
,
get_type_str
(),
file_id
,
block_len
);
get_type_str
(),
file_id
,
block_len
);
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -4608,11 +4759,12 @@ bool Delete_file_log_event::write(IO_CACHE* file)
...
@@ -4608,11 +4759,12 @@ bool Delete_file_log_event::write(IO_CACHE* file)
void
Delete_file_log_event
::
print
(
FILE
*
file
,
void
Delete_file_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
);
if
(
print_event_info
->
short_form
)
if
(
print_event_info
->
short_form
)
return
;
return
;
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fputc
(
'\n'
,
file
);
my_b_printf
(
&
cache
,
"
\n
#Delete_file: file_id=%u
\n
"
,
file_id
);
fprintf
(
file
,
"#Delete_file: file_id=%u
\n
"
,
file_id
);
}
}
#endif
/* MYSQL_CLIENT */
#endif
/* MYSQL_CLIENT */
...
@@ -4703,11 +4855,12 @@ bool Execute_load_log_event::write(IO_CACHE* file)
...
@@ -4703,11 +4855,12 @@ bool Execute_load_log_event::write(IO_CACHE* file)
void
Execute_load_log_event
::
print
(
FILE
*
file
,
void
Execute_load_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
PRINT_EVENT_INFO
*
print_event_info
)
{
{
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
);
if
(
print_event_info
->
short_form
)
if
(
print_event_info
->
short_form
)
return
;
return
;
print_header
(
file
,
print_event_info
);
print_header
(
&
cache
,
print_event_info
,
FALSE
);
fputc
(
'\n'
,
file
);
my_b_printf
(
&
cache
,
"
\n
#Exec_load: file_id=%d
\n
"
,
fprintf
(
file
,
"#Exec_load: file_id=%d
\n
"
,
file_id
);
file_id
);
}
}
#endif
#endif
...
@@ -4925,29 +5078,30 @@ void Execute_load_query_log_event::print(FILE* file,
...
@@ -4925,29 +5078,30 @@ void Execute_load_query_log_event::print(FILE* file,
PRINT_EVENT_INFO
*
print_event_info
,
PRINT_EVENT_INFO
*
print_event_info
,
const
char
*
local_fname
)
const
char
*
local_fname
)
{
{
print_query_header
(
file
,
print_event_info
);
Write_on_release_cache
cache
(
&
print_event_info
->
head_cache
,
file
);
print_query_header
(
&
cache
,
print_event_info
);
if
(
local_fname
)
if
(
local_fname
)
{
{
my_
fwrite
(
file
,
(
byte
*
)
query
,
fn_pos_start
,
MYF
(
MY_NABP
|
MY_WME
)
);
my_
b_write
(
&
cache
,
(
byte
*
)
query
,
fn_pos_start
);
fprintf
(
fil
e
,
" LOCAL INFILE
\'
"
);
my_b_printf
(
&
cach
e
,
" LOCAL INFILE
\'
"
);
fprintf
(
fil
e
,
local_fname
);
my_b_printf
(
&
cach
e
,
local_fname
);
fprintf
(
fil
e
,
"
\'
"
);
my_b_printf
(
&
cach
e
,
"
\'
"
);
if
(
dup_handling
==
LOAD_DUP_REPLACE
)
if
(
dup_handling
==
LOAD_DUP_REPLACE
)
fprintf
(
file
,
" REPLACE"
);
my_b_printf
(
&
cache
,
" REPLACE"
);
fprintf
(
file
,
" INTO"
);
my_b_printf
(
&
cache
,
" INTO"
);
my_fwrite
(
file
,
(
byte
*
)
query
+
fn_pos_end
,
q_len
-
fn_pos_end
,
my_b_write
(
&
cache
,
(
byte
*
)
query
+
fn_pos_end
,
q_len
-
fn_pos_end
);
MYF
(
MY_NABP
|
MY_WME
));
my_b_printf
(
&
cache
,
";
\n
"
);
fprintf
(
file
,
";
\n
"
);
}
}
else
else
{
{
my_
fwrite
(
file
,
(
byte
*
)
query
,
q_len
,
MYF
(
MY_NABP
|
MY_WME
)
);
my_
b_write
(
&
cache
,
(
byte
*
)
query
,
q_len
);
fprintf
(
fil
e
,
";
\n
"
);
my_b_printf
(
&
cach
e
,
";
\n
"
);
}
}
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
fprintf
(
fil
e
,
"# file_id: %d
\n
"
,
file_id
);
my_b_printf
(
&
cach
e
,
"# file_id: %d
\n
"
,
file_id
);
}
}
#endif
#endif
...
@@ -5797,6 +5951,31 @@ void Rows_log_event::pack_info(Protocol *protocol)
...
@@ -5797,6 +5951,31 @@ void Rows_log_event::pack_info(Protocol *protocol)
}
}
#endif
#endif
#ifdef MYSQL_CLIENT
void
Rows_log_event
::
print_helper
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
,
char
const
*
const
name
)
{
IO_CACHE
*
const
head
=
&
print_event_info
->
head_cache
;
IO_CACHE
*
const
body
=
&
print_event_info
->
body_cache
;
if
(
!
print_event_info
->
short_form
)
{
bool
const
last_stmt_event
=
get_flags
(
STMT_END_F
);
print_header
(
head
,
print_event_info
,
!
last_stmt_event
);
my_b_printf
(
head
,
"
\t
%s: table id %lu"
,
name
,
m_table_id
);
print_base64
(
body
,
print_event_info
,
!
last_stmt_event
);
}
if
(
get_flags
(
STMT_END_F
))
{
my_b_copy_to_file
(
head
,
file
);
my_b_copy_to_file
(
body
,
file
);
reinit_io_cache
(
head
,
WRITE_CACHE
,
0
,
FALSE
,
TRUE
);
reinit_io_cache
(
body
,
WRITE_CACHE
,
0
,
FALSE
,
TRUE
);
}
}
#endif
/**************************************************************************
/**************************************************************************
Table_map_log_event member functions and support functions
Table_map_log_event member functions and support functions
**************************************************************************/
**************************************************************************/
...
@@ -6148,10 +6327,11 @@ void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
...
@@ -6148,10 +6327,11 @@ void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
{
{
if
(
!
print_event_info
->
short_form
)
if
(
!
print_event_info
->
short_form
)
{
{
print_header
(
file
,
print_event_info
);
print_header
(
&
print_event_info
->
head_cache
,
print_event_info
,
TRUE
);
fprintf
(
file
,
"
\t
Table_map: `%s`.`%s` mapped to number %lu
\n
"
,
my_b_printf
(
&
print_event_info
->
head_cache
,
"
\t
Table_map: `%s`.`%s` mapped to number %lu
\n
"
,
m_dbnam
,
m_tblnam
,
m_table_id
);
m_dbnam
,
m_tblnam
,
m_table_id
);
print_base64
(
file
,
print_event_info
);
print_base64
(
&
print_event_info
->
body_cache
,
print_event_info
,
TRUE
);
}
}
}
}
#endif
#endif
...
@@ -6513,12 +6693,7 @@ int Write_rows_log_event::do_exec_row(TABLE *table)
...
@@ -6513,12 +6693,7 @@ int Write_rows_log_event::do_exec_row(TABLE *table)
#ifdef MYSQL_CLIENT
#ifdef MYSQL_CLIENT
void
Write_rows_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
void
Write_rows_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
{
{
if
(
!
print_event_info
->
short_form
)
Rows_log_event
::
print_helper
(
file
,
print_event_info
,
"Write_rows"
);
{
print_header
(
file
,
print_event_info
);
fprintf
(
file
,
"
\t
Write_rows: table id %lu"
,
m_table_id
);
print_base64
(
file
,
print_event_info
);
}
}
}
#endif
#endif
...
@@ -6846,12 +7021,7 @@ int Delete_rows_log_event::do_exec_row(TABLE *table)
...
@@ -6846,12 +7021,7 @@ int Delete_rows_log_event::do_exec_row(TABLE *table)
void
Delete_rows_log_event
::
print
(
FILE
*
file
,
void
Delete_rows_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
PRINT_EVENT_INFO
*
print_event_info
)
{
{
if
(
!
print_event_info
->
short_form
)
Rows_log_event
::
print_helper
(
file
,
print_event_info
,
"Delete_rows"
);
{
print_header
(
file
,
print_event_info
);
fprintf
(
file
,
"
\t
Delete_rows: table id %lu"
,
m_table_id
);
print_base64
(
file
,
print_event_info
);
}
}
}
#endif
#endif
...
@@ -7017,12 +7187,7 @@ int Update_rows_log_event::do_exec_row(TABLE *table)
...
@@ -7017,12 +7187,7 @@ int Update_rows_log_event::do_exec_row(TABLE *table)
void
Update_rows_log_event
::
print
(
FILE
*
file
,
void
Update_rows_log_event
::
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
PRINT_EVENT_INFO
*
print_event_info
)
{
{
if
(
!
print_event_info
->
short_form
)
Rows_log_event
::
print_helper
(
file
,
print_event_info
,
"Update_rows"
);
{
print_header
(
file
,
print_event_info
);
fprintf
(
file
,
"
\t
Update_rows: table id %lu"
,
m_table_id
);
print_base64
(
file
,
print_event_info
);
}
}
}
#endif
#endif
...
...
sql/log_event.h
View file @
d4d26ba7
...
@@ -519,14 +519,30 @@ typedef struct st_print_event_info
...
@@ -519,14 +519,30 @@ typedef struct st_print_event_info
bzero
(
db
,
sizeof
(
db
));
bzero
(
db
,
sizeof
(
db
));
bzero
(
charset
,
sizeof
(
charset
));
bzero
(
charset
,
sizeof
(
charset
));
bzero
(
time_zone_str
,
sizeof
(
time_zone_str
));
bzero
(
time_zone_str
,
sizeof
(
time_zone_str
));
uint
const
flags
=
MYF
(
MY_WME
|
MY_NABP
);
init_io_cache
(
&
head_cache
,
-
1
,
0
,
WRITE_CACHE
,
0L
,
FALSE
,
flags
);
init_io_cache
(
&
body_cache
,
-
1
,
0
,
WRITE_CACHE
,
0L
,
FALSE
,
flags
);
}
}
~
st_print_event_info
()
{
end_io_cache
(
&
head_cache
);
end_io_cache
(
&
body_cache
);
}
/* Settings on how to print the events */
/* Settings on how to print the events */
bool
short_form
;
bool
short_form
;
bool
base64_output
;
bool
base64_output
;
my_off_t
hexdump_from
;
my_off_t
hexdump_from
;
uint8
common_header_len
;
uint8
common_header_len
;
/*
These two caches are used by the row-based replication events to
collect the header information and the main body of the events
making up a statement.
*/
IO_CACHE
head_cache
;
IO_CACHE
body_cache
;
}
PRINT_EVENT_INFO
;
}
PRINT_EVENT_INFO
;
#endif
#endif
...
@@ -637,9 +653,11 @@ public:
...
@@ -637,9 +653,11 @@ public:
const
Format_description_log_event
*
description_event
);
const
Format_description_log_event
*
description_event
);
/* print*() functions are used by mysqlbinlog */
/* print*() functions are used by mysqlbinlog */
virtual
void
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
=
0
;
virtual
void
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
)
=
0
;
void
print_timestamp
(
FILE
*
file
,
time_t
*
ts
=
0
);
void
print_timestamp
(
IO_CACHE
*
file
,
time_t
*
ts
=
0
);
void
print_header
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
);
void
print_header
(
IO_CACHE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
,
void
print_base64
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
);
bool
is_more
);
void
print_base64
(
IO_CACHE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
,
bool
is_more
);
#endif
#endif
static
void
*
operator
new
(
size_t
size
)
static
void
*
operator
new
(
size_t
size
)
...
@@ -804,7 +822,7 @@ public:
...
@@ -804,7 +822,7 @@ public:
uint32
q_len_arg
);
uint32
q_len_arg
);
#endif
/* HAVE_REPLICATION */
#endif
/* HAVE_REPLICATION */
#else
#else
void
print_query_header
(
FIL
E
*
file
,
PRINT_EVENT_INFO
*
print_event_info
);
void
print_query_header
(
IO_CACH
E
*
file
,
PRINT_EVENT_INFO
*
print_event_info
);
void
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
);
void
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
);
#endif
#endif
...
@@ -1864,6 +1882,10 @@ protected:
...
@@ -1864,6 +1882,10 @@ protected:
Log_event_type
event_type
,
Log_event_type
event_type
,
const
Format_description_log_event
*
description_event
);
const
Format_description_log_event
*
description_event
);
#ifdef MYSQL_CLIENT
void
print_helper
(
FILE
*
,
PRINT_EVENT_INFO
*
,
char
const
*
const
name
);
#endif
#ifndef MYSQL_CLIENT
#ifndef MYSQL_CLIENT
virtual
int
do_add_row_data
(
byte
*
data
,
my_size_t
length
);
virtual
int
do_add_row_data
(
byte
*
data
,
my_size_t
length
);
#endif
#endif
...
...
sql/share/errmsg.txt
View file @
d4d26ba7
...
@@ -5968,6 +5968,9 @@ ER_CANT_ACTIVATE_LOG
...
@@ -5968,6 +5968,9 @@ ER_CANT_ACTIVATE_LOG
ger "Kann Logdatei '%-.64s' nicht aktivieren"
ger "Kann Logdatei '%-.64s' nicht aktivieren"
ER_RBR_NOT_AVAILABLE
ER_RBR_NOT_AVAILABLE
eng "The server was not built with row-based replication"
eng "The server was not built with row-based replication"
ER_BASE64_DECODE_ERROR
eng "Decoding of base64 string failed"
swe "Avkodning av base64 strng misslyckades"
ger "Der Server hat keine zeilenbasierte Replikation"
ger "Der Server hat keine zeilenbasierte Replikation"
ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
eng "Triggers can not be created on system tables"
eng "Triggers can not be created on system tables"
...
...
sql/sql_binlog.cc
View file @
d4d26ba7
...
@@ -31,6 +31,7 @@
...
@@ -31,6 +31,7 @@
void
mysql_client_binlog_statement
(
THD
*
thd
)
void
mysql_client_binlog_statement
(
THD
*
thd
)
{
{
DBUG_ENTER
(
"mysql_client_binlog_statement"
);
DBUG_PRINT
(
"info"
,(
"binlog base64: '%*s'"
,
DBUG_PRINT
(
"info"
,(
"binlog base64: '%*s'"
,
(
thd
->
lex
->
comment
.
length
<
2048
?
(
thd
->
lex
->
comment
.
length
<
2048
?
thd
->
lex
->
comment
.
length
:
2048
),
thd
->
lex
->
comment
.
length
:
2048
),
...
@@ -43,8 +44,8 @@ void mysql_client_binlog_statement(THD* thd)
...
@@ -43,8 +44,8 @@ void mysql_client_binlog_statement(THD* thd)
my_bool
nsok
=
thd
->
net
.
no_send_ok
;
my_bool
nsok
=
thd
->
net
.
no_send_ok
;
thd
->
net
.
no_send_ok
=
TRUE
;
thd
->
net
.
no_send_ok
=
TRUE
;
const
my_size_t
coded_len
=
thd
->
lex
->
comment
.
length
+
1
;
my_size_t
coded_len
=
thd
->
lex
->
comment
.
length
+
1
;
const
my_size_t
event
_len
=
base64_needed_decoded_length
(
coded_len
);
my_size_t
decoded
_len
=
base64_needed_decoded_length
(
coded_len
);
DBUG_ASSERT
(
coded_len
>
0
);
DBUG_ASSERT
(
coded_len
>
0
);
/*
/*
...
@@ -57,9 +58,8 @@ void mysql_client_binlog_statement(THD* thd)
...
@@ -57,9 +58,8 @@ void mysql_client_binlog_statement(THD* thd)
new
Format_description_log_event
(
4
);
new
Format_description_log_event
(
4
);
const
char
*
error
=
0
;
const
char
*
error
=
0
;
char
*
buf
=
(
char
*
)
my_malloc
(
event
_len
,
MYF
(
MY_WME
));
char
*
buf
=
(
char
*
)
my_malloc
(
decoded
_len
,
MYF
(
MY_WME
));
Log_event
*
ev
=
0
;
Log_event
*
ev
=
0
;
int
res
;
/*
/*
Out of memory check
Out of memory check
...
@@ -73,45 +73,99 @@ void mysql_client_binlog_statement(THD* thd)
...
@@ -73,45 +73,99 @@ void mysql_client_binlog_statement(THD* thd)
thd
->
rli_fake
->
sql_thd
=
thd
;
thd
->
rli_fake
->
sql_thd
=
thd
;
thd
->
rli_fake
->
no_storage
=
TRUE
;
thd
->
rli_fake
->
no_storage
=
TRUE
;
res
=
base64_decode
(
thd
->
lex
->
comment
.
str
,
coded_len
,
buf
);
for
(
char
const
*
strptr
=
thd
->
lex
->
comment
.
str
;
strptr
<
thd
->
lex
->
comment
.
str
+
thd
->
lex
->
comment
.
length
;
)
{
char
const
*
endptr
=
0
;
int
bytes_decoded
=
base64_decode
(
strptr
,
coded_len
,
buf
,
&
endptr
);
DBUG_PRINT
(
"info"
,
(
"bytes_decoded=%d; strptr=0x%lu; endptr=0x%lu ('%c':%d)"
,
bytes_decoded
,
strptr
,
endptr
,
*
endptr
,
*
endptr
));
if
(
bytes_decoded
<
0
)
{
my_error
(
ER_BASE64_DECODE_ERROR
,
MYF
(
0
));
goto
end
;
}
else
if
(
bytes_decoded
==
0
)
break
;
// If no bytes where read, the string contained only whitespace
DBUG_ASSERT
(
bytes_decoded
>
0
);
DBUG_ASSERT
(
endptr
>
strptr
);
coded_len
-=
endptr
-
strptr
;
strptr
=
endptr
;
/*
Now we have one or more events stored in the buffer. The size of
the buffer is computed based on how much base64-encoded data
there were, so there should be ample space for the data (maybe
even too much, since a statement can consist of a considerable
number of events).
TODO: Switch to use a stream-based base64 encoder/decoder in
order to be able to read exactly what is necessary.
*/
DBUG_PRINT
(
"info"
,(
"binlog base64 decoded_len=%d, bytes_decoded=%d"
,
decoded_len
,
bytes_decoded
));
DBUG_PRINT
(
"info"
,(
"binlog base64 decoded_len=%d, event_len=%d
\n
"
,
res
,
uint4korr
(
buf
+
EVENT_LEN_OFFSET
)));
/*
/*
Note that 'res' is the correct event length, 'event_len' was
Now we start to read events of the buffer, until there are no
calculated based on the base64-string that possibly contained
more.
extra spaces, so it can be longer than the real event.
*/
*/
if
(
res
<
EVENT_LEN_OFFSET
for
(
char
*
bufptr
=
buf
;
bytes_decoded
>
0
;
)
||
(
uint
)
res
!=
uint4korr
(
buf
+
EVENT_LEN_OFFSET
))
{
/*
Checking that the first event in the buffer is not truncated.
*/
ulong
event_len
=
uint4korr
(
bufptr
+
EVENT_LEN_OFFSET
);
DBUG_PRINT
(
"info"
,
(
"event_len=%lu, bytes_decoded=%d"
,
event_len
,
bytes_decoded
));
if
(
bytes_decoded
<
EVENT_LEN_OFFSET
||
(
uint
)
bytes_decoded
<
event_len
)
{
{
my_error
(
ER_SYNTAX_ERROR
,
MYF
(
0
));
my_error
(
ER_SYNTAX_ERROR
,
MYF
(
0
));
goto
end
;
goto
end
;
}
}
ev
=
Log_event
::
read_log_event
(
buf
,
res
,
&
error
,
desc
);
ev
=
Log_event
::
read_log_event
(
bufptr
,
event_len
,
&
error
,
desc
);
DBUG_PRINT
(
"info"
,(
"binlog base64 err=%s"
,
error
));
DBUG_PRINT
(
"info"
,(
"binlog base64 err=%s"
,
error
));
if
(
!
ev
)
if
(
!
ev
)
{
{
/*
/*
This could actually be an out-of-memory, but it is more
This could actually be an out-of-memory, but it is more likely
likely
causes by a bad statement
causes by a bad statement
*/
*/
my_error
(
ER_SYNTAX_ERROR
,
MYF
(
0
));
my_error
(
ER_SYNTAX_ERROR
,
MYF
(
0
));
goto
end
;
goto
end
;
}
}
DBUG_PRINT
(
"info"
,(
"ev->get_type_code()=%d"
,
ev
->
get_type_code
()))
;
bytes_decoded
-=
event_len
;
DBUG_PRINT
(
"info"
,(
"buf+EVENT_TYPE_OFFSET=%d"
,
buf
+
EVENT_TYPE_OFFSET
))
;
bufptr
+=
event_len
;
DBUG_PRINT
(
"info"
,(
"ev->get_type_code()=%d"
,
ev
->
get_type_code
()));
DBUG_PRINT
(
"info"
,(
"bufptr+EVENT_TYPE_OFFSET=0x%lx"
,
bufptr
+
EVENT_TYPE_OFFSET
));
DBUG_PRINT
(
"info"
,
(
"bytes_decoded=%d; bufptr=0x%lx; buf[EVENT_LEN_OFFSET]=%u"
,
bytes_decoded
,
bufptr
,
uint4korr
(
bufptr
+
EVENT_LEN_OFFSET
)));
ev
->
thd
=
thd
;
ev
->
thd
=
thd
;
if
(
ev
->
exec_event
(
thd
->
rli_fake
))
if
(
int
err
=
ev
->
exec_event
(
thd
->
rli_fake
))
{
{
DBUG_PRINT
(
"info"
,
(
"exec_event() - error=%d"
,
error
));
/*
TODO: Maybe a better error message since the BINLOG statement
now contains several events.
*/
my_error
(
ER_UNKNOWN_ERROR
,
MYF
(
0
),
"Error executing BINLOG statement"
);
my_error
(
ER_UNKNOWN_ERROR
,
MYF
(
0
),
"Error executing BINLOG statement"
);
goto
end
;
goto
end
;
}
}
delete
ev
;
ev
=
0
;
}
}
/*
/*
Restore setting of no_send_ok
Restore setting of no_send_ok
*/
*/
...
@@ -126,10 +180,7 @@ end:
...
@@ -126,10 +180,7 @@ end:
*/
*/
thd
->
net
.
no_send_ok
=
nsok
;
thd
->
net
.
no_send_ok
=
nsok
;
if
(
ev
)
delete
ev
;
if
(
desc
)
delete
desc
;
delete
desc
;
if
(
buf
)
my_free
(
buf
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
(
buf
,
MYF
(
0
))
;
DBUG_VOID_RETURN
;
}
}
storage/ndb/src/mgmapi/mgmapi.cpp
View file @
d4d26ba7
...
@@ -1906,7 +1906,7 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
...
@@ -1906,7 +1906,7 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
break
;
break
;
void
*
tmp_data
=
malloc
(
base64_needed_decoded_length
((
size_t
)
(
len
-
1
)));
void
*
tmp_data
=
malloc
(
base64_needed_decoded_length
((
size_t
)
(
len
-
1
)));
const
int
res
=
base64_decode
(
buf64
,
len
-
1
,
tmp_data
);
const
int
res
=
base64_decode
(
buf64
,
len
-
1
,
tmp_data
,
NULL
);
delete
[]
buf64
;
delete
[]
buf64
;
UtilBuffer
tmp
;
UtilBuffer
tmp
;
tmp
.
append
((
void
*
)
tmp_data
,
res
);
tmp
.
append
((
void
*
)
tmp_data
,
res
);
...
...
unittest/mysys/base64-t.c
View file @
d4d26ba7
...
@@ -54,7 +54,7 @@ main(void)
...
@@ -54,7 +54,7 @@ main(void)
/* Decode */
/* Decode */
dst
=
(
char
*
)
malloc
(
base64_needed_decoded_length
(
strlen
(
str
)));
dst
=
(
char
*
)
malloc
(
base64_needed_decoded_length
(
strlen
(
str
)));
dst_len
=
base64_decode
(
str
,
strlen
(
str
),
dst
);
dst_len
=
base64_decode
(
str
,
strlen
(
str
),
dst
,
NULL
);
ok
(
dst_len
==
src_len
,
"Comparing lengths"
);
ok
(
dst_len
==
src_len
,
"Comparing lengths"
);
cmp
=
memcmp
(
src
,
dst
,
src_len
);
cmp
=
memcmp
(
src
,
dst
,
src_len
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment