1
/* Copyright (C) 2005-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
#include <drizzled/server_includes.h>
17
#include <drizzled/rpl_rli.h>
18
#include <mysys/base64.h>
19
#include <drizzled/error.h>
20
#include <drizzled/slave.h>
23
Execute a BINLOG statement
25
To execute the BINLOG command properly the server needs to know
26
which format the BINLOG command's event is in. Therefore, the first
27
BINLOG statement seen must be a base64 encoding of the
28
Format_description_log_event, as outputted by mysqlbinlog. This
29
Format_description_log_event is cached in
30
rli->description_event_for_exec.
33
void mysql_client_binlog_statement(Session* session)
35
size_t coded_len= session->lex->comment.length + 1;
36
size_t decoded_len= base64_needed_decoded_length(coded_len);
37
assert(coded_len > 0);
44
If we do not have a Format_description_event, we create a dummy
45
one here. In this case, the first event we read must be a
46
Format_description_event.
48
bool have_fd_event= true;
49
if (!session->rli_fake)
51
session->rli_fake= new Relay_log_info;
53
session->rli_fake->is_fake= true;
57
if (session->rli_fake && !session->rli_fake->relay_log.description_event_for_exec)
59
session->rli_fake->relay_log.description_event_for_exec=
60
new Format_description_log_event(4);
65
char *buf= (char *) my_malloc(decoded_len, MYF(MY_WME));
71
if (!(session->rli_fake &&
72
session->rli_fake->relay_log.description_event_for_exec &&
75
my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
79
session->rli_fake->sql_session= session;
80
session->rli_fake->no_storage= true;
82
for (char const *strptr= session->lex->comment.str ;
83
strptr < session->lex->comment.str + session->lex->comment.length ; )
85
char const *endptr= 0;
86
int bytes_decoded= base64_decode(strptr, coded_len, buf, &endptr);
88
if (bytes_decoded < 0)
90
my_error(ER_BASE64_DECODE_ERROR, MYF(0));
93
else if (bytes_decoded == 0)
94
break; // If no bytes where read, the string contained only whitespace
96
assert(bytes_decoded > 0);
97
assert(endptr > strptr);
98
coded_len-= endptr - strptr;
102
Now we have one or more events stored in the buffer. The size of
103
the buffer is computed based on how much base64-encoded data
104
there were, so there should be ample space for the data (maybe
105
even too much, since a statement can consist of a considerable
108
TODO: Switch to use a stream-based base64 encoder/decoder in
109
order to be able to read exactly what is necessary.
113
Now we start to read events of the buffer, until there are no
116
for (char *bufptr= buf ; bytes_decoded > 0 ; )
119
Checking that the first event in the buffer is not truncated.
121
uint32_t event_len= uint4korr(bufptr + EVENT_LEN_OFFSET);
122
if (bytes_decoded < EVENT_LEN_OFFSET || (uint) bytes_decoded < event_len)
124
my_error(ER_SYNTAX_ERROR, MYF(0));
129
If we have not seen any Format_description_event, then we must
130
see one; it is the only statement that can be read in base64
131
without a prior Format_description_event.
135
int type = bufptr[EVENT_TYPE_OFFSET];
136
if (type == FORMAT_DESCRIPTION_EVENT || type == START_EVENT_V3)
140
my_error(ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT,
141
MYF(0), Log_event::get_type_str((Log_event_type)type));
146
ev= Log_event::read_log_event(bufptr, event_len, &error,
147
session->rli_fake->relay_log.
148
description_event_for_exec);
153
This could actually be an out-of-memory, but it is more likely
154
causes by a bad statement
156
my_error(ER_SYNTAX_ERROR, MYF(0));
160
bytes_decoded -= event_len;
163
ev->session= session;
165
We go directly to the application phase, since we don't need
166
to check if the event shall be skipped or not.
168
Neither do we have to update the log positions, since that is
169
not used at all: the rli_fake instance is used only for error
172
if (apply_event_and_update_pos(ev, session, session->rli_fake, false))
175
TODO: Maybe a better error message since the BINLOG statement
176
now contains several events.
178
my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
183
Format_description_log_event should not be deleted because it
184
will be used to read info about the relay log's format; it
185
will be deleted when the SQL thread does not need it,
186
i.e. when this thread terminates.
188
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
197
session->rli_fake->clear_tables_to_lock();