Commit 786b5e95 authored by unknown's avatar unknown

Merge rkalimullin@bk-internal.mysql.com:/home/bk/mysql-5.0

into  mysql.com:/usr/home/ram/work/5.0.b10303

parents 39af58db 215602cb
...@@ -62,6 +62,7 @@ static const char *load_default_groups[]= { "mysqlbinlog","client",0 }; ...@@ -62,6 +62,7 @@ static const char *load_default_groups[]= { "mysqlbinlog","client",0 };
void sql_print_error(const char *format, ...); void sql_print_error(const char *format, ...);
static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0;
static bool opt_hexdump= 0;
static const char* database= 0; static const char* database= 0;
static my_bool force_opt= 0, short_form= 0, remote_opt= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
static ulonglong offset = 0; static ulonglong offset = 0;
...@@ -489,12 +490,13 @@ static bool check_database(const char *log_dbname) ...@@ -489,12 +490,13 @@ static bool check_database(const char *log_dbname)
int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev, int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
my_off_t pos) my_off_t pos)
{ {
char ll_buff[21]; char ll_buff[21];
Log_event_type ev_type= ev->get_type_code(); Log_event_type ev_type= ev->get_type_code();
DBUG_ENTER("process_event"); DBUG_ENTER("process_event");
print_event_info->short_form= short_form;
/* /*
Format events are not concerned by --offset and such, we always need to Format events are not concerned by --offset and such, we always need to
...@@ -522,12 +524,17 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev, ...@@ -522,12 +524,17 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev,
} }
if (!short_form) if (!short_form)
fprintf(result_file, "# at %s\n",llstr(pos,ll_buff)); fprintf(result_file, "# at %s\n",llstr(pos,ll_buff));
if (!opt_hexdump)
print_event_info->hexdump_from= 0; /* Disabled */
else
print_event_info->hexdump_from= pos;
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;
ev->print(result_file, short_form, last_event_info); ev->print(result_file, print_event_info);
break; break;
case CREATE_FILE_EVENT: case CREATE_FILE_EVENT:
{ {
...@@ -547,7 +554,8 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev, ...@@ -547,7 +554,8 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev,
filename and use LOCAL), prepared in the 'case EXEC_LOAD_EVENT' filename and use LOCAL), prepared in the 'case EXEC_LOAD_EVENT'
below. below.
*/ */
ce->print(result_file, short_form, last_event_info, TRUE); ce->print(result_file, print_event_info, TRUE);
// If this binlog is not 3.23 ; why this test?? // If this binlog is not 3.23 ; why this test??
if (description_event->binlog_version >= 3) if (description_event->binlog_version >= 3)
{ {
...@@ -558,13 +566,13 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev, ...@@ -558,13 +566,13 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev,
break; break;
} }
case APPEND_BLOCK_EVENT: case APPEND_BLOCK_EVENT:
ev->print(result_file, short_form, last_event_info); ev->print(result_file, print_event_info);
if (load_processor.process((Append_block_log_event*) ev)) if (load_processor.process((Append_block_log_event*) ev))
break; // Error break; // Error
break; break;
case EXEC_LOAD_EVENT: case EXEC_LOAD_EVENT:
{ {
ev->print(result_file, short_form, last_event_info); ev->print(result_file, print_event_info);
Execute_load_log_event *exv= (Execute_load_log_event*)ev; Execute_load_log_event *exv= (Execute_load_log_event*)ev;
Create_file_log_event *ce= load_processor.grab_event(exv->file_id); Create_file_log_event *ce= load_processor.grab_event(exv->file_id);
/* /*
...@@ -574,7 +582,7 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev, ...@@ -574,7 +582,7 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev,
*/ */
if (ce) if (ce)
{ {
ce->print(result_file, short_form, last_event_info, TRUE); ce->print(result_file, print_event_info, TRUE);
my_free((char*)ce->fname,MYF(MY_WME)); my_free((char*)ce->fname,MYF(MY_WME));
delete ce; delete ce;
} }
...@@ -586,7 +594,8 @@ Create_file event for file_id: %u\n",exv->file_id); ...@@ -586,7 +594,8 @@ Create_file event for file_id: %u\n",exv->file_id);
case FORMAT_DESCRIPTION_EVENT: case FORMAT_DESCRIPTION_EVENT:
delete description_event; delete description_event;
description_event= (Format_description_log_event*) ev; description_event= (Format_description_log_event*) ev;
ev->print(result_file, short_form, last_event_info); print_event_info->common_header_len= description_event->common_header_len;
ev->print(result_file, print_event_info);
/* /*
We don't want this event to be deleted now, so let's hide it (I We don't want this event to be deleted now, so let's hide it (I
(Guilhem) should later see if this triggers a non-serious Valgrind (Guilhem) should later see if this triggers a non-serious Valgrind
...@@ -596,7 +605,7 @@ Create_file event for file_id: %u\n",exv->file_id); ...@@ -596,7 +605,7 @@ Create_file event for file_id: %u\n",exv->file_id);
ev= 0; ev= 0;
break; break;
case BEGIN_LOAD_QUERY_EVENT: case BEGIN_LOAD_QUERY_EVENT:
ev->print(result_file, short_form, last_event_info); ev->print(result_file, print_event_info);
load_processor.process((Begin_load_query_log_event*) ev); load_processor.process((Begin_load_query_log_event*) ev);
break; break;
case EXECUTE_LOAD_QUERY_EVENT: case EXECUTE_LOAD_QUERY_EVENT:
...@@ -613,7 +622,7 @@ Create_file event for file_id: %u\n",exv->file_id); ...@@ -613,7 +622,7 @@ Create_file event for file_id: %u\n",exv->file_id);
if (fname) if (fname)
{ {
exlq->print(result_file, short_form, last_event_info, fname); exlq->print(result_file, print_event_info, fname);
my_free(fname, MYF(MY_WME)); my_free(fname, MYF(MY_WME));
} }
else else
...@@ -622,7 +631,7 @@ Begin_load_query event for file_id: %u\n", exlq->file_id); ...@@ -622,7 +631,7 @@ Begin_load_query event for file_id: %u\n", exlq->file_id);
break; break;
} }
default: default:
ev->print(result_file, short_form, last_event_info); ev->print(result_file, print_event_info);
} }
} }
...@@ -669,6 +678,9 @@ static struct my_option my_long_options[] = ...@@ -669,6 +678,9 @@ static struct my_option my_long_options[] =
0, 0}, 0, 0},
{"help", '?', "Display this help and exit.", {"help", '?', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"hexdump", 'H', "Augment output with hexadecimal and ASCII event dump.",
(gptr*) &opt_hexdump, (gptr*) &opt_hexdump, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"host", 'h', "Get the binlog from server.", (gptr*) &host, (gptr*) &host, {"host", 'h', "Get the binlog from server.", (gptr*) &host, (gptr*) &host,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset, {"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset,
...@@ -1002,7 +1014,7 @@ static int dump_remote_log_entries(const char* logname) ...@@ -1002,7 +1014,7 @@ static int dump_remote_log_entries(const char* logname)
{ {
char buf[128]; char buf[128];
LAST_EVENT_INFO last_event_info; PRINT_EVENT_INFO print_event_info;
ulong len; ulong len;
uint logname_len; uint logname_len;
NET* net; NET* net;
...@@ -1125,7 +1137,7 @@ could be out of memory"); ...@@ -1125,7 +1137,7 @@ could be out of memory");
len= 1; // fake Rotate, so don't increment old_off len= 1; // fake Rotate, so don't increment old_off
} }
} }
if ((error= process_event(&last_event_info,ev,old_off))) if ((error= process_event(&print_event_info, ev, old_off)))
{ {
error= ((error < 0) ? 0 : 1); error= ((error < 0) ? 0 : 1);
goto err; goto err;
...@@ -1144,7 +1156,7 @@ could be out of memory"); ...@@ -1144,7 +1156,7 @@ could be out of memory");
goto err; goto err;
} }
if ((error= process_event(&last_event_info,ev,old_off))) if ((error= process_event(&print_event_info, ev, old_off)))
{ {
my_close(file,MYF(MY_WME)); my_close(file,MYF(MY_WME));
error= ((error < 0) ? 0 : 1); error= ((error < 0) ? 0 : 1);
...@@ -1273,7 +1285,7 @@ static int dump_local_log_entries(const char* logname) ...@@ -1273,7 +1285,7 @@ static int dump_local_log_entries(const char* logname)
{ {
File fd = -1; File fd = -1;
IO_CACHE cache,*file= &cache; IO_CACHE cache,*file= &cache;
LAST_EVENT_INFO last_event_info; PRINT_EVENT_INFO print_event_info;
byte tmp_buff[BIN_LOG_HEADER_SIZE]; byte tmp_buff[BIN_LOG_HEADER_SIZE];
int error= 0; int error= 0;
...@@ -1345,7 +1357,7 @@ static int dump_local_log_entries(const char* logname) ...@@ -1345,7 +1357,7 @@ static int dump_local_log_entries(const char* logname)
// file->error == 0 means EOF, that's OK, we break in this case // file->error == 0 means EOF, that's OK, we break in this case
break; break;
} }
if ((error= process_event(&last_event_info,ev,old_off))) if ((error= process_event(&print_event_info, ev, old_off)))
{ {
if (error < 0) if (error < 0)
error= 0; error= 0;
......
...@@ -14,15 +14,38 @@ ...@@ -14,15 +14,38 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef __BASE64_HPP_INCLUDED__ #ifndef __BASE64_H_INCLUDED__
#define __BASE64_HPP_INCLUDED__ #define __BASE64_H_INCLUDED__
#include <UtilBuffer.hpp> #ifdef __cplusplus
#include <BaseString.hpp> extern "C" {
#endif
int base64_encode(const UtilBuffer &src, BaseString &dst);
int base64_encode(const void * s, size_t src_len, BaseString &dst);
int base64_decode(const BaseString &src, UtilBuffer &dst);
int base64_decode(const char * s, size_t len, UtilBuffer &dst);
#endif /* !__BASE64_HPP_INCLUDED__ */ #include <mysys_priv.h>
/*
Calculate how much memory needed for dst of base64_encode()
*/
int base64_needed_encoded_length(int length_of_data);
/*
Calculate how much memory needed for dst of base64_decode()
*/
int base64_needed_decoded_length(int length_of_encoded_data);
/*
Encode data as a base64 string
*/
int base64_encode(const void *src, size_t src_len, char *dst);
/*
Decode a base64 string into data
*/
int base64_decode(const char *src, size_t src_len, void *dst);
#ifdef __cplusplus
}
#endif
#endif /* !__BASE64_H_INCLUDED__ */
...@@ -3181,3 +3181,15 @@ from t1 inner join (t2 right join t3 on t2.id = t3.b_id) on t1.id = t3.a_id; ...@@ -3181,3 +3181,15 @@ from t1 inner join (t2 right join t3 on t2.id = t3.b_id) on t1.id = t3.a_id;
count(*) count(*)
6 6
drop table t1,t2,t3; drop table t1,t2,t3;
create table t1 (a int);
create table t2 (b int);
create table t3 (c int);
select * from t1 join t2 join t3 on (t1.a=t3.c);
a b c
select * from t1 join t2 left join t3 on (t1.a=t3.c);
a b c
select * from t1 join t2 right join t3 on (t1.a=t3.c);
a b c
select * from t1 join t2 straight_join t3 on (t1.a=t3.c);
a b c
drop table t1, t2 ,t3;
...@@ -512,6 +512,13 @@ t1 CREATE TABLE `t1` ( ...@@ -512,6 +512,13 @@ t1 CREATE TABLE `t1` (
KEY `c2` USING BTREE (`c2`) KEY `c2` USING BTREE (`c2`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
flush tables;
SHOW TABLE STATUS like 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm'
show create table t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
drop table t1;
CREATE TABLE txt1(a int); CREATE TABLE txt1(a int);
CREATE TABLE tyt2(a int); CREATE TABLE tyt2(a int);
CREATE TABLE urkunde(a int); CREATE TABLE urkunde(a int);
...@@ -557,10 +564,3 @@ DROP TABLE tyt2; ...@@ -557,10 +564,3 @@ DROP TABLE tyt2;
DROP TABLE urkunde; DROP TABLE urkunde;
SHOW TABLES FROM non_existing_database; SHOW TABLES FROM non_existing_database;
ERROR 42000: Unknown database 'non_existing_database' ERROR 42000: Unknown database 'non_existing_database'
flush tables;
SHOW TABLE STATUS like 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm'
show create table t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
drop table t1;
...@@ -3532,4 +3532,47 @@ select @a| ...@@ -3532,4 +3532,47 @@ select @a|
Local Local
drop function bug13941| drop function bug13941|
drop procedure bug13941| drop procedure bug13941|
DROP PROCEDURE IF EXISTS bug13095;
DROP TABLE IF EXISTS bug13095_t1;
DROP VIEW IF EXISTS bug13095_v1;
CREATE PROCEDURE bug13095(tbl_name varchar(32))
BEGIN
SET @str =
CONCAT("CREATE TABLE ", tbl_name, "(stuff char(15))");
SELECT @str;
PREPARE stmt FROM @str;
EXECUTE stmt;
SET @str =
CONCAT("INSERT INTO ", tbl_name, " VALUES('row1'),('row2'),('row3')" );
SELECT @str;
PREPARE stmt FROM @str;
EXECUTE stmt;
SET @str =
CONCAT("CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM ", tbl_name);
SELECT @str;
PREPARE stmt FROM @str;
EXECUTE stmt;
SELECT * FROM bug13095_v1;
SET @str =
"DROP VIEW bug13095_v1";
SELECT @str;
PREPARE stmt FROM @str;
EXECUTE stmt;
END|
CALL bug13095('bug13095_t1');
@str
CREATE TABLE bug13095_t1(stuff char(15))
@str
INSERT INTO bug13095_t1 VALUES('row1'),('row2'),('row3')
@str
CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM bug13095_t1
c1
row1
row2
row3
@str
DROP VIEW bug13095_v1
DROP PROCEDURE IF EXISTS bug13095;
DROP VIEW IF EXISTS bug13095_v1;
DROP TABLE IF EXISTS bug13095_t1;
drop table t1,t2; drop table t1,t2;
...@@ -15,3 +15,4 @@ rpl_relayrotate : Unstable test case, bug#12429 ...@@ -15,3 +15,4 @@ rpl_relayrotate : Unstable test case, bug#12429
rpl_until : Unstable test case, bug#12429 rpl_until : Unstable test case, bug#12429
rpl_deadlock : Unstable test case, bug#12429 rpl_deadlock : Unstable test case, bug#12429
kill : Unstable test case, bug#9712 kill : Unstable test case, bug#9712
federated : Broken test case, bug#14272
...@@ -2688,3 +2688,17 @@ select count(*) ...@@ -2688,3 +2688,17 @@ select count(*)
from t1 inner join (t2 right join t3 on t2.id = t3.b_id) on t1.id = t3.a_id; from t1 inner join (t2 right join t3 on t2.id = t3.b_id) on t1.id = t3.a_id;
drop table t1,t2,t3; drop table t1,t2,t3;
#
# Bug #13832 Incorrect parse order of join productions due to unspecified
# operator priorities results in incorrect join tree.
#
create table t1 (a int);
create table t2 (b int);
create table t3 (c int);
select * from t1 join t2 join t3 on (t1.a=t3.c);
select * from t1 join t2 left join t3 on (t1.a=t3.c);
select * from t1 join t2 right join t3 on (t1.a=t3.c);
select * from t1 join t2 straight_join t3 on (t1.a=t3.c);
drop table t1, t2 ,t3;
...@@ -4433,6 +4433,62 @@ drop function bug13941| ...@@ -4433,6 +4433,62 @@ drop function bug13941|
drop procedure bug13941| drop procedure bug13941|
#
# BUG#13095: Cannot create VIEWs in prepared statements
#
delimiter ;|
--disable_warnings
DROP PROCEDURE IF EXISTS bug13095;
DROP TABLE IF EXISTS bug13095_t1;
DROP VIEW IF EXISTS bug13095_v1;
--enable_warnings
delimiter |;
CREATE PROCEDURE bug13095(tbl_name varchar(32))
BEGIN
SET @str =
CONCAT("CREATE TABLE ", tbl_name, "(stuff char(15))");
SELECT @str;
PREPARE stmt FROM @str;
EXECUTE stmt;
SET @str =
CONCAT("INSERT INTO ", tbl_name, " VALUES('row1'),('row2'),('row3')" );
SELECT @str;
PREPARE stmt FROM @str;
EXECUTE stmt;
SET @str =
CONCAT("CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM ", tbl_name);
SELECT @str;
PREPARE stmt FROM @str;
EXECUTE stmt;
SELECT * FROM bug13095_v1;
SET @str =
"DROP VIEW bug13095_v1";
SELECT @str;
PREPARE stmt FROM @str;
EXECUTE stmt;
END|
delimiter ;|
CALL bug13095('bug13095_t1');
--disable_warnings
DROP PROCEDURE IF EXISTS bug13095;
DROP VIEW IF EXISTS bug13095_v1;
DROP TABLE IF EXISTS bug13095_t1;
--enable_warnings
delimiter |;
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
......
...@@ -55,7 +55,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ ...@@ -55,7 +55,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \
my_handler.c my_netware.c my_largepage.c \ my_handler.c my_netware.c my_largepage.c \
my_windac.c my_access.c my_windac.c my_access.c base64.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@ libmysys_a_LIBADD = @THREAD_LOBJECTS@
...@@ -116,5 +116,10 @@ test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES) ...@@ -116,5 +116,10 @@ test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS) $(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS)
$(RM) -f ./test_gethwaddr.c $(RM) -f ./test_gethwaddr.c
test_base64$(EXEEXT): base64.c $(LIBRARIES)
$(CP) $(srcdir)/base64.c ./test_base64.c
$(LINK) $(FLAGS) -DMAIN ./test_base64.c $(LDADD) $(LIBS)
$(RM) -f ./test_base64.c
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
/* Copyright (C) 2003 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; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <base64.h>
#include <m_string.h> // strchr()
#ifndef MAIN
static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
int
base64_needed_encoded_length(int length_of_data)
{
return ceil(length_of_data * 4 / 3) /* base64 chars */ +
ceil(length_of_data / (76 * 3 / 4)) /* Newlines */ +
3 /* Padding */;
}
int
base64_needed_decoded_length(int length_of_encoded_data)
{
return ceil(length_of_encoded_data * 3 / 4);
}
/*
Encode a data as base64.
Note: We require that dst is pre-allocated to correct size.
See base64_needed_encoded_length().
*/
int
base64_encode(const void *src, size_t src_len, char *dst)
{
const unsigned char *s= (const unsigned char*)src;
size_t i= 0;
size_t len= 0;
for (; i < src_len; len += 4)
{
if (len == 76)
{
len= 0;
*dst++= '\n';
}
unsigned c;
c= s[i++];
c <<= 8;
if (i < src_len)
c += s[i];
c <<= 8;
i++;
if (i < src_len)
c += s[i];
i++;
*dst++= base64_table[(c >> 18) & 0x3f];
*dst++= base64_table[(c >> 12) & 0x3f];
if (i > (src_len + 1))
*dst++= '=';
else
*dst++= base64_table[(c >> 6) & 0x3f];
if (i > src_len)
*dst++= '=';
else
*dst++= base64_table[(c >> 0) & 0x3f];
}
return 0;
}
static inline unsigned
pos(unsigned char c)
{
return strchr(base64_table, c) - base64_table;
}
#define SKIP_SPACE(src, i, size) \
{ \
while (i < size && my_isspace(&my_charset_latin1, * src)) \
{ \
i++; \
src++; \
} \
if (i == size) \
{ \
i= size + 1; \
break; \
} \
}
/*
Decode a base64 string
Note: We require that dst is pre-allocated to correct size.
See base64_needed_decoded_length().
RETURN Number of bytes produced in dst or -1 in case of failure
*/
int
base64_decode(const char *src, size_t size, void *dst)
{
char b[3];
size_t i= 0;
void *d= dst;
size_t j;
while (i < size)
{
unsigned c= 0;
size_t mark= 0;
SKIP_SPACE(src, i, size);
c += pos(*src++);
c <<= 6;
i++;
SKIP_SPACE(src, i, size);
c += pos(*src++);
c <<= 6;
i++;
SKIP_SPACE(src, i, size);
if (* src != '=')
c += pos(*src++);
else
{
i= size;
mark= 2;
c <<= 6;
goto end;
}
c <<= 6;
i++;
SKIP_SPACE(src, i, size);
if (*src != '=')
c += pos(*src++);
else
{
i= size;
mark= 1;
goto end;
}
i++;
end:
b[0]= (c >> 16) & 0xff;
b[1]= (c >> 8) & 0xff;
b[2]= (c >> 0) & 0xff;
for (j=0; j<3-mark; j++)
*(char *)d++= b[j];
}
if (i != size)
{
return -1;
}
return d - dst;
}
#else /* MAIN */
#define require(b) { \
if (!(b)) { \
printf("Require failed at %s:%d\n", __FILE__, __LINE__); \
abort(); \
} \
}
int
main(void)
{
int i;
size_t j;
size_t k, l;
size_t dst_len;
for (i= 0; i < 500; i++)
{
/* Create source data */
const size_t src_len= rand() % 1000 + 1;
char * src= (char *) malloc(src_len);
char * s= src;
for (j= 0; j<src_len; j++)
{
char c= rand();
*s++= c;
}
/* Encode */
char * str= (char *) malloc(base64_needed_encoded_length(src_len));
require(base64_encode(src, src_len, str) == 0);
/* Decode */
char * dst= (char *) malloc(base64_needed_decoded_length(strlen(str)));
dst_len= base64_decode(str, strlen(str), dst);
require(dst_len == src_len);
if (memcmp(src, dst, src_len) != 0)
{
printf(" --------- src --------- --------- dst ---------\n");
for (k= 0; k<src_len; k+=8)
{
printf("%.4x ", (uint) k);
for (l=0; l<8 && k+l<src_len; l++)
{
unsigned char c= src[k+l];
printf("%.2x ", (unsigned)c);
}
printf(" ");
for (l=0; l<8 && k+l<dst_len; l++)
{
unsigned char c= dst[k+l];
printf("%.2x ", (unsigned)c);
}
printf("\n");
}
printf("src length: %.8x, dst length: %.8x\n",
(uint) src_len, (uint) dst_len);
require(0);
}
}
printf("Test succeeded.\n");
return 0;
}
#endif
INCLUDES += \ INCLUDES += \
-I$(srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/ndb/include \ -I$(srcdir) -I$(top_srcdir)/include \
-I$(top_srcdir)/mysys \
-I$(top_srcdir)/ndb/include \
-I$(top_srcdir)/ndb/include/kernel \ -I$(top_srcdir)/ndb/include/kernel \
-I$(top_srcdir)/ndb/include/transporter \ -I$(top_srcdir)/ndb/include/transporter \
-I$(top_srcdir)/ndb/include/debugger \ -I$(top_srcdir)/ndb/include/debugger \
......
INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ INCLUDES += -I$(srcdir) \
-I$(top_srcdir)/include \
-I$(top_srcdir)/mysys \
-I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include \
-I$(top_srcdir)/ndb/include/util \ -I$(top_srcdir)/ndb/include/util \
-I$(top_srcdir)/ndb/include/portlib \ -I$(top_srcdir)/ndb/include/portlib \
......
/* Copyright (C) 2003 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; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <ndb_global.h>
#include <Base64.hpp>
static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
int
base64_encode(const UtilBuffer &src, BaseString &dst)
{
return base64_encode(src.get_data(), src.length(), dst);
}
int
base64_encode(const void * _s, size_t src_len, BaseString &dst) {
const unsigned char * s = (const unsigned char*)_s;
size_t i = 0;
size_t len = 0;
while(i < src_len) {
if(len == 76){
len = 0;
dst.append('\n');
}
unsigned c;
c = s[i++];
c <<= 8;
if(i < src_len)
c += s[i];
c <<= 8;
i++;
if(i < src_len)
c += s[i];
i++;
dst.append(base64_table[(c >> 18) & 0x3f]);
dst.append(base64_table[(c >> 12) & 0x3f]);
if(i > (src_len + 1))
dst.append('=');
else
dst.append(base64_table[(c >> 6) & 0x3f]);
if(i > src_len)
dst.append('=');
else
dst.append(base64_table[(c >> 0) & 0x3f]);
len += 4;
}
return 0;
}
static inline unsigned
pos(unsigned char c) {
return strchr(base64_table, c) - base64_table;
}
int
base64_decode(const BaseString &src, UtilBuffer &dst) {
return base64_decode(src.c_str(), src.length(), dst);
}
#define SKIP_SPACE(src, i, size){ \
while(i < size && isspace(* src)){ \
i++; \
src++; \
} \
if(i == size){ \
i = size + 1; \
break; \
} \
}
int
base64_decode(const char * src, size_t size, UtilBuffer &dst) {
size_t i = 0;
while(i < size){
unsigned c = 0;
int mark = 0;
SKIP_SPACE(src, i, size);
c += pos(*src++);
c <<= 6;
i++;
SKIP_SPACE(src, i, size);
c += pos(*src++);
c <<= 6;
i++;
SKIP_SPACE(src, i, size);
if(* src != '=')
c += pos(*src++);
else {
i = size;
mark = 2;
c <<= 6;
goto end;
}
c <<= 6;
i++;
SKIP_SPACE(src, i, size);
if(*src != '=')
c += pos(*src++);
else {
i = size;
mark = 1;
goto end;
}
i++;
end:
char b[3];
b[0] = (c >> 16) & 0xff;
b[1] = (c >> 8) & 0xff;
b[2] = (c >> 0) & 0xff;
dst.append((void *)b, 3-mark);
}
if(i != size){
abort();
return -1;
}
return 0;
}
#ifdef __TEST__B64
/**
* USER_FLAGS="-D__TEST__B64" make Base64.o && g++ Base64.o BaseString.o
*/
inline
void
require(bool b){
if(!b)
abort();
}
int
main(void){
for(int i = 0; i < 500; i++){
const size_t len = rand() % 10000 + 1;
UtilBuffer src;
for(size_t j = 0; j<len; j++){
char c = rand();
src.append(&c, 1);
}
require(src.length() == len);
BaseString str;
require(base64_encode(src, str) == 0);
if(str.length() == 3850){
printf(">%s<\n", str.c_str());
}
UtilBuffer dst;
require(base64_decode(str, dst) == 0);
require(dst.length() == src.length());
const char * c_src = (char*)src.get_data();
const char * c_dst = (char*)dst.get_data();
if(memcmp(src.get_data(), dst.get_data(), src.length()) != 0){
printf("-- src --\n");
for(int i2 = 0; i2<len; i2++){
unsigned char c = c_src[i2];
printf("%.2x ", (unsigned)c);
if((i2 % 8) == 7)
printf("\n");
}
printf("\n");
printf("-- dst --\n");
for(int i2 = 0; i2<len; i2++){
unsigned char c = c_dst[i2];
printf("%.2x ", (unsigned)c);
if((i2 % 8) == 7)
printf("\n");
}
printf("\n");
abort();
}
}
return 0;
}
#endif
...@@ -5,7 +5,7 @@ libgeneral_la_SOURCES = \ ...@@ -5,7 +5,7 @@ libgeneral_la_SOURCES = \
File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \ File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \
SimpleProperties.cpp Parser.cpp InputStream.cpp \ SimpleProperties.cpp Parser.cpp InputStream.cpp \
SocketServer.cpp SocketClient.cpp SocketAuthenticator.cpp\ SocketServer.cpp SocketClient.cpp SocketAuthenticator.cpp\
OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \ OutputStream.cpp NdbOut.cpp BaseString.cpp \
NdbSqlUtil.cpp new.cpp \ NdbSqlUtil.cpp new.cpp \
uucode.c random.c version.c \ uucode.c random.c version.c \
strdup.c \ strdup.c \
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include "Parser.hpp" #include "Parser.hpp"
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <Properties.hpp> #include <Properties.hpp>
#include <Base64.hpp>
#undef DEBUG #undef DEBUG
#define DEBUG(x) ndbout << x << endl; #define DEBUG(x) ndbout << x << endl;
...@@ -316,11 +315,7 @@ ParserImpl::parseArg(Context * ctx, ...@@ -316,11 +315,7 @@ ParserImpl::parseArg(Context * ctx,
} }
case DummyRow::Properties: { case DummyRow::Properties: {
Properties *sp = new Properties(); abort();
BaseString v(value);
UtilBuffer b;
base64_decode(v, b);
sp->unpack((const Uint32 *)b.get_data(), b.length());
break; break;
} }
default: default:
......
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
#include <Parser.hpp> #include <Parser.hpp>
#include <OutputStream.hpp> #include <OutputStream.hpp>
#include <InputStream.hpp> #include <InputStream.hpp>
#include <Base64.hpp>
#include <base64.h>
#define MGM_CMD(name, fun, desc) \ #define MGM_CMD(name, fun, desc) \
{ name, \ { name, \
...@@ -1770,11 +1770,15 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { ...@@ -1770,11 +1770,15 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
} while(start < len); } while(start < len);
if(buf64 == 0) if(buf64 == 0)
break; break;
void *tmp_data = malloc(base64_needed_decoded_length((size_t) (len - 1)));
const int res = base64_decode(buf64, len-1, tmp_data);
delete[] buf64;
UtilBuffer tmp; UtilBuffer tmp;
const int res = base64_decode(buf64, len-1, tmp); tmp.append((void *) tmp_data, res);
delete[] buf64; free(tmp_data);
if(res != 0){ if (res < 0)
{
fprintf(handle->errstream, "Failed to decode buffer\n"); fprintf(handle->errstream, "Failed to decode buffer\n");
break; break;
} }
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <signaldata/SetLogLevelOrd.hpp> #include <signaldata/SetLogLevelOrd.hpp>
#include <LogLevel.hpp> #include <LogLevel.hpp>
#include <BaseString.hpp> #include <BaseString.hpp>
#include <Base64.hpp>
#include <ConfigValues.hpp> #include <ConfigValues.hpp>
#include <mgmapi_configuration.hpp> #include <mgmapi_configuration.hpp>
...@@ -33,6 +32,8 @@ ...@@ -33,6 +32,8 @@
#include "Services.hpp" #include "Services.hpp"
#include "../mgmapi/ndb_logevent.hpp" #include "../mgmapi/ndb_logevent.hpp"
#include <base64.h>
extern bool g_StopServer; extern bool g_StopServer;
static const unsigned int MAX_READ_TIMEOUT = 1000 ; static const unsigned int MAX_READ_TIMEOUT = 1000 ;
...@@ -581,17 +582,18 @@ MgmApiSession::getConfig_common(Parser_t::Context &, ...@@ -581,17 +582,18 @@ MgmApiSession::getConfig_common(Parser_t::Context &,
cfg->pack(src); cfg->pack(src);
NdbMutex_Unlock(m_mgmsrv.m_configMutex); NdbMutex_Unlock(m_mgmsrv.m_configMutex);
BaseString str; char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length()));
int res = base64_encode(src, str); int res = base64_encode(src.get_data(), src.length(), tmp_str);
m_output->println("get config reply"); m_output->println("get config reply");
m_output->println("result: Ok"); m_output->println("result: Ok");
m_output->println("Content-Length: %d", str.length()); m_output->println("Content-Length: %d", strlen(tmp_str));
m_output->println("Content-Type: ndbconfig/octet-stream"); m_output->println("Content-Type: ndbconfig/octet-stream");
m_output->println("Content-Transfer-Encoding: base64"); m_output->println("Content-Transfer-Encoding: base64");
m_output->println(""); m_output->println("");
m_output->println(str.c_str()); m_output->println(tmp_str);
free(tmp_str);
return; return;
} }
......
...@@ -6811,6 +6811,7 @@ ha_innobase::store_lock( ...@@ -6811,6 +6811,7 @@ ha_innobase::store_lock(
|| thd->lex->sql_command == SQLCOM_CALL) || thd->lex->sql_command == SQLCOM_CALL)
&& !thd->tablespace_op && !thd->tablespace_op
&& thd->lex->sql_command != SQLCOM_TRUNCATE && thd->lex->sql_command != SQLCOM_TRUNCATE
&& thd->lex->sql_command != SQLCOM_OPTIMIZE
&& thd->lex->sql_command != SQLCOM_CREATE_TABLE) { && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
lock_type = TL_WRITE_ALLOW_WRITE; lock_type = TL_WRITE_ALLOW_WRITE;
......
...@@ -696,7 +696,6 @@ failed my_b_read")); ...@@ -696,7 +696,6 @@ failed my_b_read"));
*/ */
DBUG_RETURN(0); DBUG_RETURN(0);
} }
uint data_len = uint4korr(head + EVENT_LEN_OFFSET); uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
char *buf= 0; char *buf= 0;
const char *error= 0; const char *error= 0;
...@@ -876,15 +875,76 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, ...@@ -876,15 +875,76 @@ 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) void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
char llbuff[22]; char llbuff[22];
my_off_t hexdump_from= print_event_info->hexdump_from;
fputc('#', file); fputc('#', file);
print_timestamp(file); print_timestamp(file);
fprintf(file, " server id %d end_log_pos %s ", server_id, fprintf(file, " server id %d end_log_pos %s ", server_id,
llstr(log_pos,llbuff)); llstr(log_pos,llbuff));
/* mysqlbinlog --hexdump */
if (print_event_info->hexdump_from)
{
fprintf(file, "\n");
uchar *ptr= (uchar*)temp_buf;
my_off_t size=
uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
my_off_t i;
/* Header len * 4 >= header len * (2 chars + space + extra space) */
char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
char *c, char_string[16+1]= {0};
/* Pretty-print event common header if header is exactly 19 bytes */
if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
{
fprintf(file, "# Position Timestamp Type Master ID "
"Size Master Pos Flags \n");
fprintf(file, "# %8.8lx %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x\n",
hexdump_from, 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[14], ptr[15], ptr[16], ptr[17], ptr[18]);
ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
}
/* Rest of event (without common header) */
for (i= 0, c= char_string, h=hex_string;
i < size;
i++, ptr++)
{
my_snprintf(h, 4, "%02x ", *ptr);
h += 3;
*c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
if (i % 16 == 15)
{
fprintf(file, "# %8.8lx %-48.48s |%16s|\n",
hexdump_from + (i & 0xfffffff0), hex_string, char_string);
hex_string[0]= 0;
char_string[0]= 0;
c= char_string;
h= hex_string;
}
else if (i % 8 == 7) *h++ = ' ';
}
*c= '\0';
/* Non-full last line */
if (hex_string[0]) {
printf("# %8.8lx %-48.48s |%s|\n# ",
hexdump_from + (i & 0xfffffff0), hex_string, char_string);
}
}
} }
/* /*
Log_event::print_timestamp() Log_event::print_timestamp()
*/ */
...@@ -1367,25 +1427,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, ...@@ -1367,25 +1427,25 @@ 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(FILE* file, bool short_form, void Query_log_event::print_query_header(FILE* file,
LAST_EVENT_INFO* last_event_info) PRINT_EVENT_INFO* print_event_info)
{ {
// TODO: print the catalog ?? // TODO: print the catalog ??
char buff[40],*end; // Enough for SET TIMESTAMP char buff[40],*end; // Enough for SET TIMESTAMP
bool different_db= 1; bool different_db= 1;
uint32 tmp; uint32 tmp;
if (!short_form) if (!print_event_info->short_form)
{ {
print_header(file); print_header(file, print_event_info);
fprintf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n", fprintf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_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)
{ {
if (different_db= memcmp(last_event_info->db, db, db_len + 1)) if (different_db= memcmp(print_event_info->db, db, db_len + 1))
memcpy(last_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)
fprintf(file, "use %s;\n", db); fprintf(file, "use %s;\n", db);
} }
...@@ -1405,12 +1465,12 @@ void Query_log_event::print_query_header(FILE* file, bool short_form, ...@@ -1405,12 +1465,12 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */ if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
{ {
/* tmp is a bitmask of bits which have changed. */ /* tmp is a bitmask of bits which have changed. */
if (likely(last_event_info->flags2_inited)) if (likely(print_event_info->flags2_inited))
/* All bits which have changed */ /* All bits which have changed */
tmp= (last_event_info->flags2) ^ flags2; tmp= (print_event_info->flags2) ^ flags2;
else /* that's the first Query event we read */ else /* that's the first Query event we read */
{ {
last_event_info->flags2_inited= 1; print_event_info->flags2_inited= 1;
tmp= ~((uint32)0); /* all bits have changed */ tmp= ~((uint32)0); /* all bits have changed */
} }
...@@ -1425,7 +1485,7 @@ void Query_log_event::print_query_header(FILE* file, bool short_form, ...@@ -1425,7 +1485,7 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
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);
fprintf(file,";\n"); fprintf(file,";\n");
last_event_info->flags2= flags2; print_event_info->flags2= flags2;
} }
} }
...@@ -1444,37 +1504,37 @@ void Query_log_event::print_query_header(FILE* file, bool short_form, ...@@ -1444,37 +1504,37 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
if (likely(sql_mode_inited)) if (likely(sql_mode_inited))
{ {
if (unlikely(!last_event_info->sql_mode_inited)) /* first Query event */ if (unlikely(!print_event_info->sql_mode_inited)) /* first Query event */
{ {
last_event_info->sql_mode_inited= 1; print_event_info->sql_mode_inited= 1;
/* force a difference to force write */ /* force a difference to force write */
last_event_info->sql_mode= ~sql_mode; print_event_info->sql_mode= ~sql_mode;
} }
if (unlikely(last_event_info->sql_mode != sql_mode)) if (unlikely(print_event_info->sql_mode != sql_mode))
{ {
fprintf(file,"SET @@session.sql_mode=%lu;\n",(ulong)sql_mode); fprintf(file,"SET @@session.sql_mode=%lu;\n",(ulong)sql_mode);
last_event_info->sql_mode= sql_mode; print_event_info->sql_mode= sql_mode;
} }
} }
if (last_event_info->auto_increment_increment != auto_increment_increment || if (print_event_info->auto_increment_increment != auto_increment_increment ||
last_event_info->auto_increment_offset != auto_increment_offset) print_event_info->auto_increment_offset != auto_increment_offset)
{ {
fprintf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;\n", fprintf(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);
last_event_info->auto_increment_increment= auto_increment_increment; print_event_info->auto_increment_increment= auto_increment_increment;
last_event_info->auto_increment_offset= auto_increment_offset; print_event_info->auto_increment_offset= auto_increment_offset;
} }
/* TODO: print the catalog when we feature SET CATALOG */ /* TODO: print the catalog when we feature SET CATALOG */
if (likely(charset_inited)) if (likely(charset_inited))
{ {
if (unlikely(!last_event_info->charset_inited)) /* first Query event */ if (unlikely(!print_event_info->charset_inited)) /* first Query event */
{ {
last_event_info->charset_inited= 1; print_event_info->charset_inited= 1;
last_event_info->charset[0]= ~charset[0]; // force a difference to force write print_event_info->charset[0]= ~charset[0]; // force a difference to force write
} }
if (unlikely(bcmp(last_event_info->charset, charset, 6))) if (unlikely(bcmp(print_event_info->charset, charset, 6)))
{ {
fprintf(file,"SET " fprintf(file,"SET "
"@@session.character_set_client=%d," "@@session.character_set_client=%d,"
...@@ -1484,24 +1544,23 @@ void Query_log_event::print_query_header(FILE* file, bool short_form, ...@@ -1484,24 +1544,23 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
uint2korr(charset), uint2korr(charset),
uint2korr(charset+2), uint2korr(charset+2),
uint2korr(charset+4)); uint2korr(charset+4));
memcpy(last_event_info->charset, charset, 6); memcpy(print_event_info->charset, charset, 6);
} }
} }
if (time_zone_len) if (time_zone_len)
{ {
if (bcmp(last_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))
{ {
fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str); fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
memcpy(last_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);
} }
} }
} }
void Query_log_event::print(FILE* file, bool short_form, void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
LAST_EVENT_INFO* last_event_info)
{ {
print_query_header(file, short_form, last_event_info); print_query_header(file, print_event_info);
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME)); my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
fputs(";\n", file); fputs(";\n", file);
} }
...@@ -1799,11 +1858,11 @@ void Start_log_event_v3::pack_info(Protocol *protocol) ...@@ -1799,11 +1858,11 @@ void Start_log_event_v3::pack_info(Protocol *protocol)
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Start_log_event_v3::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
if (!short_form) if (!print_event_info->short_form)
{ {
print_header(file); print_header(file, print_event_info);
fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version, fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version,
server_version); server_version);
print_timestamp(file); print_timestamp(file);
...@@ -2527,19 +2586,19 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, ...@@ -2527,19 +2586,19 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
print(file, short_form, last_event_info, 0); print(file, print_event_info, 0);
} }
void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
bool commented) bool commented)
{ {
DBUG_ENTER("Load_log_event::print"); DBUG_ENTER("Load_log_event::print");
if (!short_form) if (!print_event_info->short_form)
{ {
print_header(file); print_header(file, print_event_info);
fprintf(file, "\tQuery\tthread_id=%ld\texec_time=%ld\n", fprintf(file, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
thread_id, exec_time); thread_id, exec_time);
} }
...@@ -2553,9 +2612,9 @@ void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_ev ...@@ -2553,9 +2612,9 @@ void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_ev
But if commented, the "use" is going to be commented so we should not But if commented, the "use" is going to be commented so we should not
update the last_db. update the last_db.
*/ */
if ((different_db= memcmp(last_event_info->db, db, db_len + 1)) && if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
!commented) !commented)
memcpy(last_event_info->db, db, db_len + 1); memcpy(print_event_info->db, db, db_len + 1);
} }
if (db && db[0] && different_db) if (db && db[0] && different_db)
...@@ -2944,13 +3003,13 @@ void Rotate_log_event::pack_info(Protocol *protocol) ...@@ -2944,13 +3003,13 @@ void Rotate_log_event::pack_info(Protocol *protocol)
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Rotate_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
char buf[22]; char buf[22];
if (short_form) if (print_event_info->short_form)
return; return;
print_header(file); print_header(file, print_event_info);
fprintf(file, "\tRotate to "); fprintf(file, "\tRotate to ");
if (new_log_ident) if (new_log_ident)
my_fwrite(file, (byte*) new_log_ident, (uint)ident_len, my_fwrite(file, (byte*) new_log_ident, (uint)ident_len,
...@@ -3168,16 +3227,15 @@ bool Intvar_log_event::write(IO_CACHE* file) ...@@ -3168,16 +3227,15 @@ bool Intvar_log_event::write(IO_CACHE* file)
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Intvar_log_event::print(FILE* file, bool short_form, void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
LAST_EVENT_INFO* last_event_info)
{ {
char llbuff[22]; char llbuff[22];
const char *msg; const char *msg;
LINT_INIT(msg); LINT_INIT(msg);
if (!short_form) if (!print_event_info->short_form)
{ {
print_header(file); print_header(file, print_event_info);
fprintf(file, "\tIntvar\n"); fprintf(file, "\tIntvar\n");
} }
...@@ -3258,12 +3316,12 @@ bool Rand_log_event::write(IO_CACHE* file) ...@@ -3258,12 +3316,12 @@ bool Rand_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Rand_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
char llbuff[22],llbuff2[22]; char llbuff[22],llbuff2[22];
if (!short_form) if (!print_event_info->short_form)
{ {
print_header(file); print_header(file, print_event_info);
fprintf(file, "\tRand\n"); fprintf(file, "\tRand\n");
} }
fprintf(file, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n", fprintf(file, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
...@@ -3328,14 +3386,14 @@ bool Xid_log_event::write(IO_CACHE* file) ...@@ -3328,14 +3386,14 @@ bool Xid_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Xid_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
if (!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_header(file, print_event_info);
fprintf(file, "\tXid = %s\n", buf); fprintf(file, "\tXid = %s\n", buf);
fflush(file); fflush(file);
} }
...@@ -3526,11 +3584,11 @@ bool User_var_log_event::write(IO_CACHE* file) ...@@ -3526,11 +3584,11 @@ bool User_var_log_event::write(IO_CACHE* file)
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
if (!short_form) if (!print_event_info->short_form)
{ {
print_header(file); print_header(file, print_event_info);
fprintf(file, "\tUser_var\n"); fprintf(file, "\tUser_var\n");
} }
...@@ -3701,11 +3759,11 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli) ...@@ -3701,11 +3759,11 @@ 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, bool short_form, LAST_EVENT_INFO* last_event_info) void Unknown_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
if (short_form) if (print_event_info->short_form)
return; return;
print_header(file); print_header(file, print_event_info);
fputc('\n', file); fputc('\n', file);
fprintf(file, "# %s", "Unknown event\n"); fprintf(file, "# %s", "Unknown event\n");
} }
...@@ -3772,12 +3830,12 @@ Slave_log_event::~Slave_log_event() ...@@ -3772,12 +3830,12 @@ Slave_log_event::~Slave_log_event()
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Slave_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
char llbuff[22]; char llbuff[22];
if (short_form) if (print_event_info->short_form)
return; return;
print_header(file); print_header(file, print_event_info);
fputc('\n', file); fputc('\n', file);
fprintf(file, "\ 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",
...@@ -3857,12 +3915,12 @@ int Slave_log_event::exec_event(struct st_relay_log_info* rli) ...@@ -3857,12 +3915,12 @@ 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, bool short_form, LAST_EVENT_INFO* last_event_info) void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{ {
if (short_form) if (print_event_info->short_form)
return; return;
print_header(file); print_header(file, print_event_info);
fprintf(file, "\tStop\n"); fprintf(file, "\tStop\n");
fflush(file); fflush(file);
} }
...@@ -4036,19 +4094,20 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len, ...@@ -4036,19 +4094,20 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len,
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Create_file_log_event::print(FILE* file, bool short_form, void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
LAST_EVENT_INFO* last_event_info, bool enable_local) bool enable_local)
{ {
if (short_form) if (print_event_info->short_form)
{ {
if (enable_local && check_fname_outside_temp_buf()) if (enable_local && check_fname_outside_temp_buf())
Load_log_event::print(file, 1, last_event_info); Load_log_event::print(file, print_event_info);
return; return;
} }
if (enable_local) if (enable_local)
{ {
Load_log_event::print(file, short_form, last_event_info, !check_fname_outside_temp_buf()); Load_log_event::print(file, print_event_info,
!check_fname_outside_temp_buf());
/* /*
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.
...@@ -4060,10 +4119,9 @@ void Create_file_log_event::print(FILE* file, bool short_form, ...@@ -4060,10 +4119,9 @@ void Create_file_log_event::print(FILE* file, bool short_form,
} }
void Create_file_log_event::print(FILE* file, bool short_form, void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
LAST_EVENT_INFO* last_event_info)
{ {
print(file,short_form,last_event_info,0); print(file, print_event_info, 0);
} }
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
...@@ -4223,12 +4281,12 @@ bool Append_block_log_event::write(IO_CACHE* file) ...@@ -4223,12 +4281,12 @@ bool Append_block_log_event::write(IO_CACHE* file)
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Append_block_log_event::print(FILE* file, bool short_form, void Append_block_log_event::print(FILE* file,
LAST_EVENT_INFO* last_event_info) PRINT_EVENT_INFO* print_event_info)
{ {
if (short_form) if (print_event_info->short_form)
return; return;
print_header(file); print_header(file, print_event_info);
fputc('\n', file); fputc('\n', file);
fprintf(file, "#%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);
...@@ -4367,12 +4425,12 @@ bool Delete_file_log_event::write(IO_CACHE* file) ...@@ -4367,12 +4425,12 @@ bool Delete_file_log_event::write(IO_CACHE* file)
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Delete_file_log_event::print(FILE* file, bool short_form, void Delete_file_log_event::print(FILE* file,
LAST_EVENT_INFO* last_event_info) PRINT_EVENT_INFO* print_event_info)
{ {
if (short_form) if (print_event_info->short_form)
return; return;
print_header(file); print_header(file, print_event_info);
fputc('\n', file); fputc('\n', file);
fprintf(file, "#Delete_file: file_id=%u\n", file_id); fprintf(file, "#Delete_file: file_id=%u\n", file_id);
} }
...@@ -4463,12 +4521,12 @@ bool Execute_load_log_event::write(IO_CACHE* file) ...@@ -4463,12 +4521,12 @@ bool Execute_load_log_event::write(IO_CACHE* file)
*/ */
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Execute_load_log_event::print(FILE* file, bool short_form, void Execute_load_log_event::print(FILE* file,
LAST_EVENT_INFO* last_event_info) PRINT_EVENT_INFO* print_event_info)
{ {
if (short_form) if (print_event_info->short_form)
return; return;
print_header(file); print_header(file, print_event_info);
fputc('\n', file); fputc('\n', file);
fprintf(file, "#Exec_load: file_id=%d\n", fprintf(file, "#Exec_load: file_id=%d\n",
file_id); file_id);
...@@ -4675,18 +4733,18 @@ Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file) ...@@ -4675,18 +4733,18 @@ Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Execute_load_query_log_event::print(FILE* file, bool short_form, void Execute_load_query_log_event::print(FILE* file,
LAST_EVENT_INFO* last_event_info) PRINT_EVENT_INFO* print_event_info)
{ {
print(file, short_form, last_event_info, 0); print(file, print_event_info, 0);
} }
void Execute_load_query_log_event::print(FILE* file, bool short_form, void Execute_load_query_log_event::print(FILE* file,
LAST_EVENT_INFO* last_event_info, PRINT_EVENT_INFO* print_event_info,
const char *local_fname) const char *local_fname)
{ {
print_query_header(file, short_form, last_event_info); print_query_header(file, print_event_info);
if (local_fname) if (local_fname)
{ {
...@@ -4707,7 +4765,7 @@ void Execute_load_query_log_event::print(FILE* file, bool short_form, ...@@ -4707,7 +4765,7 @@ void Execute_load_query_log_event::print(FILE* file, bool short_form,
fprintf(file, ";\n"); fprintf(file, ";\n");
} }
if (!short_form) if (!print_event_info->short_form)
fprintf(file, "# file_id: %d \n", file_id); fprintf(file, "# file_id: %d \n", file_id);
} }
#endif #endif
......
...@@ -403,27 +403,38 @@ enum Log_event_type ...@@ -403,27 +403,38 @@ enum Log_event_type
Every time you update this enum (when you add a type), you have to Every time you update this enum (when you add a type), you have to
fix Format_description_log_event::Format_description_log_event(). fix Format_description_log_event::Format_description_log_event().
*/ */
UNKNOWN_EVENT= 0, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT, UNKNOWN_EVENT= 0,
INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT, START_EVENT_V3= 1,
APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT, QUERY_EVENT= 2,
STOP_EVENT= 3,
ROTATE_EVENT= 4,
INTVAR_EVENT= 5,
LOAD_EVENT= 6,
SLAVE_EVENT= 7,
CREATE_FILE_EVENT= 8,
APPEND_BLOCK_EVENT= 9,
EXEC_LOAD_EVENT= 10,
DELETE_FILE_EVENT= 11,
/* /*
NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
sql_ex, allowing multibyte TERMINATED BY etc; both types share the sql_ex, allowing multibyte TERMINATED BY etc; both types share the
same class (Load_log_event) same class (Load_log_event)
*/ */
NEW_LOAD_EVENT, NEW_LOAD_EVENT= 12,
RAND_EVENT, USER_VAR_EVENT, RAND_EVENT= 13,
FORMAT_DESCRIPTION_EVENT, USER_VAR_EVENT= 14,
XID_EVENT, FORMAT_DESCRIPTION_EVENT= 15,
BEGIN_LOAD_QUERY_EVENT, XID_EVENT= 16,
EXECUTE_LOAD_QUERY_EVENT, BEGIN_LOAD_QUERY_EVENT= 17,
EXECUTE_LOAD_QUERY_EVENT= 18,
/* /*
add new events here - right above this comment! Add new events here - right above this comment!
existing events should never change their numbers And change the ENUM_END_EVENT_MARKER below.
Existing events should never change their numbers
*/ */
ENUM_END_EVENT /* end marker */ ENUM_END_EVENT= 19 /* end marker */
}; };
/* /*
...@@ -451,12 +462,23 @@ struct st_relay_log_info; ...@@ -451,12 +462,23 @@ struct st_relay_log_info;
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
/* /*
A structure for mysqlbinlog to remember the last db, flags2, sql_mode etc; it A structure for mysqlbinlog to know how to print events
is passed to events' print() methods, so that they print only the necessary
USE and SET commands. This structure is passed to the event's print() methods,
There are two types of settings stored here:
1. Last db, flags2, sql_mode etc comes from the last printed event.
They are stored so that only the necessary USE and SET commands
are printed.
2. Other information on how to print the events, e.g. short_form,
hexdump_from. These are not dependent on the last event.
*/ */
typedef struct st_last_event_info typedef struct st_print_event_info
{ {
/*
Settings for database, sql_mode etc that comes from the last event
that was printed.
*/
// TODO: have the last catalog here ?? // TODO: have the last catalog here ??
char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is
bool flags2_inited; bool flags2_inited;
...@@ -467,12 +489,12 @@ typedef struct st_last_event_info ...@@ -467,12 +489,12 @@ typedef struct st_last_event_info
bool charset_inited; bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes char charset[6]; // 3 variables, each of them storable in 2 bytes
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH]; char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
st_last_event_info() st_print_event_info()
:flags2_inited(0), sql_mode_inited(0), :flags2_inited(0), sql_mode_inited(0),
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0) auto_increment_increment(1),auto_increment_offset(1), charset_inited(0)
{ {
/* /*
Currently we only use static LAST_EVENT_INFO objects, so zeroed at Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
program's startup, but these explicit bzero() is for the day someone program's startup, but these explicit bzero() is for the day someone
creates dynamic instances. creates dynamic instances.
*/ */
...@@ -480,7 +502,13 @@ typedef struct st_last_event_info ...@@ -480,7 +502,13 @@ typedef struct st_last_event_info
bzero(charset, sizeof(charset)); bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str)); bzero(time_zone_str, sizeof(time_zone_str));
} }
} LAST_EVENT_INFO;
/* Settings on how to print the events */
bool short_form;
my_off_t hexdump_from;
uint8 common_header_len;
} PRINT_EVENT_INFO;
#endif #endif
...@@ -589,9 +617,9 @@ public: ...@@ -589,9 +617,9 @@ public:
static Log_event* read_log_event(IO_CACHE* file, static Log_event* read_log_event(IO_CACHE* file,
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, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0) = 0; virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0) = 0;
void print_timestamp(FILE* file, time_t *ts = 0); void print_timestamp(FILE* file, time_t *ts = 0);
void print_header(FILE* file); void print_header(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
static void *operator new(size_t size) static void *operator new(size_t size)
...@@ -751,8 +779,8 @@ public: ...@@ -751,8 +779,8 @@ public:
uint32 q_len_arg); uint32 q_len_arg);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print_query_header(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print_query_header(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Query_log_event(const char* buf, uint event_len, Query_log_event(const char* buf, uint event_len,
...@@ -806,7 +834,7 @@ public: ...@@ -806,7 +834,7 @@ public:
void pack_info(Protocol* protocol); void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Slave_log_event(const char* buf, uint event_len); Slave_log_event(const char* buf, uint event_len);
...@@ -894,8 +922,8 @@ public: ...@@ -894,8 +922,8 @@ public:
bool use_rli_only_for_errors); bool use_rli_only_for_errors);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info = 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info = 0);
void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool commented); void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented);
#endif #endif
/* /*
...@@ -984,7 +1012,7 @@ public: ...@@ -984,7 +1012,7 @@ public:
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
Start_log_event_v3() {} Start_log_event_v3() {}
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Start_log_event_v3(const char* buf, Start_log_event_v3(const char* buf,
...@@ -1079,7 +1107,7 @@ public: ...@@ -1079,7 +1107,7 @@ public:
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Intvar_log_event(const char* buf, const Format_description_log_event* description_event); Intvar_log_event(const char* buf, const Format_description_log_event* description_event);
...@@ -1120,7 +1148,7 @@ class Rand_log_event: public Log_event ...@@ -1120,7 +1148,7 @@ class Rand_log_event: public Log_event
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Rand_log_event(const char* buf, const Format_description_log_event* description_event); Rand_log_event(const char* buf, const Format_description_log_event* description_event);
...@@ -1157,7 +1185,7 @@ class Xid_log_event: public Log_event ...@@ -1157,7 +1185,7 @@ class Xid_log_event: public Log_event
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Xid_log_event(const char* buf, const Format_description_log_event* description_event); Xid_log_event(const char* buf, const Format_description_log_event* description_event);
...@@ -1199,7 +1227,7 @@ public: ...@@ -1199,7 +1227,7 @@ public:
void pack_info(Protocol* protocol); void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
User_var_log_event(const char* buf, const Format_description_log_event* description_event); User_var_log_event(const char* buf, const Format_description_log_event* description_event);
...@@ -1225,7 +1253,7 @@ public: ...@@ -1225,7 +1253,7 @@ public:
{} {}
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Stop_log_event(const char* buf, const Format_description_log_event* description_event): Stop_log_event(const char* buf, const Format_description_log_event* description_event):
...@@ -1263,7 +1291,7 @@ public: ...@@ -1263,7 +1291,7 @@ public:
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Rotate_log_event(const char* buf, uint event_len, Rotate_log_event(const char* buf, uint event_len,
...@@ -1316,8 +1344,8 @@ public: ...@@ -1316,8 +1344,8 @@ public:
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool enable_local); void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local);
#endif #endif
Create_file_log_event(const char* buf, uint event_len, Create_file_log_event(const char* buf, uint event_len,
...@@ -1384,7 +1412,7 @@ public: ...@@ -1384,7 +1412,7 @@ public:
virtual int get_create_or_append() const; virtual int get_create_or_append() const;
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Append_block_log_event(const char* buf, uint event_len, Append_block_log_event(const char* buf, uint event_len,
...@@ -1419,8 +1447,8 @@ public: ...@@ -1419,8 +1447,8 @@ public:
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool enable_local); void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local);
#endif #endif
Delete_file_log_event(const char* buf, uint event_len, Delete_file_log_event(const char* buf, uint event_len,
...@@ -1455,7 +1483,7 @@ public: ...@@ -1455,7 +1483,7 @@ public:
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif #endif
Execute_load_log_event(const char* buf, uint event_len, Execute_load_log_event(const char* buf, uint event_len,
...@@ -1540,11 +1568,10 @@ public: ...@@ -1540,11 +1568,10 @@ public:
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
#else #else
void print(FILE* file, bool short_form = 0, void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
LAST_EVENT_INFO* last_event_info= 0);
/* Prints the query as LOAD DATA LOCAL and with rewritten filename */ /* Prints the query as LOAD DATA LOCAL and with rewritten filename */
void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
const char *local_fname); const char *local_fname);
#endif #endif
Execute_load_query_log_event(const char* buf, uint event_len, Execute_load_query_log_event(const char* buf, uint event_len,
const Format_description_log_event *description_event); const Format_description_log_event *description_event);
...@@ -1573,7 +1600,7 @@ public: ...@@ -1573,7 +1600,7 @@ public:
Log_event(buf, description_event) Log_event(buf, description_event)
{} {}
~Unknown_log_event() {} ~Unknown_log_event() {}
void print(FILE* file, bool short_form= 0, LAST_EVENT_INFO* last_event_info= 0); void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
Log_event_type get_type_code() { return UNKNOWN_EVENT;} Log_event_type get_type_code() { return UNKNOWN_EVENT;}
bool is_valid() const { return 1; } bool is_valid() const { return 1; }
}; };
......
...@@ -738,6 +738,7 @@ typedef struct st_lex ...@@ -738,6 +738,7 @@ typedef struct st_lex
/* store original leaf_tables for INSERT SELECT and PS/SP */ /* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert; TABLE_LIST *leaf_tables_insert;
st_lex_user *create_view_definer; st_lex_user *create_view_definer;
char *create_view_start;
char *create_view_select_start; char *create_view_select_start;
List<key_part_spec> col_list; List<key_part_spec> col_list;
......
...@@ -1742,6 +1742,8 @@ static bool check_prepared_statement(Prepared_statement *stmt, ...@@ -1742,6 +1742,8 @@ static bool check_prepared_statement(Prepared_statement *stmt,
case SQLCOM_ROLLBACK: case SQLCOM_ROLLBACK:
case SQLCOM_TRUNCATE: case SQLCOM_TRUNCATE:
case SQLCOM_CALL: case SQLCOM_CALL:
case SQLCOM_CREATE_VIEW:
case SQLCOM_DROP_VIEW:
break; break;
default: default:
......
...@@ -273,7 +273,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -273,7 +273,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
*(end=fn_ext(path))=0; // Remove extension for delete *(end=fn_ext(path))=0; // Remove extension for delete
error= ha_delete_table(thd, table_type, path, table->table_name, error= ha_delete_table(thd, table_type, path, table->table_name,
!dont_log_query); !dont_log_query);
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists) if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
(if_exists || table_type == DB_TYPE_UNKNOWN))
error= 0; error= 0;
if (error == HA_ERR_ROW_IS_REFERENCED) if (error == HA_ERR_ROW_IS_REFERENCED)
{ {
......
...@@ -643,7 +643,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -643,7 +643,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
view->query.length= str.length()-1; // we do not need last \0 view->query.length= str.length()-1; // we do not need last \0
view->source.str= thd->lex->create_view_select_start; view->source.str= thd->lex->create_view_select_start;
view->source.length= (thd->query_length - view->source.length= (thd->query_length -
(thd->lex->create_view_select_start - thd->query)); (thd->lex->create_view_select_start -
thd->lex->create_view_start));
view->file_version= 1; view->file_version= 1;
view->calc_md5(md5); view->calc_md5(md5);
view->md5.str= md5; view->md5.str= md5;
......
...@@ -660,7 +660,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -660,7 +660,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token YEAR_SYM %token YEAR_SYM
%token ZEROFILL %token ZEROFILL
%left JOIN_SYM %left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT
/* A dummy token to force the priority of table_ref production in a join. */ /* A dummy token to force the priority of table_ref production in a join. */
%left TABLE_REF_PRIORITY %left TABLE_REF_PRIORITY
%left SET_VAR %left SET_VAR
...@@ -1263,6 +1263,7 @@ create: ...@@ -1263,6 +1263,7 @@ create:
THD *thd= YYTHD; THD *thd= YYTHD;
LEX *lex= thd->lex; LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_VIEW; lex->sql_command= SQLCOM_CREATE_VIEW;
lex->create_view_start= thd->query;
/* first table in list is target VIEW name */ /* first table in list is target VIEW name */
if (!lex->select_lex.add_table_to_list(thd, $7, NULL, 0)) if (!lex->select_lex.add_table_to_list(thd, $7, NULL, 0))
YYABORT; YYABORT;
...@@ -3425,6 +3426,7 @@ alter: ...@@ -3425,6 +3426,7 @@ alter:
THD *thd= YYTHD; THD *thd= YYTHD;
LEX *lex= thd->lex; LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_VIEW; lex->sql_command= SQLCOM_CREATE_VIEW;
lex->create_view_start= thd->query;
lex->create_view_mode= VIEW_ALTER; lex->create_view_mode= VIEW_ALTER;
/* first table in list is target VIEW name */ /* first table in list is target VIEW name */
lex->select_lex.add_table_to_list(thd, $6, NULL, 0); lex->select_lex.add_table_to_list(thd, $6, NULL, 0);
...@@ -5225,14 +5227,22 @@ derived_table_list: ...@@ -5225,14 +5227,22 @@ derived_table_list:
} }
; ;
/*
Notice that JOIN is a left-associative operation, and it must be parsed
as such, that is, the parser must process first the left join operand
then the right one. Such order of processing ensures that the parser
produces correct join trees which is essential for semantic analysis
and subsequent optimization phases.
*/
join_table: join_table:
/* INNER JOIN variants */
/* /*
Evaluate production 'table_ref' before 'normal_join' so that Use %prec to evaluate production 'table_ref' before 'normal_join'
[INNER | CROSS] JOIN is properly nested as other left-associative so that [INNER | CROSS] JOIN is properly nested as other
joins. left-associative joins.
*/ */
table_ref %prec TABLE_REF_PRIORITY normal_join table_ref table_ref %prec TABLE_REF_PRIORITY normal_join table_ref
{ YYERROR_UNLESS($1 && ($$=$3)); } { YYERROR_UNLESS($1 && ($$=$3)); }
| table_ref STRAIGHT_JOIN table_factor | table_ref STRAIGHT_JOIN table_factor
{ YYERROR_UNLESS($1 && ($$=$3)); $3->straight=1; } { YYERROR_UNLESS($1 && ($$=$3)); $3->straight=1; }
| table_ref normal_join table_ref | table_ref normal_join table_ref
...@@ -5274,6 +5284,13 @@ join_table: ...@@ -5274,6 +5284,13 @@ join_table:
} }
'(' using_list ')' '(' using_list ')'
{ add_join_natural($1,$3,$7); $$=$3; } { add_join_natural($1,$3,$7); $$=$3; }
| table_ref NATURAL JOIN_SYM table_factor
{
YYERROR_UNLESS($1 && ($$=$4));
add_join_natural($1,$4,NULL);
}
/* LEFT JOIN variants */
| table_ref LEFT opt_outer JOIN_SYM table_ref | table_ref LEFT opt_outer JOIN_SYM table_ref
ON ON
{ {
...@@ -5305,6 +5322,8 @@ join_table: ...@@ -5305,6 +5322,8 @@ join_table:
$6->outer_join|=JOIN_TYPE_LEFT; $6->outer_join|=JOIN_TYPE_LEFT;
$$=$6; $$=$6;
} }
/* RIGHT JOIN variants */
| table_ref RIGHT opt_outer JOIN_SYM table_ref | table_ref RIGHT opt_outer JOIN_SYM table_ref
ON ON
{ {
...@@ -5342,10 +5361,7 @@ join_table: ...@@ -5342,10 +5361,7 @@ join_table:
LEX *lex= Lex; LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join())) if (!($$= lex->current_select->convert_right_join()))
YYABORT; YYABORT;
} };
| table_ref NATURAL JOIN_SYM table_factor
{ YYERROR_UNLESS($1 && ($$=$4)); add_join_natural($1,$4,NULL); };
normal_join: normal_join:
JOIN_SYM {} JOIN_SYM {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment