mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
175507b766
include/my_dbug.h: Added macro for fixing compiler warnings. sql/field.cc: Fixed compiler warnings. sql/ha_ndbcluster.cc: Fixed compiler warnings. sql/ha_ndbcluster_binlog.cc: Fixed compiler warnings. Changed some tabs into spaces. sql/rpl_injector.h: Fixed compiler warnings. sql/sql_binlog.cc: Fixed compiler warnings. sql/sql_repl.cc: Fixed compiler warnings. sql/sql_table.cc: Fixed compiler warnings. storage/myisammrg/ha_myisammrg.cc: Fixed compiler warnings. strings/ctype-ucs2.c: Fixed compiler warnings. strings/ctype-utf8.c: Fixed compiler warnings. support-files/compiler_warnings.supp: Added suppressed warnings.
199 lines
6 KiB
C++
199 lines
6 KiB
C++
/* Copyright (C) 2005-2006 MySQL AB
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
#include "mysql_priv.h"
|
|
#include "base64.h"
|
|
|
|
/*
|
|
Execute a BINLOG statement
|
|
|
|
TODO: This currently assumes a MySQL 5.x binlog.
|
|
When we'll have binlog with a different format, to execute the
|
|
BINLOG command properly the server will need to know which format
|
|
the BINLOG command's event is in. mysqlbinlog should then send
|
|
the Format_description_log_event of the binlog it reads and the
|
|
server thread should cache this format into
|
|
rli->description_event_for_exec.
|
|
*/
|
|
|
|
void mysql_client_binlog_statement(THD* thd)
|
|
{
|
|
DBUG_ENTER("mysql_client_binlog_statement");
|
|
DBUG_PRINT("info",("binlog base64: '%*s'",
|
|
(thd->lex->comment.length < 2048 ?
|
|
thd->lex->comment.length : 2048),
|
|
thd->lex->comment.str));
|
|
|
|
/*
|
|
Temporarily turn off send_ok, since different events handle this
|
|
differently
|
|
*/
|
|
my_bool nsok= thd->net.no_send_ok;
|
|
thd->net.no_send_ok= TRUE;
|
|
|
|
my_size_t coded_len= thd->lex->comment.length + 1;
|
|
my_size_t decoded_len= base64_needed_decoded_length(coded_len);
|
|
DBUG_ASSERT(coded_len > 0);
|
|
|
|
/*
|
|
Allocation
|
|
*/
|
|
if (!thd->rli_fake)
|
|
thd->rli_fake= new RELAY_LOG_INFO;
|
|
|
|
const Format_description_log_event *desc=
|
|
new Format_description_log_event(4);
|
|
|
|
const char *error= 0;
|
|
char *buf= (char *) my_malloc(decoded_len, MYF(MY_WME));
|
|
Log_event *ev = 0;
|
|
|
|
/*
|
|
Out of memory check
|
|
*/
|
|
if (!(thd->rli_fake && desc && buf))
|
|
{
|
|
my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
|
|
goto end;
|
|
}
|
|
|
|
thd->rli_fake->sql_thd= thd;
|
|
thd->rli_fake->no_storage= TRUE;
|
|
|
|
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);
|
|
|
|
#ifndef HAVE_purify
|
|
/*
|
|
This debug printout should not be used for valgrind builds
|
|
since it will read from unassigned memory.
|
|
*/
|
|
DBUG_PRINT("info",
|
|
("bytes_decoded: %d strptr: 0x%lx endptr: 0x%lx ('%c':%d)",
|
|
bytes_decoded, (long) strptr, (long) endptr, *endptr,
|
|
*endptr));
|
|
#endif
|
|
|
|
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: %lu bytes_decoded: %d",
|
|
(ulong) decoded_len, bytes_decoded));
|
|
|
|
/*
|
|
Now we start to read events of the buffer, until there are no
|
|
more.
|
|
*/
|
|
for (char *bufptr= buf ; bytes_decoded > 0 ; )
|
|
{
|
|
/*
|
|
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));
|
|
goto end;
|
|
}
|
|
|
|
ev= Log_event::read_log_event(bufptr, event_len, &error, desc);
|
|
|
|
DBUG_PRINT("info",("binlog base64 err=%s", error));
|
|
if (!ev)
|
|
{
|
|
/*
|
|
This could actually be an out-of-memory, but it is more likely
|
|
causes by a bad statement
|
|
*/
|
|
my_error(ER_SYNTAX_ERROR, MYF(0));
|
|
goto end;
|
|
}
|
|
|
|
bytes_decoded -= event_len;
|
|
bufptr += event_len;
|
|
|
|
DBUG_PRINT("info",("ev->get_type_code()=%d", ev->get_type_code()));
|
|
#ifndef HAVE_purify
|
|
/*
|
|
This debug printout should not be used for valgrind builds
|
|
since it will read from unassigned memory.
|
|
*/
|
|
DBUG_PRINT("info",("bufptr+EVENT_TYPE_OFFSET: 0x%lx",
|
|
(long) (bufptr+EVENT_TYPE_OFFSET)));
|
|
DBUG_PRINT("info", ("bytes_decoded: %d bufptr: 0x%lx buf[EVENT_LEN_OFFSET]: %lu",
|
|
bytes_decoded, (long) bufptr,
|
|
(ulong) uint4korr(bufptr+EVENT_LEN_OFFSET)));
|
|
#endif
|
|
ev->thd= thd;
|
|
if (IF_DBUG(int err= ) ev->exec_event(thd->rli_fake))
|
|
{
|
|
DBUG_PRINT("error", ("exec_event() returned: %d", err));
|
|
/*
|
|
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");
|
|
goto end;
|
|
}
|
|
|
|
delete ev;
|
|
ev= 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
Restore setting of no_send_ok
|
|
*/
|
|
thd->net.no_send_ok= nsok;
|
|
|
|
DBUG_PRINT("info",("binlog base64 execution finished successfully"));
|
|
send_ok(thd);
|
|
|
|
end:
|
|
/*
|
|
Restore setting of no_send_ok
|
|
*/
|
|
thd->net.no_send_ok= nsok;
|
|
|
|
delete desc;
|
|
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
|
|
DBUG_VOID_RETURN;
|
|
}
|