repositories merge
This commit is contained in:
commit
da8a5592d9
41
Makefile
Normal file
41
Makefile
Normal file
@ -0,0 +1,41 @@
|
||||
# This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
#
|
||||
# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Copyright SkySQL Ab 2013
|
||||
#
|
||||
# Revision History
|
||||
# Date Who Description
|
||||
# 16/07/13 Mark Riddoch Initial implementation
|
||||
|
||||
DEST=$(HOME)/usr/local/skysql
|
||||
|
||||
all:
|
||||
(cd log_manager; make)
|
||||
(cd query_classifier; make)
|
||||
(cd epoll_v1.0; make)
|
||||
|
||||
clean:
|
||||
(cd log_manager; make clean)
|
||||
(cd query_classifier; make clean)
|
||||
(cd epoll_v1.0; make clean)
|
||||
|
||||
depend:
|
||||
(cd log_manager; make depend)
|
||||
(cd query_classifier; make depend)
|
||||
(cd epoll_v1.0; make depend)
|
||||
|
||||
install:
|
||||
(cd epoll_v1.0; make DEST=$(DEST) install)
|
||||
(cd log_manager; make DEST=$(DEST) install)
|
||||
(cd query_classifier; make DEST=$(DEST) install)
|
32
build_gateway.inc
Normal file
32
build_gateway.inc
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# This file includes all dynamically changing build-related
|
||||
# variables.
|
||||
#
|
||||
# Modify to match with your needs. Do not commit any private
|
||||
# changes to this file!
|
||||
#
|
||||
|
||||
#
|
||||
# Set debug flags
|
||||
#
|
||||
# DEBUG :=
|
||||
# DEBUGGER :=
|
||||
# DEBUGGER_PATH :=
|
||||
# DEBUGGER_BIN :=
|
||||
#
|
||||
# Set build env
|
||||
#
|
||||
UNIX :=
|
||||
|
||||
#
|
||||
# Set path for root directory, that is, path to directory where
|
||||
# makefile.inc and build_gateway.inc are located.
|
||||
# ROOT_PATH is used in makefile.
|
||||
#
|
||||
ROOT_PATH :=
|
||||
|
||||
# MARIADB_SRC_PATH may be defined either as an environment variable or
|
||||
# specifically here
|
||||
ifndef $(MARIADB_SRC_PATH)
|
||||
MARIADB_SRC_PATH :=
|
||||
endif
|
1641
log_manager/log_manager.cc
Normal file
1641
log_manager/log_manager.cc
Normal file
File diff suppressed because it is too large
Load Diff
103
log_manager/log_manager.h
Normal file
103
log_manager/log_manager.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2013
|
||||
*/
|
||||
|
||||
|
||||
typedef struct filewriter_st filewriter_t;
|
||||
typedef struct logfile_st logfile_t;
|
||||
typedef struct fnames_conf_st fnames_conf_t;
|
||||
typedef struct logmanager_st logmanager_t;
|
||||
|
||||
typedef enum {
|
||||
LOGFILE_TRACE = 0,
|
||||
LOGFILE_FIRST = LOGFILE_TRACE,
|
||||
LOGFILE_MESSAGE,
|
||||
LOGFILE_ERROR,
|
||||
LOGFILE_LAST = LOGFILE_ERROR
|
||||
} logfile_id_t;
|
||||
|
||||
typedef enum { FILEWRITER_INIT, FILEWRITER_RUN, FILEWRITER_DONE }
|
||||
filewriter_state_t;
|
||||
typedef enum { LOGFILE_INIT, LOGFILE_OPENED, LOGFILE_DONE } logfile_state_t;
|
||||
|
||||
/**
|
||||
* UNINIT means zeroed memory buffer allocated for the struct.
|
||||
* INIT means that struct members may have values, and memory may
|
||||
* have been allocated. Done function must check and free it.
|
||||
* RUN Struct is valid for run-time checking.
|
||||
* DONE means that possible memory allocations have been released.
|
||||
*/
|
||||
typedef enum { UNINIT = 0, INIT, RUN, DONE } flat_obj_state_t;
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
bool skygw_logmanager_init(void** buf, int argc, char* argv[]);
|
||||
void skygw_logmanager_done(void** buf);
|
||||
void skygw_logmanager_exit(void);
|
||||
/** not implemented yet */
|
||||
/**
|
||||
* init write buffer list for private use for this client. Same as
|
||||
* skygw_logmanager_init except that arguments are not set.
|
||||
*/
|
||||
bool skygw_log_init(void** writebuf);
|
||||
/**
|
||||
* free private write buffer list
|
||||
*/
|
||||
void skygw_log_done(void* writebuf);
|
||||
int skygw_log_write(void* writebuf, logfile_id_t id, char* format, ...);
|
||||
int skygw_log_flush(logfile_id_t id);
|
||||
int skygw_log_write_flush(void* writebuf, logfile_id_t id, char* format, ...);
|
||||
|
||||
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
void writebuf_clear(void* data);
|
||||
|
||||
const char* get_trace_prefix_default(void);
|
||||
const char* get_trace_suffix_default(void);
|
||||
const char* get_msg_prefix_default(void);
|
||||
const char* get_msg_suffix_default(void);
|
||||
const char* get_err_prefix_default(void);
|
||||
const char* get_err_suffix_default(void);
|
||||
const char* get_logpath_default(void);
|
||||
|
||||
/*
|
||||
bool logfile_write(
|
||||
skygw_ctx_t* ctx,
|
||||
logmgr_t* mgr,
|
||||
logfile_id_t id,
|
||||
char* msg);
|
||||
|
||||
bool logfile_write_flush(
|
||||
skygw_ctx_t* ctx,
|
||||
logmgr_t* mgr,
|
||||
logfile_id_t id,
|
||||
char* msg);
|
||||
|
||||
bool logfile_flush(
|
||||
logmgr_t* mgr,
|
||||
logfile_id_t id);
|
||||
|
||||
bool logfile_init(
|
||||
logmgr_t* mgr,
|
||||
logfile_id_t id);
|
||||
|
||||
void logfile_done(
|
||||
logmgr_t* mgr,
|
||||
logfile_id_t id);
|
||||
*/
|
53
log_manager/makefile
Normal file
53
log_manager/makefile
Normal file
@ -0,0 +1,53 @@
|
||||
include ../build_gateway.inc
|
||||
include ../makefile.inc
|
||||
|
||||
CC = gcc
|
||||
CPP = g++
|
||||
|
||||
SRCS = log_manager.cc
|
||||
|
||||
LOG_WRITER_PATH := $(shell pwd)
|
||||
|
||||
makeall: clean all
|
||||
|
||||
clean:
|
||||
make -C ../utils clean
|
||||
- $(DEL) *.o
|
||||
- $(DEL) *.so
|
||||
- $(DEL) *.so.1.0.1
|
||||
- $(DEL) *~
|
||||
- $(DEL) depend
|
||||
|
||||
all: utils lib
|
||||
|
||||
utils:
|
||||
make -C $(ROOT_PATH)/utils clean all
|
||||
$(COPY) $(ROOT_PATH)/utils/skygw_utils.o ./
|
||||
|
||||
lib: libcomp liblink
|
||||
|
||||
libcomp:
|
||||
$(CPP) -c $(CFLAGS) \
|
||||
-I$(MARIADB_SRC_PATH)/include/ \
|
||||
-I../utils/ -I./ \
|
||||
-fPIC ./log_manager.cc -o log_manager.o $(LDLIBS)
|
||||
|
||||
liblink:
|
||||
$(CPP) -shared \
|
||||
-Wl,-soname,liblog_manager.so \
|
||||
-o liblog_manager.so.1.0.1 log_manager.o \
|
||||
$(LDLIBS) $(CPP_LDLIBS)
|
||||
$(DEL) ./liblog_manager.so
|
||||
$(LINK) ./liblog_manager.so.1.0.1 ./liblog_manager.so
|
||||
|
||||
install: liblink
|
||||
install liblog_manager.so.1.0.1 liblog_manager.so $(DEST)/lib
|
||||
|
||||
depend:
|
||||
@rm -f depend
|
||||
$(CPP) -M $(CFLAGS) \
|
||||
-I$(MARIADB_SRC_PATH)/include/ \
|
||||
-I../utils/ -I./ \
|
||||
$(SRCS) > depend
|
||||
|
||||
include depend
|
36
log_manager/test/makefile
Normal file
36
log_manager/test/makefile
Normal file
@ -0,0 +1,36 @@
|
||||
include ../../build_gateway.inc
|
||||
include ../../makefile.inc
|
||||
|
||||
CC = gcc
|
||||
CPP = g++
|
||||
|
||||
TESTPATH := $(shell pwd)
|
||||
LOG_MANAGER_PATH := $(ROOT_PATH)/log_manager
|
||||
TESTAPP = $(TESTPATH)/testlog
|
||||
|
||||
runtest: makeall testall
|
||||
|
||||
makeall: clean all
|
||||
|
||||
clean:
|
||||
- $(DEL) *.o
|
||||
- $(DEL) testlog
|
||||
- $(DEL) *~
|
||||
|
||||
all: testcomp testall
|
||||
|
||||
testcomp:
|
||||
$(CC) $(CFLAGS) \
|
||||
-L$(LOG_MANAGER_PATH) \
|
||||
-Wl,-rpath,$(DEST)/lib \
|
||||
-Wl,-rpath,$(LOG_MANAGER_PATH)/ \
|
||||
-o testlog -DSS_DEBUG \
|
||||
-I$(SOLIDDB_SRC_PATH)/include \
|
||||
-I$(MARIADB_SRC_PATH)/include \
|
||||
-I$(LOG_MANAGER_PATH) -I$(ROOT_PATH)/utils testlog.c \
|
||||
-llog_manager $(LDLIBS) \
|
||||
$(LOG_MANAGER_PATH)/skygw_utils.o \
|
||||
|
||||
|
||||
testall:
|
||||
- $(LAUNCH_DEBUGGER) $(TESTAPP) $(BACKGR)
|
369
log_manager/test/testlog.c
Normal file
369
log_manager/test/testlog.c
Normal file
@ -0,0 +1,369 @@
|
||||
/*
|
||||
* This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2013
|
||||
*/
|
||||
|
||||
|
||||
/** @file
|
||||
@brief (brief description)
|
||||
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
|
||||
typedef struct thread_st {
|
||||
skygw_message_t* mes;
|
||||
simple_mutex_t* mtx;
|
||||
size_t* nactive;
|
||||
pthread_t tid;
|
||||
} thread_t;
|
||||
|
||||
static void* thr_run(void* data);
|
||||
static void* thr_run_morelog(void* data);
|
||||
|
||||
#define NTHR 256
|
||||
#define NITER 100
|
||||
|
||||
#if 0
|
||||
#define TEST1
|
||||
#define TEST2
|
||||
#endif
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int err = 0;
|
||||
char* logstr;
|
||||
|
||||
int i;
|
||||
bool r;
|
||||
skygw_message_t* mes;
|
||||
simple_mutex_t* mtx;
|
||||
size_t nactive;
|
||||
thread_t* thr[NTHR];
|
||||
time_t t;
|
||||
struct tm tm;
|
||||
|
||||
i = atexit(skygw_logmanager_exit);
|
||||
|
||||
if (i != 0) {
|
||||
fprintf(stderr, "Couldn't register exit function.\n");
|
||||
}
|
||||
|
||||
r = skygw_logmanager_init(NULL, argc, argv);
|
||||
ss_dassert(r);
|
||||
|
||||
t = time(NULL);
|
||||
tm = *(localtime(&t));
|
||||
err = skygw_log_write_flush(NULL,
|
||||
LOGFILE_ERROR,
|
||||
"%04d %02d/%02d %02d.%02d.%02d",
|
||||
tm.tm_year+1900,
|
||||
tm.tm_mon+1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
|
||||
skygw_logmanager_init(NULL, argc, argv);
|
||||
logstr = ("First write with flush.");
|
||||
err = skygw_log_write_flush(NULL, LOGFILE_ERROR, logstr);
|
||||
|
||||
logstr = ("Second write with flush.");
|
||||
err = skygw_log_write_flush(NULL, LOGFILE_ERROR, logstr);
|
||||
|
||||
logstr = ("Third write, no flush.");
|
||||
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
|
||||
|
||||
logstr = ("Fourth write, no flush. Next flush only.");
|
||||
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
|
||||
|
||||
err = skygw_log_flush(LOGFILE_ERROR);
|
||||
|
||||
logstr = "My name is %s %d years and %d months.";
|
||||
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr, "TraceyTracey", 3, 7);
|
||||
skygw_log_flush(LOGFILE_TRACE);
|
||||
|
||||
logstr = "My name is Tracey Tracey 47 years and 7 months.";
|
||||
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
|
||||
|
||||
logstr = "My name is Stacey %s";
|
||||
err = skygw_log_write_flush(NULL, LOGFILE_TRACE, logstr, " ");
|
||||
skygw_logmanager_done(NULL);
|
||||
|
||||
logstr = "My name is Philip";
|
||||
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
|
||||
|
||||
logstr = "Philip.";
|
||||
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
|
||||
|
||||
logstr = "Ph%dlip.";
|
||||
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr, 1);
|
||||
|
||||
skygw_logmanager_init(NULL, argc, argv);
|
||||
logstr = ("A terrible error has occurred!");
|
||||
err = skygw_log_write_flush(NULL, LOGFILE_ERROR, logstr);
|
||||
|
||||
logstr = ("Hi, how are you?");
|
||||
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
|
||||
|
||||
logstr = ("I'm doing fine!");
|
||||
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
|
||||
|
||||
logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) immediately; the two forms are equivalent. Applying the operators & to both parts of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the address of the i-th element beyond a.");
|
||||
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
|
||||
|
||||
logstr = ("I was wondering, you know, it has been such a lovely weather whole morning and I thought that would you like to come to my place and have a little piece of cheese with us. Just me and my mom - and you, of course. Then, if you wish, we could listen to the radio and keep company for our little Steven, my mom's cat, you know.");
|
||||
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
|
||||
skygw_logmanager_done(NULL);
|
||||
|
||||
#if defined(TEST1)
|
||||
|
||||
mes = skygw_message_init();
|
||||
mtx = simple_mutex_init(NULL, strdup("testmtx"));
|
||||
/** Test starts */
|
||||
|
||||
fprintf(stderr, "\nStarting test #1 \n");
|
||||
|
||||
/** 1 */
|
||||
for (i=0; i<NTHR; i++) {
|
||||
thr[i] = (thread_t*)calloc(1, sizeof(thread_t));
|
||||
thr[i]->mes = mes;
|
||||
thr[i]->mtx = mtx;
|
||||
thr[i]->nactive = &nactive;
|
||||
}
|
||||
nactive = NTHR;
|
||||
|
||||
for (i=0; i<NTHR; i++) {
|
||||
pthread_t p;
|
||||
pthread_create(&p, NULL, thr_run, thr[i]);
|
||||
thr[i]->tid = p;
|
||||
}
|
||||
|
||||
do {
|
||||
skygw_message_wait(mes);
|
||||
simple_mutex_lock(mtx, TRUE);
|
||||
if (nactive > 0) {
|
||||
simple_mutex_unlock(mtx);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} while(TRUE);
|
||||
|
||||
for (i=0; i<NTHR; i++) {
|
||||
pthread_join(thr[i]->tid, NULL);
|
||||
}
|
||||
/** This is to release memory */
|
||||
skygw_logmanager_done(NULL);
|
||||
|
||||
simple_mutex_unlock(mtx);
|
||||
|
||||
for (i=0; i<NTHR; i++) {
|
||||
free(thr[i]);
|
||||
}
|
||||
#endif
|
||||
#if defined(TEST2)
|
||||
fprintf(stderr, "\nStarting test #2 \n");
|
||||
|
||||
/** 2 */
|
||||
for (i=0; i<NTHR; i++) {
|
||||
thr[i] = (thread_t*)calloc(1, sizeof(thread_t));
|
||||
thr[i]->mes = mes;
|
||||
thr[i]->mtx = mtx;
|
||||
thr[i]->nactive = &nactive;
|
||||
}
|
||||
nactive = NTHR;
|
||||
|
||||
fprintf(stderr,
|
||||
"\nLaunching %d threads, each iterating %d times.",
|
||||
NTHR,
|
||||
NITER);
|
||||
|
||||
for (i=0; i<NTHR; i++) {
|
||||
pthread_t p;
|
||||
pthread_create(&p, NULL, thr_run_morelog, thr[i]);
|
||||
thr[i]->tid = p;
|
||||
}
|
||||
|
||||
fprintf(stderr, ".. done");
|
||||
|
||||
fprintf(stderr, "\nStarting to wait threads.\n");
|
||||
|
||||
do {
|
||||
skygw_message_wait(mes);
|
||||
simple_mutex_lock(mtx, TRUE);
|
||||
if (nactive > 0) {
|
||||
simple_mutex_unlock(mtx);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} while(TRUE);
|
||||
|
||||
for (i=0; i<NTHR; i++) {
|
||||
pthread_join(thr[i]->tid, NULL);
|
||||
}
|
||||
/** This is to release memory */
|
||||
skygw_logmanager_done(NULL);
|
||||
|
||||
simple_mutex_unlock(mtx);
|
||||
|
||||
fprintf(stderr, "\nFreeing thread memory.");
|
||||
|
||||
for (i=0; i<NTHR; i++) {
|
||||
free(thr[i]);
|
||||
}
|
||||
|
||||
/** Test ended here */
|
||||
skygw_message_done(mes);
|
||||
simple_mutex_done(mtx);
|
||||
#endif
|
||||
fprintf(stderr, ".. done.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void* thr_run(
|
||||
void* data)
|
||||
{
|
||||
thread_t* td = (thread_t *)data;
|
||||
char* logstr;
|
||||
int err;
|
||||
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
skygw_logmanager_done(NULL);
|
||||
skygw_log_flush(LOGFILE_MESSAGE);
|
||||
logstr = ("Hi, how are you?");
|
||||
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_done(NULL);
|
||||
skygw_log_flush(LOGFILE_TRACE);
|
||||
skygw_log_flush(LOGFILE_MESSAGE);
|
||||
logstr = ("I was wondering, you know, it has been such a lovely weather whole morning and I thought that would you like to come to my place and have a little piece of cheese with us. Just me and my mom - and you, of course. Then, if you wish, we could listen to the radio and keep company for our little Steven, my mom's cat, you know.");
|
||||
ss_dassert(err == 0);
|
||||
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
logstr = ("Testing. One, two, three\n");
|
||||
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
skygw_log_flush(LOGFILE_ERROR);
|
||||
logstr = ("For automatic and register variables, it is done each time the function or block is entered.");
|
||||
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_done(NULL);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) immediately; the two forms are equivalent. Applying the operatos & to both parts of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the address of the i-th element beyond a.");
|
||||
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
skygw_logmanager_done(NULL);
|
||||
skygw_log_flush(LOGFILE_ERROR);
|
||||
skygw_logmanager_done(NULL);
|
||||
skygw_logmanager_done(NULL);
|
||||
logstr = ("..and you?");
|
||||
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
logstr = ("For automatic and register variables, it is done each time the function or block is entered.");
|
||||
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) immediately; the two forms are equivalent. Applying the operatos & to both parts of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the address of the i-th element beyond a.");
|
||||
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
logstr = ("..... and you too?");
|
||||
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_done(NULL);
|
||||
skygw_log_flush(LOGFILE_TRACE);
|
||||
logstr = ("For automatic and register variables, it is done each time the function or block is entered.");
|
||||
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_done(NULL);
|
||||
logstr = ("Testing. One, two, three, four\n");
|
||||
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
logstr = ("Testing. One, two, three, .. where was I?\n");
|
||||
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
|
||||
ss_dassert(err == 0);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
skygw_logmanager_init(NULL, 0, NULL);
|
||||
skygw_logmanager_done(NULL);
|
||||
simple_mutex_lock(td->mtx, TRUE);
|
||||
*td->nactive -= 1;
|
||||
simple_mutex_unlock(td->mtx);
|
||||
skygw_message_send(td->mes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int nstr(
|
||||
char** str_arr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; str_arr[i] != NULL; i++) {
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
char* logs[] = {
|
||||
"foo",
|
||||
"bar",
|
||||
"done",
|
||||
"critical test logging",
|
||||
"longer test l o g g g i n g",
|
||||
"reeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeally loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line",
|
||||
"shoorter one",
|
||||
"two",
|
||||
"scrap : 834nuft984pnw8ynup4598yp8wup8upwn48t5gpn45",
|
||||
"more the same : f98uft5p8ut2p44449upnt5",
|
||||
"asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd98987",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void* thr_run_morelog(
|
||||
void* data)
|
||||
{
|
||||
thread_t* td = (thread_t *)data;
|
||||
char* logstr;
|
||||
int err;
|
||||
int i;
|
||||
int nmsg;
|
||||
|
||||
nmsg = nstr(logs);
|
||||
|
||||
for (i=0; i<NITER; i++) {
|
||||
char* str = logs[rand()%nmsg];
|
||||
err = skygw_log_write(NULL,
|
||||
(logfile_id_t)(rand()%(LOGFILE_LAST+1)),
|
||||
"%s - iteration # %d",
|
||||
str,
|
||||
i);
|
||||
}
|
||||
simple_mutex_lock(td->mtx, TRUE);
|
||||
*td->nactive -= 1;
|
||||
simple_mutex_unlock(td->mtx);
|
||||
skygw_message_send(td->mes);
|
||||
return NULL;
|
||||
}
|
48
makefile.inc
Normal file
48
makefile.inc
Normal file
@ -0,0 +1,48 @@
|
||||
#
|
||||
# This file is static. It handles the dynamic content of build.inc,
|
||||
# for example, by setting compiler flags etc.
|
||||
|
||||
# Changes to environment, such as building directories etc. are made to
|
||||
# build_gateway.inc.
|
||||
# A template file build_gateway_l2x64.inc is stored in directory 'config'.
|
||||
# Template can't be used as such, but hopefully only little modifications are
|
||||
# needed, such as setting build directory etc.
|
||||
#
|
||||
|
||||
#ifdef UNIX
|
||||
DEL := rm -f
|
||||
LINK := ln -s
|
||||
COPY := cp
|
||||
NOHUP := nohup
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGGER
|
||||
BACKGR := >> /dev/null &
|
||||
#else
|
||||
BACKGR :=
|
||||
#endif
|
||||
|
||||
CFLAGS := $(CFLAGS) -Wall
|
||||
LDLIBS := $(LDLIBS) -pthread
|
||||
LDMYSQL := -lmysqld
|
||||
CPP_LDLIBS := -lstdc++
|
||||
|
||||
#
|
||||
# Compiler flags, httpd arguments and debugger options
|
||||
#
|
||||
ifdef DEBUG
|
||||
DEBUG_FLAGS := -DSS_DEBUG
|
||||
CFLAGS := $(CFLAGS) -ggdb -O0 -pthread $(DEBUG_FLAGS)
|
||||
endif
|
||||
|
||||
ifdef PROF
|
||||
CFLAGS := $(CFLAGS) -DSS_PROF
|
||||
endif
|
||||
|
||||
ifdef DEBUGGER
|
||||
DEBUG := Y
|
||||
LAUNCH_DEBUGGER := $(NOHUP) $(DEBUGGER_PATH)/$(DEBUGGER_BIN) \
|
||||
$(DEBUGGER_PARAMS)
|
||||
else
|
||||
LAUNCH_DEBUGGER :=
|
||||
endif
|
0
protocol_1.0/.deps
Normal file
0
protocol_1.0/.deps
Normal file
50
protocol_1.0/Makefile
Normal file
50
protocol_1.0/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
##
|
||||
## Makefile -- Build procedure for sample skysql Apache module
|
||||
## Autogenerated via ``apxs -n skysql -g''.
|
||||
##
|
||||
|
||||
builddir=.
|
||||
top_srcdir=/packages/inst/apache_2.4.2
|
||||
top_builddir=/packages/inst/apache_2.4.2
|
||||
include /packages/inst/apache_2.4.2/build/special.mk
|
||||
|
||||
# the used tools
|
||||
APXS=apxs
|
||||
APACHECTL=apachectl
|
||||
|
||||
# additional defines, includes and libraries
|
||||
#DEFS=-Dmy_define=my_value
|
||||
|
||||
#INCLUDES=
|
||||
|
||||
#LIBS=-lskysqlclient -lmysqlcompat
|
||||
|
||||
#LDFLAGS=
|
||||
|
||||
# the default target
|
||||
all: local-shared-build
|
||||
|
||||
# install the shared object file into Apache
|
||||
install: install-modules-yes
|
||||
|
||||
# cleanup
|
||||
clean:
|
||||
-rm -f mod_skysql.o mod_skysql.lo mod_skysql.slo mod_skysql.la skysql_utils.o skysql_utils.lo skysql_utils.slo skysql_utils.la
|
||||
|
||||
# simple test
|
||||
test: reload
|
||||
lynx -mime_header http://localhost/skysql
|
||||
|
||||
# install and activate shared object by reloading Apache to
|
||||
# force a reload of the shared object file
|
||||
reload: install restart
|
||||
|
||||
# the general Apache start/restart/stop
|
||||
# procedures
|
||||
start:
|
||||
$(APACHECTL) start
|
||||
restart:
|
||||
$(APACHECTL) restart
|
||||
stop:
|
||||
$(APACHECTL) stop
|
||||
|
20
protocol_1.0/README
Normal file
20
protocol_1.0/README
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Copyright SkySQL Ab
|
||||
|
||||
*/
|
||||
|
||||
Apache 2.4.2
|
27
protocol_1.0/gateway.conf
Normal file
27
protocol_1.0/gateway.conf
Normal file
@ -0,0 +1,27 @@
|
||||
#Apache 2.4.2 configuration
|
||||
|
||||
########################
|
||||
# The Mysql protocol enabled in the main server
|
||||
#
|
||||
AcceptFilter http httpready
|
||||
AcceptFilter mysqld none
|
||||
|
||||
LoadModule skysql_module modules/mod_skysql.so
|
||||
|
||||
Listen 4402 mysqld
|
||||
|
||||
Timeout 300
|
||||
SkySQLProtocol On
|
||||
SkySQLPool Off
|
||||
SkySQLSingleDBbresource "Master/Slaves" "127.0.0.1:3306,127.0.0.1:3307,127.0.0.1:3308;test"
|
||||
SkySQLTimeout 300
|
||||
|
||||
<VirtualHost *:81>
|
||||
## HTTP on port 81, in this virtual host
|
||||
SkySQLProtocol Off
|
||||
<Location /skycc>
|
||||
SetHandler skysql
|
||||
</Location>
|
||||
</VirtualHost>
|
||||
|
||||
########################
|
2
protocol_1.0/live_config.txt
Normal file
2
protocol_1.0/live_config.txt
Normal file
@ -0,0 +1,2 @@
|
||||
curl 'http://127.0.0.1:81/skycc?show=1'
|
||||
curl 'http://127.0.0.1:81/skycc?update=127.0.0.1:3306,127.0.0.1:3307,127.0.0.1:3308'
|
1490
protocol_1.0/mod_skysql.c
Normal file
1490
protocol_1.0/mod_skysql.c
Normal file
File diff suppressed because it is too large
Load Diff
4
protocol_1.0/modules.mk
Normal file
4
protocol_1.0/modules.mk
Normal file
@ -0,0 +1,4 @@
|
||||
mod_skysql.la: mod_skysql.slo skysql_utils.slo skysql_backend.slo
|
||||
$(SH_LINK) -rpath $(libexecdir) -module -avoid-version mod_skysql.lo skysql_utils.lo skysql_backend.lo
|
||||
DISTCLEAN_TARGETS = modules.mk
|
||||
shared = mod_skysql.la
|
143
protocol_1.0/skysql_backend.c
Normal file
143
protocol_1.0/skysql_backend.c
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Copyright SkySQL Ab
|
||||
|
||||
*/
|
||||
|
||||
////////////////////////////////////////
|
||||
// SKYSQL Backend
|
||||
// By Massimiliano Pinto 2012/2013
|
||||
////////////////////////////////////////
|
||||
|
||||
#include "skysql_gw.h"
|
||||
|
||||
int skysql_ext_file_ver(void) {
|
||||
int ret = 13;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// The function takes the server list,
|
||||
// find the total server number
|
||||
// and return a random selection for slaves (from total -1)
|
||||
//////////////////////////////////////////////////////////////
|
||||
int select_random_slave_server(const char *server_list, int *num_slaves) {
|
||||
int nslaves = 0;
|
||||
int random_balancer = 0;
|
||||
char *p = (char *)server_list;
|
||||
while( (p = strchr(p, ',')) != NULL) {
|
||||
p++;
|
||||
nslaves++;
|
||||
}
|
||||
|
||||
memcpy(num_slaves, &nslaves, sizeof(int));
|
||||
|
||||
if (nslaves == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// random selection
|
||||
random_balancer = (int) ((nslaves+1) * (rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
return random_balancer;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// This takes a server from the list
|
||||
// index 0 is always the Master
|
||||
// the others refer to the salve,
|
||||
// the slave number comes from: select_random_slave_server()
|
||||
///////////////////////////////////////////////////////////////
|
||||
int get_server_from_list(char **selected_host, int *selected_port, char *server_list, int num, apr_pool_t *p) {
|
||||
int ret = -1;
|
||||
int curr_srv = 0;
|
||||
char *next = NULL;
|
||||
char *tmp = NULL;
|
||||
int port;
|
||||
|
||||
if (num == 0) {
|
||||
port = atoi(strchr(server_list, ':') + 1), sizeof(port);
|
||||
memcpy(selected_port, &port, sizeof(int));
|
||||
*selected_host = apr_pstrndup(p, server_list, strchr(server_list, ':') - server_list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
next = server_list;
|
||||
|
||||
while (curr_srv < num) {
|
||||
|
||||
tmp = strchr(next, ',');
|
||||
if (tmp != NULL) {
|
||||
curr_srv++;
|
||||
next = tmp+1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (curr_srv == num) {
|
||||
port = atoi(strchr(next, ':') + 1);
|
||||
|
||||
memcpy(selected_port, &port, sizeof(port));
|
||||
|
||||
// the host string must be allocated in the memory pool!
|
||||
*selected_host = apr_pstrndup(p, next, strchr(next, ':') - next);
|
||||
ret = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// This funcion take the master from the list
|
||||
// The index is always 0
|
||||
//////////////////////////////////////////////
|
||||
int get_master_from_list(char **selected_host, int *selected_port, char *server_list, apr_pool_t *p) {
|
||||
int ret = -1;
|
||||
int curr_srv = 0;
|
||||
char *next = NULL;
|
||||
char *tmp = NULL;
|
||||
int port;
|
||||
|
||||
port = atoi(strchr(server_list, ':') + 1), sizeof(port);
|
||||
memcpy(selected_port, &port, sizeof(int));
|
||||
|
||||
// the host string must be allocated in the memory pool!
|
||||
*selected_host = apr_pstrndup(p, server_list, strchr(server_list, ':') - server_list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Query Routing basic implementation
|
||||
///////////////////////////////////////
|
||||
|
||||
int query_routing(const char *server_list, const char *sql_command, int procotol_command, int current_slave) {
|
||||
|
||||
if (strstr(sql_command, "select ")) {
|
||||
// to the slave
|
||||
return SKYSQL_READ;
|
||||
} else {
|
||||
// to the master
|
||||
return SKYSQL_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////
|
169
protocol_1.0/skysql_client.h
Normal file
169
protocol_1.0/skysql_client.h
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Copyright SkySQL Ab
|
||||
|
||||
*/
|
||||
|
||||
////////////////////////////////////////
|
||||
// SKYSQL mysql protocol header file
|
||||
// By Massimiliano Pinto 2012/2013
|
||||
////////////////////////////////////////
|
||||
|
||||
#include "ap_config.h"
|
||||
#include "ap_mmn.h"
|
||||
#include "httpd.h"
|
||||
#include "http_core.h"
|
||||
#include "http_main.h"
|
||||
#include "http_config.h"
|
||||
#include "http_connection.h"
|
||||
#include "http_request.h"
|
||||
#include "http_log.h"
|
||||
#include "http_protocol.h"
|
||||
#include "ap_config_auto.h"
|
||||
#include "http_connection.h"
|
||||
|
||||
#include "util_filter.h"
|
||||
#include "util_script.h"
|
||||
#include "apr.h"
|
||||
#include "apr_general.h"
|
||||
#include "apr_buckets.h"
|
||||
#include "apr_optional.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_tables.h"
|
||||
#include "apr_lib.h"
|
||||
#include "apr_fnmatch.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_dbm.h"
|
||||
#include "apr_rmm.h"
|
||||
#include "apr_shm.h"
|
||||
#include "apr_global_mutex.h"
|
||||
#include "apr_time.h"
|
||||
#include "scoreboard.h"
|
||||
|
||||
// sha1
|
||||
#include "apr_sha1.h"
|
||||
|
||||
// getpid
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
/* Protocol packing macros. */
|
||||
#define skysql_set_byte2(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); } while (0)
|
||||
#define skysql_set_byte3(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); \
|
||||
(__buffer)[2]= (uint8_t)(((__int) >> 16) & 0xFF); } while (0)
|
||||
#define skysql_set_byte4(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); \
|
||||
(__buffer)[2]= (uint8_t)(((__int) >> 16) & 0xFF); \
|
||||
(__buffer)[3]= (uint8_t)(((__int) >> 24) & 0xFF); } while (0)
|
||||
|
||||
|
||||
/* Protocol unpacking macros. */
|
||||
#define skysql_get_byte2(__buffer) \
|
||||
(uint16_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8))
|
||||
#define skysql_get_byte3(__buffer) \
|
||||
(uint32_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8) | \
|
||||
((__buffer)[2] << 16))
|
||||
#define skysql_get_byte4(__buffer) \
|
||||
(uint32_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8) | \
|
||||
((__buffer)[2] << 16) | \
|
||||
((__buffer)[3] << 24))
|
||||
#define skysql_get_byte8(__buffer) \
|
||||
((uint64_t)(__buffer)[0] | \
|
||||
((uint64_t)(__buffer)[1] << 8) | \
|
||||
((uint64_t)(__buffer)[2] << 16) | \
|
||||
((uint64_t)(__buffer)[3] << 24) | \
|
||||
((uint64_t)(__buffer)[4] << 32) | \
|
||||
((uint64_t)(__buffer)[5] << 40) | \
|
||||
((uint64_t)(__buffer)[6] << 48) | \
|
||||
((uint64_t)(__buffer)[7] << 56))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SKYSQL_CAPABILITIES_NONE= 0,
|
||||
SKYSQL_CAPABILITIES_LONG_PASSWORD= (1 << 0),
|
||||
SKYSQL_CAPABILITIES_FOUND_ROWS= (1 << 1),
|
||||
SKYSQL_CAPABILITIES_LONG_FLAG= (1 << 2),
|
||||
SKYSQL_CAPABILITIES_CONNECT_WITH_DB= (1 << 3),
|
||||
SKYSQL_CAPABILITIES_NO_SCHEMA= (1 << 4),
|
||||
SKYSQL_CAPABILITIES_COMPRESS= (1 << 5),
|
||||
SKYSQL_CAPABILITIES_ODBC= (1 << 6),
|
||||
SKYSQL_CAPABILITIES_LOCAL_FILES= (1 << 7),
|
||||
SKYSQL_CAPABILITIES_IGNORE_SPACE= (1 << 8),
|
||||
SKYSQL_CAPABILITIES_PROTOCOL_41= (1 << 9),
|
||||
SKYSQL_CAPABILITIES_INTERACTIVE= (1 << 10),
|
||||
SKYSQL_CAPABILITIES_SSL= (1 << 11),
|
||||
SKYSQL_CAPABILITIES_IGNORE_SIGPIPE= (1 << 12),
|
||||
SKYSQL_CAPABILITIES_TRANSACTIONS= (1 << 13),
|
||||
SKYSQL_CAPABILITIES_RESERVED= (1 << 14),
|
||||
SKYSQL_CAPABILITIES_SECURE_CONNECTION= (1 << 15),
|
||||
SKYSQL_CAPABILITIES_MULTI_STATEMENTS= (1 << 16),
|
||||
SKYSQL_CAPABILITIES_MULTI_RESULTS= (1 << 17),
|
||||
SKYSQL_CAPABILITIES_PS_MULTI_RESULTS= (1 << 18),
|
||||
SKYSQL_CAPABILITIES_PLUGIN_AUTH= (1 << 19),
|
||||
SKYSQL_CAPABILITIES_SSL_VERIFY_SERVER_CERT= (1 << 30),
|
||||
SKYSQL_CAPABILITIES_REMEMBER_OPTIONS= (1 << 31),
|
||||
SKYSQL_CAPABILITIES_CLIENT= (SKYSQL_CAPABILITIES_LONG_PASSWORD |
|
||||
SKYSQL_CAPABILITIES_FOUND_ROWS |
|
||||
SKYSQL_CAPABILITIES_LONG_FLAG |
|
||||
SKYSQL_CAPABILITIES_CONNECT_WITH_DB |
|
||||
SKYSQL_CAPABILITIES_LOCAL_FILES |
|
||||
SKYSQL_CAPABILITIES_PLUGIN_AUTH |
|
||||
SKYSQL_CAPABILITIES_TRANSACTIONS |
|
||||
SKYSQL_CAPABILITIES_PROTOCOL_41 |
|
||||
SKYSQL_CAPABILITIES_MULTI_STATEMENTS |
|
||||
SKYSQL_CAPABILITIES_MULTI_RESULTS |
|
||||
SKYSQL_CAPABILITIES_PS_MULTI_RESULTS |
|
||||
SKYSQL_CAPABILITIES_SECURE_CONNECTION),
|
||||
SKYSQL_CAPABILITIES_CLIENT_COMPRESS= (SKYSQL_CAPABILITIES_LONG_PASSWORD |
|
||||
SKYSQL_CAPABILITIES_FOUND_ROWS |
|
||||
SKYSQL_CAPABILITIES_LONG_FLAG |
|
||||
SKYSQL_CAPABILITIES_CONNECT_WITH_DB |
|
||||
SKYSQL_CAPABILITIES_LOCAL_FILES |
|
||||
SKYSQL_CAPABILITIES_PLUGIN_AUTH |
|
||||
SKYSQL_CAPABILITIES_TRANSACTIONS |
|
||||
SKYSQL_CAPABILITIES_PROTOCOL_41 |
|
||||
SKYSQL_CAPABILITIES_MULTI_STATEMENTS |
|
||||
SKYSQL_CAPABILITIES_MULTI_RESULTS |
|
||||
SKYSQL_CAPABILITIES_PS_MULTI_RESULTS |
|
||||
SKYSQL_CAPABILITIES_COMPRESS
|
||||
),
|
||||
} skysql_capabilities_t;
|
||||
|
||||
|
||||
#define SMALL_CHUNK 1024
|
||||
#define MAX_CHUNK SMALL_CHUNK * 8 * 4
|
||||
#define ToHex(Y) (Y>='0'&&Y<='9'?Y-'0':Y-'A'+10)
|
||||
|
||||
#define MYSQL_CONN_DEBUG
|
||||
#undef MYSQL_CONN_DEBUG
|
||||
|
||||
typedef struct {
|
||||
apr_socket_t *socket;
|
||||
char scramble[33];
|
||||
uint32_t server_capabs;
|
||||
uint32_t client_capabs;
|
||||
unsigned long tid;
|
||||
apr_pool_t *pool;
|
||||
} MYSQL_conn;
|
||||
|
161
protocol_1.0/skysql_gw.h
Normal file
161
protocol_1.0/skysql_gw.h
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Copyright SkySQL Ab
|
||||
|
||||
*/
|
||||
|
||||
////////////////////////////////////////
|
||||
// SKYSQL header file
|
||||
// By Massimiliano Pinto 2012/2013
|
||||
////////////////////////////////////////
|
||||
|
||||
#include "ap_config.h"
|
||||
#include "ap_mmn.h"
|
||||
#include "httpd.h"
|
||||
#include "http_core.h"
|
||||
#include "http_main.h"
|
||||
#include "http_config.h"
|
||||
#include "http_connection.h"
|
||||
#include "http_request.h"
|
||||
#include "http_log.h"
|
||||
#include "http_protocol.h"
|
||||
#include "ap_config_auto.h"
|
||||
#include "http_connection.h"
|
||||
|
||||
#include "util_filter.h"
|
||||
#include "util_script.h"
|
||||
#include "apr.h"
|
||||
#include "apr_general.h"
|
||||
#include "apr_buckets.h"
|
||||
#include "apr_optional.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_tables.h"
|
||||
#include "apr_lib.h"
|
||||
#include "apr_fnmatch.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_dbm.h"
|
||||
#include "apr_rmm.h"
|
||||
#include "apr_shm.h"
|
||||
#include "apr_global_mutex.h"
|
||||
#include "apr_time.h"
|
||||
#include "scoreboard.h"
|
||||
|
||||
// getpid
|
||||
#include <unistd.h>
|
||||
|
||||
// mapped I/O
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "skysql_client.h"
|
||||
|
||||
#define SKYSQL_GATEWAY_VERSION "0.0.1"
|
||||
#define SKYSQL_VERSION "5.5.22-SKY-1.6.5"
|
||||
|
||||
#define SKYSQL_READ 0
|
||||
#define SKYSQL_WRITE 1
|
||||
|
||||
#define HTTP_WELCOME_MESSAGE "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Type: text/plain\r\n\r\nSKYSQL Gateway " SKYSQL_GATEWAY_VERSION
|
||||
|
||||
#define SKYSQL_LISTENER_VERSION "MySQL Community Server (GPL)"
|
||||
#define SKYSQL_PROTOCOL_VERSION 10 // version is 10
|
||||
#define SKYSQL_THREAD_ID 11
|
||||
#define SKYSQL_HANDSKAKE_FILLER 0x00
|
||||
#define SKYSQL_SERVER_CAPABILITIES_BYTE1 0xff
|
||||
#define SKYSQL_SERVER_CAPABILITIES_BYTE2 0xf7
|
||||
#define SKYSQL_SERVER_LANGUAGE 0x08
|
||||
|
||||
module AP_MODULE_DECLARE_DATA skysql_module;
|
||||
|
||||
static unsigned char *config_area=NULL;
|
||||
|
||||
//const int SKY_SQL_MAX_PACKET_LEN = 0xffffffL;
|
||||
|
||||
typedef struct {
|
||||
MYSQL_conn *conn;
|
||||
unsigned long mysql_tid;
|
||||
unsigned long gateway_id;
|
||||
int protocol_enabled;
|
||||
int pool_enabled;
|
||||
char backend_servers[2][128];
|
||||
char *server_list;
|
||||
apr_hash_t *resources;
|
||||
int loop_timeout;
|
||||
} skysql_server_conf;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
char *raw_config;
|
||||
char *server_list;
|
||||
int r_port;
|
||||
char *dbname;
|
||||
char *defaults;
|
||||
int nshards;
|
||||
} conn_details;
|
||||
|
||||
typedef struct {
|
||||
char *driver_name;
|
||||
char *username;
|
||||
char *password;
|
||||
char *database;
|
||||
void *driver_details;
|
||||
} skysql_client_auth;
|
||||
|
||||
typedef struct {
|
||||
uint8_t client_flags[4];
|
||||
uint8_t max_packet_size[4];
|
||||
uint8_t charset;
|
||||
uint8_t scramble_buff;
|
||||
int connect_with_db;
|
||||
int compress;
|
||||
} mysql_driver_details;
|
||||
|
||||
typedef struct {
|
||||
int num;
|
||||
char *list;
|
||||
} backend_list;
|
||||
|
||||
int skysql_ext_file_ver();
|
||||
int skysql_query_is_select(const char *query);
|
||||
apr_status_t skysql_read_client_autentication(conn_rec *c, apr_pool_t *pool, uint8_t *scramble, int scramble_len, skysql_client_auth *mysql_client_data, uint8_t *stage1_hash);
|
||||
apr_status_t skysql_send_handshake(conn_rec *c, uint8_t *scramble, int *scramble_len);
|
||||
apr_status_t skysql_send_error (conn_rec *c, uint8_t packet_number, MYSQL_conn *conn);
|
||||
//apr_status_t skysql_prepare_ok(conn_rec *c, uint8_t packet_number, MYSQL_STMT *statement, MYSQL_conn *conn);
|
||||
apr_status_t skysql_send_ok(conn_rec *c, apr_pool_t *p, uint8_t packet_number, uint8_t in_affected_rows, const char* skysql_message);
|
||||
apr_status_t skysql_send_eof(conn_rec *c, apr_pool_t *p, uint8_t packet_number);
|
||||
apr_status_t skysql_send_result(conn_rec *c, uint8_t *data, uint8_t len);
|
||||
int select_random_slave_server(const char *server_listi, int *num_slaves);
|
||||
apr_status_t gateway_send_error (conn_rec *c, apr_pool_t *p, uint8_t packet_number);
|
||||
apr_status_t gateway_reply_data(conn_rec *c, apr_pool_t *pool, void *data, int len);
|
||||
char *gateway_find_user_password_sha1(char *username, void *repository, conn_rec *c, apr_pool_t *p);
|
||||
void skysql_sha1_str(const uint8_t *in, int in_len, uint8_t *out);
|
||||
int skygateway_query_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query);
|
||||
char *bin2hex(char *out, const uint8_t *in, unsigned int len);
|
||||
void skysql_sha1_2_str(const uint8_t *in, int in_len, const uint8_t *in2, int in2_len, uint8_t *out);
|
||||
void skysql_str_xor(char *output, const uint8_t *input1, const uint8_t *input2, unsigned int len);
|
||||
int get_server_from_list(char **selected_host, int *selected_port, char *server_list, int num, apr_pool_t *p);
|
||||
int get_master_from_list(char **selected_host, int *selected_port, char *server_list, apr_pool_t *p);
|
||||
int mysql_pass_packet(MYSQL_conn *conn, const char *command, int len);
|
||||
int mysql_receive_packet(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn);
|
||||
int skygateway_statement_prepare_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query, int len);
|
||||
int skygateway_statement_execute_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query, int len);
|
||||
int mysql_send_command(MYSQL_conn *conn, const char *command, int cmd, int len);
|
||||
apr_status_t skysql_change_user(conn_rec *c, apr_pool_t *p, char *username, char *database, MYSQL_conn *conn, uint8_t *stage1_hash);
|
||||
int query_routing(const char *server_list, const char *sql_command, int procotol_command, int current_slave);
|
||||
unsigned int mysql_errno(MYSQL_conn *mysql);
|
||||
const char *mysql_error(MYSQL_conn *mysql);
|
||||
const char *mysql_sqlstate(MYSQL_conn *mysql);
|
||||
int mysql_query(MYSQL_conn *conn, const char *query);
|
1377
protocol_1.0/skysql_utils.c
Normal file
1377
protocol_1.0/skysql_utils.c
Normal file
File diff suppressed because it is too large
Load Diff
64
query_classifier/makefile
Normal file
64
query_classifier/makefile
Normal file
@ -0,0 +1,64 @@
|
||||
include ../build_gateway.inc
|
||||
include ../makefile.inc
|
||||
|
||||
CC = gcc
|
||||
CPP = g++
|
||||
|
||||
SRCS = query_classifier.cc
|
||||
|
||||
QUERY_CLASSIFIER_PATH := $(shell pwd)
|
||||
|
||||
makeall: clean all
|
||||
|
||||
clean:
|
||||
make -C ../utils clean
|
||||
- $(DEL) query_classifier.o
|
||||
- $(DEL) libquery_classifier.so
|
||||
- $(DEL) libquery_classifier.so.1.0.1
|
||||
- $(DEL) skygw_utils.o
|
||||
- $(DEL) *~
|
||||
- $(DEL) depend
|
||||
|
||||
all: utils lib
|
||||
|
||||
utils:
|
||||
make -C $(ROOT_PATH)/utils clean all
|
||||
$(COPY) $(ROOT_PATH)/utils/skygw_utils.o ./
|
||||
|
||||
lib: libcomp liblink
|
||||
|
||||
libcomp:
|
||||
$(CPP) -c $(CFLAGS) \
|
||||
-I$(MARIADB_SRC_PATH)/libmysqld/ \
|
||||
-I$(MARIADB_SRC_PATH)/include/ \
|
||||
-I$(MARIADB_SRC_PATH)/sql \
|
||||
-I$(MARIADB_SRC_PATH)/regex/ \
|
||||
-I./ \
|
||||
-fPIC ./query_classifier.cc -o query_classifier.o
|
||||
|
||||
liblink:
|
||||
$(CPP) -shared \
|
||||
-L$(MARIADB_SRC_PATH)/libmysqld \
|
||||
-Wl,-soname,libquery_classifier.so \
|
||||
-Wl,-rpath,$(DEST)/lib \
|
||||
-Wl,-rpath,$(MARIADB_SRC_PATH)/libmysqld \
|
||||
-o libquery_classifier.so.1.0.1 ./query_classifier.o \
|
||||
$(LDLIBS) $(LDMYSQL) $(CPP_LDLIBS)
|
||||
$(DEL) ./libquery_classifier.so
|
||||
$(LINK) ./libquery_classifier.so.1.0.1 ./libquery_classifier.so
|
||||
|
||||
|
||||
install: liblink
|
||||
install ./libquery_classifier.so.1.0.1 ./libquery_classifier.so $(DEST)/lib
|
||||
|
||||
depend:
|
||||
@rm -f depend
|
||||
$(CPP) -M $(CFLAGS) \
|
||||
-I$(MARIADB_SRC_PATH)/libmysqld/ \
|
||||
-I$(MARIADB_SRC_PATH)/include/ \
|
||||
-I$(MARIADB_SRC_PATH)/sql \
|
||||
-I$(MARIADB_SRC_PATH)/regex/ \
|
||||
-I./ \
|
||||
$(SRCS) > depend
|
||||
|
||||
include depend
|
410
query_classifier/query_classifier.cc
Normal file
410
query_classifier/query_classifier.cc
Normal file
@ -0,0 +1,410 @@
|
||||
/**
|
||||
* @section LICENCE
|
||||
*
|
||||
* This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab
|
||||
*
|
||||
* @file
|
||||
*
|
||||
*/
|
||||
|
||||
#define EMBEDDED_LIBRARY
|
||||
#define MYSQL_YACC
|
||||
#define MYSQL_LEX012
|
||||
#define MYSQL_SERVER
|
||||
#if defined(MYSQL_CLIENT)
|
||||
# undef MYSQL_CLIENT
|
||||
#endif
|
||||
|
||||
#include <query_classifier.h>
|
||||
#include "../utils/skygw_types.h"
|
||||
#include "../utils/skygw_debug.h"
|
||||
|
||||
#include <mysql.h>
|
||||
#include <my_sys.h>
|
||||
#include <my_global.h>
|
||||
#include <my_dbug.h>
|
||||
#include <my_base.h>
|
||||
#include <sql_list.h>
|
||||
#include <mysqld_error.h>
|
||||
#include <sql_class.h>
|
||||
#include <sql_lex.h>
|
||||
#include <embedded_priv.h>
|
||||
#include <sql_class.h>
|
||||
#include <sql_lex.h>
|
||||
#include <sql_parse.h>
|
||||
#include <errmsg.h>
|
||||
#include <client_settings.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
static THD* get_or_create_thd_for_parsing(
|
||||
MYSQL* mysql,
|
||||
char* query_str);
|
||||
|
||||
static unsigned long set_client_flags(
|
||||
MYSQL* mysql);
|
||||
|
||||
static bool create_parse_tree(
|
||||
THD* thd);
|
||||
|
||||
static skygw_query_type_t resolve_query_type(
|
||||
THD* thd);
|
||||
|
||||
/**
|
||||
* @node (write brief function description here)
|
||||
*
|
||||
* Parameters:
|
||||
* @param query_str - <usage>
|
||||
* <description>
|
||||
*
|
||||
* @param client_flag - <usage>
|
||||
* <description>
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*
|
||||
* @details (write detailed description here)
|
||||
*
|
||||
*/
|
||||
skygw_query_type_t skygw_query_classifier_get_type(
|
||||
const char* query,
|
||||
unsigned long client_flags)
|
||||
{
|
||||
MYSQL* mysql;
|
||||
char* query_str;
|
||||
const char* user = "skygw";
|
||||
const char* db = "skygw";
|
||||
THD* thd;
|
||||
skygw_query_type_t qtype = QUERY_TYPE_UNKNOWN;
|
||||
bool failp = FALSE;
|
||||
|
||||
//ss_dfprintf(stderr, ">> skygw_query_classifier_get_type\n");
|
||||
ss_info_dassert(query != NULL, ("query_str is NULL"));
|
||||
|
||||
query_str = const_cast<char*>(query);
|
||||
#if QUERY_DEBUG
|
||||
fprintf(stderr, " Query \"%s\"\n", query_str);
|
||||
#endif
|
||||
|
||||
/** Get server handle */
|
||||
mysql = mysql_init(NULL);
|
||||
|
||||
if (mysql == NULL) {
|
||||
fprintf(stderr,
|
||||
"mysql_real_connect failed, %d : %s\n",
|
||||
mysql_errno(mysql),
|
||||
mysql_error(mysql));
|
||||
mysql_library_end();
|
||||
goto return_without_server;
|
||||
}
|
||||
|
||||
/** Set methods and authentication to mysql */
|
||||
mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_skygw");
|
||||
mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
|
||||
mysql->methods = &embedded_methods;
|
||||
mysql->user = my_strdup(user, MYF(0));
|
||||
mysql->db = my_strdup(db, MYF(0));
|
||||
mysql->passwd = NULL;
|
||||
|
||||
/** Get one or create new THD object to be use in parsing */
|
||||
thd = get_or_create_thd_for_parsing(mysql, query_str);
|
||||
|
||||
if (thd == NULL) {
|
||||
goto return_with_server_handle;
|
||||
}
|
||||
/** Create parse_tree inside thd */
|
||||
failp = create_parse_tree(thd);
|
||||
|
||||
if (failp) {
|
||||
goto return_with_thd;
|
||||
}
|
||||
qtype = resolve_query_type(thd);
|
||||
|
||||
return_with_thd:
|
||||
(*mysql->methods->free_embedded_thd)(mysql);
|
||||
mysql->thd = 0;
|
||||
return_with_server_handle:
|
||||
mysql_close(mysql);
|
||||
mysql_thread_end();
|
||||
return_without_server:
|
||||
//ss_dfprintf(stderr,
|
||||
// "<< skygw_query_classifier_get_type : %s\n",
|
||||
// STRQTYPE(qtype));
|
||||
//ss_dfflush(stderr);
|
||||
return qtype;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @node (write brief function description here)
|
||||
*
|
||||
* Parameters:
|
||||
* @param mysql - <usage>
|
||||
* <description>
|
||||
*
|
||||
* @param query_str - <usage>
|
||||
* <description>
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*
|
||||
* @details (write detailed description here)
|
||||
*
|
||||
*/
|
||||
static THD* get_or_create_thd_for_parsing(
|
||||
MYSQL* mysql,
|
||||
char* query_str)
|
||||
{
|
||||
THD* thd = NULL;
|
||||
unsigned long client_flags;
|
||||
char* db = mysql->options.db;
|
||||
bool failp = FALSE;
|
||||
size_t query_len;
|
||||
|
||||
//ss_dfprintf(stderr, "> get_or_create_thd_for_parsing\n");
|
||||
ss_info_dassert(mysql != NULL, ("mysql is NULL"));
|
||||
ss_info_dassert(query_str != NULL, ("query_str is NULL"));
|
||||
|
||||
query_len = strlen(query_str);
|
||||
client_flags = set_client_flags(mysql);
|
||||
|
||||
/** Get THD.
|
||||
* NOTE: Instead of creating new every time, THD instance could
|
||||
* be get from a pool of them.
|
||||
*/
|
||||
thd = (THD *)create_embedded_thd(client_flags);
|
||||
|
||||
if (thd == NULL) {
|
||||
ss_dfprintf(stderr, "Couldn't create embedded thd\n");
|
||||
goto return_thd;
|
||||
}
|
||||
mysql->thd = thd;
|
||||
init_embedded_mysql(mysql, client_flags);
|
||||
failp = check_embedded_connection(mysql, db);
|
||||
|
||||
if (failp) {
|
||||
ss_dfprintf(stderr, "Checking embedded connection failed.\n");
|
||||
goto return_err_with_thd;
|
||||
}
|
||||
thd->clear_data_list();
|
||||
|
||||
/** Check that we are calling the client functions in right order */
|
||||
if (mysql->status != MYSQL_STATUS_READY) {
|
||||
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
|
||||
goto return_err_with_thd;
|
||||
}
|
||||
/* Clear result variables */
|
||||
thd->current_stmt= NULL;
|
||||
thd->store_globals();
|
||||
/*
|
||||
We have to call free_old_query before we start to fill mysql->fields
|
||||
for new query. In the case of embedded server we collect field data
|
||||
during query execution (not during data retrieval as it is in remote
|
||||
client). So we have to call free_old_query here
|
||||
*/
|
||||
free_old_query(mysql);
|
||||
thd->extra_length = query_len;
|
||||
thd->extra_data = query_str;
|
||||
alloc_query(thd, query_str, query_len);
|
||||
goto return_thd;
|
||||
|
||||
return_err_with_thd:
|
||||
(*mysql->methods->free_embedded_thd)(mysql);
|
||||
thd = 0;
|
||||
mysql->thd = 0;
|
||||
return_thd:
|
||||
//ss_dfprintf(stderr, "< get_or_create_thd_for_parsing : %p\n", thd);
|
||||
//ss_dfflush(stderr);
|
||||
return thd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @node Set client flags. This is copied from libmysqld.c:mysql_real_connect
|
||||
*
|
||||
* Parameters:
|
||||
* @param mysql - <usage>
|
||||
* <description>
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*
|
||||
* @details (write detailed description here)
|
||||
*
|
||||
*/
|
||||
static unsigned long set_client_flags(
|
||||
MYSQL* mysql)
|
||||
{
|
||||
unsigned long f = 0;
|
||||
//ss_dfprintf(stderr, "> set_client_flags\n");
|
||||
f |= mysql->options.client_flag;
|
||||
|
||||
/* Send client information for access check */
|
||||
f |= CLIENT_CAPABILITIES;
|
||||
|
||||
if (f & CLIENT_MULTI_STATEMENTS) {
|
||||
f |= CLIENT_MULTI_RESULTS;
|
||||
}
|
||||
/**
|
||||
* No compression in embedded as we don't send any data,
|
||||
* and no pluggable auth, as we cannot do a client-server dialog
|
||||
*/
|
||||
f &= ~(CLIENT_COMPRESS | CLIENT_PLUGIN_AUTH);
|
||||
|
||||
if (mysql->options.db != NULL) {
|
||||
f |= CLIENT_CONNECT_WITH_DB;
|
||||
}
|
||||
//ss_dfprintf(stderr, "< set_client_flags : %lu\n", f);
|
||||
//ss_dfflush(stderr);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static bool create_parse_tree(
|
||||
THD* thd)
|
||||
{
|
||||
Parser_state parser_state;
|
||||
bool failp = FALSE;
|
||||
const char* virtual_db = "skygw_virtual";
|
||||
//ss_dfprintf(stderr, "> create_parse_tree\n");
|
||||
|
||||
if (parser_state.init(thd, thd->query(), thd->query_length())) {
|
||||
failp = TRUE;
|
||||
goto return_here;
|
||||
}
|
||||
mysql_reset_thd_for_next_command(thd, opt_userstat_running);
|
||||
|
||||
/** Set some database to thd so that parsing won't fail because of
|
||||
* missing database. Then parse. */
|
||||
failp = thd->set_db(virtual_db, sizeof(virtual_db));
|
||||
|
||||
if (failp) {
|
||||
fprintf(stderr, "Setting database for thd failed\n");
|
||||
}
|
||||
failp = parse_sql(thd, &parser_state, NULL);
|
||||
|
||||
if (failp) {
|
||||
fprintf(stderr, "parse_sql failed\n");
|
||||
}
|
||||
return_here:
|
||||
//ss_dfprintf(stderr, "< create_parse_tree : %s\n", STRBOOL(failp));
|
||||
//fflush(stderr);
|
||||
return failp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @node Detect query type, read-only, write, or session update
|
||||
*
|
||||
* Parameters:
|
||||
* @param thd - <usage>
|
||||
* <description>
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*
|
||||
* @details Query type is deduced by checking for certain properties
|
||||
* of them. The order is essential. Some SQL commands have multiple
|
||||
* flags set and changing the order in which flags are tested,
|
||||
* the resulting type may be different.
|
||||
*
|
||||
*/
|
||||
static skygw_query_type_t resolve_query_type(
|
||||
THD* thd)
|
||||
{
|
||||
skygw_query_type_t qtype = QUERY_TYPE_UNKNOWN;
|
||||
LEX* lex;
|
||||
/**
|
||||
* By default, if sql_log_bin, that is, recording data modifications
|
||||
* to binary log, is disabled, gateway treats operations normally.
|
||||
* Effectively nothing is replicated.
|
||||
* When force_data_modify_op_replication is TRUE, gateway distributes
|
||||
* all write operations to all nodes.
|
||||
*/
|
||||
bool force_data_modify_op_replication;
|
||||
|
||||
//ss_dfprintf(stderr, "> resolve_query_type\n");
|
||||
ss_info_dassert(thd != NULL, ("thd is NULL\n"));
|
||||
|
||||
force_data_modify_op_replication = FALSE;
|
||||
lex = thd->lex;
|
||||
|
||||
/** SELECT ..INTO variable|OUTFILE|DUMPFILE */
|
||||
if (lex->result != NULL) {
|
||||
qtype = QUERY_TYPE_SESSION_WRITE;
|
||||
goto return_here;
|
||||
}
|
||||
/**
|
||||
* 1:ALTER TABLE, TRUNCATE, REPAIR, OPTIMIZE, ANALYZE, CHECK.
|
||||
* 2:CREATE|ALTER|DROP|TRUNCATE|RENAME TABLE, LOAD, CREATE|DROP|ALTER DB,
|
||||
* CREATE|DROP INDEX, CREATE|DROP VIEW, CREATE|DROP TRIGGER,
|
||||
* CREATE|ALTER|DROP EVENT, UPDATE, INSERT, INSERT(SELECT),
|
||||
* DELETE, REPLACE, REPLACE(SELECT), CREATE|RENAME|DROP USER,
|
||||
* GRANT, REVOKE, OPTIMIZE, CREATE|ALTER|DROP FUNCTION|PROCEDURE,
|
||||
* CREATE SPFUNCTION, INSTALL|UNINSTALL PLUGIN
|
||||
*/
|
||||
if (is_log_table_write_query(lex->sql_command) ||
|
||||
is_update_query(lex->sql_command))
|
||||
{
|
||||
if (thd->variables.sql_log_bin == 0 &&
|
||||
force_data_modify_op_replication)
|
||||
{
|
||||
qtype = QUERY_TYPE_SESSION_WRITE;
|
||||
} else {
|
||||
qtype = QUERY_TYPE_WRITE;
|
||||
}
|
||||
|
||||
goto return_here;
|
||||
}
|
||||
|
||||
/**
|
||||
* REVOKE ALL, ASSIGN_TO_KEYCACHE,
|
||||
* PRELOAD_KEYS, FLUSH, RESET, CREATE|ALTER|DROP SERVER
|
||||
*/
|
||||
if (sql_command_flags[lex->sql_command] & CF_AUTO_COMMIT_TRANS) {
|
||||
qtype = QUERY_TYPE_SESSION_WRITE;
|
||||
goto return_here;
|
||||
}
|
||||
|
||||
/** Try to catch session modifications here */
|
||||
switch (lex->sql_command) {
|
||||
case SQLCOM_CHANGE_DB:
|
||||
case SQLCOM_SET_OPTION:
|
||||
qtype = QUERY_TYPE_SESSION_WRITE;
|
||||
break;
|
||||
|
||||
case SQLCOM_SELECT:
|
||||
qtype = QUERY_TYPE_READ;
|
||||
break;
|
||||
|
||||
case SQLCOM_CALL:
|
||||
qtype = QUERY_TYPE_WRITE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return_here:
|
||||
//ss_dfprintf(stderr, "< resolve_query_type : %s\n", STRQTYPE(qtype));
|
||||
return qtype;
|
||||
}
|
45
query_classifier/query_classifier.h
Normal file
45
query_classifier/query_classifier.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Copyright SkySQL Ab
|
||||
|
||||
*/
|
||||
|
||||
/** getpid */
|
||||
#include <unistd.h>
|
||||
#include "../utils/skygw_utils.h"
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
/**
|
||||
* Query type for skygateway.
|
||||
* The meaninful difference is whether master data was modified
|
||||
*/
|
||||
typedef enum {
|
||||
QUERY_TYPE_UNKNOWN = 7, /*!< Couln't find out or parse error */
|
||||
QUERY_TYPE_WRITE, /*!< Master data will be modified */
|
||||
QUERY_TYPE_READ, /*!< No updates */
|
||||
QUERY_TYPE_SESSION_WRITE /*!< Session data will be modified */
|
||||
} skygw_query_type_t;
|
||||
|
||||
|
||||
|
||||
skygw_query_type_t skygw_query_classifier_get_type(
|
||||
const char* query_str,
|
||||
unsigned long client_flags);
|
||||
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
36
query_classifier/test/makefile
Normal file
36
query_classifier/test/makefile
Normal file
@ -0,0 +1,36 @@
|
||||
include ../../build_gateway.inc
|
||||
include ../../makefile.inc
|
||||
|
||||
CC = gcc
|
||||
CPP = g++
|
||||
|
||||
TESTPATH := $(shell pwd)
|
||||
QUERY_CLASSIFIER_PATH := $(ROOT_PATH)/query_classifier/
|
||||
TESTAPP = $(TESTPATH)/testmain
|
||||
|
||||
runtest: makeall testall
|
||||
|
||||
makeall: clean all
|
||||
|
||||
clean:
|
||||
- $(DEL) testmain.o
|
||||
- $(DEL) testmain
|
||||
- $(DEL) *~
|
||||
|
||||
all: testcomp testall
|
||||
|
||||
testcomp:
|
||||
$(CC) $(CFLAGS) \
|
||||
-L$(QUERY_CLASSIFIER_PATH) \
|
||||
-L$(MARIADB_SRC_PATH)/libmysqld \
|
||||
-Wl,-rpath,$(DEST)/lib \
|
||||
-Wl,-rpath,$(MARIADB_SRC_PATH)/libmysqld \
|
||||
-Wl,-rpath,$(QUERY_CLASSIFIER_PATH)/ \
|
||||
-o testmain -DSS_DEBUG \
|
||||
-I$(MARIADB_SRC_PATH)/include testmain.c \
|
||||
-lquery_classifier $(LDLIBS) $(LDMYSQL) \
|
||||
$(QUERY_CLASSIFIER_PATH)/skygw_utils.o
|
||||
|
||||
|
||||
testall:
|
||||
- $(LAUNCH_DEBUGGER) $(TESTAPP) $(BACKGR)
|
471
query_classifier/test/testmain.c
Normal file
471
query_classifier/test/testmain.c
Normal file
@ -0,0 +1,471 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <mysql.h>
|
||||
|
||||
#include "../../utils/skygw_utils.h"
|
||||
//#include "skygw_debug.h"
|
||||
//#include "skygw_types.h"
|
||||
#include "../query_classifier.h"
|
||||
|
||||
static char* server_options[] = {
|
||||
"raatikka",
|
||||
"--datadir=/home/raatikka/data/skygw_parse/",
|
||||
"--skip-innodb",
|
||||
"--default-storage-engine=myisam",
|
||||
NULL
|
||||
};
|
||||
|
||||
const int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
|
||||
|
||||
static char* server_groups[] = {
|
||||
"embedded",
|
||||
"server",
|
||||
"server",
|
||||
"server",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void slcursor_add_case(
|
||||
slist_cursor_t* c,
|
||||
void* data)
|
||||
{
|
||||
slcursor_add_data(c, data);
|
||||
}
|
||||
|
||||
|
||||
typedef struct query_test_st query_test_t;
|
||||
|
||||
struct query_test_st {
|
||||
skygw_chk_t qt_chk_top;
|
||||
const char* qt_query_str;
|
||||
skygw_query_type_t qt_query_type;
|
||||
skygw_query_type_t qt_result_type;
|
||||
bool qt_should_fail;
|
||||
bool qt_exec_also_in_server;
|
||||
skygw_chk_t qt_chk_tail;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static query_test_t* query_test_init(
|
||||
const char* query_str,
|
||||
skygw_query_type_t query_type,
|
||||
bool case_should_fail,
|
||||
bool exec_also_in_server)
|
||||
{
|
||||
query_test_t* qtest;
|
||||
|
||||
qtest = (query_test_t *)calloc(1, sizeof(query_test_t));
|
||||
ss_dassert(qtest != NULL);
|
||||
qtest->qt_chk_top = CHK_NUM_QUERY_TEST;
|
||||
qtest->qt_chk_tail = CHK_NUM_QUERY_TEST;
|
||||
qtest->qt_query_str = query_str;
|
||||
qtest->qt_query_type = query_type;
|
||||
qtest->qt_should_fail = case_should_fail;
|
||||
qtest->qt_exec_also_in_server = exec_also_in_server;
|
||||
return qtest;
|
||||
}
|
||||
|
||||
const char* query_test_get_querystr(
|
||||
query_test_t* qt)
|
||||
{
|
||||
CHK_QUERY_TEST(qt);
|
||||
return qt->qt_query_str;
|
||||
}
|
||||
|
||||
static skygw_query_type_t query_test_get_query_type(
|
||||
query_test_t* qt)
|
||||
{
|
||||
CHK_QUERY_TEST(qt);
|
||||
return qt->qt_query_type;
|
||||
}
|
||||
|
||||
static skygw_query_type_t query_test_get_result_type(
|
||||
query_test_t* qt)
|
||||
{
|
||||
CHK_QUERY_TEST(qt);
|
||||
return qt->qt_result_type;
|
||||
}
|
||||
|
||||
|
||||
static bool query_test_types_match(
|
||||
query_test_t* qt)
|
||||
{
|
||||
CHK_QUERY_TEST(qt);
|
||||
return (qt->qt_query_type == qt->qt_result_type);
|
||||
}
|
||||
|
||||
static bool query_test_exec_also_in_server(
|
||||
query_test_t* qt)
|
||||
{
|
||||
CHK_QUERY_TEST(qt);
|
||||
return (qt->qt_exec_also_in_server);
|
||||
}
|
||||
|
||||
static query_test_t* slcursor_get_case(
|
||||
slist_cursor_t* c)
|
||||
{
|
||||
return (query_test_t*)slcursor_get_data(c);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
slist_cursor_t* c;
|
||||
const char* q;
|
||||
query_test_t* qtest;
|
||||
skygw_query_type_t qtype;
|
||||
bool succp;
|
||||
bool failp = TRUE;
|
||||
unsigned int f = 0;
|
||||
int nsucc = 0;
|
||||
int nfail = 0;
|
||||
MYSQL* mysql;
|
||||
|
||||
ss_dfprintf(stderr, ">> testmain\n");
|
||||
c = slist_init();
|
||||
|
||||
/** Read-only SELECTs */
|
||||
q = "SELECT user from mysql.user";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_READ, FALSE, TRUE));
|
||||
|
||||
q = "select tt1.id, tt2.id from t1 tt1, t2 tt2 where tt1.name is "
|
||||
"not null and tt2.name is not null";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_READ, FALSE, FALSE));
|
||||
|
||||
/** SELECT ..INTO clauses > session updates */
|
||||
q = "SELECT user from mysql.user INTO DUMPFILE '/tmp/dump1'";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "SELECT user INTO DUMPFILE '/tmp/dump2 ' from mysql.user";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "SELECT user from mysql.user INTO OUTFILE '/tmp/out1'";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, FALSE));
|
||||
|
||||
/** Database and table name must be separated by a dot */
|
||||
q = "SELECT user INTO OUTFILE '/tmp/out2 ' from mysql-user";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, TRUE, FALSE));
|
||||
|
||||
/** Database and table name must be separated by a dot */
|
||||
q = "SELECT user INTO OUTFILE '/tmp/out2 ' from mysql_foo_user";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "SELECT user FROM mysql.user limit 1 INTO @local_variable";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "SELECT user INTO @local_variable FROM mysql.user limit 1";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "SELECT non_existent_attr INTO @d FROM non_existent_table";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "select * from table1 "
|
||||
"where table1.field IN "
|
||||
"(select * from table1a union select * from table1b) union "
|
||||
"select * from table2 where table2.field = "
|
||||
"(select (select f1 from table2a where table2a.f2 = table2b.f3) "
|
||||
"from table2b where table2b.f1 = table2.f2) union "
|
||||
"select * from table3";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, TRUE));
|
||||
|
||||
/** Functions */
|
||||
q = "SELECT NOW()";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_READ, FALSE, FALSE));
|
||||
|
||||
q = "SELECT SOUNDEX('Hello')";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_READ, FALSE, FALSE));
|
||||
|
||||
q = "SELECT MY_UDF('Hello')";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_READ, FALSE, TRUE));
|
||||
|
||||
/** RENAME TABLEs */
|
||||
q = "RENAME TABLE T1 to T2";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, FALSE));
|
||||
|
||||
|
||||
/** INSERTs */
|
||||
q = "INSERT INTO T1 (SELECT * FROM T2)";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, TRUE));
|
||||
|
||||
q = "INSERT INTO T1 VALUES(2, 'foo', 'toomanyattributes')";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, TRUE));
|
||||
|
||||
q = "INSERT INTO T2 VALUES(1, 'sthrgey')";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "INSERT INTO T2 VALUES(8, 'ergstrhe')";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "INSERT INTO T2 VALUES(9, NULL)";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, FALSE));
|
||||
|
||||
|
||||
/** Ok, delimeter is client-side parameter which shouldn't be handled
|
||||
* on server side.
|
||||
*/
|
||||
q = "delimiter //";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, TRUE, TRUE));
|
||||
|
||||
/** SETs, USEs > Session updates */
|
||||
q = "SET @a=1";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, TRUE));
|
||||
|
||||
q = "USE TEST";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, FALSE));
|
||||
|
||||
|
||||
/** Object creation statements */
|
||||
q = "create procedure si (out param1 int) \nbegin select count(*) "
|
||||
"into param1 from t1; \nend";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, TRUE));
|
||||
|
||||
q = "CREATE TABLE T1 (id integer primary key, name varchar(10))";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, TRUE));
|
||||
|
||||
q = "DROP TABLE T1";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "ALTER TABLE T1 ADD COLUMN WHYME INTEGER NOT NULL";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "TRUNCATE TABLE T1";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, FALSE));
|
||||
|
||||
q = "DROP SERVER IF EXISTS VICTIMSRV";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, TRUE));
|
||||
|
||||
q = "CREATE USER FOO IDENTIFIED BY 'BAR'";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, TRUE));
|
||||
|
||||
q = "OPTIMIZE NO_WRITE_TO_BINLOG TABLE T1";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, TRUE));
|
||||
|
||||
q = "SELECT NOW();CREATE TABLE T1 (ID INTEGER);"
|
||||
"SET sql_log_bin=0;CREATE TABLE T2 (ID INTEGER)";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_WRITE, FALSE, TRUE));
|
||||
|
||||
|
||||
/** Setting database makes this SESSION_WRITE */
|
||||
q = "USE TEST;CREATE TABLE T1 (ID INTEGER);"
|
||||
"SET sql_log_bin=0;CREATE TABLE T2 (ID INTEGER)";
|
||||
slcursor_add_case(
|
||||
c,
|
||||
query_test_init(q, QUERY_TYPE_SESSION_WRITE, FALSE, TRUE));
|
||||
|
||||
/**
|
||||
* Init libmysqld.
|
||||
*/
|
||||
failp = mysql_library_init(num_elements, server_options, server_groups);
|
||||
|
||||
if (failp) {
|
||||
MYSQL* mysql = mysql_init(NULL);
|
||||
ss_dassert(mysql != NULL);
|
||||
fprintf(stderr,
|
||||
"mysql_init failed, %d : %s\n",
|
||||
mysql_errno(mysql),
|
||||
mysql_error(mysql));
|
||||
goto return_without_server;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"\nExecuting selected cases in "
|
||||
"skygw_query_classifier_get_type :\n\n");
|
||||
/**
|
||||
* Set cursor to the beginning, scan through the list and execute
|
||||
* test cases.
|
||||
*/
|
||||
succp = slcursor_move_to_begin(c);
|
||||
|
||||
while(succp) {
|
||||
qtest = slcursor_get_case(c);
|
||||
qtest->qt_result_type =
|
||||
skygw_query_classifier_get_type(qtest->qt_query_str, f);
|
||||
succp = slcursor_step_ahead(c);
|
||||
}
|
||||
/**
|
||||
* Scan through test results and compare them against expected
|
||||
* results.
|
||||
*/
|
||||
succp = slcursor_move_to_begin(c);
|
||||
fprintf(stderr, "\nScanning through the results :\n\n");
|
||||
|
||||
while(succp) {
|
||||
qtest = slcursor_get_case(c);
|
||||
|
||||
if (!query_test_types_match(qtest)) {
|
||||
nfail += 1;
|
||||
ss_dfprintf(stderr,
|
||||
"* Failed: \"%s\" -> %s (Expected %s)\n",
|
||||
query_test_get_querystr(qtest),
|
||||
STRQTYPE(query_test_get_result_type(qtest)),
|
||||
STRQTYPE(query_test_get_query_type(qtest)));
|
||||
} else {
|
||||
nsucc += 1;
|
||||
ss_dfprintf(stderr,
|
||||
"Succeed\t: \"%s\" -> %s\n",
|
||||
query_test_get_querystr(qtest),
|
||||
STRQTYPE(query_test_get_query_type(qtest)));
|
||||
}
|
||||
succp = slcursor_step_ahead(c);
|
||||
}
|
||||
fprintf(stderr,
|
||||
"------------------------------------------\n"
|
||||
"Tests in total %d, SUCCEED %d, FAILED %d\n",
|
||||
nsucc+nfail,
|
||||
nsucc,
|
||||
nfail);
|
||||
|
||||
/**
|
||||
* Scan test results and re-execute those which are marked to be
|
||||
* executed also in the server. This serves mostly debugging purposes.
|
||||
*/
|
||||
succp = slcursor_move_to_begin(c);
|
||||
mysql = mysql_init(NULL);
|
||||
|
||||
if (mysql == NULL) {
|
||||
fprintf(stderr, "mysql_init failed\n");
|
||||
goto return_without_server;
|
||||
}
|
||||
|
||||
mysql_options(mysql,
|
||||
MYSQL_READ_DEFAULT_GROUP,
|
||||
"libmysqld_client");
|
||||
mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
|
||||
mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
|
||||
|
||||
mysql = mysql_real_connect(mysql,
|
||||
NULL,
|
||||
"skygw",
|
||||
"skygw",
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
CLIENT_MULTI_STATEMENTS);
|
||||
|
||||
if (mysql == NULL) {
|
||||
fprintf(stderr, "mysql_real_connect failed\n");
|
||||
goto return_with_handle;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"\nRe-execution of selected cases in Embedded server :\n\n");
|
||||
|
||||
while(succp) {
|
||||
qtest = slcursor_get_case(c);
|
||||
|
||||
if (query_test_exec_also_in_server(qtest)) {
|
||||
MYSQL_RES* results;
|
||||
MYSQL_ROW record;
|
||||
const char* query_str;
|
||||
|
||||
query_str = query_test_get_querystr(qtest);
|
||||
failp = mysql_query(mysql, query_str);
|
||||
|
||||
if (failp) {
|
||||
ss_dfprintf(stderr,
|
||||
"* Failed: \"%s\" -> %d : %s\n",
|
||||
query_str,
|
||||
mysql_errno(mysql),
|
||||
mysql_error(mysql));
|
||||
} else {
|
||||
ss_dfprintf(stderr,
|
||||
"Succeed\t: \"%s\"\n",
|
||||
query_str);
|
||||
results = mysql_store_result(mysql);
|
||||
|
||||
if (results != NULL) {
|
||||
|
||||
while((record = mysql_fetch_row(results))) {
|
||||
while(record != NULL && *record != NULL) {
|
||||
ss_dfprintf(stderr, "%s ", *record);
|
||||
record++;
|
||||
}
|
||||
ss_dfprintf(stderr, "\n");
|
||||
}
|
||||
mysql_free_result(results);
|
||||
}
|
||||
}
|
||||
}
|
||||
succp = slcursor_step_ahead(c);
|
||||
|
||||
}
|
||||
slist_done(c);
|
||||
fprintf(stderr, "------------------------------------------\n");
|
||||
|
||||
return_with_handle:
|
||||
mysql_close(mysql);
|
||||
mysql_thread_end();
|
||||
mysql_library_end();
|
||||
|
||||
return_without_server:
|
||||
ss_dfprintf(stderr, "\n<< testmain\n");
|
||||
fflush(stderr);
|
||||
return 0;
|
||||
}
|
159
replication_listener/CMakeLists.txt
Normal file
159
replication_listener/CMakeLists.txt
Normal file
@ -0,0 +1,159 @@
|
||||
project (mysql-5.6-labs-binary-log-api)
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
set(MySQL_BINLOG_VERSION_MAJOR "0")
|
||||
set(MySQL_BINLOG_VERSION_MINOR "0.1")
|
||||
set(MRL_VERSION "${MySQL_BINLOG_VERSION_MAJOR}.${MySQL_BINLOG_VERSION_MINOR}")
|
||||
|
||||
set(CMAKE_VERSION_STRING "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}")
|
||||
|
||||
# Options for building
|
||||
option(WITH_SERVER_TESTS
|
||||
"Build the unit test suite with tests requiring a server"
|
||||
OFF)
|
||||
|
||||
# GTest download variables
|
||||
set(GTEST_VERSION "1.5.0")
|
||||
set(GTEST_PACKAGE_NAME "gtest-${GTEST_VERSION}")
|
||||
set(GTEST_TARBALL "${GTEST_PACKAGE_NAME}.tar.gz")
|
||||
set(GTEST_DOWNLOAD_URL "http://googletest.googlecode.com/files/${GTEST_TARBALL}")
|
||||
if(NOT DOWNLOAD_ROOT)
|
||||
set(DOWNLOAD_ROOT ${CMAKE_SOURCE_DIR}/source_downloads)
|
||||
endif()
|
||||
set(GTEST_SOURCE_DIR ${DOWNLOAD_ROOT}/${GTEST_PACKAGE_NAME})
|
||||
|
||||
# General settings
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||
include_directories(include)
|
||||
link_directories(${PROJECT_BINARY_DIR}/lib)
|
||||
|
||||
# ---------- Find Boost Headers/Libraries -----------------------
|
||||
SET(Boost_DEBUG FALSE)
|
||||
SET(Boost_FIND_REQUIRED TRUE)
|
||||
SET(Boost_FIND_QUIETLY TRUE)
|
||||
SET(Boost_USE_STATIC_LIBS FALSE)
|
||||
SET(Boost_ADDITIONAL_VERSIONS "1.41" "1.41.0")
|
||||
FIND_PACKAGE(Boost REQUIRED system thread)
|
||||
|
||||
# --------- Find crypt
|
||||
FIND_LIBRARY(LIB_CRYPTO crypto /opt/local/lib /opt/lib /usr/lib /usr/local/lib)
|
||||
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
|
||||
|
||||
# Locate Google Test package and enable tests if it is found
|
||||
find_package(GTest ${GTEST_VERSION} QUIET)
|
||||
|
||||
if (NOT GTEST_FOUND)
|
||||
if (NOT ENABLE_DOWNLOADS)
|
||||
# Give one-time warning
|
||||
if (NOT ONETIME_GTEST_WARNING)
|
||||
message(STATUS
|
||||
"Googletest was not found. gtest-based unit tests will be disabled. "
|
||||
"You can run cmake . -DENABLE_DOWNLOADS=1 to automatically download and "
|
||||
"build required components from source.")
|
||||
SET(ONETIME_GTEST_WARNING 1 CACHE INTERNAL "")
|
||||
endif (NOT ONETIME_GTEST_WARNING)
|
||||
else (NOT ENABLE_DOWNLOADS)
|
||||
# Download gtest source
|
||||
if (NOT EXISTS ${GTEST_SOURCE_DIR} AND
|
||||
NOT EXISTS ${DOWNLOAD_ROOT}/${GTEST_TARBALL})
|
||||
if (${CMAKE_VERSION_STRING} LESS "2.8")
|
||||
# In versions earlier than 2.8, try wget for downloading
|
||||
find_program(WGET_EXECUTABLE wget)
|
||||
mark_as_advanced(WGET_EXECUTABLE)
|
||||
if (WGET_EXECUTABLE)
|
||||
if (NOT EXISTS ${DOWNLOAD_ROOT})
|
||||
make_directory(${DOWNLOAD_ROOT})
|
||||
endif (NOT EXISTS ${DOWNLOAD_ROOT})
|
||||
execute_process(COMMAND ${WGET_EXECUTABLE} -T 30 ${GTEST_DOWNLOAD_URL}
|
||||
WORKING_DIRECTORY ${DOWNLOAD_ROOT} RESULT_VARIABLE ERR)
|
||||
if (ERR EQUAL 0)
|
||||
SET(DOWNLOAD_SUCCEEDED 1)
|
||||
endif (ERR EQUAL 0)
|
||||
endif (WGET_EXECUTABLE)
|
||||
else (${CMAKE_VERSION_STRING} LESS "2.8")
|
||||
# Use CMake builtin download capabilities
|
||||
file(DOWNLOAD ${GTEST_DOWNLOAD_URL} ${DOWNLOAD_ROOT}/${GTEST_TARBALL}
|
||||
TIMEOUT 30
|
||||
STATUS ERR)
|
||||
if (ERR EQUAL 0)
|
||||
SET(DOWNLOAD_SUCCEEDED 1)
|
||||
endif (ERR EQUAL 0)
|
||||
endif(${CMAKE_VERSION_STRING} LESS "2.8")
|
||||
|
||||
if (NOT DOWNLOAD_SUCCEEDED)
|
||||
message(STATUS
|
||||
"To enable google test, please download ${GTEST_DOWNLOAD_URL} "
|
||||
"to the directory ${DOWNLOAD_ROOT}")
|
||||
else (NOT DOWNLOAD_SUCCEEDED)
|
||||
message(STATUS
|
||||
"Successfully downloaded ${GTEST_DOWNLOAD_URL} to ${DOWNLOAD_ROOT}")
|
||||
# Unpack tarball
|
||||
execute_process (
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xfz "${DOWNLOAD_ROOT}/${GTEST_TARBALL}"
|
||||
WORKING_DIRECTORY "${DOWNLOAD_ROOT}"
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
)
|
||||
set(GTEST_DOWNLOADED 1 CACHE INTERNAL "")
|
||||
set(GTEST_FOUND 1 CACHE INTERNAL "")
|
||||
endif (NOT DOWNLOAD_SUCCEEDED)
|
||||
else(NOT EXISTS ${GTEST_SOURCE_DIR} AND NOT EXISTS ${DOWNLOAD_ROOT}/${GTEST_TARBALL})
|
||||
set(GTEST_DOWNLOADED 1 CACHE INTERNAL "")
|
||||
set(GTEST_FOUND 1 CACHE INTERNAL "")
|
||||
endif(NOT EXISTS ${GTEST_SOURCE_DIR} AND NOT EXISTS ${DOWNLOAD_ROOT}/${GTEST_TARBALL})
|
||||
endif (NOT ENABLE_DOWNLOADS)
|
||||
endif (NOT GTEST_FOUND)
|
||||
|
||||
if (GTEST_DOWNLOADED)
|
||||
# Build gtest library
|
||||
include_directories(
|
||||
${GTEST_SOURCE_DIR}
|
||||
${GTEST_SOURCE_DIR}/include
|
||||
)
|
||||
add_library(gtest STATIC ${GTEST_SOURCE_DIR}/src/gtest-all.cc)
|
||||
|
||||
# Set CMake variables to make FindPackage(GTest) happy next time.
|
||||
SET(GTEST_FOUND 1 CACHE INTERNAL "")
|
||||
SET(GTEST_LIBRARY gtest CACHE INTERNAL "")
|
||||
SET(GTEST_LIBRARIES gtest CACHE INTERNAL "")
|
||||
SET(GTEST_MAIN_LIBRARY no_gtest_main_library CACHE INTERNAL "")
|
||||
SET(GTEST_INCLUDE_DIRS ${GTEST_SOURCE_DIR}/include CACHE INTERNAL "")
|
||||
SET(GTEST_INCLUDE_DIR "${GTEST_SOURCE_DIR}/include" CACHE INTERNAL "")
|
||||
endif (GTEST_DOWNLOADED)
|
||||
|
||||
if(GTEST_FOUND)
|
||||
message(STATUS "Tests from subdirectory 'tests' added")
|
||||
enable_testing(true)
|
||||
include_directories(${GTEST_INCLUDE_DIRS})
|
||||
add_subdirectory(tests)
|
||||
endif(GTEST_FOUND)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
# -- Build the examples
|
||||
add_subdirectory(examples EXCLUDE_FROM_ALL)
|
||||
|
||||
# Configure installation
|
||||
install(DIRECTORY include DESTINATION . FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
# Configure packaging
|
||||
SET(CPACK_PACKAGE_NAME "mysql-5.6-labs-binary-log-api")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR "${MySQL_BINLOG_VERSION_MAJOR}")
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR "${MySQL_BINLOG_VERSION_MINOR}")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||
"mysql-5.6-labs-binary-log-api: a MySQL client library for interfacing with the binary log mechanism.")
|
||||
|
||||
SET(CPACK_GENERATOR "STGZ;TGZ;TZ;DEB;RPM")
|
||||
|
||||
# Get package name correctly formatted with name, version, and platform
|
||||
execute_process(COMMAND uname -m OUTPUT_VARIABLE SYSTEM_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
SET(CPACK_PACKAGE_FILE_NAME
|
||||
"${CPACK_PACKAGE_NAME}.${MRL_VERSION}.${CMAKE_SYSTEM_NAME}.${SYSTEM_ARCH}")
|
||||
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Oracle Corporation")
|
||||
|
||||
include(CPack)
|
280
replication_listener/COPYING
Normal file
280
replication_listener/COPYING
Normal file
@ -0,0 +1,280 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
65
replication_listener/CPackConfig.cmake
Normal file
65
replication_listener/CPackConfig.cmake
Normal file
@ -0,0 +1,65 @@
|
||||
# This file will be configured to contain variables for CPack. These variables
|
||||
# should be set in the CMake list file of the project before CPack module is
|
||||
# included. The list of available CPACK_xxx variables and their associated
|
||||
# documentation may be obtained using
|
||||
# cpack --help-variable-list
|
||||
#
|
||||
# Some variables are common to all generators (e.g. CPACK_PACKAGE_NAME)
|
||||
# and some are specific to a generator
|
||||
# (e.g. CPACK_NSIS_EXTRA_INSTALL_COMMANDS). The generator specific variables
|
||||
# usually begin with CPACK_<GENNAME>_xxxx.
|
||||
|
||||
|
||||
SET(CPACK_BINARY_BUNDLE "")
|
||||
SET(CPACK_BINARY_CYGWIN "")
|
||||
SET(CPACK_BINARY_DEB "")
|
||||
SET(CPACK_BINARY_DRAGNDROP "")
|
||||
SET(CPACK_BINARY_NSIS "")
|
||||
SET(CPACK_BINARY_OSXX11 "")
|
||||
SET(CPACK_BINARY_PACKAGEMAKER "")
|
||||
SET(CPACK_BINARY_RPM "")
|
||||
SET(CPACK_BINARY_STGZ "")
|
||||
SET(CPACK_BINARY_TBZ2 "")
|
||||
SET(CPACK_BINARY_TGZ "")
|
||||
SET(CPACK_BINARY_TZ "")
|
||||
SET(CPACK_BINARY_ZIP "")
|
||||
SET(CPACK_CMAKE_GENERATOR "Unix Makefiles")
|
||||
SET(CPACK_COMPONENT_UNSPECIFIED_HIDDEN "TRUE")
|
||||
SET(CPACK_COMPONENT_UNSPECIFIED_REQUIRED "TRUE")
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Oracle Corporation")
|
||||
SET(CPACK_GENERATOR "STGZ;TGZ;TZ;DEB;RPM")
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "/home/jan/skysql/skygateway/skygateway/replication_listener;mysql-5.6-labs-binary-log-api;ALL;/")
|
||||
SET(CPACK_INSTALL_PREFIX "/usr/local")
|
||||
SET(CPACK_MODULE_PATH "")
|
||||
SET(CPACK_NSIS_DISPLAY_NAME "mysql-5.6-labs-binary-log-api 0.0.1.1")
|
||||
SET(CPACK_NSIS_INSTALLER_ICON_CODE "")
|
||||
SET(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
|
||||
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
|
||||
SET(CPACK_NSIS_PACKAGE_NAME "mysql-5.6-labs-binary-log-api 0.0.1.1")
|
||||
SET(CPACK_OUTPUT_CONFIG_FILE "/home/jan/skysql/skygateway/skygateway/replication_listener/CPackConfig.cmake")
|
||||
SET(CPACK_PACKAGE_DEFAULT_LOCATION "/")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "/usr/share/cmake-2.8/Templates/CPack.GenericDescription.txt")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "mysql-5.6-labs-binary-log-api: a MySQL client library for interfacing with the binary log mechanism.")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "mysql-5.6-labs-binary-log-api.0.0.1.Linux.x86_64")
|
||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "mysql-5.6-labs-binary-log-api 0.0.1.1")
|
||||
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "mysql-5.6-labs-binary-log-api 0.0.1.1")
|
||||
SET(CPACK_PACKAGE_NAME "mysql-5.6-labs-binary-log-api")
|
||||
SET(CPACK_PACKAGE_RELOCATABLE "true")
|
||||
SET(CPACK_PACKAGE_VENDOR "Humanity")
|
||||
SET(CPACK_PACKAGE_VERSION "0.0.1.1")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR "0.1")
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH "1")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "/usr/share/cmake-2.8/Templates/CPack.GenericLicense.txt")
|
||||
SET(CPACK_RESOURCE_FILE_README "/usr/share/cmake-2.8/Templates/CPack.GenericDescription.txt")
|
||||
SET(CPACK_RESOURCE_FILE_WELCOME "/usr/share/cmake-2.8/Templates/CPack.GenericWelcome.txt")
|
||||
SET(CPACK_SET_DESTDIR "OFF")
|
||||
SET(CPACK_SOURCE_CYGWIN "")
|
||||
SET(CPACK_SOURCE_GENERATOR "TGZ;TBZ2;TZ")
|
||||
SET(CPACK_SOURCE_OUTPUT_CONFIG_FILE "/home/jan/skysql/skygateway/skygateway/replication_listener/CPackSourceConfig.cmake")
|
||||
SET(CPACK_SOURCE_TBZ2 "ON")
|
||||
SET(CPACK_SOURCE_TGZ "ON")
|
||||
SET(CPACK_SOURCE_TZ "ON")
|
||||
SET(CPACK_SOURCE_ZIP "OFF")
|
||||
SET(CPACK_SYSTEM_NAME "Linux")
|
||||
SET(CPACK_TOPLEVEL_TAG "Linux")
|
72
replication_listener/CPackSourceConfig.cmake
Normal file
72
replication_listener/CPackSourceConfig.cmake
Normal file
@ -0,0 +1,72 @@
|
||||
# This file will be configured to contain variables for CPack. These variables
|
||||
# should be set in the CMake list file of the project before CPack module is
|
||||
# included. The list of available CPACK_xxx variables and their associated
|
||||
# documentation may be obtained using
|
||||
# cpack --help-variable-list
|
||||
#
|
||||
# Some variables are common to all generators (e.g. CPACK_PACKAGE_NAME)
|
||||
# and some are specific to a generator
|
||||
# (e.g. CPACK_NSIS_EXTRA_INSTALL_COMMANDS). The generator specific variables
|
||||
# usually begin with CPACK_<GENNAME>_xxxx.
|
||||
|
||||
|
||||
SET(CPACK_BINARY_BUNDLE "")
|
||||
SET(CPACK_BINARY_CYGWIN "")
|
||||
SET(CPACK_BINARY_DEB "")
|
||||
SET(CPACK_BINARY_DRAGNDROP "")
|
||||
SET(CPACK_BINARY_NSIS "")
|
||||
SET(CPACK_BINARY_OSXX11 "")
|
||||
SET(CPACK_BINARY_PACKAGEMAKER "")
|
||||
SET(CPACK_BINARY_RPM "")
|
||||
SET(CPACK_BINARY_STGZ "")
|
||||
SET(CPACK_BINARY_TBZ2 "")
|
||||
SET(CPACK_BINARY_TGZ "")
|
||||
SET(CPACK_BINARY_TZ "")
|
||||
SET(CPACK_BINARY_ZIP "")
|
||||
SET(CPACK_CMAKE_GENERATOR "Unix Makefiles")
|
||||
SET(CPACK_COMPONENT_UNSPECIFIED_HIDDEN "TRUE")
|
||||
SET(CPACK_COMPONENT_UNSPECIFIED_REQUIRED "TRUE")
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Oracle Corporation")
|
||||
SET(CPACK_GENERATOR "TGZ;TBZ2;TZ")
|
||||
SET(CPACK_IGNORE_FILES "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#")
|
||||
SET(CPACK_INSTALLED_DIRECTORIES "/home/jan/skysql/skygateway/skygateway/replication_listener;/")
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "")
|
||||
SET(CPACK_INSTALL_PREFIX "/usr/local")
|
||||
SET(CPACK_MODULE_PATH "")
|
||||
SET(CPACK_NSIS_DISPLAY_NAME "mysql-5.6-labs-binary-log-api 0.0.1.1")
|
||||
SET(CPACK_NSIS_INSTALLER_ICON_CODE "")
|
||||
SET(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
|
||||
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
|
||||
SET(CPACK_NSIS_PACKAGE_NAME "mysql-5.6-labs-binary-log-api 0.0.1.1")
|
||||
SET(CPACK_OUTPUT_CONFIG_FILE "/home/jan/skysql/skygateway/skygateway/replication_listener/CPackConfig.cmake")
|
||||
SET(CPACK_PACKAGE_DEFAULT_LOCATION "/")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "/usr/share/cmake-2.8/Templates/CPack.GenericDescription.txt")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "mysql-5.6-labs-binary-log-api: a MySQL client library for interfacing with the binary log mechanism.")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "mysql-5.6-labs-binary-log-api-0.0.1.1-Source")
|
||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "mysql-5.6-labs-binary-log-api 0.0.1.1")
|
||||
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "mysql-5.6-labs-binary-log-api 0.0.1.1")
|
||||
SET(CPACK_PACKAGE_NAME "mysql-5.6-labs-binary-log-api")
|
||||
SET(CPACK_PACKAGE_RELOCATABLE "true")
|
||||
SET(CPACK_PACKAGE_VENDOR "Humanity")
|
||||
SET(CPACK_PACKAGE_VERSION "0.0.1.1")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR "0.1")
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH "1")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "/usr/share/cmake-2.8/Templates/CPack.GenericLicense.txt")
|
||||
SET(CPACK_RESOURCE_FILE_README "/usr/share/cmake-2.8/Templates/CPack.GenericDescription.txt")
|
||||
SET(CPACK_RESOURCE_FILE_WELCOME "/usr/share/cmake-2.8/Templates/CPack.GenericWelcome.txt")
|
||||
SET(CPACK_SET_DESTDIR "OFF")
|
||||
SET(CPACK_SOURCE_CYGWIN "")
|
||||
SET(CPACK_SOURCE_GENERATOR "TGZ;TBZ2;TZ")
|
||||
SET(CPACK_SOURCE_IGNORE_FILES "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#")
|
||||
SET(CPACK_SOURCE_INSTALLED_DIRECTORIES "/home/jan/skysql/skygateway/skygateway/replication_listener;/")
|
||||
SET(CPACK_SOURCE_OUTPUT_CONFIG_FILE "/home/jan/skysql/skygateway/skygateway/replication_listener/CPackSourceConfig.cmake")
|
||||
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mysql-5.6-labs-binary-log-api-0.0.1.1-Source")
|
||||
SET(CPACK_SOURCE_TBZ2 "ON")
|
||||
SET(CPACK_SOURCE_TGZ "ON")
|
||||
SET(CPACK_SOURCE_TOPLEVEL_TAG "Linux-Source")
|
||||
SET(CPACK_SOURCE_TZ "ON")
|
||||
SET(CPACK_SOURCE_ZIP "OFF")
|
||||
SET(CPACK_STRIP_FILES "")
|
||||
SET(CPACK_SYSTEM_NAME "Linux")
|
||||
SET(CPACK_TOPLEVEL_TAG "Linux-Source")
|
1551
replication_listener/Doxyfile
Normal file
1551
replication_listener/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
267
replication_listener/Makefile
Normal file
267
replication_listener/Makefile
Normal file
@ -0,0 +1,267 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 2.8
|
||||
|
||||
# Default target executed when no arguments are given to make.
|
||||
default_target: all
|
||||
.PHONY : default_target
|
||||
|
||||
#=============================================================================
|
||||
# Special targets provided by cmake.
|
||||
|
||||
# Disable implicit rules so canonical targets will work.
|
||||
.SUFFIXES:
|
||||
|
||||
# Remove some rules from gmake that .SUFFIXES does not remove.
|
||||
SUFFIXES =
|
||||
|
||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
||||
|
||||
# Suppress display of executed commands.
|
||||
$(VERBOSE).SILENT:
|
||||
|
||||
# A target that is always out of date.
|
||||
cmake_force:
|
||||
.PHONY : cmake_force
|
||||
|
||||
#=============================================================================
|
||||
# Set environment variables for the build.
|
||||
|
||||
# The shell in which to execute make rules.
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The CMake executable.
|
||||
CMAKE_COMMAND = /usr/bin/cmake
|
||||
|
||||
# The command to remove a file.
|
||||
RM = /usr/bin/cmake -E remove -f
|
||||
|
||||
# Escaping for special characters.
|
||||
EQUALS = =
|
||||
|
||||
# The top-level source directory on which CMake was run.
|
||||
CMAKE_SOURCE_DIR = /home/jan/skysql/skygateway/skygateway/replication_listener
|
||||
|
||||
# The top-level build directory on which CMake was run.
|
||||
CMAKE_BINARY_DIR = /home/jan/skysql/skygateway/skygateway/replication_listener
|
||||
|
||||
#=============================================================================
|
||||
# Targets provided globally by CMake.
|
||||
|
||||
# Special rule for the target edit_cache
|
||||
edit_cache:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..."
|
||||
/usr/bin/cmake -i .
|
||||
.PHONY : edit_cache
|
||||
|
||||
# Special rule for the target edit_cache
|
||||
edit_cache/fast: edit_cache
|
||||
.PHONY : edit_cache/fast
|
||||
|
||||
# Special rule for the target install
|
||||
install: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
|
||||
/usr/bin/cmake -P cmake_install.cmake
|
||||
.PHONY : install
|
||||
|
||||
# Special rule for the target install
|
||||
install/fast: preinstall/fast
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
|
||||
/usr/bin/cmake -P cmake_install.cmake
|
||||
.PHONY : install/fast
|
||||
|
||||
# Special rule for the target install/local
|
||||
install/local: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
|
||||
/usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
|
||||
.PHONY : install/local
|
||||
|
||||
# Special rule for the target install/local
|
||||
install/local/fast: install/local
|
||||
.PHONY : install/local/fast
|
||||
|
||||
# Special rule for the target list_install_components
|
||||
list_install_components:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\""
|
||||
.PHONY : list_install_components
|
||||
|
||||
# Special rule for the target list_install_components
|
||||
list_install_components/fast: list_install_components
|
||||
.PHONY : list_install_components/fast
|
||||
|
||||
# Special rule for the target package
|
||||
package: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool..."
|
||||
/usr/bin/cpack --config ./CPackConfig.cmake
|
||||
.PHONY : package
|
||||
|
||||
# Special rule for the target package
|
||||
package/fast: package
|
||||
.PHONY : package/fast
|
||||
|
||||
# Special rule for the target package_source
|
||||
package_source:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool for source..."
|
||||
/usr/bin/cpack --config ./CPackSourceConfig.cmake /home/jan/skysql/skygateway/skygateway/replication_listener/CPackSourceConfig.cmake
|
||||
.PHONY : package_source
|
||||
|
||||
# Special rule for the target package_source
|
||||
package_source/fast: package_source
|
||||
.PHONY : package_source/fast
|
||||
|
||||
# Special rule for the target rebuild_cache
|
||||
rebuild_cache:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
|
||||
/usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
||||
.PHONY : rebuild_cache
|
||||
|
||||
# Special rule for the target rebuild_cache
|
||||
rebuild_cache/fast: rebuild_cache
|
||||
.PHONY : rebuild_cache/fast
|
||||
|
||||
# The main all target
|
||||
all: cmake_check_build_system
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /home/jan/skysql/skygateway/skygateway/replication_listener/CMakeFiles /home/jan/skysql/skygateway/skygateway/replication_listener/CMakeFiles/progress.marks
|
||||
$(MAKE) -f CMakeFiles/Makefile2 all
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /home/jan/skysql/skygateway/skygateway/replication_listener/CMakeFiles 0
|
||||
.PHONY : all
|
||||
|
||||
# The main clean target
|
||||
clean:
|
||||
$(MAKE) -f CMakeFiles/Makefile2 clean
|
||||
.PHONY : clean
|
||||
|
||||
# The main clean target
|
||||
clean/fast: clean
|
||||
.PHONY : clean/fast
|
||||
|
||||
# Prepare targets for installation.
|
||||
preinstall: all
|
||||
$(MAKE) -f CMakeFiles/Makefile2 preinstall
|
||||
.PHONY : preinstall
|
||||
|
||||
# Prepare targets for installation.
|
||||
preinstall/fast:
|
||||
$(MAKE) -f CMakeFiles/Makefile2 preinstall
|
||||
.PHONY : preinstall/fast
|
||||
|
||||
# clear depends
|
||||
depend:
|
||||
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
|
||||
.PHONY : depend
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named replication_shared
|
||||
|
||||
# Build rule for target.
|
||||
replication_shared: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 replication_shared
|
||||
.PHONY : replication_shared
|
||||
|
||||
# fast build rule for target.
|
||||
replication_shared/fast:
|
||||
$(MAKE) -f src/CMakeFiles/replication_shared.dir/build.make src/CMakeFiles/replication_shared.dir/build
|
||||
.PHONY : replication_shared/fast
|
||||
|
||||
# Manual pre-install relink rule for target.
|
||||
replication_shared/preinstall:
|
||||
$(MAKE) -f src/CMakeFiles/replication_shared.dir/build.make src/CMakeFiles/replication_shared.dir/preinstall
|
||||
.PHONY : replication_shared/preinstall
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named replication_static
|
||||
|
||||
# Build rule for target.
|
||||
replication_static: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 replication_static
|
||||
.PHONY : replication_static
|
||||
|
||||
# fast build rule for target.
|
||||
replication_static/fast:
|
||||
$(MAKE) -f src/CMakeFiles/replication_static.dir/build.make src/CMakeFiles/replication_static.dir/build
|
||||
.PHONY : replication_static/fast
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named basic-1
|
||||
|
||||
# Build rule for target.
|
||||
basic-1: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 basic-1
|
||||
.PHONY : basic-1
|
||||
|
||||
# fast build rule for target.
|
||||
basic-1/fast:
|
||||
$(MAKE) -f examples/CMakeFiles/basic-1.dir/build.make examples/CMakeFiles/basic-1.dir/build
|
||||
.PHONY : basic-1/fast
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named basic-2
|
||||
|
||||
# Build rule for target.
|
||||
basic-2: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 basic-2
|
||||
.PHONY : basic-2
|
||||
|
||||
# fast build rule for target.
|
||||
basic-2/fast:
|
||||
$(MAKE) -f examples/CMakeFiles/basic-2.dir/build.make examples/CMakeFiles/basic-2.dir/build
|
||||
.PHONY : basic-2/fast
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named jan_test
|
||||
|
||||
# Build rule for target.
|
||||
jan_test: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 jan_test
|
||||
.PHONY : jan_test
|
||||
|
||||
# fast build rule for target.
|
||||
jan_test/fast:
|
||||
$(MAKE) -f examples/CMakeFiles/jan_test.dir/build.make examples/CMakeFiles/jan_test.dir/build
|
||||
.PHONY : jan_test/fast
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named mysql2lucene
|
||||
|
||||
# Build rule for target.
|
||||
mysql2lucene: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 mysql2lucene
|
||||
.PHONY : mysql2lucene
|
||||
|
||||
# fast build rule for target.
|
||||
mysql2lucene/fast:
|
||||
$(MAKE) -f examples/mysql2lucene/CMakeFiles/mysql2lucene.dir/build.make examples/mysql2lucene/CMakeFiles/mysql2lucene.dir/build
|
||||
.PHONY : mysql2lucene/fast
|
||||
|
||||
# Help Target
|
||||
help:
|
||||
@echo "The following are some of the valid targets for this Makefile:"
|
||||
@echo "... all (the default if no target is provided)"
|
||||
@echo "... clean"
|
||||
@echo "... depend"
|
||||
@echo "... edit_cache"
|
||||
@echo "... install"
|
||||
@echo "... install/local"
|
||||
@echo "... list_install_components"
|
||||
@echo "... package"
|
||||
@echo "... package_source"
|
||||
@echo "... rebuild_cache"
|
||||
@echo "... replication_shared"
|
||||
@echo "... replication_static"
|
||||
@echo "... basic-1"
|
||||
@echo "... basic-2"
|
||||
@echo "... jan_test"
|
||||
@echo "... mysql2lucene"
|
||||
.PHONY : help
|
||||
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Special targets to cleanup operation of make.
|
||||
|
||||
# Special rule to run CMake to check the build system integrity.
|
||||
# No rule that depends on this can have commands that come from listfiles
|
||||
# because they might be regenerated.
|
||||
cmake_check_build_system:
|
||||
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
|
||||
.PHONY : cmake_check_build_system
|
||||
|
68
replication_listener/README
Normal file
68
replication_listener/README
Normal file
@ -0,0 +1,68 @@
|
||||
This repository was forked from https://launchpad.net/mysql-replication-listener.
|
||||
---
|
||||
|
||||
The MySQL Replicant Library is a C++ library for reading MySQL
|
||||
replication events, either by connecting to a server or by reading
|
||||
from a file. To handle reading from a server, it includes a very
|
||||
simple client.
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
You need to have CMake version 2.8 or later and Boost version 1.35.0
|
||||
or later since Asio is required.
|
||||
|
||||
To be able to run the unit tests, you have to have Google Test
|
||||
installed. Google Test will be automatically installed if cmake is
|
||||
called as:
|
||||
|
||||
cmake . -DENABLE_DOWNLOADS=1
|
||||
|
||||
|
||||
Directory structure
|
||||
-------------------
|
||||
|
||||
.
|
||||
|-- doc Documentation
|
||||
|-- examples Examples
|
||||
| `-- mysql2lucene Example application replicating rows to SOLR
|
||||
|-- include Include files
|
||||
|-- src Source files for library
|
||||
`-- tests Unit test files and directories
|
||||
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
To build the entire package, it is first necessary to run CMake to build all the makefiles.
|
||||
|
||||
cmake .
|
||||
make -j4
|
||||
|
||||
Some of the examples are using third-party software, which can require
|
||||
extra parameters to be given to CMake.
|
||||
|
||||
If you want to perform an out-of-source build, you can just create a
|
||||
build directory and execute CMake there.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake <source directory>
|
||||
make -j4
|
||||
|
||||
|
||||
Building the mysql2lucene Example
|
||||
---------------------------------
|
||||
|
||||
To build the mysql2lucene example, it is necessary to ensure that the
|
||||
'FindCLucene.cmake' is in the CMAKE_MODULE_PATH, which on my machine
|
||||
require me to write:
|
||||
|
||||
cmake . -DCMAKE_MODULE_PATH:String=/usr/share/kde4/apps/cmake/modules
|
||||
|
||||
In addition, there is a bug in the packaging of CLucene on Ubuntu in
|
||||
that the 'clucene-config.h' file is placed in '/usr/lib/CLucene' but
|
||||
not in '/usr/include/CLucene', causing compiler failure when
|
||||
attempting to use CLucene. The 'CMakeLists.txt' file hacks around this
|
||||
by adding the libraries explicitly, but it seems unnecessary.
|
54
replication_listener/cmake_install.cmake
Normal file
54
replication_listener/cmake_install.cmake
Normal file
@ -0,0 +1,54 @@
|
||||
# Install script for directory: /home/jan/skysql/skygateway/skygateway/replication_listener
|
||||
|
||||
# Set the install prefix
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/local")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
IF(BUILD_TYPE)
|
||||
STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
ELSE(BUILD_TYPE)
|
||||
SET(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
||||
ENDIF(BUILD_TYPE)
|
||||
MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
|
||||
# Set the component getting installed.
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
IF(COMPONENT)
|
||||
MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
|
||||
SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
ELSE(COMPONENT)
|
||||
SET(CMAKE_INSTALL_COMPONENT)
|
||||
ENDIF(COMPONENT)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
# Install shared libraries without execute permission?
|
||||
IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
SET(CMAKE_INSTALL_SO_NO_EXE "1")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")
|
||||
FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/." TYPE DIRECTORY FILES "/home/jan/skysql/skygateway/skygateway/replication_listener/include" FILES_MATCHING REGEX "/[^/]*\\.h$")
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")
|
||||
|
||||
IF(NOT CMAKE_INSTALL_LOCAL_ONLY)
|
||||
# Include the install script for each subdirectory.
|
||||
INCLUDE("/home/jan/skysql/skygateway/skygateway/replication_listener/src/cmake_install.cmake")
|
||||
|
||||
ENDIF(NOT CMAKE_INSTALL_LOCAL_ONLY)
|
||||
|
||||
IF(CMAKE_INSTALL_COMPONENT)
|
||||
SET(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
|
||||
ELSE(CMAKE_INSTALL_COMPONENT)
|
||||
SET(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
|
||||
ENDIF(CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
FILE(WRITE "/home/jan/skysql/skygateway/skygateway/replication_listener/${CMAKE_INSTALL_MANIFEST}" "")
|
||||
FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES})
|
||||
FILE(APPEND "/home/jan/skysql/skygateway/skygateway/replication_listener/${CMAKE_INSTALL_MANIFEST}" "${file}\n")
|
||||
ENDFOREACH(file)
|
BIN
replication_listener/doc/libreplication.odp
Normal file
BIN
replication_listener/doc/libreplication.odp
Normal file
Binary file not shown.
22
replication_listener/examples/CMakeLists.txt
Normal file
22
replication_listener/examples/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
||||
project(examples)
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
link_directories(${PROJECT_BUILD_DIR}/lib)
|
||||
include_directories(${PROJECT_BUILD_DIR}/include)
|
||||
|
||||
# Find MySQL client library and header files
|
||||
find_path(MySQL_INCLUDE_DIR mysql.h
|
||||
/usr/local/include/mysql /usr/include/mysql)
|
||||
include_directories(${MySQL_INCLUDE_DIR})
|
||||
include_directories(../../table_replication_consistency)
|
||||
include_directories(../../utils)
|
||||
|
||||
|
||||
# Create build rules for all the simple examples that only require a
|
||||
# single file.
|
||||
foreach(prog basic-1 basic-2 jan_test)
|
||||
ADD_EXECUTABLE(${prog} ${prog}.cpp /usr/local/mysql/lib/libmysqld.a)
|
||||
TARGET_LINK_LIBRARIES(${prog} replication boost_system boost_thread pthread aio crypt ${MySQL_LIBRARY})
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(mysql2lucene EXCLUDE_FROM_ALL)
|
36
replication_listener/examples/basic-1.cpp
Normal file
36
replication_listener/examples/basic-1.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "binlog_api.h"
|
||||
|
||||
/**
|
||||
@file basic-1
|
||||
@author Mats Kindahl <mats.kindahl@oracle.com>
|
||||
|
||||
This is a basic example that just opens a binary log either from a
|
||||
file or a server and print out what events are found. It uses a
|
||||
simple event loop and checks information in the events using a
|
||||
switch.
|
||||
*/
|
||||
|
||||
using mysql::Binary_log;
|
||||
using mysql::system::create_transport;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: basic-2 <uri>" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
Binary_log binlog(create_transport(argv[1]));
|
||||
binlog.connect();
|
||||
|
||||
Binary_log_event *event;
|
||||
|
||||
while (true) {
|
||||
int result = binlog.wait_for_next_event(&event);
|
||||
if (result == ERR_EOF)
|
||||
break;
|
||||
std::cout << "Found event of type "
|
||||
<< event->get_event_type()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
94
replication_listener/examples/basic-2.cpp
Normal file
94
replication_listener/examples/basic-2.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include "binlog_api.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
/*
|
||||
Here is a basic system using the event loop to fetch context events
|
||||
and store them in an associative array.
|
||||
*/
|
||||
using mysql::Binary_log;
|
||||
using mysql::system::create_transport;
|
||||
using mysql::system::get_event_type_str;
|
||||
using mysql::User_var_event;
|
||||
|
||||
/**
|
||||
* Class to maintain variable values.
|
||||
*/
|
||||
template <class AssociativeContainer>
|
||||
class Save_variables : public Content_handler {
|
||||
public:
|
||||
Save_variables(AssociativeContainer& container)
|
||||
: m_var(container)
|
||||
{
|
||||
}
|
||||
|
||||
Binary_log_event *process_event(User_var_event *event) {
|
||||
m_var[event->name] = event->value;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
AssociativeContainer &m_var;
|
||||
};
|
||||
|
||||
|
||||
template <class AssociativeContainer>
|
||||
class Replace_variables : public Content_handler {
|
||||
public:
|
||||
Replace_variables(AssociativeContainer& variables)
|
||||
: m_var(variables)
|
||||
{
|
||||
}
|
||||
|
||||
Binary_log_event *process_event(Query_event *event) {
|
||||
std::string *query = &event->query;
|
||||
size_t start, end = 0;
|
||||
while (true) {
|
||||
start = query->find_first_of("@", end);
|
||||
if (start == std::string::npos)
|
||||
break;
|
||||
end = query->find_first_not_of("abcdefghijklmnopqrstuvwxyz", start+1);
|
||||
std::string key = query->substr(start + 1, end - start - 1);
|
||||
query->replace(start, end - start, "'" + m_var[key] + "'");
|
||||
}
|
||||
return event;
|
||||
}
|
||||
private:
|
||||
AssociativeContainer &m_var;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
typedef std::map<std::string, std::string> Map;
|
||||
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: basic-2 <uri>" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
Binary_log binlog(create_transport(argv[1]));
|
||||
binlog.connect();
|
||||
|
||||
binlog.set_position(4);
|
||||
|
||||
Map variables;
|
||||
Save_variables<Map> save_variables(variables);
|
||||
binlog.content_handler_pipeline()->push_back(&save_variables);
|
||||
Replace_variables<Map> replace_variables(variables);
|
||||
binlog.content_handler_pipeline()->push_back(&replace_variables);
|
||||
|
||||
while (true) {
|
||||
Binary_log_event *event;
|
||||
int result = binlog.wait_for_next_event(&event);
|
||||
if (result == ERR_EOF)
|
||||
break;
|
||||
switch (event->get_event_type()) {
|
||||
case QUERY_EVENT:
|
||||
std::cout << static_cast<Query_event*>(event)->query
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
39
replication_listener/examples/cmake_install.cmake
Normal file
39
replication_listener/examples/cmake_install.cmake
Normal file
@ -0,0 +1,39 @@
|
||||
# Install script for directory: /home/jan/skysql/skygateway/skygateway/replication_listener/examples
|
||||
|
||||
# Set the install prefix
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/local")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
IF(BUILD_TYPE)
|
||||
STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
ELSE(BUILD_TYPE)
|
||||
SET(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
||||
ENDIF(BUILD_TYPE)
|
||||
MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
|
||||
# Set the component getting installed.
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
IF(COMPONENT)
|
||||
MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
|
||||
SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
ELSE(COMPONENT)
|
||||
SET(CMAKE_INSTALL_COMPONENT)
|
||||
ENDIF(COMPONENT)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
# Install shared libraries without execute permission?
|
||||
IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
SET(CMAKE_INSTALL_SO_NO_EXE "1")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
|
||||
IF(NOT CMAKE_INSTALL_LOCAL_ONLY)
|
||||
# Include the install script for each subdirectory.
|
||||
|
||||
ENDIF(NOT CMAKE_INSTALL_LOCAL_ONLY)
|
||||
|
218
replication_listener/examples/jan_test.cpp
Normal file
218
replication_listener/examples/jan_test.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
#include "binlog_api.h"
|
||||
#include "my_pthread.h"
|
||||
#include "listener_exception.h"
|
||||
#include "table_replication_consistency.h"
|
||||
#include <getopt.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <regex.h>
|
||||
#include <algorithm>
|
||||
#include <mysql.h>
|
||||
|
||||
using mysql::Binary_log;
|
||||
using mysql::system::create_transport;
|
||||
using namespace std;
|
||||
using namespace mysql::system;
|
||||
|
||||
static char* server_options[] = {
|
||||
"jan_test",
|
||||
"--datadir=/tmp/",
|
||||
"--skip-innodb",
|
||||
"--default-storage-engine=myisam",
|
||||
NULL
|
||||
};
|
||||
|
||||
const int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
|
||||
|
||||
static char* server_groups[] = {
|
||||
"libmysqld_server",
|
||||
"libmysqld_client",
|
||||
"libmysqld_server",
|
||||
"libmysqld_server", NULL
|
||||
};
|
||||
|
||||
void* binlog_reader(void * arg)
|
||||
{
|
||||
replication_listener_t *rlt = (replication_listener_t*)arg;
|
||||
char *uri = rlt->server_url;
|
||||
map<int, string> tid2tname;
|
||||
map<int, string>::iterator tb_it;
|
||||
pthread_t id = pthread_self();
|
||||
string database_dot_table;
|
||||
const char* server_type;
|
||||
Gtid gtid();
|
||||
|
||||
try {
|
||||
Binary_log binlog(create_transport(uri));
|
||||
binlog.connect();
|
||||
|
||||
server_type = binlog.get_mysql_server_type_str();
|
||||
|
||||
cout << "Server " << uri << " type: " << server_type << endl;
|
||||
|
||||
Binary_log_event *event;
|
||||
|
||||
while (true) {
|
||||
Log_event_header *lheader;
|
||||
|
||||
int result = binlog.wait_for_next_event(&event);
|
||||
|
||||
if (result == ERR_EOF)
|
||||
break;
|
||||
|
||||
lheader = event->header();
|
||||
|
||||
switch(event->get_event_type()) {
|
||||
|
||||
case QUERY_EVENT: {
|
||||
Query_event *qevent = dynamic_cast<Query_event *>(event);
|
||||
|
||||
std::cout << "Thread: " << id << " server_id " << lheader->server_id
|
||||
<< " position " << lheader->next_position << " : Found event of type "
|
||||
<< event->get_event_type()
|
||||
<< " txt " << get_event_type_str(event->get_event_type())
|
||||
<< " query " << qevent->query << " db " << qevent->db_name
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case GTID_EVENT_MARIADB:
|
||||
case GTID_EVENT_MYSQL: {
|
||||
Gtid_event *gevent = dynamic_cast<Gtid_event *>(event);
|
||||
|
||||
std::cout << "Thread: " << id << " server_id " << lheader->server_id
|
||||
<< " position " << lheader->next_position << " : Found event of type "
|
||||
<< event->get_event_type()
|
||||
<< " txt " << get_event_type_str(event->get_event_type())
|
||||
<< " GTID " << std::string((char *)gevent->m_gtid.get_gtid())
|
||||
<< " GTID " << gevent->m_gtid.get_string()
|
||||
<< std::endl;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_MAP_EVENT: {
|
||||
Table_map_event *table_map_event= dynamic_cast<Table_map_event*>(event);
|
||||
database_dot_table= table_map_event->db_name;
|
||||
database_dot_table.append(".");
|
||||
database_dot_table.append(table_map_event->table_name);
|
||||
tid2tname[table_map_event->table_id]= database_dot_table;
|
||||
break;
|
||||
}
|
||||
|
||||
case WRITE_ROWS_EVENT:
|
||||
case UPDATE_ROWS_EVENT:
|
||||
case DELETE_ROWS_EVENT: {
|
||||
Row_event *revent = dynamic_cast<Row_event*>(event);
|
||||
tb_it= tid2tname.begin();
|
||||
tb_it= tid2tname.find(revent->table_id);
|
||||
if (tb_it != tid2tname.end())
|
||||
{
|
||||
database_dot_table= tb_it->second;
|
||||
}
|
||||
|
||||
std::cout << "Thread: " << id << " server_id " << lheader->server_id
|
||||
<< " position " << lheader->next_position << " : Found event of type "
|
||||
<< event->get_event_type()
|
||||
<< " txt " << get_event_type_str(event->get_event_type())
|
||||
<< " table " << revent->table_id
|
||||
<< " tb " << database_dot_table
|
||||
<< std::endl;
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
} // while
|
||||
} // try
|
||||
catch(ListenerException e)
|
||||
{
|
||||
std::cerr << "Listener exception: " << e.what() << std::endl;
|
||||
}
|
||||
catch(boost::system::error_code e)
|
||||
{
|
||||
std::cerr << "Listener system error: " << e.message() << std::endl;
|
||||
}
|
||||
// Try and catch all exceptions
|
||||
catch(std::exception const& e)
|
||||
{
|
||||
std::cerr << "Listener other error: " << e.what() << std::endl;
|
||||
}
|
||||
// Rest of them
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Unknown exception: " << std::endl;
|
||||
// Re-Throw this one.
|
||||
// It was not handled so you want to make sure it is handled correctly by
|
||||
// the OS. So just allow the exception to keep propagating.
|
||||
throw;
|
||||
}
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
int number_of_args = argc;
|
||||
int i=0,k=0;
|
||||
pthread_t *tid=NULL;
|
||||
char *uri;
|
||||
replication_listener_t *mrl;
|
||||
int err=0;
|
||||
|
||||
tid = (pthread_t*)malloc(sizeof(pthread_t) * argc);
|
||||
mrl = (replication_listener_t*)calloc(argc, sizeof(replication_listener_t));
|
||||
|
||||
if (argc < 2) {
|
||||
std::cerr << "Usage: basic-2 <uri>" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (mysql_library_init(num_elements, server_options, server_groups)) {
|
||||
std::cerr << "Failed to init MySQL server" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
argc =0;
|
||||
while(argc != number_of_args)
|
||||
{
|
||||
uri= argv[argc++];
|
||||
|
||||
if ( strncmp("mysql://", uri, 8) == 0) {
|
||||
|
||||
mrl[i].server_url = uri;
|
||||
|
||||
if (argc == 1) {
|
||||
mrl[i].is_master = 1;
|
||||
}
|
||||
|
||||
err = pthread_create(&(tid[i++]), NULL, &binlog_reader, (void *)&mrl[i]);
|
||||
|
||||
if (err ) {
|
||||
perror(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}//end of outer while loop
|
||||
|
||||
for(k=0; k < i; k++)
|
||||
{
|
||||
err = pthread_join(tid[k], (void **)&(mrl[k]));
|
||||
|
||||
if (err) {
|
||||
perror(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
project (mysql2lucene)
|
||||
|
||||
find_package(CLucene)
|
||||
|
||||
add_executable(mysql2lucene
|
||||
main.cpp table_delete.cpp table_index.cpp
|
||||
table_insert.cpp table_update.cpp)
|
||||
include_directories(${CLUCENE_INCLUDE_DIR} ${CLUCENE_LIBRARY_DIR})
|
||||
target_link_libraries(mysql2lucene ${CLUCENE_LIBRARY} replication_static)
|
@ -0,0 +1,34 @@
|
||||
# Install script for directory: /home/jan/skysql/skygateway/skygateway/replication_listener/examples/mysql2lucene
|
||||
|
||||
# Set the install prefix
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/local")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
IF(BUILD_TYPE)
|
||||
STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
ELSE(BUILD_TYPE)
|
||||
SET(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
||||
ENDIF(BUILD_TYPE)
|
||||
MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
|
||||
# Set the component getting installed.
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
IF(COMPONENT)
|
||||
MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
|
||||
SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
ELSE(COMPONENT)
|
||||
SET(CMAKE_INSTALL_COMPONENT)
|
||||
ENDIF(COMPONENT)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
# Install shared libraries without execute permission?
|
||||
IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
SET(CMAKE_INSTALL_SO_NO_EXE "1")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
|
34
replication_listener/examples/mysql2lucene/globals.h
Normal file
34
replication_listener/examples/mysql2lucene/globals.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: globals.h
|
||||
* Author: thek
|
||||
*
|
||||
* Created on den 15 juni 2010, 09:37
|
||||
*/
|
||||
|
||||
#ifndef _GLOBALS_H
|
||||
#define _GLOBALS_H
|
||||
#include <string>
|
||||
#include "binlog_api.h"
|
||||
extern std::string cl_index_file;
|
||||
|
||||
#endif /* _GLOBALS_H */
|
212
replication_listener/examples/mysql2lucene/main.cpp
Normal file
212
replication_listener/examples/mysql2lucene/main.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: main.cpp
|
||||
* Author: thek
|
||||
*
|
||||
* Created on den 12 maj 2010, 14:47
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <boost/foreach.hpp>
|
||||
#include "binlog_api.h"
|
||||
|
||||
#include "table_update.h"
|
||||
#include "table_delete.h"
|
||||
#include "table_insert.h"
|
||||
|
||||
#include "table_index.h"
|
||||
|
||||
using mysql::system::create_transport;
|
||||
using mysql::Binary_log;
|
||||
|
||||
std::string cl_index_file;
|
||||
|
||||
class Incident_handler : public mysql::Content_handler
|
||||
{
|
||||
public:
|
||||
Incident_handler() : mysql::Content_handler() {}
|
||||
|
||||
Binary_log_event *process_event(mysql::Incident_event *incident)
|
||||
{
|
||||
std::cout << "Event type: "
|
||||
<< mysql::system::get_event_type_str(incident->get_event_type())
|
||||
<< " length: " << incident->header()->event_length
|
||||
<< " next pos: " << incident->header()->next_position
|
||||
<< std::endl;
|
||||
std::cout << "type= "
|
||||
<< (unsigned)incident->type
|
||||
<< " message= "
|
||||
<< incident->message
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
/* Consume the event */
|
||||
delete incident;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class Applier : public mysql::Content_handler
|
||||
{
|
||||
public:
|
||||
Applier(Table_index *index)
|
||||
{
|
||||
m_table_index= index;
|
||||
}
|
||||
|
||||
mysql::Binary_log_event *process_event(mysql::Row_event *rev)
|
||||
{
|
||||
boost::uint64_t table_id= rev->table_id;
|
||||
Int2event_map::iterator ti_it= m_table_index->find(table_id);
|
||||
if (ti_it == m_table_index->end ())
|
||||
{
|
||||
std::cout << "Table id "
|
||||
<< table_id
|
||||
<< " was not registered by any preceding table map event."
|
||||
<< std::endl;
|
||||
return rev;
|
||||
}
|
||||
/*
|
||||
Each row event contains multiple rows and fields. The Row_iterator
|
||||
allows us to iterate one row at a time.
|
||||
*/
|
||||
mysql::Row_event_set rows(rev, ti_it->second);
|
||||
/*
|
||||
Create a fuly qualified table name
|
||||
*/
|
||||
std::ostringstream os;
|
||||
os << ti_it->second->db_name << '.' << ti_it->second->table_name;
|
||||
mysql::Row_event_set::iterator it= rows.begin();
|
||||
do {
|
||||
mysql::Row_of_fields fields= *it;
|
||||
if (rev->get_event_type() == mysql::WRITE_ROWS_EVENT)
|
||||
table_insert(os.str(),fields);
|
||||
if (rev->get_event_type() == mysql::UPDATE_ROWS_EVENT)
|
||||
{
|
||||
++it;
|
||||
mysql::Row_of_fields fields2= *it;
|
||||
table_update(os.str(),fields,fields2);
|
||||
}
|
||||
if (rev->get_event_type() == mysql::DELETE_ROWS_EVENT)
|
||||
table_delete(os.str(),fields);
|
||||
} while (++it != rows.end());
|
||||
|
||||
/* Consume the event */
|
||||
delete rev;
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
Table_index *m_table_index;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
fprintf(stderr,"Usage:\n\nmysql2lucene URL\n\nExample:\n\nmysql2lucene mysql://root@127.0.0.1:3306 myindexfile\n\n");
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
Binary_log binlog(create_transport(argv[1]));
|
||||
|
||||
|
||||
cl_index_file.append (argv[2]);
|
||||
|
||||
/*
|
||||
Attach a custom event content handlers
|
||||
*/
|
||||
Incident_handler incident_hndlr;
|
||||
Table_index table_event_hdlr;
|
||||
Applier replay_hndlr(&table_event_hdlr);
|
||||
|
||||
binlog.content_handler_pipeline()->push_back(&table_event_hdlr);
|
||||
binlog.content_handler_pipeline()->push_back(&incident_hndlr);
|
||||
binlog.content_handler_pipeline()->push_back(&replay_hndlr);
|
||||
|
||||
if (binlog.connect())
|
||||
{
|
||||
fprintf(stderr,"Can't connect to the master.\n");
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
binlog.set_position("searchbin.000001", 4);
|
||||
|
||||
bool quit= false;
|
||||
while(!quit)
|
||||
{
|
||||
/*
|
||||
Pull events from the master. This is the heart beat of the event listener.
|
||||
*/
|
||||
Binary_log_event *event;
|
||||
binlog.wait_for_next_event(&event);
|
||||
|
||||
/*
|
||||
Print the event
|
||||
*/
|
||||
std::cout << "Event type: "
|
||||
<< mysql::system::get_event_type_str(event->get_event_type())
|
||||
<< " length: " << event->header()->event_length
|
||||
<< " next pos: " << event->header()->next_position
|
||||
<< std::endl;
|
||||
|
||||
/*
|
||||
Perform a special action based on event type
|
||||
*/
|
||||
|
||||
switch(event->header()->type_code)
|
||||
{
|
||||
case mysql::QUERY_EVENT:
|
||||
{
|
||||
const mysql::Query_event *qev= static_cast<const mysql::Query_event *>(event);
|
||||
std::cout << "query= "
|
||||
<< qev->query
|
||||
<< " db= "
|
||||
<< qev->db_name
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
if (qev->query.find("DROP TABLE REPLICATION_LISTENER") != std::string::npos)
|
||||
{
|
||||
quit= true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case mysql::ROTATE_EVENT:
|
||||
{
|
||||
mysql::Rotate_event *rot= static_cast<mysql::Rotate_event *>(event);
|
||||
std::cout << "filename= "
|
||||
<< rot->binlog_file.c_str()
|
||||
<< " pos= "
|
||||
<< rot->binlog_pos
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
} // end switch
|
||||
delete event;
|
||||
} // end loop
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
96
replication_listener/examples/mysql2lucene/table_delete.cpp
Normal file
96
replication_listener/examples/mysql2lucene/table_delete.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "globals.h"
|
||||
#include "table_delete.h"
|
||||
|
||||
#include <CLucene.h>
|
||||
|
||||
CL_NS_USE(index)
|
||||
CL_NS_USE(util)
|
||||
CL_NS_USE(store)
|
||||
CL_NS_USE(search)
|
||||
CL_NS_USE(document)
|
||||
CL_NS_USE(queryParser)
|
||||
CL_NS_USE(analysis)
|
||||
CL_NS_USE2(analysis,standard)
|
||||
|
||||
void table_delete(std::string table_name, mysql::Row_of_fields &fields)
|
||||
{
|
||||
|
||||
mysql::Row_of_fields::iterator field_it= fields.begin();
|
||||
/*
|
||||
* First column must be an integer key value
|
||||
*/
|
||||
if (!(field_it->type() == mysql::system::MYSQL_TYPE_LONG ||
|
||||
field_it->type() == mysql::system::MYSQL_TYPE_SHORT ||
|
||||
field_it->type() == mysql::system::MYSQL_TYPE_LONGLONG))
|
||||
return;
|
||||
|
||||
int field_id= 0;
|
||||
std::string key;
|
||||
std::string combined_key;
|
||||
mysql::Converter converter;
|
||||
converter.to(key, *field_it);
|
||||
combined_key.append (table_name);
|
||||
combined_key.append ("_");
|
||||
combined_key.append (key);
|
||||
do {
|
||||
/*
|
||||
Each row contains a vector of Value objects. The converter
|
||||
allows us to transform the value into another
|
||||
representation.
|
||||
Only index fields which might contain searchable information.
|
||||
*/
|
||||
if (field_it->type() == mysql::system::MYSQL_TYPE_VARCHAR ||
|
||||
field_it->type() == mysql::system::MYSQL_TYPE_MEDIUM_BLOB ||
|
||||
field_it->type() == mysql::system::MYSQL_TYPE_BLOB)
|
||||
{
|
||||
std::string str;
|
||||
converter.to(str, *field_it);
|
||||
StandardAnalyzer an;
|
||||
IndexReader *reader;
|
||||
/*
|
||||
* Create a Lucene index writer
|
||||
*/
|
||||
if ( IndexReader::indexExists(cl_index_file.c_str()) )
|
||||
{
|
||||
if ( IndexReader::isLocked(cl_index_file.c_str()) )
|
||||
{
|
||||
std::cout << "Index was locked; unlocking it."
|
||||
<< std::endl;
|
||||
IndexReader::unlock(cl_index_file.c_str());
|
||||
}
|
||||
reader= IndexReader::open(cl_index_file.c_str());
|
||||
}
|
||||
|
||||
std::cout << "Deleting index '"
|
||||
<< combined_key
|
||||
<< "'" << std::endl;
|
||||
TCHAR *combined_key_w= STRDUP_AtoW(combined_key.c_str ());
|
||||
Term uniqueKey(_T("id"),combined_key_w);
|
||||
reader->deleteDocuments(&uniqueKey);
|
||||
delete combined_key_w;
|
||||
reader->close();
|
||||
delete reader;
|
||||
break;
|
||||
}
|
||||
} while(++field_it != fields.end());
|
||||
}
|
35
replication_listener/examples/mysql2lucene/table_delete.h
Normal file
35
replication_listener/examples/mysql2lucene/table_delete.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: table_delete.h
|
||||
* Author: thek
|
||||
*
|
||||
* Created on den 17 juni 2010, 14:28
|
||||
*/
|
||||
|
||||
#ifndef _TABLE_DELETE_H
|
||||
#define _TABLE_DELETE_H
|
||||
#include <string>
|
||||
#include "binlog_api.h"
|
||||
|
||||
void table_delete(std::string table_name, mysql::Row_of_fields &fields);
|
||||
|
||||
#endif /* _TABLE_DELETE_H */
|
54
replication_listener/examples/mysql2lucene/table_index.cpp
Normal file
54
replication_listener/examples/mysql2lucene/table_index.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "table_index.h"
|
||||
|
||||
mysql::Binary_log_event *Table_index::process_event(mysql::Table_map_event *tm)
|
||||
{
|
||||
if (find(tm->table_id) == end())
|
||||
insert(Event_index_element(tm->table_id,tm));
|
||||
|
||||
/* Consume this event so it won't be deallocated beneith our feet */
|
||||
return 0;
|
||||
}
|
||||
|
||||
Table_index::~Table_index ()
|
||||
{
|
||||
Int2event_map::iterator it= begin();
|
||||
do
|
||||
{
|
||||
delete it->second;
|
||||
} while( ++it != end());
|
||||
}
|
||||
|
||||
int Table_index::get_table_name(int table_id, std::string out)
|
||||
{
|
||||
iterator it;
|
||||
if ((it= find(table_id)) == end())
|
||||
{
|
||||
std::stringstream os;
|
||||
os << "unknown_table_" << table_id;
|
||||
out.append(os.str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
out.append(it->second->table_name);
|
||||
return 0;
|
||||
}
|
49
replication_listener/examples/mysql2lucene/table_index.h
Normal file
49
replication_listener/examples/mysql2lucene/table_index.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: table_index.h
|
||||
* Author: thek
|
||||
*
|
||||
* Created on den 8 september 2010, 13:47
|
||||
*/
|
||||
|
||||
#ifndef TABLE_INDEX_H
|
||||
#define TABLE_INDEX_H
|
||||
#include "binlog_event.h"
|
||||
#include <map>
|
||||
#include "basic_content_handler.h"
|
||||
|
||||
typedef std::pair<boost::uint64_t, mysql::Table_map_event *> Event_index_element;
|
||||
typedef std::map<boost::uint64_t, mysql::Table_map_event *> Int2event_map;
|
||||
|
||||
class Table_index : public mysql::Content_handler, public Int2event_map
|
||||
{
|
||||
public:
|
||||
mysql::Binary_log_event *process_event(mysql::Table_map_event *tm);
|
||||
|
||||
~Table_index();
|
||||
|
||||
int get_table_name(int table_id, std::string out);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* TABLE_INDEX_H */
|
152
replication_listener/examples/mysql2lucene/table_insert.cpp
Normal file
152
replication_listener/examples/mysql2lucene/table_insert.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "globals.h"
|
||||
#include "table_insert.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <CLucene.h>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
CL_NS_USE(index)
|
||||
CL_NS_USE(util)
|
||||
CL_NS_USE(store)
|
||||
CL_NS_USE(search)
|
||||
CL_NS_USE(document)
|
||||
CL_NS_USE(queryParser)
|
||||
CL_NS_USE(analysis)
|
||||
CL_NS_USE2(analysis,standard)
|
||||
|
||||
void table_insert(std::string table_name, mysql::Row_of_fields &fields)
|
||||
{
|
||||
mysql::Row_of_fields::iterator field_it= fields.begin();
|
||||
/*
|
||||
* First column must be an integer key value
|
||||
*/
|
||||
if (!(field_it->type() == mysql::system::MYSQL_TYPE_LONG ||
|
||||
field_it->type() == mysql::system::MYSQL_TYPE_SHORT ||
|
||||
field_it->type() == mysql::system::MYSQL_TYPE_LONGLONG))
|
||||
return;
|
||||
|
||||
Document *doc= new Document();
|
||||
IndexWriter* writer = NULL;
|
||||
StandardAnalyzer an;
|
||||
mysql::Converter converter;
|
||||
bool found_searchable= false;
|
||||
int col= 0;
|
||||
TCHAR *w_table_name;
|
||||
TCHAR *w_str;
|
||||
TCHAR *w_key_str;
|
||||
TCHAR *w_combined_key;
|
||||
std::string aggstr;
|
||||
|
||||
/*
|
||||
* Create a Lucene index writer
|
||||
*/
|
||||
if ( IndexReader::indexExists(cl_index_file.c_str()) )
|
||||
{
|
||||
if ( IndexReader::isLocked(cl_index_file.c_str()) )
|
||||
{
|
||||
printf("Index was locked... unlocking it.\n");
|
||||
IndexReader::unlock(cl_index_file.c_str());
|
||||
}
|
||||
writer = new IndexWriter( cl_index_file.c_str(), &an, false);
|
||||
}else{
|
||||
writer = new IndexWriter( cl_index_file.c_str() ,&an, true);
|
||||
}
|
||||
writer->setMaxFieldLength(IndexWriter::DEFAULT_MAX_FIELD_LENGTH);
|
||||
|
||||
/*
|
||||
* Save the presumed table key for later use when we discover if this row
|
||||
* should be indexed.
|
||||
*/
|
||||
std::string key;
|
||||
converter.to(key, *field_it);
|
||||
|
||||
do {
|
||||
/*
|
||||
Each row contains a vector of Value objects. The converter
|
||||
allows us to transform the value into another
|
||||
representation.
|
||||
Only index fields which might contain searchable information.
|
||||
*/
|
||||
if (field_it->type() == mysql::system::MYSQL_TYPE_VARCHAR ||
|
||||
field_it->type() == mysql::system::MYSQL_TYPE_MEDIUM_BLOB ||
|
||||
field_it->type() == mysql::system::MYSQL_TYPE_BLOB)
|
||||
{
|
||||
std::string str;
|
||||
converter.to(str, *field_it);
|
||||
if (!found_searchable)
|
||||
{
|
||||
std::string combined_key;
|
||||
combined_key.append(table_name);
|
||||
combined_key.append("_");
|
||||
combined_key.append(key);
|
||||
w_table_name= STRDUP_AtoW(table_name.c_str());
|
||||
Field *table_field= new Field(_T("table"),w_table_name, Field::STORE_YES | Field::INDEX_UNTOKENIZED);
|
||||
doc->add( *table_field );
|
||||
found_searchable= true;
|
||||
w_key_str= STRDUP_AtoW(key.c_str());
|
||||
Field *key_field= new Field(_T("row_id"),w_key_str, Field::STORE_YES | Field::INDEX_UNTOKENIZED);
|
||||
doc->add(*key_field);
|
||||
w_combined_key= STRDUP_AtoW(combined_key.c_str());
|
||||
Field *combined_key_field= new Field(_T("id"),w_combined_key, Field::STORE_YES | Field::INDEX_UNTOKENIZED);
|
||||
doc->add(*combined_key_field);
|
||||
}
|
||||
/*
|
||||
* Aggregate all searchable information into one string. The key is the
|
||||
* qualified table name.
|
||||
*/
|
||||
aggstr.append(" "); // This separator helps us loosing important tokens.
|
||||
aggstr.append(str);
|
||||
++col;
|
||||
}
|
||||
} while(++field_it != fields.end());
|
||||
if (found_searchable)
|
||||
{
|
||||
std::cout << "Indexing "
|
||||
<< aggstr.length()
|
||||
<< " characters in table '"
|
||||
<< table_name
|
||||
<< "' using key value '"
|
||||
<< key
|
||||
<< "'."
|
||||
<< std::endl;
|
||||
std::cout.flush ();
|
||||
w_str= STRDUP_AtoW(aggstr.c_str());
|
||||
Field *content_field= new Field(_T("text"),w_str, Field::STORE_YES | Field::INDEX_TOKENIZED);
|
||||
doc->add( *content_field );
|
||||
}
|
||||
writer->addDocument(doc);
|
||||
writer->close();
|
||||
|
||||
/*
|
||||
* Clean up dynamic allocations during indexing
|
||||
*/
|
||||
if (found_searchable)
|
||||
{
|
||||
free(w_table_name);
|
||||
free(w_str);
|
||||
free(w_key_str);
|
||||
free(w_combined_key);
|
||||
}
|
||||
delete(doc);
|
||||
delete(writer);
|
||||
}
|
36
replication_listener/examples/mysql2lucene/table_insert.h
Normal file
36
replication_listener/examples/mysql2lucene/table_insert.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: table_insert.h
|
||||
* Author: thek
|
||||
*
|
||||
* Created on den 15 juni 2010, 09:34
|
||||
*/
|
||||
|
||||
#ifndef _TABLE_INSERT_H
|
||||
#define _TABLE_INSERT_H
|
||||
|
||||
#include <string>
|
||||
#include "binlog_api.h"
|
||||
|
||||
void table_insert(std::string table_name, mysql::Row_of_fields &fields);
|
||||
|
||||
#endif /* _TABLE_INSERT_H */
|
37
replication_listener/examples/mysql2lucene/table_update.cpp
Normal file
37
replication_listener/examples/mysql2lucene/table_update.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "table_update.h"
|
||||
#include "table_insert.h"
|
||||
#include "table_delete.h"
|
||||
|
||||
void table_update(std::string table_name, mysql::Row_of_fields &old_fields, mysql::Row_of_fields &new_fields)
|
||||
{
|
||||
/*
|
||||
Find previous entry and delete it.
|
||||
*/
|
||||
table_delete(table_name, old_fields);
|
||||
|
||||
/*
|
||||
Insert new entry.
|
||||
*/
|
||||
table_insert(table_name, new_fields);
|
||||
|
||||
}
|
34
replication_listener/examples/mysql2lucene/table_update.h
Normal file
34
replication_listener/examples/mysql2lucene/table_update.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: table_update.h
|
||||
* Author: thek
|
||||
*
|
||||
* Created on den 17 juni 2010, 14:27
|
||||
*/
|
||||
|
||||
#ifndef _TABLE_UPDATE_H
|
||||
#define _TABLE_UPDATE_H
|
||||
#include <string>
|
||||
#include "binlog_api.h"
|
||||
void table_update(std::string table_name, mysql::Row_of_fields &old_fields, mysql::Row_of_fields &new_fields);
|
||||
|
||||
#endif /* _TABLE_UPDATE_H */
|
35
replication_listener/examples/test.sql
Normal file
35
replication_listener/examples/test.sql
Normal file
@ -0,0 +1,35 @@
|
||||
DROP DATABASE NEW1;
|
||||
DROP DATABASE NEW2;
|
||||
CREATE DATABASE NEW1;
|
||||
CREATE DATABASE NEW2;
|
||||
USE NEW1;
|
||||
CREATE TABLE NEW_TEST1(A INT NOT NULL PRIMARY KEY, B INT) ENGINE=INNODB;
|
||||
CREATE TABLE NEW_TEST2(A INT NOT NULL PRIMARY KEY, B INT) ENGINE=INNODB;
|
||||
USE NEW2;
|
||||
CREATE TABLE NEW_TEST3(A INT NOT NULL PRIMARY KEY, B INT) ENGINE=INNODB;
|
||||
CREATE TABLE NEW_TEST4(A INT NOT NULL PRIMARY KEY, B INT) ENGINE=INNODB;
|
||||
USE NEW1;
|
||||
INSERT INTO NEW_TEST1 VALUES (1,1),(2,2)(3,3),(4,4);
|
||||
INSERT INTO NEW_TEST1 VALUES (5,5),(6,2)(7,3),(8,4);
|
||||
INSERT INTO NEW_TEST2 VALUES (1,1),(2,2)(3,3),(4,4);
|
||||
INSERT INTO NEW_TEST2 VALUES (5,5),(6,2)(7,3),(8,4);
|
||||
INSERT INTO NEW_TEST1 VALUES (9,9);
|
||||
USE NEW2;
|
||||
INSERT INTO NEW_TEST3 VALUES (1,1),(2,2)(3,3),(4,4);
|
||||
INSERT INTO NEW_TEST3 VALUES (5,5),(6,2)(7,3),(8,4);
|
||||
INSERT INTO NEW_TEST4 VALUES (1,1),(2,2)(3,3),(4,4);
|
||||
INSERT INTO NEW_TEST4 VALUES (5,5),(6,2)(7,3),(8,4);
|
||||
INSERT INTO NEW_TEST4 VALUES (9,9);
|
||||
COMMIT;
|
||||
USE NEW1;
|
||||
UPDATE NEW_TEST1 SET B = B + 1;
|
||||
USE NEW2;
|
||||
UPDATE NEW_TEST4 SET B = B + 1;
|
||||
COMMIT;
|
||||
DELETE FROM NEW1.NEW_TEST2 WHERE A = 3;
|
||||
DELETE FROM NEW2.NEW_TEST3 WHERE A = 3;
|
||||
UPDATE NEW1.NEW_TEST1 SET B = B + 5 WHERE A = 4;
|
||||
UPDATE NEW2.NEW_TEST4 SET B = B + 5 WHERE A = 4;
|
||||
USE NEW1;
|
||||
DROP TABLE NEW_TEST1;
|
||||
DROP TABLE NEW2.NEW_TEST3;
|
16
replication_listener/homebrew/mysql-replication-listener.rb
Normal file
16
replication_listener/homebrew/mysql-replication-listener.rb
Normal file
@ -0,0 +1,16 @@
|
||||
require 'formula'
|
||||
|
||||
class MysqlReplicationListener < Formula
|
||||
url 'https://bitbucket.org/winebarrel/mysql-replication-listener.git', :tag => '0.0.47-10'
|
||||
homepage 'https://bitbucket.org/winebarrel/mysql-replication-listener'
|
||||
|
||||
depends_on 'cmake'
|
||||
depends_on 'boost'
|
||||
#depends_on 'openssl'
|
||||
|
||||
def install
|
||||
system 'cmake', '.'
|
||||
system 'make'
|
||||
system 'make install'
|
||||
end
|
||||
end
|
36
replication_listener/include/access_method_factory.h
Normal file
36
replication_listener/include/access_method_factory.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _ACCESS_METHOD_FACTORY_H
|
||||
#define _ACCESS_METHOD_FACTORY_H
|
||||
|
||||
#include "binlog_driver.h"
|
||||
|
||||
namespace mysql {
|
||||
namespace system {
|
||||
Binary_log_driver *create_transport(const char *url);
|
||||
Binary_log_driver *parse_mysql_url(char *url, const char
|
||||
*mysql_access_method);
|
||||
Binary_log_driver *parse_file_url(char *url, const char
|
||||
*file_access_method);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _ACCESS_METHOD_FACTORY_H */
|
81
replication_listener/include/basic_content_handler.h
Normal file
81
replication_listener/include/basic_content_handler.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
#ifndef BASIC_CONTENT_HANDLER_H
|
||||
#define BASIC_CONTENT_HANDLER_H
|
||||
|
||||
#include "binlog_event.h"
|
||||
|
||||
namespace mysql {
|
||||
|
||||
class Injection_queue : public std::list<mysql::Binary_log_event * >
|
||||
{
|
||||
public:
|
||||
Injection_queue() : std::list<mysql::Binary_log_event * >() {}
|
||||
~Injection_queue() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* A content handler accepts an event and returns the same event,
|
||||
* a new one or 0 (the event was consumed by the content handler).
|
||||
* The default behaviour is to return the event unaffected.
|
||||
* The generic event handler is used for events which aren't routed to
|
||||
* a dedicated member function, user defined events being the most
|
||||
* common case.
|
||||
*/
|
||||
|
||||
class Content_handler {
|
||||
public:
|
||||
Content_handler();
|
||||
Content_handler(const mysql::Content_handler& orig);
|
||||
virtual ~Content_handler();
|
||||
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Query_event *ev);
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Row_event *ev);
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Table_map_event *ev);
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Xid *ev);
|
||||
virtual mysql::Binary_log_event *process_event(mysql::User_var_event *ev);
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Incident_event *ev);
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Rotate_event *ev);
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Int_var_event *ev);
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Gtid_event *ev);
|
||||
|
||||
/**
|
||||
Process any event which hasn't been registered yet.
|
||||
*/
|
||||
virtual mysql::Binary_log_event *process_event(mysql::Binary_log_event *ev);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The Injection queue is emptied before any new event is pulled from
|
||||
* the Binary_log_driver. Injected events will pass through all content
|
||||
* handlers. The Injection_queue is a derived std::list.
|
||||
*/
|
||||
Injection_queue *get_injection_queue();
|
||||
|
||||
private:
|
||||
Injection_queue *m_reinject_queue;
|
||||
void set_injection_queue(Injection_queue *injection_queue);
|
||||
mysql::Binary_log_event *internal_process_event(mysql::Binary_log_event *ev);
|
||||
|
||||
friend class Binary_log;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
#endif /* BASIC_CONTENT_HANDLER_H */
|
83
replication_listener/include/basic_transaction_parser.h
Normal file
83
replication_listener/include/basic_transaction_parser.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
#ifndef _BASIC_TRANSACTION_PARSER_H
|
||||
#define _BASIC_TRANSACTION_PARSER_H
|
||||
|
||||
/*
|
||||
TODO The Transaction_log_event and Basic_transaction_parser will be removed
|
||||
from this library and replaced with a table map indexer instead which can be
|
||||
used to retrive table names.
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "binlog_event.h"
|
||||
#include "basic_content_handler.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mysql {
|
||||
typedef std::pair<boost::uint64_t, Binary_log_event *> Event_index_element;
|
||||
typedef std::map<boost::uint64_t, Binary_log_event *> Int_to_Event_map;
|
||||
class Transaction_log_event : public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Transaction_log_event() : Binary_log_event() {}
|
||||
Transaction_log_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
virtual ~Transaction_log_event();
|
||||
|
||||
Int_to_Event_map &table_map() { return m_table_map; }
|
||||
/**
|
||||
* Index for easier table name look up
|
||||
*/
|
||||
Int_to_Event_map m_table_map;
|
||||
|
||||
std::list<Binary_log_event *> m_events;
|
||||
};
|
||||
|
||||
Transaction_log_event *create_transaction_log_event(void);
|
||||
|
||||
class Basic_transaction_parser : public mysql::Content_handler
|
||||
{
|
||||
public:
|
||||
Basic_transaction_parser() : mysql::Content_handler()
|
||||
{
|
||||
m_transaction_state= NOT_IN_PROGRESS;
|
||||
}
|
||||
|
||||
mysql::Binary_log_event *process_event(mysql::Query_event *ev);
|
||||
mysql::Binary_log_event *process_event(mysql::Row_event *ev);
|
||||
mysql::Binary_log_event *process_event(mysql::Table_map_event *ev);
|
||||
mysql::Binary_log_event *process_event(mysql::Xid *ev);
|
||||
mysql::Binary_log_event *process_event(mysql::Binary_log_event *ev) {return ev; }
|
||||
mysql::Binary_log_event *process_event(mysql::Gtid_event *ev);
|
||||
|
||||
private:
|
||||
boost::uint32_t m_start_time;
|
||||
enum Transaction_states { STARTING, IN_PROGRESS, COMMITTING, NOT_IN_PROGRESS } ;
|
||||
enum Transaction_states m_transaction_state;
|
||||
std::list <mysql::Binary_log_event *> m_event_stack;
|
||||
mysql::Binary_log_event *process_transaction_state(mysql::Binary_log_event *ev);
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
||||
#endif /* _BASIC_TRANSACTION_PARSER_H */
|
||||
|
179
replication_listener/include/binlog_api.h
Normal file
179
replication_listener/include/binlog_api.h
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _REPEVENT_H
|
||||
#define _REPEVENT_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
#include <boost/iostreams/concepts.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <list>
|
||||
#include <cassert>
|
||||
#include "binlog_event.h"
|
||||
#include "binlog_driver.h"
|
||||
#include "tcp_driver.h"
|
||||
#include "file_driver.h"
|
||||
#include "basic_content_handler.h"
|
||||
#include "basic_transaction_parser.h"
|
||||
#include "field_iterator.h"
|
||||
#include "rowset.h"
|
||||
#include "access_method_factory.h"
|
||||
#include "gtid.h"
|
||||
|
||||
namespace io = boost::iostreams;
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
/**
|
||||
* Error codes.
|
||||
*/
|
||||
enum Error_code {
|
||||
ERR_OK = 0, /* All OK */
|
||||
ERR_EOF, /* End of file */
|
||||
ERR_FAIL, /* Unspecified failure */
|
||||
ERROR_CODE_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the event is consumed
|
||||
*/
|
||||
typedef boost::function< bool (Binary_log_event *& )> Event_content_handler;
|
||||
|
||||
class Dummy_driver : public system::Binary_log_driver
|
||||
{
|
||||
public:
|
||||
Dummy_driver() : Binary_log_driver("", 0) {}
|
||||
virtual ~Dummy_driver() {}
|
||||
|
||||
virtual int connect(Gtid gtid = Gtid()) { return 1; }
|
||||
|
||||
virtual int wait_for_next_event(mysql::Binary_log_event **event) {
|
||||
return ERR_EOF;
|
||||
}
|
||||
|
||||
virtual int set_position(const std::string &str, unsigned long position) {
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
virtual int set_position_gtid(const Gtid gtid) {
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
virtual int get_position(std::string *str, unsigned long *position) {
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
virtual int fetch_server_version(const std::string& user,
|
||||
const std::string& passwd,
|
||||
const std::string& host,
|
||||
long port)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
virtual void shutdown() {}
|
||||
|
||||
};
|
||||
|
||||
class Content_handler;
|
||||
|
||||
typedef std::list<Content_handler *> Content_handler_pipeline;
|
||||
|
||||
class Binary_log {
|
||||
private:
|
||||
system::Binary_log_driver *m_driver;
|
||||
Dummy_driver m_dummy_driver;
|
||||
Content_handler_pipeline m_content_handlers;
|
||||
unsigned long m_binlog_position;
|
||||
std::string m_binlog_file;
|
||||
mysql_server_types m_server_type;
|
||||
std::string m_uri;
|
||||
public:
|
||||
Binary_log(system::Binary_log_driver *drv);
|
||||
Binary_log(system::Binary_log_driver *drv, std::string);
|
||||
~Binary_log() {}
|
||||
|
||||
int connect(Gtid gtid = Gtid());
|
||||
|
||||
/**
|
||||
* Blocking attempt to get the next binlog event from the stream
|
||||
*/
|
||||
int wait_for_next_event(Binary_log_event **event);
|
||||
|
||||
|
||||
/**
|
||||
* Inserts/removes content handlers in and out of the chain
|
||||
* The Content_handler_pipeline is a derived std::list
|
||||
*/
|
||||
Content_handler_pipeline *content_handler_pipeline();
|
||||
|
||||
/**
|
||||
* Set the binlog position (filename, position)
|
||||
*
|
||||
* @return Error_code
|
||||
* @retval ERR_OK The position is updated.
|
||||
* @retval ERR_EOF The position is out-of-range
|
||||
* @retval >= ERR_CODE_COUNT An unspecified error occurred
|
||||
*/
|
||||
int set_position(const std::string &filename, unsigned long position);
|
||||
|
||||
/**
|
||||
* Set the binlog position using current filename
|
||||
* @param position Requested position
|
||||
*
|
||||
* @return Error_code
|
||||
* @retval ERR_OK The position is updated.
|
||||
* @retval ERR_EOF The position is out-of-range
|
||||
* @retval >= ERR_CODE_COUNT An unspecified error occurred
|
||||
*/
|
||||
int set_position(unsigned long position);
|
||||
|
||||
int set_position_gtid(const Gtid gtid);
|
||||
|
||||
/**
|
||||
* Fetch the binlog position for the current file
|
||||
*/
|
||||
unsigned long get_position(void);
|
||||
|
||||
/**
|
||||
* Fetch the current active binlog file name.
|
||||
* @param[out] filename
|
||||
* TODO replace reference with a pointer.
|
||||
* @return The file position
|
||||
*/
|
||||
unsigned long get_position(std::string &filename);
|
||||
|
||||
mysql_server_types get_mysql_server_type() const;
|
||||
const char *get_mysql_server_type_str() const;
|
||||
|
||||
std::string get_url() const {return m_uri; }
|
||||
|
||||
void shutdown();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _REPEVENT_H */
|
104
replication_listener/include/binlog_driver.h
Normal file
104
replication_listener/include/binlog_driver.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _BINLOG_DRIVER_H
|
||||
#define _BINLOG_DRIVER_H
|
||||
#include "binlog_event.h"
|
||||
#include "protocol.h"
|
||||
#include "gtid.h"
|
||||
|
||||
namespace mysql {
|
||||
namespace system {
|
||||
|
||||
class Binary_log_driver
|
||||
{
|
||||
public:
|
||||
template <class FilenameT>
|
||||
Binary_log_driver(const FilenameT& filename = FilenameT(), unsigned int offset = 0)
|
||||
: m_binlog_file_name(filename), m_binlog_offset(offset), m_server_type(MYSQL_SERVER_TYPE_NA)
|
||||
{
|
||||
}
|
||||
|
||||
~Binary_log_driver() {}
|
||||
|
||||
/**
|
||||
* Connect to the binary log using previously declared connection parameters
|
||||
* @return Success or error code
|
||||
* @retval 0 Success
|
||||
* @retval >0 Error code (to be specified)
|
||||
*/
|
||||
virtual int connect(Gtid gtid = Gtid())= 0;
|
||||
|
||||
|
||||
/**
|
||||
* Blocking attempt to get the next binlog event from the stream
|
||||
* @param event [out] Pointer to a binary log event to be fetched.
|
||||
*/
|
||||
virtual int wait_for_next_event(mysql::Binary_log_event **event)= 0;
|
||||
|
||||
/**
|
||||
* Set the reader position
|
||||
* @param str The file name
|
||||
* @param position The file position
|
||||
*
|
||||
* @return False on success and True if an error occurred.
|
||||
*/
|
||||
virtual int set_position(const std::string &str, unsigned long position)= 0;
|
||||
|
||||
virtual int set_position_gtid(const Gtid gtid) = 0;
|
||||
|
||||
/**
|
||||
* Get the read position.
|
||||
*
|
||||
* @param[out] string_ptr Pointer to location where the filename will be stored.
|
||||
* @param[out] position_ptr Pointer to location where the position will be stored.
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval >0 Error code
|
||||
*/
|
||||
virtual int get_position(std::string *filename_ptr, unsigned long *position_ptr) = 0;
|
||||
|
||||
virtual int fetch_server_version(const std::string& user,
|
||||
const std::string& passwd,
|
||||
const std::string& host,
|
||||
long port) = 0;
|
||||
|
||||
virtual void shutdown() = 0;
|
||||
|
||||
Binary_log_event* parse_event(std::istream &sbuff, Log_event_header *header);
|
||||
|
||||
mysql_server_types get_mysql_server_type() const
|
||||
{
|
||||
return m_server_type;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Used each time the client reconnects to the server to specify an
|
||||
* offset position.
|
||||
*/
|
||||
unsigned long m_binlog_offset;
|
||||
std::string m_binlog_file_name;
|
||||
mysql_server_types m_server_type;
|
||||
};
|
||||
|
||||
} // namespace mysql::system
|
||||
} // namespace mysql
|
||||
#endif /* _BINLOG_DRIVER_H */
|
287
replication_listener/include/binlog_event.h
Normal file
287
replication_listener/include/binlog_event.h
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
#ifndef _BINLOG_EVENT_H
|
||||
#define _BINLOG_EVENT_H
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <list>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <vector>
|
||||
#include "gtid.h"
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
/**
|
||||
@enum Log_event_type
|
||||
|
||||
Enumeration type for the different types of log events.
|
||||
*/
|
||||
enum Log_event_type
|
||||
{
|
||||
/*
|
||||
Every time you update this enum (when you add a type), you have to
|
||||
fix Format_description_log_event::Format_description_log_event().
|
||||
*/
|
||||
UNKNOWN_EVENT= 0,
|
||||
START_EVENT_V3= 1,
|
||||
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
|
||||
sql_ex, allowing multibyte TERMINATED BY etc; both types share the
|
||||
same class (Load_log_event)
|
||||
*/
|
||||
NEW_LOAD_EVENT= 12,
|
||||
RAND_EVENT= 13,
|
||||
USER_VAR_EVENT= 14,
|
||||
FORMAT_DESCRIPTION_EVENT= 15,
|
||||
XID_EVENT= 16,
|
||||
BEGIN_LOAD_QUERY_EVENT= 17,
|
||||
EXECUTE_LOAD_QUERY_EVENT= 18,
|
||||
|
||||
TABLE_MAP_EVENT = 19,
|
||||
|
||||
/*
|
||||
These event numbers were used for 5.1.0 to 5.1.15 and are
|
||||
therefore obsolete.
|
||||
*/
|
||||
PRE_GA_WRITE_ROWS_EVENT = 20,
|
||||
PRE_GA_UPDATE_ROWS_EVENT = 21,
|
||||
PRE_GA_DELETE_ROWS_EVENT = 22,
|
||||
|
||||
/*
|
||||
These event numbers are used from 5.1.16 and forward
|
||||
*/
|
||||
WRITE_ROWS_EVENT = 23,
|
||||
UPDATE_ROWS_EVENT = 24,
|
||||
DELETE_ROWS_EVENT = 25,
|
||||
|
||||
/*
|
||||
Something out of the ordinary happened on the master
|
||||
*/
|
||||
INCIDENT_EVENT= 26,
|
||||
|
||||
/*
|
||||
* A user defined event
|
||||
*/
|
||||
USER_DEFINED= 27,
|
||||
|
||||
/* We have two different implementations of global transaction id */
|
||||
GTID_EVENT_MYSQL=33,
|
||||
GTID_EVENT_MARIADB= 162,
|
||||
/*
|
||||
Add new events here - right above this comment!
|
||||
Existing events (except ENUM_END_EVENT) should never change their numbers
|
||||
*/
|
||||
|
||||
|
||||
ENUM_END_EVENT /* end marker */
|
||||
};
|
||||
|
||||
namespace system {
|
||||
/**
|
||||
* Convenience function to get the string representation of a binlog event.
|
||||
*/
|
||||
const char* get_event_type_str(Log_event_type type);
|
||||
} // end namespace system
|
||||
|
||||
#define LOG_EVENT_HEADER_SIZE 20
|
||||
class Log_event_header
|
||||
{
|
||||
public:
|
||||
boost::uint8_t marker; // always 0 or 0xFF
|
||||
boost::uint32_t timestamp;
|
||||
boost::uint8_t type_code;
|
||||
boost::uint32_t server_id;
|
||||
boost::uint32_t event_length;
|
||||
boost::uint32_t next_position;
|
||||
boost::uint16_t flags;
|
||||
};
|
||||
|
||||
|
||||
class Binary_log_event;
|
||||
|
||||
/**
|
||||
* TODO Base class for events. Implementation is in body()
|
||||
*/
|
||||
class Binary_log_event
|
||||
{
|
||||
public:
|
||||
Binary_log_event()
|
||||
{
|
||||
/*
|
||||
An event length of 0 indicates that the header isn't initialized
|
||||
*/
|
||||
m_header.event_length= 0;
|
||||
m_header.type_code= 0;
|
||||
}
|
||||
|
||||
Binary_log_event(Log_event_header *header)
|
||||
{
|
||||
m_header= *header;
|
||||
}
|
||||
|
||||
virtual ~Binary_log_event();
|
||||
|
||||
/**
|
||||
* Helper method
|
||||
*/
|
||||
enum Log_event_type get_event_type() const
|
||||
{
|
||||
return (enum Log_event_type) m_header.type_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to the header of the log event
|
||||
*/
|
||||
Log_event_header *header() { return &m_header; }
|
||||
|
||||
private:
|
||||
Log_event_header m_header;
|
||||
};
|
||||
|
||||
class Query_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Query_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
boost::uint32_t thread_id;
|
||||
boost::uint32_t exec_time;
|
||||
boost::uint16_t error_code;
|
||||
std::vector<boost::uint8_t > variables;
|
||||
|
||||
std::string db_name;
|
||||
std::string query;
|
||||
};
|
||||
|
||||
class Gtid_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Gtid_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
|
||||
size_t gtid_length() { return MYSQL_GTID_ENCODED_SIZE;}
|
||||
boost::uint32_t domain_id;
|
||||
boost::uint32_t server_id;
|
||||
boost::uint64_t sequence_number;
|
||||
unsigned char m_mysql_gtid[MYSQL_GTID_ENCODED_SIZE];
|
||||
Gtid m_gtid;
|
||||
};
|
||||
|
||||
class Rotate_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Rotate_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
std::string binlog_file;
|
||||
boost::uint64_t binlog_pos;
|
||||
};
|
||||
|
||||
class Format_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Format_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
boost::uint16_t binlog_version;
|
||||
std::string master_version;
|
||||
boost::uint32_t created_ts;
|
||||
boost::uint8_t log_header_len;
|
||||
};
|
||||
|
||||
class User_var_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
enum Value_type {
|
||||
STRING_TYPE,
|
||||
REAL_TYPE,
|
||||
INT_TYPE,
|
||||
ROW_TYPE,
|
||||
DECIMAL_TYPE,
|
||||
VALUE_TYPE_COUNT
|
||||
};
|
||||
|
||||
User_var_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
std::string name;
|
||||
boost::uint8_t is_null;
|
||||
boost::uint8_t type;
|
||||
boost::uint32_t charset; /* charset of the string */
|
||||
std::string value; /* encoded in binary speak, depends on .type */
|
||||
};
|
||||
|
||||
class Table_map_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Table_map_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
boost::uint64_t table_id;
|
||||
boost::uint16_t flags;
|
||||
std::string db_name;
|
||||
std::string table_name;
|
||||
std::vector<uint8_t> columns;
|
||||
std::vector<uint8_t> metadata;
|
||||
std::vector<uint8_t> null_bits;
|
||||
};
|
||||
|
||||
class Row_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Row_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
boost::uint64_t table_id;
|
||||
boost::uint16_t flags;
|
||||
boost::uint64_t columns_len;
|
||||
boost::uint32_t null_bits_len;
|
||||
std::vector<boost::uint8_t> columns_before_image;
|
||||
std::vector<uint8_t> used_columns;
|
||||
std::vector<uint8_t> row;
|
||||
};
|
||||
|
||||
class Int_var_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Int_var_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
boost::uint8_t type;
|
||||
boost::uint64_t value;
|
||||
};
|
||||
|
||||
class Incident_event: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Incident_event() : Binary_log_event() {}
|
||||
Incident_event(Log_event_header *header) : Binary_log_event(header) {}
|
||||
boost::uint8_t type;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
class Xid: public Binary_log_event
|
||||
{
|
||||
public:
|
||||
Xid(Log_event_header *header) : Binary_log_event(header) {}
|
||||
boost::uint64_t xid_id;
|
||||
};
|
||||
|
||||
Binary_log_event *create_incident_event(unsigned int type, const char *message, unsigned long pos= 0);
|
||||
|
||||
} // end namespace mysql
|
||||
|
||||
#endif /* _BINLOG_EVENT_H */
|
91
replication_listener/include/bounded_buffer.h
Normal file
91
replication_listener/include/bounded_buffer.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _BOUNDED_BUFFER_H
|
||||
#define _BOUNDED_BUFFER_H
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/progress.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
template <class T>
|
||||
class bounded_buffer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::circular_buffer<T> container_type;
|
||||
typedef typename container_type::size_type size_type;
|
||||
typedef typename container_type::value_type value_type;
|
||||
|
||||
explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {}
|
||||
|
||||
void push_front(const value_type& item)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_mutex);
|
||||
m_not_full.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_full, this));
|
||||
m_container.push_front(item);
|
||||
++m_unread;
|
||||
lock.unlock();
|
||||
m_not_empty.notify_one();
|
||||
}
|
||||
|
||||
void pop_back(value_type* pItem)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_mutex);
|
||||
m_not_empty.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_empty, this));
|
||||
*pItem = m_container[--m_unread];
|
||||
lock.unlock();
|
||||
m_not_full.notify_one();
|
||||
}
|
||||
|
||||
bool has_unread()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_mutex);
|
||||
return is_not_empty();
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
private:
|
||||
bounded_buffer(const bounded_buffer&); // Disabled copy constructor
|
||||
bounded_buffer& operator = (const bounded_buffer&); // Disabled assign operator
|
||||
|
||||
bool is_not_empty() const { return m_unread > 0; }
|
||||
bool is_not_full() const { return m_unread < m_container.capacity(); }
|
||||
|
||||
size_type m_unread;
|
||||
container_type m_container;
|
||||
boost::mutex m_mutex;
|
||||
boost::condition m_not_empty;
|
||||
boost::condition m_not_full;
|
||||
};
|
||||
|
||||
#endif /* _BOUNDED_BUFFER_H */
|
||||
|
196
replication_listener/include/field_iterator.h
Normal file
196
replication_listener/include/field_iterator.h
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _FIELD_ITERATOR_H
|
||||
#define _FIELD_ITERATOR_H
|
||||
#include "binlog_event.h"
|
||||
#include "value.h"
|
||||
#include "row_of_fields.h"
|
||||
#include <vector>
|
||||
|
||||
using namespace mysql;
|
||||
|
||||
namespace mysql {
|
||||
|
||||
bool is_null(unsigned char *bitmap, int index);
|
||||
|
||||
int lookup_metadata_field_size(enum mysql::system::enum_field_types field_type);
|
||||
boost::uint32_t extract_metadata(const Table_map_event *map, int col_no);
|
||||
|
||||
template <class Iterator_value_type >
|
||||
class Row_event_iterator : public std::iterator<std::forward_iterator_tag,
|
||||
Iterator_value_type>
|
||||
{
|
||||
public:
|
||||
Row_event_iterator() : m_row_event(0), m_table_map(0),
|
||||
m_new_field_offset_calculated(0), m_field_offset(0)
|
||||
{ }
|
||||
|
||||
Row_event_iterator(const Row_event *row_event,
|
||||
const Table_map_event *table_map)
|
||||
: m_row_event(row_event), m_table_map(table_map),
|
||||
m_new_field_offset_calculated(0)
|
||||
{
|
||||
m_field_offset= 0;
|
||||
}
|
||||
|
||||
Iterator_value_type operator*();
|
||||
|
||||
Row_event_iterator& operator++();
|
||||
|
||||
Row_event_iterator operator++(int);
|
||||
|
||||
bool operator==(const Row_event_iterator& x) const;
|
||||
|
||||
bool operator!=(const Row_event_iterator& x) const;
|
||||
|
||||
//Row_iterator end() const;
|
||||
private:
|
||||
size_t fields(Iterator_value_type& fields_vector );
|
||||
const Row_event *m_row_event;
|
||||
const Table_map_event *m_table_map;
|
||||
unsigned long m_new_field_offset_calculated;
|
||||
unsigned long m_field_offset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <class Iterator_value_type>
|
||||
size_t Row_event_iterator<Iterator_value_type>::fields(Iterator_value_type& fields_vector )
|
||||
{
|
||||
size_t field_offset= m_field_offset;
|
||||
int row_field_col_index= 0;
|
||||
std::vector<boost::uint8_t> nullbits(m_row_event->null_bits_len);
|
||||
std::copy(m_row_event->row.begin()+m_field_offset,
|
||||
m_row_event->row.begin()+(m_field_offset+m_row_event->null_bits_len),
|
||||
nullbits.begin());
|
||||
|
||||
field_offset += m_row_event->null_bits_len;
|
||||
for(unsigned col_no=0; col_no < m_table_map->columns.size(); ++col_no)
|
||||
{
|
||||
++row_field_col_index;
|
||||
unsigned int type= m_table_map->columns[col_no]&0xFF;
|
||||
boost::uint32_t metadata= extract_metadata(m_table_map, col_no);
|
||||
mysql::Value val((enum mysql::system::enum_field_types)type,
|
||||
metadata,
|
||||
(const char *)&m_row_event->row[field_offset]);
|
||||
if (is_null((unsigned char *)&nullbits[0], col_no ))
|
||||
{
|
||||
val.is_null(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
If the value is null it is not in the list of values and thus we won't
|
||||
increse the offset. TODO what if all values are null?!
|
||||
*/
|
||||
field_offset += val.length();
|
||||
}
|
||||
fields_vector.push_back(val);
|
||||
}
|
||||
return field_offset;
|
||||
}
|
||||
|
||||
template <class Iterator_value_type >
|
||||
Iterator_value_type Row_event_iterator<Iterator_value_type>::operator*()
|
||||
{ // dereferencing
|
||||
Iterator_value_type fields_vector;
|
||||
/*
|
||||
* Remember this offset if we need to increate the row pointer
|
||||
*/
|
||||
m_new_field_offset_calculated= fields(fields_vector);
|
||||
|
||||
return fields_vector;
|
||||
}
|
||||
|
||||
template< class Iterator_value_type >
|
||||
Row_event_iterator< Iterator_value_type >&
|
||||
Row_event_iterator< Iterator_value_type >::operator++()
|
||||
{ // prefix
|
||||
if (m_field_offset < m_row_event->row.size())
|
||||
{
|
||||
/*
|
||||
* If we requested the fields in a previous operations
|
||||
* we also calculated the new offset at the same time.
|
||||
*/
|
||||
if (m_new_field_offset_calculated != 0)
|
||||
{
|
||||
m_field_offset= m_new_field_offset_calculated;
|
||||
//m_field_offset += m_row_event->null_bits_len;
|
||||
m_new_field_offset_calculated= 0;
|
||||
if (m_field_offset >= m_row_event->row.size())
|
||||
m_field_offset= 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Advance the field offset to the next row
|
||||
*/
|
||||
int row_field_col_index= 0;
|
||||
std::vector<uint8_t> nullbits(m_row_event->null_bits_len);
|
||||
std::copy(m_row_event->row.begin()+m_field_offset,
|
||||
m_row_event->row.begin()+(m_field_offset+m_row_event->null_bits_len),
|
||||
nullbits.begin());
|
||||
m_field_offset += m_row_event->null_bits_len;
|
||||
for(unsigned col_no=0; col_no < m_table_map->columns.size(); ++col_no)
|
||||
{
|
||||
++row_field_col_index;
|
||||
mysql::Value val((enum mysql::system::enum_field_types)m_table_map->columns[col_no],
|
||||
m_table_map->metadata[col_no],
|
||||
(const char *)&m_row_event->row[m_field_offset]);
|
||||
if (!is_null((unsigned char *)&nullbits[0], col_no))
|
||||
{
|
||||
m_field_offset += val.length();
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_field_offset= 0;
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
template <class Iterator_value_type >
|
||||
Row_event_iterator< Iterator_value_type >
|
||||
Row_event_iterator< Iterator_value_type >::operator++(int)
|
||||
{ // postfix
|
||||
Row_event_iterator temp = *this;
|
||||
++*this;
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <class Iterator_value_type >
|
||||
bool Row_event_iterator< Iterator_value_type >::operator==(const Row_event_iterator& x) const
|
||||
{
|
||||
return m_field_offset == x.m_field_offset;
|
||||
}
|
||||
|
||||
template <class Iterator_value_type >
|
||||
bool Row_event_iterator< Iterator_value_type >::operator!=(const Row_event_iterator& x) const
|
||||
{
|
||||
return m_field_offset != x.m_field_offset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* _FIELD_ITERATOR_H */
|
92
replication_listener/include/file_driver.h
Normal file
92
replication_listener/include/file_driver.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _FILE_DRIVER_H
|
||||
#define _FILE_DRIVER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "binlog_api.h"
|
||||
#include "binlog_driver.h"
|
||||
#include "protocol.h"
|
||||
|
||||
#define MAGIC_NUMBER_SIZE 4
|
||||
|
||||
namespace mysql {
|
||||
namespace system {
|
||||
|
||||
class Binlog_file_driver
|
||||
: public Binary_log_driver
|
||||
{
|
||||
public:
|
||||
template <class TFilename>
|
||||
Binlog_file_driver(const TFilename& filename = TFilename(),
|
||||
unsigned int offset = 0)
|
||||
: Binary_log_driver(filename, offset)
|
||||
{
|
||||
}
|
||||
|
||||
int connect(Gtid gtid = Gtid());
|
||||
int disconnect();
|
||||
int wait_for_next_event(mysql::Binary_log_event **event);
|
||||
int set_position(const std::string &str, unsigned long position);
|
||||
int get_position(std::string *str, unsigned long *position);
|
||||
|
||||
int set_position_gtid(const Gtid gtid)
|
||||
{
|
||||
return 0; // TODO
|
||||
}
|
||||
|
||||
int fetch_server_version(const std::string& user,
|
||||
const std::string& passwd,
|
||||
const std::string& host,
|
||||
long port)
|
||||
{
|
||||
return 0; // TODO
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
unsigned long m_binlog_file_size;
|
||||
|
||||
/*
|
||||
Bytes that has been read so for from the file.
|
||||
Updated after every event is read.
|
||||
*/
|
||||
unsigned long m_bytes_read;
|
||||
|
||||
std::ifstream m_binlog_file;
|
||||
|
||||
Log_event_header m_event_log_header;
|
||||
};
|
||||
|
||||
} // namespace mysql::system
|
||||
} // namespace mysql
|
||||
|
||||
#endif /* _FILE_DRIVER_H */
|
102
replication_listener/include/gtid.h
Normal file
102
replication_listener/include/gtid.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright (C) 2013, SkySQL Ab
|
||||
|
||||
|
||||
This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
|
||||
*/
|
||||
|
||||
#ifndef REPLICATION_LISTENER_MYSQL_GTID_H
|
||||
#define REPLICATION_LISTENER_MYSQL_GTID_H
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
template <class T>
|
||||
inline std::string gno_to_string (const T& t)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
enum mysql_server_types {
|
||||
MYSQL_SERVER_TYPE_NA = 0,
|
||||
MYSQL_SERVER_TYPE_MARIADB = 1,
|
||||
MYSQL_SERVER_TYPE_MYSQL = 2
|
||||
};
|
||||
|
||||
#define MYSQL_GTID_ENCODED_SIZE 24
|
||||
|
||||
class Gtid
|
||||
{
|
||||
public:
|
||||
|
||||
Gtid()
|
||||
: m_real_gtid(false), m_domain_id(0), m_server_id(0), m_sequence_number(0),
|
||||
m_server_type(MYSQL_SERVER_TYPE_NA), m_gtid_length(0), m_mariadb_gtid(std::string(""))
|
||||
{
|
||||
memset(m_mysql_gtid, 0, MYSQL_GTID_ENCODED_SIZE);
|
||||
}
|
||||
|
||||
Gtid(const boost::uint32_t domain_id,
|
||||
const boost::uint32_t server_id,
|
||||
const boost::uint64_t sequence_number);
|
||||
|
||||
Gtid(const unsigned char *mysql_gtid,
|
||||
const boost::uint64_t gno);
|
||||
|
||||
Gtid(const unsigned char *mysql_gtid);
|
||||
|
||||
~Gtid() {}
|
||||
|
||||
bool is_real_gtid() const { return m_real_gtid;}
|
||||
|
||||
const unsigned char* get_mysql_gtid() const { return m_mysql_gtid; }
|
||||
|
||||
const unsigned char* get_gtid() const;
|
||||
|
||||
size_t get_gtid_length() const { return m_gtid_length; }
|
||||
|
||||
|
||||
std::string get_string() const;
|
||||
|
||||
boost::uint32_t get_domain_id() const { return m_domain_id; }
|
||||
boost::uint32_t get_server_id() const { return m_server_id; }
|
||||
boost::uint32_t get_sequence_number() const { return m_sequence_number; }
|
||||
|
||||
private:
|
||||
|
||||
bool m_real_gtid;
|
||||
mysql_server_types m_server_type;
|
||||
|
||||
boost::uint32_t m_domain_id;
|
||||
boost::uint32_t m_server_id;
|
||||
boost::uint64_t m_sequence_number;
|
||||
boost::uint32_t m_gtid_length;
|
||||
|
||||
unsigned char m_mysql_gtid[MYSQL_GTID_ENCODED_SIZE];
|
||||
std::string m_mariadb_gtid;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
58
replication_listener/include/listener_exception.h
Normal file
58
replication_listener/include/listener_exception.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (C) 2013, SkySQL Ab
|
||||
|
||||
|
||||
This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
|
||||
*/
|
||||
|
||||
#ifndef REPLICATION_LISTENER_MYSQL_ERROR_EXCEPTION
|
||||
#define REPLICATION_LISTENER_MYSQL_ERROR_EXCEPTION
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
// Derive from std::runtime_error rather than std::exception
|
||||
// runtime_error's constructor can take a string as parameter
|
||||
// the standard's compliant version of std::exception can not
|
||||
// (though some compiler provide a non standard constructor).
|
||||
//
|
||||
|
||||
#include <sstream>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
// Helper function
|
||||
template <class T>
|
||||
inline std::string to_string (const T& t)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
class ListenerException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
|
||||
ListenerException(std::string message, const char *file, int line)
|
||||
: std::runtime_error(std::string("Exception: ") + message + std::string(" file: ") + std::string(file) + std::string(" line: ") + (to_string(line))) {}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
313
replication_listener/include/protocol.h
Normal file
313
replication_listener/include/protocol.h
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
#ifndef _PROTOCOL_H
|
||||
#define _PROTOCOL_H
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <list>
|
||||
#include "binlog_event.h"
|
||||
#include <mysql.h>
|
||||
#include <my_global.h>
|
||||
#include <mysql_com.h>
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
namespace mysql {
|
||||
namespace system {
|
||||
|
||||
/**
|
||||
Storage structure for the handshake package sent from the server to
|
||||
the client.
|
||||
*/
|
||||
struct st_handshake_package
|
||||
{
|
||||
boost::uint8_t protocol_version;
|
||||
std::string server_version_str;
|
||||
boost::uint32_t thread_id;
|
||||
boost::uint8_t scramble_buff[8];
|
||||
boost::uint16_t server_capabilities;
|
||||
boost::uint8_t server_language;
|
||||
boost::uint16_t server_status;
|
||||
boost::uint8_t scramble_buff2[13];
|
||||
};
|
||||
|
||||
/**
|
||||
Storage structure for the OK package sent from the server to
|
||||
the client.
|
||||
*/
|
||||
struct st_ok_package
|
||||
{
|
||||
boost::uint8_t result_type;
|
||||
boost::uint64_t affected_rows;
|
||||
boost::uint64_t insert_id;
|
||||
boost::uint16_t server_status;
|
||||
boost::uint16_t warning_count;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
struct st_eof_package
|
||||
{
|
||||
boost::uint16_t warning_count;
|
||||
boost::uint16_t status_flags;
|
||||
};
|
||||
|
||||
/**
|
||||
Storage structure for the Error package sent from the server to
|
||||
the client.
|
||||
*/
|
||||
struct st_error_package
|
||||
{
|
||||
boost::uint16_t error_code;
|
||||
boost::uint8_t sql_state[5];
|
||||
std::string message;
|
||||
};
|
||||
|
||||
void write_packet_header(char *buff, boost::uint16_t size, boost::uint8_t packet_no);
|
||||
|
||||
class Protocol_validator;
|
||||
class buffer_source;
|
||||
|
||||
/**
|
||||
* The Protocol interface is used to describe a grammar consisting of
|
||||
* chunks of bytes that are read or written in consequtive order.
|
||||
* Example:
|
||||
* class Protocol_impl : public Protocol;
|
||||
* Protocol_impl chunk1(chunk_datastore1);
|
||||
* Protocol_impl chunk2(chunk_datastore2);
|
||||
* input_stream >> chunk1
|
||||
* >> chunk2;
|
||||
*/
|
||||
class Protocol
|
||||
{
|
||||
public:
|
||||
Protocol() { m_length_encoded_binary= false; }
|
||||
/**
|
||||
Return the number of bytes which is read or written by this protocol chunk.
|
||||
The default size is equal to the underlying storage data type.
|
||||
*/
|
||||
virtual unsigned int size()=0;
|
||||
|
||||
/** Return a pointer to the first byte in a linear storage buffer */
|
||||
virtual const char *data()=0;
|
||||
|
||||
/**
|
||||
Change the number of bytes which will be read or written to the storage.
|
||||
The default size is euqal to the storage type size. This can change if the
|
||||
protocol is reading a length encoded binary.
|
||||
The new size must always be less than the size of the underlying storage
|
||||
type.
|
||||
*/
|
||||
virtual void collapse_size(unsigned int new_size)=0;
|
||||
|
||||
/**
|
||||
The first byte will have a special interpretation which will indicate
|
||||
how many bytes should be read next.
|
||||
*/
|
||||
void set_length_encoded_binary(bool bswitch) { m_length_encoded_binary= bswitch; }
|
||||
bool is_length_encoded_binary(void) { return m_length_encoded_binary; }
|
||||
|
||||
private:
|
||||
bool m_length_encoded_binary;
|
||||
|
||||
friend std::istream &operator<<(std::istream &is, Protocol &chunk);
|
||||
friend std::istream &operator>>(std::istream &is, Protocol &chunk);
|
||||
friend buffer_source &operator>>(buffer_source &src, Protocol &chunk);
|
||||
friend std::istream &operator>>(std::istream &is, std::string &str);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Protocol_chunk : public Protocol
|
||||
{
|
||||
public:
|
||||
|
||||
Protocol_chunk() : Protocol()
|
||||
{
|
||||
m_size= 0;
|
||||
m_data= 0;
|
||||
}
|
||||
|
||||
Protocol_chunk(T &chunk) : Protocol()
|
||||
{
|
||||
m_data= (const char *)&chunk;
|
||||
m_size= sizeof(T);
|
||||
}
|
||||
|
||||
Protocol_chunk(const T &chunk) : Protocol ()
|
||||
{
|
||||
m_data= (const char *) &chunk;
|
||||
m_size= sizeof(T);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param buffer A pointer to the storage
|
||||
* @param size The size of the storage
|
||||
*
|
||||
* @note If size == 0 then the chunk is a
|
||||
* length coded binary.
|
||||
*/
|
||||
Protocol_chunk(T *buffer, unsigned long size) : Protocol ()
|
||||
{
|
||||
m_data= (const char *)buffer;
|
||||
m_size= size;
|
||||
}
|
||||
|
||||
virtual unsigned int size() { return m_size; }
|
||||
virtual const char *data() { return m_data; }
|
||||
virtual void collapse_size(unsigned int new_size)
|
||||
{
|
||||
//assert(new_size <= m_size);
|
||||
memset((char *)m_data+new_size,'\0', m_size-new_size);
|
||||
m_size= new_size;
|
||||
}
|
||||
private:
|
||||
const char *m_data;
|
||||
unsigned long m_size;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, Protocol &chunk);
|
||||
|
||||
typedef Protocol_chunk<boost::uint8_t> Protocol_chunk_uint8;
|
||||
|
||||
class Protocol_chunk_string //: public Protocol_chunk_uint8
|
||||
{
|
||||
public:
|
||||
Protocol_chunk_string(std::string &chunk, unsigned long size) //: Protocol_chunk_uint8()
|
||||
{
|
||||
m_str= &chunk;
|
||||
m_str->assign(size,'*');
|
||||
}
|
||||
|
||||
virtual unsigned int size() const { return m_str->size(); }
|
||||
virtual const char *data() const { return m_str->data(); }
|
||||
virtual void collapse_size(unsigned int new_size)
|
||||
{
|
||||
m_str->resize(new_size);
|
||||
}
|
||||
private:
|
||||
friend std::istream &operator>>(std::istream &is, Protocol_chunk_string &str);
|
||||
std::string *m_str;
|
||||
};
|
||||
|
||||
class Protocol_chunk_vector : public Protocol_chunk_uint8
|
||||
{
|
||||
public:
|
||||
Protocol_chunk_vector(std::vector<boost::uint8_t> &chunk, unsigned long size)
|
||||
: Protocol_chunk_uint8()
|
||||
{
|
||||
m_vec= &chunk;
|
||||
m_vec->reserve(size);
|
||||
m_size= size;
|
||||
}
|
||||
|
||||
virtual unsigned int size() { return m_vec->size(); }
|
||||
virtual const char *data() { return reinterpret_cast<const char *>(&*m_vec->begin()); }
|
||||
virtual void collapse_size(unsigned int new_size)
|
||||
{
|
||||
m_vec->resize(new_size);
|
||||
}
|
||||
private:
|
||||
friend std::istream &operator>>(std::istream &is, Protocol_chunk_vector &chunk);
|
||||
std::vector<boost::uint8_t> *m_vec;
|
||||
unsigned long m_size;
|
||||
};
|
||||
|
||||
|
||||
std::istream &operator>>(std::istream &is, Protocol_chunk_vector &chunk);
|
||||
|
||||
class buffer_source
|
||||
{
|
||||
public:
|
||||
|
||||
buffer_source(const char *src, int sz)
|
||||
{
|
||||
m_src= src;
|
||||
m_size= sz;
|
||||
m_ptr= 0;
|
||||
}
|
||||
|
||||
friend buffer_source &operator>>(buffer_source &src, Protocol &chunk);
|
||||
private:
|
||||
const char *m_src;
|
||||
int m_size;
|
||||
int m_ptr;
|
||||
|
||||
};
|
||||
|
||||
class Protocol_chunk_string_len
|
||||
{
|
||||
public:
|
||||
Protocol_chunk_string_len(std::string &str)
|
||||
{
|
||||
m_storage= &str;
|
||||
}
|
||||
|
||||
private:
|
||||
friend std::istream &operator>>(std::istream &is, Protocol_chunk_string_len &lenstr);
|
||||
std::string *m_storage;
|
||||
};
|
||||
|
||||
buffer_source &operator>>(buffer_source &src, Protocol &chunk);
|
||||
/** TODO assert that the correct endianess is used */
|
||||
std::istream &operator>>(std::istream &is, Protocol &chunk);
|
||||
std::istream &operator>>(std::istream &is, std::string &str);
|
||||
std::istream &operator>>(std::istream &is, Protocol_chunk_string_len &lenstr);
|
||||
std::istream &operator>>(std::istream &is, Protocol_chunk_string &str);
|
||||
|
||||
int proto_read_package_header(tcp::socket *socket, unsigned long *packet_length, unsigned char *packet_no);
|
||||
|
||||
/**
|
||||
* Read a server package header from a stream buffer
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval >0 An error occurred
|
||||
*/
|
||||
int proto_read_package_header(tcp::socket *socket, boost::asio::streambuf &buff, unsigned long *packet_length, unsigned char *packet_no);
|
||||
|
||||
/**
|
||||
* Get one complete packet from the server
|
||||
*
|
||||
* @param socket Pointer to the active tcp-socket
|
||||
* @param buff A reference to a stream buffer
|
||||
* @param packet_no [out] The number of the packet as given by the server
|
||||
*
|
||||
* @return the size of the packet or 0 to indicate an error
|
||||
*/
|
||||
int proto_get_one_package(tcp::socket *socket, boost::asio::streambuf &buff, boost::uint8_t *packet_no);
|
||||
void prot_parse_error_message(std::istream &is, struct st_error_package &err, int packet_length);
|
||||
void prot_parse_ok_message(std::istream &is, struct st_ok_package &ok, int packet_length);
|
||||
void prot_parse_eof_message(std::istream &is, struct st_eof_package &eof);
|
||||
void proto_get_handshake_package(std::istream &is, struct st_handshake_package &p, int packet_length);
|
||||
|
||||
/**
|
||||
Allocates a new event and copy the header. The caller must be responsible for
|
||||
releasing the allocated memory.
|
||||
*/
|
||||
Query_event *proto_query_event(std::istream &is, Log_event_header *header);
|
||||
Rotate_event *proto_rotate_event(std::istream &is, Log_event_header *header);
|
||||
Incident_event *proto_incident_event(std::istream &is, Log_event_header *header);
|
||||
Row_event *proto_rows_event(std::istream &is, Log_event_header *header);
|
||||
Table_map_event *proto_table_map_event(std::istream &is, Log_event_header *header);
|
||||
Int_var_event *proto_intvar_event(std::istream &is, Log_event_header *header);
|
||||
User_var_event *proto_uservar_event(std::istream &is, Log_event_header *header);
|
||||
Gtid_event *proto_gtid_event(std::istream &is, Log_event_header *header);
|
||||
|
||||
} // end namespace system
|
||||
} // end namespace mysql
|
||||
|
||||
#endif /* _PROTOCOL_H */
|
185
replication_listener/include/resultset_iterator.h
Normal file
185
replication_listener/include/resultset_iterator.h
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _RESULTSET_ITERATOR_H
|
||||
#define _RESULTSET_ITERATOR_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// if error; try #include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include "value.h"
|
||||
#include "rowset.h"
|
||||
#include "row_of_fields.h"
|
||||
|
||||
using namespace mysql;
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
struct Field_packet
|
||||
{
|
||||
std::string catalog; // Length Coded String
|
||||
std::string db; // Length Coded String
|
||||
std::string table; // Length Coded String
|
||||
std::string org_table;// Length Coded String
|
||||
std::string name; // Length Coded String
|
||||
std::string org_name; // Length Coded String
|
||||
boost::uint8_t marker; // filler
|
||||
boost::uint16_t charsetnr; // charsetnr
|
||||
boost::uint32_t length; // length
|
||||
boost::uint8_t type; // field type
|
||||
boost::uint16_t flags;
|
||||
boost::uint8_t decimals;
|
||||
boost::uint16_t filler; // filler, always 0x00
|
||||
//boost::uint64_t default_value; // Length coded binary; only in table descr.
|
||||
};
|
||||
|
||||
typedef std::list<std::string > String_storage;
|
||||
|
||||
namespace system {
|
||||
void digest_result_header(std::istream &is, boost::uint64_t &field_count, boost::uint64_t extra);
|
||||
void digest_field_packet(std::istream &is, Field_packet &field_packet);
|
||||
void digest_marker(std::istream &is);
|
||||
void digest_row_content(std::istream &is, int field_count, Row_of_fields &row, String_storage &storage, bool &is_eof);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class Result_set_iterator;
|
||||
|
||||
class Result_set
|
||||
{
|
||||
public:
|
||||
typedef Result_set_iterator<Row_of_fields > iterator;
|
||||
typedef Result_set_iterator<Row_of_fields const > const_iterator;
|
||||
|
||||
Result_set(tcp::socket *socket) { source(socket); }
|
||||
void source(tcp::socket *socket) { m_socket= socket; digest_row_set(); }
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
private:
|
||||
void digest_row_set();
|
||||
friend class Result_set_iterator<Row_of_fields >;
|
||||
friend class Result_set_iterator<Row_of_fields const>;
|
||||
|
||||
std::vector<Field_packet > m_field_types;
|
||||
int m_row_count;
|
||||
std::vector<Row_of_fields > m_rows;
|
||||
String_storage m_storage;
|
||||
tcp::socket *m_socket;
|
||||
typedef enum { RESULT_HEADER,
|
||||
FIELD_PACKETS,
|
||||
MARKER,
|
||||
ROW_CONTENTS,
|
||||
EOF_PACKET
|
||||
} state_t;
|
||||
state_t m_current_state;
|
||||
|
||||
/**
|
||||
* The number of fields in the field packets block
|
||||
*/
|
||||
boost::uint64_t m_field_count;
|
||||
/**
|
||||
* Used for SHOW COLUMNS to return the number of rows in the table
|
||||
*/
|
||||
boost::uint64_t m_extra;
|
||||
};
|
||||
|
||||
template <class Iterator_value_type >
|
||||
class Result_set_iterator :
|
||||
public boost::iterator_facade<Result_set_iterator<Iterator_value_type >,
|
||||
Iterator_value_type,
|
||||
boost::forward_traversal_tag >
|
||||
{
|
||||
public:
|
||||
Result_set_iterator() : m_feeder(0), m_current_row(-1)
|
||||
{}
|
||||
|
||||
explicit Result_set_iterator(Result_set *feeder) : m_feeder(feeder),
|
||||
m_current_row(-1)
|
||||
{
|
||||
increment();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
void increment()
|
||||
{
|
||||
if (++m_current_row >= m_feeder->m_row_count)
|
||||
m_current_row= -1;
|
||||
}
|
||||
|
||||
bool equal(const Result_set_iterator& other) const
|
||||
{
|
||||
if (other.m_feeder == 0 && m_feeder == 0)
|
||||
return true;
|
||||
if (other.m_feeder == 0)
|
||||
{
|
||||
if (m_current_row == -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (m_feeder == 0)
|
||||
{
|
||||
if (other.m_current_row == -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if( other.m_feeder->m_field_count != m_feeder->m_field_count)
|
||||
return false;
|
||||
|
||||
Iterator_value_type *row1= &m_feeder->m_rows[m_current_row];
|
||||
Iterator_value_type *row2= &other.m_feeder->m_rows[m_current_row];
|
||||
for (unsigned i=0; i< m_feeder->m_field_count; ++i)
|
||||
{
|
||||
Value val1= row1->at(i);
|
||||
Value val2= row2->at(i);
|
||||
if (val1 != val2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Iterator_value_type &dereference() const
|
||||
{
|
||||
return m_feeder->m_rows[m_current_row];
|
||||
}
|
||||
|
||||
private:
|
||||
Result_set *m_feeder;
|
||||
int m_current_row;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // end namespace mysql
|
||||
|
||||
|
||||
|
||||
#endif /* _RESULTSET_ITERATOR_H */
|
47
replication_listener/include/row_of_fields.h
Normal file
47
replication_listener/include/row_of_fields.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
#ifndef _ROW_OF_FIELDS_H
|
||||
#define _ROW_OF_FIELDS_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "value.h"
|
||||
using namespace mysql;
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
class Row_of_fields : public std::vector<Value >
|
||||
{
|
||||
public:
|
||||
Row_of_fields() : std::vector<Value >(0) { }
|
||||
Row_of_fields(int field_count) : std::vector<Value >(field_count) {}
|
||||
virtual ~Row_of_fields() {}
|
||||
|
||||
Row_of_fields& operator=(const Row_of_fields &right);
|
||||
Row_of_fields& operator=(Row_of_fields &right);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _ROW_OF_FIELDS_H */
|
55
replication_listener/include/rowset.h
Normal file
55
replication_listener/include/rowset.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
#ifndef _ROWSET_H
|
||||
#define _ROWSET_H
|
||||
|
||||
#include "field_iterator.h"
|
||||
#include "resultset_iterator.h"
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
using namespace mysql;
|
||||
|
||||
namespace mysql {
|
||||
|
||||
class Row_event;
|
||||
class Table_map_event;
|
||||
|
||||
class Row_event_set
|
||||
{
|
||||
public:
|
||||
typedef Row_event_iterator<Row_of_fields > iterator;
|
||||
typedef Row_event_iterator<Row_of_fields const > const_iterator;
|
||||
|
||||
Row_event_set(Row_event *arg1, Table_map_event *arg2) { source(arg1, arg2); }
|
||||
|
||||
iterator begin() { return iterator(m_row_event, m_table_map_event); }
|
||||
iterator end() { return iterator(); }
|
||||
const_iterator begin() const { return const_iterator(m_row_event, m_table_map_event); }
|
||||
const_iterator end() const { return const_iterator(); }
|
||||
|
||||
private:
|
||||
void source(Row_event *arg1, Table_map_event *arg2) { m_row_event= arg1; m_table_map_event= arg2; }
|
||||
Row_event *m_row_event;
|
||||
Table_map_event *m_table_map_event;
|
||||
};
|
||||
|
||||
}
|
||||
#endif /* _ROWSET_H */
|
293
replication_listener/include/tcp_driver.h
Normal file
293
replication_listener/include/tcp_driver.h
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _TCP_DRIVER_H
|
||||
#define _TCP_DRIVER_H
|
||||
#include "binlog_driver.h"
|
||||
#include "bounded_buffer.h"
|
||||
#include "protocol.h"
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include "gtid.h"
|
||||
|
||||
|
||||
#define MAX_PACKAGE_SIZE 0xffffff
|
||||
|
||||
#define GET_NEXT_PACKET_HEADER \
|
||||
boost::asio::async_read(*m_socket, boost::asio::buffer(m_net_header, 4), \
|
||||
boost::bind(&Binlog_tcp_driver::handle_net_packet_header, this, \
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)) \
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
namespace mysql { namespace system {
|
||||
|
||||
class Binlog_tcp_driver : public Binary_log_driver
|
||||
{
|
||||
public:
|
||||
|
||||
Binlog_tcp_driver(const std::string& user, const std::string& passwd,
|
||||
const std::string& host, unsigned long port)
|
||||
: Binary_log_driver("", 4), m_host(host), m_user(user), m_passwd(passwd),
|
||||
m_port(port), m_socket(NULL), m_waiting_event(0), m_event_loop(0),
|
||||
m_total_bytes_transferred(0), m_shutdown(false), m_packet_no(0),
|
||||
m_event_queue(new bounded_buffer<Binary_log_event*>(50))
|
||||
{
|
||||
}
|
||||
|
||||
~Binlog_tcp_driver()
|
||||
{
|
||||
delete m_event_queue;
|
||||
delete m_socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect using previously declared connection parameters.
|
||||
*/
|
||||
int connect(Gtid gtid = Gtid());
|
||||
|
||||
/**
|
||||
* Blocking wait for the next binary log event to reach the client
|
||||
*/
|
||||
int wait_for_next_event(mysql::Binary_log_event **event);
|
||||
|
||||
/**
|
||||
* Reconnects to the master with a new binlog dump request.
|
||||
*/
|
||||
int set_position(const std::string &str, unsigned long position);
|
||||
|
||||
/**
|
||||
* Reconnects to the master with a new binlog dump request.
|
||||
*/
|
||||
int set_position_gtid(const Gtid gtid);
|
||||
|
||||
|
||||
int get_position(std::string *str, unsigned long *position);
|
||||
|
||||
const std::string& user() const { return m_user; }
|
||||
const std::string& password() const { return m_passwd; }
|
||||
const std::string& host() const { return m_host; }
|
||||
unsigned long port() const { return m_port; }
|
||||
|
||||
int fetch_server_version(const std::string& user,
|
||||
const std::string& passwd,
|
||||
const std::string& host,
|
||||
long port);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Connects to a mysql server, authenticates and initiates the event
|
||||
* request loop.
|
||||
*
|
||||
* @param user The user account on the server side
|
||||
* @param passwd The password used to authenticate the user
|
||||
* @param host The DNS host name or IP of the server
|
||||
* @param port The service port number to connect to
|
||||
*
|
||||
*
|
||||
* @return Success or failure code
|
||||
* @retval 0 Successfully established a connection
|
||||
* @retval >1 An error occurred.
|
||||
*/
|
||||
int connect(const std::string& user, const std::string& passwd,
|
||||
const std::string& host, long port,
|
||||
const Gtid gtid = Gtid(),
|
||||
const std::string& binlog_filename="", size_t offset=4);
|
||||
|
||||
bool send_client_capabilites(tcp::socket *socket);
|
||||
|
||||
bool send_slave_connect_state(tcp::socket *socket,Gtid gtid);
|
||||
|
||||
bool get_master_binlog_checksum(tcp::socket *socket);
|
||||
|
||||
tcp::socket *sync_connect_and_authenticate(boost::asio::io_service &io_service,
|
||||
const std::string &user,
|
||||
const std::string &passwd,
|
||||
const std::string &host,
|
||||
long port);
|
||||
int authenticate(tcp::socket *socket,
|
||||
const std::string& user,
|
||||
const std::string& passwd,
|
||||
const st_handshake_package &handshake_package);
|
||||
|
||||
bool fetch_master_status(tcp::socket *socket,
|
||||
std::string *filename,
|
||||
unsigned long *position);
|
||||
|
||||
bool fetch_binlogs_name_and_size(tcp::socket *socket,
|
||||
std::map<std::string,
|
||||
unsigned long> &binlog_map);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Request a binlog dump and starts the event loop in a new thread
|
||||
* @param binlog_file_name The base name of the binlog files to query
|
||||
*
|
||||
*/
|
||||
void start_binlog_dump(const std::string &binlog_file_name, size_t offset);
|
||||
void start_binlog_dump(const Gtid gtid);
|
||||
|
||||
/**
|
||||
* Handles a completed mysql server package header and put a
|
||||
* request for the body in the job queue.
|
||||
*/
|
||||
void handle_net_packet_header(const boost::system::error_code& err, std::size_t bytes_transferred);
|
||||
|
||||
/**
|
||||
* Handles a completed network package with the assumption that it contains
|
||||
* a binlog event.
|
||||
*
|
||||
* TODO rename to handle_event_log_packet?
|
||||
*/
|
||||
void handle_net_packet(const boost::system::error_code& err, std::size_t bytes_transferred);
|
||||
|
||||
/**
|
||||
* Called from handle_net_packet(). The function handle a stream of bytes
|
||||
* representing event packets which may or may not be complete.
|
||||
* It uses m_waiting_event and the size of the stream as parameters
|
||||
* in a state machine. If there is no m_waiting_event then the event
|
||||
* header must be parsed for the event packet length. This can only
|
||||
* be done if the accumulated stream of bytes are more than 19.
|
||||
* Next, if there is a m_waiting_event, it can only be completed if
|
||||
* event_length bytes are waiting on the stream.
|
||||
*
|
||||
* If none of these conditions are fullfilled, the function exits without
|
||||
* any action.
|
||||
*
|
||||
* @param err Not used
|
||||
* @param bytes_transferred The number of bytes waiting in the event stream
|
||||
*
|
||||
*/
|
||||
void handle_event_packet(const boost::system::error_code& err, std::size_t bytes_transferred);
|
||||
|
||||
/**
|
||||
* Executes io_service in a loop.
|
||||
* TODO Checks for connection errors and reconnects to the server
|
||||
* if necessary.
|
||||
*/
|
||||
void start_event_loop(void);
|
||||
|
||||
/**
|
||||
* Reconnect to the server by first calling disconnect and then connect.
|
||||
*/
|
||||
void reconnect(Gtid gtid = Gtid());
|
||||
|
||||
/**
|
||||
* Disconnet from the server. The io service must have been stopped before
|
||||
* this function is called.
|
||||
* The event queue is emptied.
|
||||
*/
|
||||
void disconnect(void);
|
||||
|
||||
/**
|
||||
* Terminates the io service and sets the shudown flag.
|
||||
* this causes the event loop to terminate.
|
||||
*/
|
||||
void shutdown(void);
|
||||
|
||||
boost::thread *m_event_loop;
|
||||
boost::asio::io_service m_io_service;
|
||||
tcp::socket *m_socket;
|
||||
bool m_shutdown;
|
||||
|
||||
/**
|
||||
* Temporary storage for a handshake package
|
||||
*/
|
||||
st_handshake_package m_handshake_package;
|
||||
|
||||
/**
|
||||
* Temporary storage for an OK package
|
||||
*/
|
||||
st_ok_package m_ok_package;
|
||||
|
||||
/**
|
||||
* Temporary storage for an error package
|
||||
*/
|
||||
st_error_package m_error_package;
|
||||
|
||||
/**
|
||||
* each bin log event starts with a 19 byte long header
|
||||
* We use this sturcture every time we initiate an async
|
||||
* read.
|
||||
*/
|
||||
boost::uint8_t m_event_header[19];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
boost::uint8_t m_net_header[4];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
boost::uint8_t m_net_packet[MAX_PACKAGE_SIZE];
|
||||
boost::asio::streambuf m_event_stream_buffer;
|
||||
char * m_event_packet;
|
||||
|
||||
/**
|
||||
* This pointer points to an object constructed from event
|
||||
* stream during async communication with
|
||||
* server. If it is 0 it means that no event has been
|
||||
* constructed yet.
|
||||
*/
|
||||
Log_event_header *m_waiting_event;
|
||||
Log_event_header m_log_event_header;
|
||||
/**
|
||||
* A ring buffer used to dispatch aggregated events to the user application
|
||||
*/
|
||||
bounded_buffer<Binary_log_event *> *m_event_queue;
|
||||
|
||||
std::string m_user;
|
||||
std::string m_host;
|
||||
std::string m_passwd;
|
||||
long m_port;
|
||||
boost::uint32_t m_packet_no;
|
||||
|
||||
boost::uint64_t m_total_bytes_transferred;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a SHOW MASTER STATUS command to the server and retrieve the
|
||||
* current binlog position.
|
||||
*
|
||||
* @return False if the operation succeeded, true if it failed.
|
||||
*/
|
||||
bool fetch_master_status(tcp::socket *socket, std::string *filename, unsigned long *position);
|
||||
/**
|
||||
* Sends a SHOW BINARY LOGS command to the server and stores the file
|
||||
* names and sizes in a map.
|
||||
*/
|
||||
bool fetch_binlogs_name_and_size(tcp::socket *socket, std::map<std::string, unsigned long> &binlog_map);
|
||||
|
||||
int authenticate(tcp::socket *socket, const std::string& user,
|
||||
const std::string& passwd,
|
||||
const st_handshake_package &handshake_package);
|
||||
|
||||
tcp::socket *
|
||||
sync_connect_and_authenticate(boost::asio::io_service &io_service, const std::string &user,
|
||||
const std::string &passwd, const std::string &host, long port);
|
||||
|
||||
|
||||
} }
|
||||
|
||||
#endif /* _TCP_DRIVER_H */
|
53
replication_listener/include/utilities.h
Normal file
53
replication_listener/include/utilities.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _UTILITIES_H
|
||||
#define _UTILITIES_H
|
||||
|
||||
#include "value.h"
|
||||
#include "protocol.h"
|
||||
|
||||
|
||||
using namespace mysql;
|
||||
|
||||
namespace mysql {
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Q_FLAGS2_CODE= 0,
|
||||
Q_SQL_MODE_CODE,
|
||||
Q_CATALOG_CODE,
|
||||
Q_AUTO_INCREMENT,
|
||||
Q_CHARSET_CODE,
|
||||
Q_TIME_ZONE_CODE,
|
||||
Q_CATALOG_NZ_CODE,
|
||||
Q_LC_TIME_NAMES_CODE,
|
||||
Q_CHARSET_DATABASE_CODE,
|
||||
Q_TABLE_MAP_FOR_UPDATE_CODE,
|
||||
Q_MASTER_DATA_WRITTEN_CODE,
|
||||
Q_INVOKER
|
||||
} enum_var_types;
|
||||
|
||||
int server_var_decoder (std::map<std::string, mysql::Value> *my_var_map,
|
||||
std::vector<boost::uint8_t > variables);
|
||||
|
||||
}
|
||||
|
||||
#endif /* _UTILITIES_H */
|
181
replication_listener/include/value.h
Normal file
181
replication_listener/include/value.h
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _VALUE_ADAPTER_H
|
||||
#define _VALUE_ADAPTER_H
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "protocol.h"
|
||||
#include <boost/any.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace mysql;
|
||||
namespace mysql {
|
||||
|
||||
/**
|
||||
This helper function calculates the size in bytes of a particular field in a
|
||||
row type event as defined by the field_ptr and metadata_ptr arguments.
|
||||
@param column_type Field type code
|
||||
@param field_ptr The field data
|
||||
@param metadata_ptr The field metadata
|
||||
|
||||
@note We need the actual field data because the string field size is not
|
||||
part of the meta data. :(
|
||||
|
||||
@return The size in bytes of a particular field
|
||||
*/
|
||||
int calc_field_size(unsigned char column_type, const unsigned char *field_ptr,
|
||||
boost::uint32_t metadata);
|
||||
|
||||
|
||||
/**
|
||||
* A value object class which encapsluate a tuple (value type, metadata, storage)
|
||||
* and provide for views to this storage through a well defined interface.
|
||||
*
|
||||
* Can be used with a Converter to convert between different Values.
|
||||
*/
|
||||
class Value
|
||||
{
|
||||
public:
|
||||
Value(enum system::enum_field_types type, boost::uint32_t metadata, const char *storage) :
|
||||
m_type(type), m_storage(storage), m_metadata(metadata), m_is_null(false)
|
||||
{
|
||||
m_size= calc_field_size((unsigned char)type,
|
||||
(const unsigned char*)storage,
|
||||
metadata);
|
||||
//std::cout << "TYPE: " << type << " SIZE: " << m_size << std::endl;
|
||||
};
|
||||
|
||||
Value()
|
||||
{
|
||||
m_size= 0;
|
||||
m_storage= 0;
|
||||
m_metadata= 0;
|
||||
m_is_null= false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*/
|
||||
Value(const Value& val);
|
||||
|
||||
Value &operator=(const Value &val);
|
||||
bool operator==(const Value &val) const;
|
||||
bool operator!=(const Value &val) const;
|
||||
|
||||
~Value() {}
|
||||
|
||||
void is_null(bool s) { m_is_null= s; }
|
||||
bool is_null(void) const { return m_is_null; }
|
||||
|
||||
const char *storage() const { return m_storage; }
|
||||
|
||||
/**
|
||||
* Get the length in bytes of the entire storage (any metadata part +
|
||||
* atual data)
|
||||
*/
|
||||
size_t length() const { return m_size; }
|
||||
enum system::enum_field_types type() const { return m_type; }
|
||||
boost::uint32_t metadata() const { return m_metadata; }
|
||||
|
||||
/**
|
||||
* Returns the integer representation of a storage of a pre-specified
|
||||
* type.
|
||||
*/
|
||||
boost::int32_t as_int32() const;
|
||||
|
||||
/**
|
||||
* Returns the integer representation of a storage of pre-specified
|
||||
* type.
|
||||
*/
|
||||
boost::int64_t as_int64() const;
|
||||
|
||||
/**
|
||||
* Returns the integer representation of a storage of pre-specified
|
||||
* type.
|
||||
*/
|
||||
boost::int8_t as_int8() const;
|
||||
|
||||
/**
|
||||
* Returns the integer representation of a storage of pre-specified
|
||||
* type.
|
||||
*/
|
||||
boost::int16_t as_int16() const;
|
||||
|
||||
/**
|
||||
* Returns a pointer to the character data of a string type stored
|
||||
* in the pre-defined storage.
|
||||
* @note The position is an offset of the storage pointer determined
|
||||
* by the metadata and type.
|
||||
*
|
||||
* @param[out] size The size in bytes of the character string.
|
||||
*
|
||||
*/
|
||||
char *as_c_str(unsigned long &size) const;
|
||||
|
||||
/**
|
||||
* Returns a pointer to the byte data of a blob type stored in the pre-
|
||||
* defined storage.
|
||||
* @note The position is an offset of the storage pointer determined
|
||||
* by the metadata and type.
|
||||
*
|
||||
* @param[out] size The size in bytes of the blob data.
|
||||
*/
|
||||
unsigned char *as_blob(unsigned long &size) const;
|
||||
|
||||
float as_float() const;
|
||||
double as_double() const;
|
||||
|
||||
private:
|
||||
enum system::enum_field_types m_type;
|
||||
size_t m_size;
|
||||
const char *m_storage;
|
||||
boost::uint32_t m_metadata;
|
||||
bool m_is_null;
|
||||
};
|
||||
|
||||
class Converter
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Converts and copies the sql value to a std::string object.
|
||||
* @param[out] str The target string
|
||||
* @param[in] val The value object to be converted
|
||||
*/
|
||||
void to(std::string &str, const Value &val) const;
|
||||
|
||||
/**
|
||||
* Converts and copies the sql value to a long integer.
|
||||
* @param[out] out The target variable
|
||||
* @param[in] val The value object to be converted
|
||||
*/
|
||||
void to(long &out, const Value &val) const;
|
||||
|
||||
/**
|
||||
* Converts and copies the sql value to a floating point number.
|
||||
* @param[out] out The target variable
|
||||
* @param[in] val The value object to be converted
|
||||
*/
|
||||
void to(float &out, const Value &val) const;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace mysql
|
||||
#endif /* _VALUE_ADAPTER_H */
|
22
replication_listener/install_manifest.txt
Normal file
22
replication_listener/install_manifest.txt
Normal file
@ -0,0 +1,22 @@
|
||||
/usr/local/./include/bounded_buffer.h
|
||||
/usr/local/./include/protocol.h
|
||||
/usr/local/./include/basic_content_handler.h
|
||||
/usr/local/./include/resultset_iterator.h
|
||||
/usr/local/./include/gtid.h
|
||||
/usr/local/./include/binlog_driver.h
|
||||
/usr/local/./include/value.h
|
||||
/usr/local/./include/binlog_event.h
|
||||
/usr/local/./include/field_iterator.h
|
||||
/usr/local/./include/basic_transaction_parser.h
|
||||
/usr/local/./include/utilities.h
|
||||
/usr/local/./include/access_method_factory.h
|
||||
/usr/local/./include/listener_exception.h
|
||||
/usr/local/./include/tcp_driver.h
|
||||
/usr/local/./include/binlog_api.h
|
||||
/usr/local/./include/rowset.h
|
||||
/usr/local/./include/file_driver.h
|
||||
/usr/local/./include/row_of_fields.h
|
||||
/usr/local/lib/libreplication.so.0.1
|
||||
/usr/local/lib/libreplication.so.1
|
||||
/usr/local/lib/libreplication.so
|
||||
/usr/local/lib/libreplication.a
|
67
replication_listener/mysql-replication-listener.spec
Normal file
67
replication_listener/mysql-replication-listener.spec
Normal file
@ -0,0 +1,67 @@
|
||||
%define _libdir /usr/lib
|
||||
|
||||
Name: mysql-replication-listener
|
||||
Version: 0.0.47
|
||||
Release: 10%{?dist}
|
||||
Summary: A STL/Boost based C++ library used for connecting to a MySQL server and process the replication stream as a slave.
|
||||
|
||||
Group: Development/Libraries
|
||||
License: GNU GPL v2
|
||||
URL: https://bitbucket.org/winebarrel/mysql-replication-listener
|
||||
#URL: https://launchpad.net/mysql-replication-listener
|
||||
Source0: mysql-replication-listener.tar.gz
|
||||
# git clone https://bitbucket.org/winebarrel/mysql-replication-listener.git
|
||||
# cd mysql-replication-listener/
|
||||
# git checkout refs/tags/0.0.47-10
|
||||
# cd ..
|
||||
# tar zcf mysql-replication-listener.tar.gz mysql-replication-listener/
|
||||
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
|
||||
BuildRequires: gcc-c++, make, cmake, boost-devel, openssl-devel
|
||||
Requires: glibc, libstdc++, zlib, boost-devel, openssl
|
||||
|
||||
%description
|
||||
The MySQL Replicant Library is a C++ library for reading MySQL
|
||||
replication events, either by connecting to a server or by reading
|
||||
from a file. To handle reading from a server, it includes a very
|
||||
simple client.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}
|
||||
|
||||
%build
|
||||
%cmake
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post -p /sbin/ldconfig
|
||||
%postun -p /sbin/ldconfig
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%{_includedir}/access_method_factory.h
|
||||
%{_includedir}/basic_content_handler.h
|
||||
%{_includedir}/basic_transaction_parser.h
|
||||
%{_includedir}/binlog_api.h
|
||||
%{_includedir}/binlog_driver.h
|
||||
%{_includedir}/binlog_event.h
|
||||
%{_includedir}/bounded_buffer.h
|
||||
%{_includedir}/field_iterator.h
|
||||
%{_includedir}/file_driver.h
|
||||
%{_includedir}/protocol.h
|
||||
%{_includedir}/resultset_iterator.h
|
||||
%{_includedir}/row_of_fields.h
|
||||
%{_includedir}/rowset.h
|
||||
%{_includedir}/tcp_driver.h
|
||||
%{_includedir}/utilities.h
|
||||
%{_includedir}/value.h
|
||||
%{_libdir}/libreplication.a
|
||||
%{_libdir}/libreplication.so
|
||||
%{_libdir}/libreplication.so.0.1
|
||||
%{_libdir}/libreplication.so.1
|
32
replication_listener/src/CMakeLists.txt
Normal file
32
replication_listener/src/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
||||
# This configuration file builds both the static and shared version of
|
||||
# the library.
|
||||
set(replication_sources
|
||||
access_method_factory.cpp field_iterator.cpp row_of_fields.cpp
|
||||
binlog_driver.cpp basic_transaction_parser.cpp tcp_driver.cpp
|
||||
file_driver.cpp binary_log.cpp protocol.cpp value.cpp binlog_event.cpp
|
||||
resultset_iterator.cpp basic_transaction_parser.cpp
|
||||
basic_content_handler.cpp utilities.cpp gtid.cpp)
|
||||
|
||||
# Find MySQL client library and header files
|
||||
find_library(MySQL_LIBRARY NAMES libmysqld.a PATHS
|
||||
/usr/lib64/mysql /usr/lib/mysql /usr/local/mysql/lib)
|
||||
find_path(MySQL_INCLUDE_DIR mysql.h
|
||||
/usr/local/include/mysql /usr/include/mysql)
|
||||
include_directories(${MySQL_INCLUDE_DIR})
|
||||
|
||||
# Configure for building static library
|
||||
add_library(replication_static STATIC ${replication_sources})
|
||||
target_link_libraries(replication_static crypto ${Boost_LIBRARIES} ${MySQL_LIBRARY})
|
||||
set_target_properties(replication_static PROPERTIES
|
||||
OUTPUT_NAME "replication")
|
||||
|
||||
# Configure for building shared library
|
||||
add_library(replication_shared SHARED ${replication_sources})
|
||||
target_link_libraries(replication_shared crypto ${Boost_LIBRARIES} ${MySQL_LIBRARY})
|
||||
|
||||
set_target_properties(replication_shared PROPERTIES
|
||||
VERSION 0.1 SOVERSION 1
|
||||
OUTPUT_NAME "replication")
|
||||
|
||||
install(TARGETS replication_shared LIBRARY DESTINATION lib)
|
||||
install(TARGETS replication_static ARCHIVE DESTINATION lib)
|
129
replication_listener/src/access_method_factory.cpp
Normal file
129
replication_listener/src/access_method_factory.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "access_method_factory.h"
|
||||
#include "tcp_driver.h"
|
||||
#include "file_driver.h"
|
||||
|
||||
using mysql::system::Binary_log_driver;
|
||||
using mysql::system::Binlog_tcp_driver;
|
||||
using mysql::system::Binlog_file_driver;
|
||||
|
||||
/**
|
||||
Parse the body of a MySQL URI.
|
||||
|
||||
The format is <code>user[:password]@host[:port]</code>
|
||||
*/
|
||||
static Binary_log_driver *parse_mysql_url(const char *body, size_t len)
|
||||
{
|
||||
/* Find the beginning of the user name */
|
||||
if (strncmp(body, "//", 2) != 0)
|
||||
return 0;
|
||||
|
||||
/* Find the user name, which is mandatory */
|
||||
const char *user = body + 2;
|
||||
const char *user_end= strpbrk(user, ":@");
|
||||
if (user_end == 0 || user_end == user)
|
||||
return 0;
|
||||
assert(user_end - user >= 1); // There has to be a username
|
||||
|
||||
/* Find the password, which can be empty */
|
||||
assert(*user_end == ':' || *user_end == '@');
|
||||
const char *const pass = user_end + 1; // Skip the ':' (or '@')
|
||||
const char *pass_end = pass;
|
||||
if (*user_end == ':')
|
||||
{
|
||||
pass_end = strchr(pass, '@');
|
||||
if (pass_end == 0)
|
||||
return 0; // There should be a password, but '@' was not found
|
||||
}
|
||||
assert(pass_end - pass >= 0); // Password can be empty
|
||||
|
||||
/* Find the host name, which is mandatory */
|
||||
// Skip the '@', if there is one
|
||||
const char *host = *pass_end == '@' ? pass_end + 1 : pass_end;
|
||||
const char *host_end = strchr(host, ':');
|
||||
if (host == host_end)
|
||||
return 0; // No hostname was found
|
||||
/* If no ':' was found there is no port, so the host end at the end
|
||||
* of the string */
|
||||
if (host_end == 0)
|
||||
host_end = body + len;
|
||||
assert(host_end - host >= 1); // There has to be a host
|
||||
|
||||
/* Find the port number */
|
||||
unsigned long portno = 3306;
|
||||
if (*host_end == ':')
|
||||
portno = strtoul(host_end + 1, NULL, 10);
|
||||
|
||||
/* Host name is now the string [host, port-1) if port != NULL and [host, EOS) otherwise. */
|
||||
/* Port number is stored in portno, either the default, or a parsed one */
|
||||
return new Binlog_tcp_driver(std::string(user, user_end - user),
|
||||
std::string(pass, pass_end - pass),
|
||||
std::string(host, host_end - host),
|
||||
portno);
|
||||
}
|
||||
|
||||
|
||||
static Binary_log_driver *parse_file_url(const char *body, size_t length)
|
||||
{
|
||||
/* Find the beginning of the file name */
|
||||
if (strncmp(body, "//", 2) != 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
Since we don't support host information yet, there should be a
|
||||
slash after the initial "//".
|
||||
*/
|
||||
if (body[2] != '/')
|
||||
return 0;
|
||||
|
||||
return new Binlog_file_driver(body + 2);
|
||||
}
|
||||
|
||||
/**
|
||||
URI parser information.
|
||||
*/
|
||||
struct Parser {
|
||||
const char* protocol;
|
||||
Binary_log_driver *(*parser)(const char *body, size_t length);
|
||||
};
|
||||
|
||||
/**
|
||||
Array of schema names and matching parsers.
|
||||
*/
|
||||
static Parser url_parser[] = {
|
||||
{ "mysql", parse_mysql_url },
|
||||
{ "file", parse_file_url },
|
||||
};
|
||||
|
||||
Binary_log_driver *
|
||||
mysql::system::create_transport(const char *url)
|
||||
{
|
||||
const char *pfx = strchr(url, ':');
|
||||
if (pfx == 0)
|
||||
return NULL;
|
||||
for (int i = 0 ; i < sizeof(url_parser)/sizeof(*url_parser) ; ++i)
|
||||
{
|
||||
const char *proto = url_parser[i].protocol;
|
||||
if (strncmp(proto, url, strlen(proto)) == 0)
|
||||
return (*url_parser[i].parser)(pfx+1, strlen(pfx+1));
|
||||
}
|
||||
return NULL;
|
||||
}
|
107
replication_listener/src/basic_content_handler.cpp
Normal file
107
replication_listener/src/basic_content_handler.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "basic_content_handler.h"
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
namespace mysql {
|
||||
|
||||
Content_handler::Content_handler () {}
|
||||
Content_handler::~Content_handler () {}
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Query_event *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Row_event *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Table_map_event *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Xid *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::User_var_event *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Incident_event *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Rotate_event *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Int_var_event *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Binary_log_event *ev) { return ev; }
|
||||
mysql::Binary_log_event *Content_handler::process_event(mysql::Gtid_event *ev) {return ev; }
|
||||
|
||||
Injection_queue *Content_handler::get_injection_queue(void)
|
||||
{
|
||||
return m_reinject_queue;
|
||||
}
|
||||
|
||||
void Content_handler::set_injection_queue(Injection_queue *queue)
|
||||
{
|
||||
m_reinject_queue= queue;
|
||||
}
|
||||
|
||||
mysql::Binary_log_event*
|
||||
Content_handler::internal_process_event(mysql::Binary_log_event *ev)
|
||||
{
|
||||
mysql::Binary_log_event *processed_event= 0;
|
||||
switch(ev->header ()->type_code) {
|
||||
case mysql::QUERY_EVENT:
|
||||
processed_event= process_event(static_cast<mysql::Query_event*>(ev));
|
||||
break;
|
||||
case mysql::GTID_EVENT_MARIADB:
|
||||
case mysql::GTID_EVENT_MYSQL:
|
||||
processed_event= process_event(static_cast<mysql::Gtid_event*>(ev));
|
||||
break;
|
||||
case mysql::WRITE_ROWS_EVENT:
|
||||
case mysql::UPDATE_ROWS_EVENT:
|
||||
case mysql::DELETE_ROWS_EVENT:
|
||||
processed_event= process_event(static_cast<mysql::Row_event*>(ev));
|
||||
break;
|
||||
case mysql::USER_VAR_EVENT:
|
||||
processed_event= process_event(static_cast<mysql::User_var_event *>(ev));
|
||||
break;
|
||||
case mysql::ROTATE_EVENT:
|
||||
processed_event= process_event(static_cast<mysql::Rotate_event *>(ev));
|
||||
break;
|
||||
case mysql::INCIDENT_EVENT:
|
||||
processed_event= process_event(static_cast<mysql::Incident_event *>(ev));
|
||||
break;
|
||||
case mysql::XID_EVENT:
|
||||
processed_event= process_event(static_cast<mysql::Xid *>(ev));
|
||||
break;
|
||||
case mysql::TABLE_MAP_EVENT:
|
||||
processed_event= process_event(static_cast<mysql::Table_map_event *>(ev));
|
||||
break;
|
||||
/* TODO ********************************************************************/
|
||||
case mysql::FORMAT_DESCRIPTION_EVENT:
|
||||
processed_event= process_event(ev);
|
||||
break;
|
||||
case mysql::BEGIN_LOAD_QUERY_EVENT:
|
||||
processed_event= process_event(ev);
|
||||
break;
|
||||
case mysql::EXECUTE_LOAD_QUERY_EVENT:
|
||||
processed_event= process_event(ev);
|
||||
break;
|
||||
case mysql::INTVAR_EVENT:
|
||||
processed_event= process_event(ev);
|
||||
break;
|
||||
case mysql::STOP_EVENT:
|
||||
processed_event= process_event(ev);
|
||||
break;
|
||||
case mysql::RAND_EVENT:
|
||||
processed_event= process_event(ev);
|
||||
break;
|
||||
/****************************************************************************/
|
||||
default:
|
||||
processed_event= process_event(ev);
|
||||
break;
|
||||
}
|
||||
return processed_event;
|
||||
}
|
||||
|
||||
} // end namespace
|
172
replication_listener/src/basic_transaction_parser.cpp
Normal file
172
replication_listener/src/basic_transaction_parser.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "binlog_event.h"
|
||||
#include "basic_transaction_parser.h"
|
||||
#include "protocol.h"
|
||||
#include "value.h"
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iostream>
|
||||
#include "field_iterator.h"
|
||||
|
||||
namespace mysql {
|
||||
|
||||
mysql::Binary_log_event *Basic_transaction_parser::process_event(mysql::Gtid_event *qev)
|
||||
{
|
||||
m_transaction_state= STARTING;
|
||||
|
||||
return process_transaction_state(qev);
|
||||
}
|
||||
|
||||
|
||||
mysql::Binary_log_event *Basic_transaction_parser::process_event(mysql::Query_event *qev)
|
||||
{
|
||||
if (qev->query == "BEGIN")
|
||||
{
|
||||
//std::cout << "Transaction has started!" << std::endl;
|
||||
m_transaction_state= STARTING;
|
||||
}
|
||||
else if (qev->query == "COMMIT")
|
||||
{
|
||||
m_transaction_state= COMMITTING;
|
||||
}
|
||||
|
||||
return process_transaction_state(qev);
|
||||
}
|
||||
|
||||
mysql::Binary_log_event *Basic_transaction_parser::process_event(mysql::Xid *ev)
|
||||
{
|
||||
m_transaction_state= COMMITTING;
|
||||
return process_transaction_state(ev);
|
||||
}
|
||||
|
||||
mysql::Binary_log_event *Basic_transaction_parser::process_event(mysql::Table_map_event *ev)
|
||||
{
|
||||
if(m_transaction_state ==IN_PROGRESS)
|
||||
{
|
||||
m_event_stack.push_back(ev);
|
||||
return 0;
|
||||
}
|
||||
return ev;
|
||||
}
|
||||
|
||||
mysql::Binary_log_event *Basic_transaction_parser::process_event(mysql::Row_event *ev)
|
||||
{
|
||||
if(m_transaction_state ==IN_PROGRESS)
|
||||
{
|
||||
m_event_stack.push_back(ev);
|
||||
return 0;
|
||||
}
|
||||
return ev;
|
||||
}
|
||||
|
||||
mysql::Binary_log_event *Basic_transaction_parser::process_transaction_state(mysql::Binary_log_event *incomming_event)
|
||||
{
|
||||
switch(m_transaction_state)
|
||||
{
|
||||
case STARTING:
|
||||
{
|
||||
m_transaction_state= IN_PROGRESS;
|
||||
m_start_time= incomming_event->header()->timestamp;
|
||||
delete incomming_event; // drop the begin event
|
||||
return 0;
|
||||
}
|
||||
case COMMITTING:
|
||||
{
|
||||
delete incomming_event; // drop the commit event
|
||||
|
||||
/**
|
||||
* Propagate the start time for the transaction to the newly created
|
||||
* event.
|
||||
*/
|
||||
mysql::Transaction_log_event *trans= mysql::create_transaction_log_event();
|
||||
trans->header()->timestamp= m_start_time;
|
||||
|
||||
//std::cout << "There are " << m_event_stack.size() << " events in the transaction: ";
|
||||
while( m_event_stack.size() > 0)
|
||||
{
|
||||
mysql::Binary_log_event *event= m_event_stack.front();
|
||||
m_event_stack.pop_front();
|
||||
switch(event->get_event_type())
|
||||
{
|
||||
case mysql::TABLE_MAP_EVENT:
|
||||
{
|
||||
/*
|
||||
Index the table name with a table id to ease lookup later.
|
||||
*/
|
||||
mysql::Table_map_event *tm= static_cast<mysql::Table_map_event *>(event);
|
||||
//std::cout << "Indexing table " << tm->table_id << " " << tm->table_name << std::endl;
|
||||
//std::cout.flush ();
|
||||
trans->m_table_map.insert(mysql::Event_index_element(tm->table_id,tm));
|
||||
trans->m_events.push_back(event);
|
||||
}
|
||||
break;
|
||||
case mysql::WRITE_ROWS_EVENT:
|
||||
case mysql::DELETE_ROWS_EVENT:
|
||||
case mysql::UPDATE_ROWS_EVENT:
|
||||
{
|
||||
trans->m_events.push_back(event);
|
||||
/*
|
||||
* Propagate last known next position
|
||||
*/
|
||||
trans->header()->next_position= event->header()->next_position;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
delete event;
|
||||
}
|
||||
} // end while
|
||||
m_transaction_state= NOT_IN_PROGRESS;
|
||||
return(trans);
|
||||
}
|
||||
case NOT_IN_PROGRESS:
|
||||
default:
|
||||
return incomming_event;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Transaction_log_event *create_transaction_log_event(void)
|
||||
{
|
||||
Transaction_log_event *trans= new Transaction_log_event();
|
||||
trans->header()->type_code= USER_DEFINED;
|
||||
return trans;
|
||||
};
|
||||
|
||||
Transaction_log_event::~Transaction_log_event()
|
||||
{
|
||||
Int_to_Event_map::iterator it;
|
||||
for(it = m_table_map.begin(); it != m_table_map.end();)
|
||||
{
|
||||
/* No need to delete the event here; it happens in the next iteration */
|
||||
m_table_map.erase(it++);
|
||||
}
|
||||
|
||||
while (m_events.size() > 0)
|
||||
{
|
||||
Binary_log_event *event= m_events.back();
|
||||
m_events.pop_back();
|
||||
delete(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // end namespace
|
164
replication_listener/src/binary_log.cpp
Normal file
164
replication_listener/src/binary_log.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 <list>
|
||||
|
||||
#include "binlog_api.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace mysql;
|
||||
using namespace mysql::system;
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
/*
|
||||
Return server type string.
|
||||
*/
|
||||
|
||||
const char *mysql_server_type_str(mysql_server_types server_type)
|
||||
{
|
||||
switch(server_type) {
|
||||
case MYSQL_SERVER_TYPE_MARIADB: return "MariaDB";
|
||||
case MYSQL_SERVER_TYPE_MYSQL: return "MySQL";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
Binary_log::Binary_log(Binary_log_driver *drv) : m_binlog_position(4), m_binlog_file(""), m_uri("")
|
||||
{
|
||||
if (drv == NULL)
|
||||
{
|
||||
m_driver= &m_dummy_driver;
|
||||
}
|
||||
else
|
||||
m_driver= drv;
|
||||
}
|
||||
|
||||
Binary_log::Binary_log(Binary_log_driver *drv, std::string uri) : m_binlog_position(4), m_binlog_file(""), m_uri(uri)
|
||||
{
|
||||
if (drv == NULL)
|
||||
{
|
||||
m_driver= &m_dummy_driver;
|
||||
}
|
||||
else
|
||||
m_driver= drv;
|
||||
}
|
||||
|
||||
Content_handler_pipeline *Binary_log::content_handler_pipeline(void)
|
||||
{
|
||||
return &m_content_handlers;
|
||||
}
|
||||
|
||||
int Binary_log::wait_for_next_event(mysql::Binary_log_event **event_ptr)
|
||||
{
|
||||
int rc;
|
||||
bool handler_code;
|
||||
mysql::Binary_log_event *event;
|
||||
|
||||
mysql::Injection_queue reinjection_queue;
|
||||
|
||||
do {
|
||||
handler_code= false;
|
||||
if (!reinjection_queue.empty())
|
||||
{
|
||||
event= reinjection_queue.front();
|
||||
reinjection_queue.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return in case of non-ERR_OK.
|
||||
if(rc= m_driver->wait_for_next_event(&event))
|
||||
return rc;
|
||||
}
|
||||
m_binlog_position= event->header()->next_position;
|
||||
mysql::Content_handler *handler;
|
||||
|
||||
BOOST_FOREACH(handler, m_content_handlers)
|
||||
{
|
||||
if (event)
|
||||
{
|
||||
handler->set_injection_queue(&reinjection_queue);
|
||||
event= handler->internal_process_event(event);
|
||||
}
|
||||
}
|
||||
} while(event == 0 || !reinjection_queue.empty());
|
||||
|
||||
if (event_ptr)
|
||||
*event_ptr= event;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Binary_log::set_position(const std::string &filename, unsigned long position)
|
||||
{
|
||||
int status= m_driver->set_position(filename, position);
|
||||
if (status == ERR_OK)
|
||||
{
|
||||
m_binlog_file= filename;
|
||||
m_binlog_position= position;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int Binary_log::set_position(unsigned long position)
|
||||
{
|
||||
std::string filename;
|
||||
m_driver->get_position(&filename, NULL);
|
||||
return this->set_position(filename, position);
|
||||
}
|
||||
|
||||
int Binary_log::set_position_gtid(const Gtid gtid)
|
||||
{
|
||||
return this->set_position_gtid(gtid);
|
||||
}
|
||||
|
||||
unsigned long Binary_log::get_position(void)
|
||||
{
|
||||
return m_binlog_position;
|
||||
}
|
||||
|
||||
unsigned long Binary_log::get_position(std::string &filename)
|
||||
{
|
||||
m_driver->get_position(&m_binlog_file, &m_binlog_position);
|
||||
filename= m_binlog_file;
|
||||
return m_binlog_position;
|
||||
}
|
||||
|
||||
int Binary_log::connect(const Gtid gtid)
|
||||
{
|
||||
return m_driver->connect(gtid);
|
||||
}
|
||||
|
||||
mysql_server_types Binary_log::get_mysql_server_type() const
|
||||
{
|
||||
return m_driver->get_mysql_server_type();
|
||||
}
|
||||
|
||||
const char *Binary_log::get_mysql_server_type_str() const
|
||||
{
|
||||
return mysql_server_type_str(get_mysql_server_type());
|
||||
}
|
||||
|
||||
void Binary_log::shutdown()
|
||||
{
|
||||
m_driver->shutdown();
|
||||
}
|
||||
|
||||
}
|
80
replication_listener/src/binlog_driver.cpp
Normal file
80
replication_listener/src/binlog_driver.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "binlog_driver.h"
|
||||
|
||||
namespace mysql { namespace system {
|
||||
|
||||
/*
|
||||
Binary_log_event* Binary_log_driver::parse_event(boost::asio::streambuf
|
||||
&sbuff, Log_event_header
|
||||
*header)
|
||||
*/
|
||||
|
||||
Binary_log_event* Binary_log_driver::parse_event(std::istream &is,
|
||||
Log_event_header *header)
|
||||
{
|
||||
Binary_log_event *parsed_event= 0;
|
||||
|
||||
switch (header->type_code) {
|
||||
case TABLE_MAP_EVENT:
|
||||
parsed_event= proto_table_map_event(is, header);
|
||||
break;
|
||||
case QUERY_EVENT:
|
||||
parsed_event= proto_query_event(is, header);
|
||||
break;
|
||||
case GTID_EVENT_MARIADB:
|
||||
case GTID_EVENT_MYSQL:
|
||||
parsed_event= proto_gtid_event(is, header);
|
||||
break;
|
||||
case INCIDENT_EVENT:
|
||||
parsed_event= proto_incident_event(is, header);
|
||||
break;
|
||||
case WRITE_ROWS_EVENT:
|
||||
case UPDATE_ROWS_EVENT:
|
||||
case DELETE_ROWS_EVENT:
|
||||
parsed_event= proto_rows_event(is, header);
|
||||
break;
|
||||
case ROTATE_EVENT:
|
||||
{
|
||||
Rotate_event *rot= proto_rotate_event(is, header);
|
||||
m_binlog_file_name= rot->binlog_file;
|
||||
m_binlog_offset= (unsigned long)rot->binlog_pos;
|
||||
parsed_event= rot;
|
||||
}
|
||||
break;
|
||||
case INTVAR_EVENT:
|
||||
parsed_event= proto_intvar_event(is, header);
|
||||
break;
|
||||
case USER_VAR_EVENT:
|
||||
parsed_event= proto_uservar_event(is, header);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// Create a dummy driver.
|
||||
parsed_event= new Binary_log_event(header);
|
||||
}
|
||||
}
|
||||
|
||||
return parsed_event;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
83
replication_listener/src/binlog_event.cpp
Normal file
83
replication_listener/src/binlog_event.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "binlog_event.h"
|
||||
#include <iostream>
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
namespace system {
|
||||
|
||||
const char *get_event_type_str(Log_event_type type)
|
||||
{
|
||||
switch(type) {
|
||||
case START_EVENT_V3: return "Start_v3";
|
||||
case STOP_EVENT: return "Stop";
|
||||
case QUERY_EVENT: return "Query";
|
||||
case ROTATE_EVENT: return "Rotate";
|
||||
case INTVAR_EVENT: return "Intvar";
|
||||
case LOAD_EVENT: return "Load";
|
||||
case NEW_LOAD_EVENT: return "New_load";
|
||||
case SLAVE_EVENT: return "Slave";
|
||||
case CREATE_FILE_EVENT: return "Create_file";
|
||||
case APPEND_BLOCK_EVENT: return "Append_block";
|
||||
case DELETE_FILE_EVENT: return "Delete_file";
|
||||
case EXEC_LOAD_EVENT: return "Exec_load";
|
||||
case RAND_EVENT: return "RAND";
|
||||
case XID_EVENT: return "Xid";
|
||||
case USER_VAR_EVENT: return "User var";
|
||||
case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
|
||||
case TABLE_MAP_EVENT: return "Table_map";
|
||||
case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
|
||||
case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
|
||||
case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
|
||||
case WRITE_ROWS_EVENT: return "Write_rows";
|
||||
case UPDATE_ROWS_EVENT: return "Update_rows";
|
||||
case DELETE_ROWS_EVENT: return "Delete_rows";
|
||||
case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
|
||||
case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
|
||||
case INCIDENT_EVENT: return "Incident";
|
||||
case USER_DEFINED: return "User defined";
|
||||
case GTID_EVENT_MYSQL: return "GTID MYSQL";
|
||||
case GTID_EVENT_MARIADB: return "GTID MARIADB";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace system
|
||||
|
||||
|
||||
Binary_log_event::~Binary_log_event()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Binary_log_event * create_incident_event(unsigned int type, const char *message, unsigned long pos)
|
||||
{
|
||||
Incident_event *incident= new Incident_event();
|
||||
incident->header()->type_code= INCIDENT_EVENT;
|
||||
incident->header()->next_position= pos;
|
||||
incident->header()->event_length= LOG_EVENT_HEADER_SIZE + 2 + strlen(message);
|
||||
incident->type= type;
|
||||
incident->message.append(message);
|
||||
return incident;
|
||||
}
|
||||
|
||||
} // end namespace mysql
|
56
replication_listener/src/cmake_install.cmake
Normal file
56
replication_listener/src/cmake_install.cmake
Normal file
@ -0,0 +1,56 @@
|
||||
# Install script for directory: /home/jan/skysql/skygateway/skygateway/replication_listener/src
|
||||
|
||||
# Set the install prefix
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/local")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
IF(BUILD_TYPE)
|
||||
STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
ELSE(BUILD_TYPE)
|
||||
SET(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
||||
ENDIF(BUILD_TYPE)
|
||||
MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
|
||||
# Set the component getting installed.
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
IF(COMPONENT)
|
||||
MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
|
||||
SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
ELSE(COMPONENT)
|
||||
SET(CMAKE_INSTALL_COMPONENT)
|
||||
ENDIF(COMPONENT)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
# Install shared libraries without execute permission?
|
||||
IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
SET(CMAKE_INSTALL_SO_NO_EXE "1")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")
|
||||
FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE SHARED_LIBRARY FILES
|
||||
"/home/jan/skysql/skygateway/skygateway/replication_listener/src/CMakeFiles/CMakeRelink.dir/libreplication.so.0.1"
|
||||
"/home/jan/skysql/skygateway/skygateway/replication_listener/src/CMakeFiles/CMakeRelink.dir/libreplication.so.1"
|
||||
"/home/jan/skysql/skygateway/skygateway/replication_listener/src/CMakeFiles/CMakeRelink.dir/libreplication.so"
|
||||
)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")
|
||||
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")
|
||||
FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "/home/jan/skysql/skygateway/skygateway/replication_listener/src/libreplication.a")
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")
|
||||
|
||||
IF(CMAKE_INSTALL_COMPONENT)
|
||||
SET(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
|
||||
ELSE(CMAKE_INSTALL_COMPONENT)
|
||||
SET(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
|
||||
ENDIF(CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
FILE(WRITE "/home/jan/skysql/skygateway/skygateway/replication_listener/src/${CMAKE_INSTALL_MANIFEST}" "")
|
||||
FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES})
|
||||
FILE(APPEND "/home/jan/skysql/skygateway/skygateway/replication_listener/src/${CMAKE_INSTALL_MANIFEST}" "${file}\n")
|
||||
ENDFOREACH(file)
|
103
replication_listener/src/field_iterator.cpp
Normal file
103
replication_listener/src/field_iterator.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "field_iterator.h"
|
||||
|
||||
//Row_iterator Row_iterator::end() const
|
||||
//{ return Row_iterator(); }
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
|
||||
bool is_null(unsigned char *bitmap, int index)
|
||||
{
|
||||
unsigned char *byte= bitmap + (index / 8);
|
||||
unsigned bit= 1 << ((index) & 7);
|
||||
return ((*byte) & bit) != 0;
|
||||
}
|
||||
|
||||
|
||||
boost::uint32_t extract_metadata(const Table_map_event *map, int col_no)
|
||||
{
|
||||
int offset= 0;
|
||||
|
||||
for (int i=0; i < col_no; ++i)
|
||||
{
|
||||
unsigned int type= (unsigned int)map->columns[i]&0xFF;
|
||||
offset += lookup_metadata_field_size((enum mysql::system::enum_field_types)type);
|
||||
}
|
||||
|
||||
boost::uint32_t metadata= 0;
|
||||
unsigned int type= (unsigned int)map->columns[col_no]&0xFF;
|
||||
switch(lookup_metadata_field_size((enum mysql::system::enum_field_types)type))
|
||||
{
|
||||
case 1:
|
||||
metadata= map->metadata[offset];
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
unsigned int tmp= ((unsigned int)map->metadata[offset])&0xFF;
|
||||
metadata= static_cast<boost::uint32_t >(tmp);
|
||||
tmp= (((unsigned int)map->metadata[offset+1])&0xFF) << 8;
|
||||
metadata+= static_cast<boost::uint32_t >(tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
int lookup_metadata_field_size(enum mysql::system::enum_field_types field_type)
|
||||
{
|
||||
switch(field_type)
|
||||
{
|
||||
case mysql::system::MYSQL_TYPE_DOUBLE:
|
||||
case mysql::system::MYSQL_TYPE_FLOAT:
|
||||
case mysql::system::MYSQL_TYPE_BLOB:
|
||||
case mysql::system::MYSQL_TYPE_GEOMETRY:
|
||||
return 1;
|
||||
case mysql::system::MYSQL_TYPE_BIT:
|
||||
case mysql::system::MYSQL_TYPE_VARCHAR:
|
||||
case mysql::system::MYSQL_TYPE_NEWDECIMAL:
|
||||
case mysql::system::MYSQL_TYPE_STRING:
|
||||
case mysql::system::MYSQL_TYPE_VAR_STRING:
|
||||
return 2;
|
||||
case mysql::system::MYSQL_TYPE_DECIMAL:
|
||||
case mysql::system::MYSQL_TYPE_SET:
|
||||
case mysql::system::MYSQL_TYPE_ENUM:
|
||||
case mysql::system::MYSQL_TYPE_YEAR:
|
||||
case mysql::system::MYSQL_TYPE_TINY:
|
||||
case mysql::system::MYSQL_TYPE_SHORT:
|
||||
case mysql::system::MYSQL_TYPE_INT24:
|
||||
case mysql::system::MYSQL_TYPE_LONG:
|
||||
case mysql::system::MYSQL_TYPE_NULL:
|
||||
case mysql::system::MYSQL_TYPE_NEWDATE:
|
||||
case mysql::system::MYSQL_TYPE_DATE:
|
||||
case mysql::system::MYSQL_TYPE_TIME:
|
||||
case mysql::system::MYSQL_TYPE_TIMESTAMP:
|
||||
case mysql::system::MYSQL_TYPE_DATETIME:
|
||||
case mysql::system::MYSQL_TYPE_TINY_BLOB:
|
||||
case mysql::system::MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case mysql::system::MYSQL_TYPE_LONG_BLOB:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace mysql
|
177
replication_listener/src/file_driver.cpp
Normal file
177
replication_listener/src/file_driver.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "file_driver.h"
|
||||
|
||||
namespace mysql { namespace system {
|
||||
|
||||
using namespace std;
|
||||
|
||||
// TODO: Gtids not used for binlog file driver
|
||||
int Binlog_file_driver::connect(const Gtid gtid)
|
||||
{
|
||||
struct stat stat_buff;
|
||||
|
||||
char magic[]= {0xfe, 0x62, 0x69, 0x6e, 0};
|
||||
char magic_buf[MAGIC_NUMBER_SIZE];
|
||||
|
||||
// Get the file size.
|
||||
if (stat(m_binlog_file_name.c_str(), &stat_buff) == -1)
|
||||
return ERR_FAIL; // Can't stat binlog file.
|
||||
m_binlog_file_size= stat_buff.st_size;
|
||||
|
||||
m_binlog_file.exceptions(ifstream::failbit | ifstream::badbit |
|
||||
ifstream::eofbit);
|
||||
|
||||
try
|
||||
{
|
||||
// Check if the file can be opened for reading.
|
||||
m_binlog_file.open(m_binlog_file_name.c_str(), ios::in | ios::binary);
|
||||
|
||||
// Check if a valid MySQL binlog file is provided, BINLOG_MAGIC.
|
||||
m_binlog_file.read(magic_buf, MAGIC_NUMBER_SIZE);
|
||||
|
||||
if(memcmp(magic, magic_buf, MAGIC_NUMBER_SIZE))
|
||||
return ERR_FAIL; // Not a valid binlog file.
|
||||
|
||||
// Reset the get pointer.
|
||||
//m_binlog_file.seekg(0, ios::beg );
|
||||
|
||||
m_bytes_read= MAGIC_NUMBER_SIZE;
|
||||
|
||||
} catch (...)
|
||||
{
|
||||
return ERR_FAIL;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
int Binlog_file_driver::disconnect()
|
||||
{
|
||||
m_binlog_file.close();
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
int Binlog_file_driver::set_position(const string &str, unsigned long position)
|
||||
{
|
||||
m_binlog_file.exceptions(ifstream::failbit | ifstream::badbit |
|
||||
ifstream::eofbit);
|
||||
try
|
||||
{
|
||||
m_binlog_file.seekg(position, ios::beg );
|
||||
} catch(...)
|
||||
{
|
||||
return ERR_FAIL;
|
||||
}
|
||||
|
||||
m_bytes_read= position;
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
int Binlog_file_driver::get_position(string *str, unsigned long *position)
|
||||
{
|
||||
m_binlog_file.exceptions(ifstream::failbit | ifstream::badbit |
|
||||
ifstream::eofbit);
|
||||
try
|
||||
{
|
||||
if(position)
|
||||
*position= m_binlog_file.tellg();
|
||||
} catch(...)
|
||||
{
|
||||
return ERR_FAIL;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
int Binlog_file_driver::wait_for_next_event(mysql::Binary_log_event **event)
|
||||
{
|
||||
|
||||
assert(m_binlog_file.tellg() >= 4 );
|
||||
m_binlog_file.exceptions(ifstream::failbit | ifstream::badbit |
|
||||
ifstream::eofbit);
|
||||
|
||||
try
|
||||
{
|
||||
if(m_bytes_read < m_binlog_file_size && m_binlog_file.good())
|
||||
{
|
||||
//Protocol_chunk<boost::uint8_t> prot_marker(m_event_log_header.marker);
|
||||
Protocol_chunk<boost::uint32_t> prot_timestamp(m_event_log_header.timestamp);
|
||||
Protocol_chunk<boost::uint8_t> prot_type_code(m_event_log_header.type_code);
|
||||
Protocol_chunk<boost::uint32_t> prot_server_id(m_event_log_header.server_id);
|
||||
Protocol_chunk<boost::uint32_t>
|
||||
prot_event_length(m_event_log_header.event_length);
|
||||
Protocol_chunk<boost::uint32_t>
|
||||
prot_next_position(m_event_log_header.next_position);
|
||||
Protocol_chunk<boost::uint16_t> prot_flags(m_event_log_header.flags);
|
||||
|
||||
m_binlog_file >> prot_timestamp
|
||||
>> prot_type_code
|
||||
>> prot_server_id
|
||||
>> prot_event_length
|
||||
>> prot_next_position
|
||||
>> prot_flags;
|
||||
|
||||
/*
|
||||
m_binlog_file.read(reinterpret_cast<char*>(&m_event_log_header.timestamp),
|
||||
sizeof(boost::uint32_t));
|
||||
m_binlog_file.read(reinterpret_cast<char*>(&m_event_log_header.type_code),
|
||||
sizeof(boost::uint8_t));
|
||||
m_binlog_file.read(reinterpret_cast<char*>(&m_event_log_header.server_id),
|
||||
sizeof(boost::uint32_t));
|
||||
m_binlog_file.read(reinterpret_cast<char*>(&m_event_log_header.event_length),
|
||||
sizeof(boost::uint32_t));
|
||||
m_binlog_file.read(reinterpret_cast<char*>(&m_event_log_header.next_position),
|
||||
sizeof(boost::uint32_t));
|
||||
m_binlog_file.read(reinterpret_cast<char*>(&m_event_log_header.flags),
|
||||
sizeof(boost::uint16_t));
|
||||
*/
|
||||
|
||||
*event= parse_event(* static_cast<std::istream*> (&m_binlog_file),
|
||||
&m_event_log_header);
|
||||
|
||||
/*
|
||||
Correction. Except for the default case (above), this condition should
|
||||
always fail.
|
||||
*/
|
||||
if (m_bytes_read + m_event_log_header.event_length !=
|
||||
m_binlog_file.tellg())
|
||||
m_binlog_file.seekg(m_bytes_read + m_event_log_header.event_length,
|
||||
ios::beg);
|
||||
|
||||
m_bytes_read= m_binlog_file.tellg();
|
||||
|
||||
if(*event)
|
||||
return ERR_OK;
|
||||
}
|
||||
} catch(...)
|
||||
{
|
||||
return ERR_FAIL;
|
||||
}
|
||||
return ERR_EOF;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
118
replication_listener/src/gtid.cpp
Normal file
118
replication_listener/src/gtid.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
Copyright (C) 2013, SkySQL Ab
|
||||
|
||||
|
||||
This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Author: Jan Lindström jan.lindstrom@skysql.com
|
||||
|
||||
*/
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include "gtid.h"
|
||||
#include "listener_exception.h"
|
||||
#include <mysql.h>
|
||||
#include <my_global.h>
|
||||
#include <my_byteorder.h>
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
Gtid::Gtid(const boost::uint32_t domain_id,
|
||||
const boost::uint32_t server_id,
|
||||
const boost::uint64_t sequence_number)
|
||||
: m_real_gtid(true),
|
||||
m_domain_id(domain_id),
|
||||
m_server_id(server_id),
|
||||
m_sequence_number(sequence_number),
|
||||
m_server_type(MYSQL_SERVER_TYPE_MARIADB)
|
||||
{
|
||||
memset(m_mysql_gtid, 0, MYSQL_GTID_ENCODED_SIZE);
|
||||
|
||||
m_mariadb_gtid = to_string(m_domain_id) + std::string("-") + to_string(m_server_id) + std::string("-") + to_string(m_sequence_number);
|
||||
m_gtid_length = m_mariadb_gtid.length();
|
||||
}
|
||||
|
||||
Gtid::Gtid(const unsigned char *mysql_gtid,
|
||||
const boost::uint64_t gno)
|
||||
:m_real_gtid(true),
|
||||
m_domain_id(0),
|
||||
m_server_id(0),
|
||||
m_sequence_number(gno),
|
||||
m_server_type(MYSQL_SERVER_TYPE_MYSQL),
|
||||
m_gtid_length(MYSQL_GTID_ENCODED_SIZE)
|
||||
{
|
||||
memcpy(m_mysql_gtid, mysql_gtid, MYSQL_GTID_ENCODED_SIZE);
|
||||
}
|
||||
|
||||
Gtid::Gtid(const unsigned char* mysql_gtid)
|
||||
:m_real_gtid(true),
|
||||
m_domain_id(0),
|
||||
m_server_id(0),
|
||||
m_sequence_number(0),
|
||||
m_server_type(MYSQL_SERVER_TYPE_MYSQL),
|
||||
m_gtid_length(MYSQL_GTID_ENCODED_SIZE)
|
||||
{
|
||||
int i,k;
|
||||
char tmp[2];
|
||||
char *sid = (char *)mysql_gtid;
|
||||
|
||||
for(i=0,k=0; i < 16*2; i+=2,k++) {
|
||||
unsigned int c;
|
||||
tmp[0] = sid[i];
|
||||
tmp[1] = sid[i+1];
|
||||
sscanf((const char *)tmp, "%02x", &c);
|
||||
m_mysql_gtid[k]=(unsigned char)c;
|
||||
}
|
||||
i++;
|
||||
k++;
|
||||
sscanf((const char *)&(sid[i]), "%lu", &m_sequence_number);
|
||||
int8store(&(m_mysql_gtid[k]), m_sequence_number);
|
||||
|
||||
std::cout << "GTID:: " << m_mysql_gtid << " " << std::endl;
|
||||
}
|
||||
|
||||
std::string Gtid::get_string() const
|
||||
{
|
||||
if (m_server_type == MYSQL_SERVER_TYPE_MARIADB) {
|
||||
return (m_mariadb_gtid);
|
||||
} else {
|
||||
std::string hexs;
|
||||
unsigned char *sid = (unsigned char *)m_mysql_gtid;
|
||||
char tmp[2];
|
||||
|
||||
// Dump the encoded SID using hexadesimal representation
|
||||
// Making it little bit more usefull
|
||||
for(size_t i=0;i < 16;i++) {
|
||||
sprintf((char *)tmp, "%02x", (unsigned char)sid[i]);
|
||||
hexs.append(std::string((const char *)tmp));
|
||||
}
|
||||
return(hexs + std::string(":") + to_string(m_sequence_number));
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned char* Gtid::get_gtid() const
|
||||
{
|
||||
if (m_server_type == MYSQL_SERVER_TYPE_MARIADB) {
|
||||
return ((const unsigned char *)m_mariadb_gtid.c_str());
|
||||
} else {
|
||||
return (m_mysql_gtid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
617
replication_listener/src/protocol.cpp
Normal file
617
replication_listener/src/protocol.cpp
Normal file
@ -0,0 +1,617 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 <stdint.h>
|
||||
#include <boost/array.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "protocol.h"
|
||||
#include "listener_exception.h"
|
||||
#include <iostream>
|
||||
#include <mysql.h>
|
||||
#include <my_global.h>
|
||||
#include <mysql_com.h>
|
||||
|
||||
using namespace mysql;
|
||||
using namespace mysql::system;
|
||||
|
||||
namespace mysql { namespace system {
|
||||
|
||||
int proto_read_package_header(tcp::socket *socket, unsigned long *packet_length, unsigned char *packet_no)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
try {
|
||||
boost::asio::read(*socket, boost::asio::buffer(buf, 4),
|
||||
boost::asio::transfer_at_least(4));
|
||||
}
|
||||
catch (boost::system::system_error const& e)
|
||||
{
|
||||
throw(ListenerException("Read package header error: " + std::string(e.what()), __FILE__, __LINE__));
|
||||
}
|
||||
catch (boost::system::error_code const& e)
|
||||
{
|
||||
throw(ListenerException("Read package header error: " + e.message(), __FILE__, __LINE__));
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
throw(ListenerException("Read package header error: " + std::string(e.what()), __FILE__, __LINE__));
|
||||
}
|
||||
|
||||
*packet_length= (unsigned long)(buf[0] &0xFF);
|
||||
*packet_length+= (unsigned long)((buf[1] &0xFF)<<8);
|
||||
*packet_length+= (unsigned long)((buf[2] &0xFF)<<16);
|
||||
*packet_no= (unsigned char)buf[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proto_read_package_header(tcp::socket *socket, boost::asio::streambuf &buff, unsigned long *packet_length, unsigned char *packet_no)
|
||||
{
|
||||
std::streamsize inbuff= buff.in_avail();
|
||||
if( inbuff < 0)
|
||||
inbuff= 0;
|
||||
|
||||
if (4 > inbuff)
|
||||
{
|
||||
try {
|
||||
boost::asio::read(*socket, buff,
|
||||
boost::asio::transfer_at_least(4-inbuff));
|
||||
}
|
||||
catch (boost::system::system_error const& e)
|
||||
{
|
||||
throw(ListenerException("Read package header error: " + std::string(e.what()), __FILE__, __LINE__));
|
||||
}
|
||||
catch (boost::system::error_code const& e)
|
||||
{
|
||||
throw(ListenerException("Read package header error: " + e.message(), __FILE__, __LINE__));
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
throw(ListenerException("Read package header error: " + std::string(e.what()), __FILE__, __LINE__));
|
||||
}
|
||||
}
|
||||
char ch;
|
||||
std::istream is(&buff);
|
||||
is.get(ch);
|
||||
*packet_length= (unsigned long)ch;
|
||||
is.get(ch);
|
||||
*packet_length+= (unsigned long)(ch<<8);
|
||||
is.get(ch);
|
||||
*packet_length+= (unsigned long)(ch<<16);
|
||||
is.get(ch);
|
||||
*packet_no= (unsigned char)ch;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int proto_get_one_package(tcp::socket *socket, boost::asio::streambuf &buff,
|
||||
boost::uint8_t *packet_no)
|
||||
{
|
||||
unsigned long packet_length;
|
||||
if (proto_read_package_header(socket, buff, &packet_length, packet_no))
|
||||
return 0;
|
||||
std::streamsize inbuffer= buff.in_avail();
|
||||
if (inbuffer < 0)
|
||||
inbuffer= 0;
|
||||
if (packet_length > inbuffer)
|
||||
boost::asio::read(*socket, buff,
|
||||
boost::asio::transfer_at_least(packet_length-inbuffer));
|
||||
|
||||
return packet_length;
|
||||
}
|
||||
|
||||
void prot_parse_error_message(std::istream &is, struct st_error_package &err,
|
||||
int packet_length)
|
||||
{
|
||||
boost::uint8_t marker;
|
||||
|
||||
Protocol_chunk<boost::uint16_t> prot_errno(err.error_code);
|
||||
Protocol_chunk<boost::uint8_t> prot_marker(marker);
|
||||
Protocol_chunk<boost::uint8_t> prot_sql_state(err.sql_state,5);
|
||||
|
||||
is >> prot_errno
|
||||
>> prot_marker
|
||||
>> prot_sql_state;
|
||||
|
||||
// TODO is the number of bytes read = is.tellg() ?
|
||||
|
||||
int message_size= packet_length -2 -1 -5; // the remaining part of the package
|
||||
Protocol_chunk_string prot_message(err.message, message_size);
|
||||
is >> prot_message;
|
||||
err.message[message_size]= '\0';
|
||||
}
|
||||
|
||||
void prot_parse_ok_message(std::istream &is, struct st_ok_package &ok, int packet_length)
|
||||
{
|
||||
// TODO: Assure that zero length messages can be but on the input stream.
|
||||
|
||||
//Protocol_chunk<boost::uint8_t> prot_result_type(result_type);
|
||||
Protocol_chunk<boost::uint64_t> prot_affected_rows(ok.affected_rows);
|
||||
Protocol_chunk<boost::uint64_t> prot_insert_id(ok.insert_id);
|
||||
Protocol_chunk<boost::uint16_t> prot_server_status(ok.server_status);
|
||||
Protocol_chunk<boost::uint16_t> prot_warning_count(ok.warning_count);
|
||||
|
||||
int message_size= packet_length -2 -prot_affected_rows.size()
|
||||
-prot_insert_id.size() -prot_server_status.size()
|
||||
-prot_warning_count.size();
|
||||
|
||||
prot_affected_rows.set_length_encoded_binary(true);
|
||||
prot_insert_id.set_length_encoded_binary(true);
|
||||
|
||||
is >> prot_affected_rows
|
||||
>> prot_insert_id
|
||||
>> prot_server_status
|
||||
>> prot_warning_count;
|
||||
|
||||
if (message_size > 0)
|
||||
{
|
||||
Protocol_chunk_string prot_message(ok.message, message_size);
|
||||
is >> prot_message;
|
||||
ok.message[message_size]= '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void prot_parse_eof_message(std::istream &is, struct st_eof_package &eof)
|
||||
{
|
||||
Protocol_chunk<boost::uint16_t> proto_warning_count(eof.warning_count);
|
||||
Protocol_chunk<boost::uint16_t> proto_status_flags(eof.status_flags);
|
||||
|
||||
is >> proto_warning_count
|
||||
>> proto_status_flags;
|
||||
}
|
||||
|
||||
void proto_get_handshake_package(std::istream &is,
|
||||
struct st_handshake_package &p,
|
||||
int packet_length)
|
||||
{
|
||||
boost::uint8_t filler;
|
||||
boost::uint8_t filler2[13];
|
||||
|
||||
Protocol_chunk<boost::uint8_t> proto_protocol_version(p.protocol_version);
|
||||
Protocol_chunk<boost::uint32_t> proto_thread_id(p.thread_id);
|
||||
Protocol_chunk<boost::uint8_t> proto_scramble_buffer(p.scramble_buff, 8);
|
||||
Protocol_chunk<boost::uint8_t> proto_filler(filler);
|
||||
Protocol_chunk<boost::uint16_t> proto_server_capabilities(p.server_capabilities);
|
||||
Protocol_chunk<boost::uint8_t> proto_server_language(p.server_language);
|
||||
Protocol_chunk<boost::uint16_t> proto_server_status(p.server_status);
|
||||
Protocol_chunk<boost::uint8_t> proto_filler2(filler2,13);
|
||||
Protocol_chunk<boost::uint8_t> proto_scramble_buffer2(p.scramble_buff2, 13);
|
||||
|
||||
is >> proto_protocol_version
|
||||
>> p.server_version_str
|
||||
>> proto_thread_id
|
||||
>> proto_scramble_buffer
|
||||
>> proto_filler
|
||||
>> proto_server_capabilities
|
||||
>> proto_server_language
|
||||
>> proto_server_status
|
||||
>> proto_filler2
|
||||
>> proto_scramble_buffer2;
|
||||
|
||||
//assert(filler == 0);
|
||||
|
||||
int remaining_bytes= packet_length - 9+13+13+8;
|
||||
boost::uint8_t extention_buffer[remaining_bytes];
|
||||
if (remaining_bytes > 0)
|
||||
{
|
||||
Protocol_chunk<boost::uint8_t> proto_extension(extention_buffer, remaining_bytes);
|
||||
is >> proto_extension;
|
||||
}
|
||||
|
||||
//std::copy(&extention_buffer[0],&extention_buffer[remaining_bytes],std::ostream_iterator<char>(std::cout,","));
|
||||
}
|
||||
|
||||
void write_packet_header(char *buff, boost::uint16_t size, boost::uint8_t packet_no)
|
||||
{
|
||||
int3store(buff, size);
|
||||
buff[3]= (char)packet_no;
|
||||
}
|
||||
|
||||
|
||||
buffer_source &operator>>(buffer_source &src, Protocol &chunk)
|
||||
{
|
||||
char ch;
|
||||
int ct= 0;
|
||||
char *ptr= (char*)chunk.data();
|
||||
|
||||
while(ct < chunk.size() && src.m_ptr < src.m_size)
|
||||
{
|
||||
ptr[ct]= src.m_src[src.m_ptr];
|
||||
++ct;
|
||||
++src.m_ptr;
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
std::istream &operator>>(std::istream &is, Protocol &chunk)
|
||||
{
|
||||
if (chunk.is_length_encoded_binary())
|
||||
{
|
||||
int ct= 0;
|
||||
is.read((char *)chunk.data(),1);
|
||||
unsigned char byte= *(unsigned char *)chunk.data();
|
||||
if (byte < 250)
|
||||
{
|
||||
chunk.collapse_size(1);
|
||||
return is;
|
||||
}
|
||||
else if (byte == 251)
|
||||
{
|
||||
// is this a row data packet? if so, then this column value is NULL
|
||||
chunk.collapse_size(1);
|
||||
ct= 1;
|
||||
}
|
||||
else if (byte == 252)
|
||||
{
|
||||
chunk.collapse_size(2);
|
||||
ct= 1;
|
||||
}
|
||||
else if(byte == 253)
|
||||
{
|
||||
chunk.collapse_size(3);
|
||||
ct= 1;
|
||||
}
|
||||
|
||||
/* Read remaining bytes */
|
||||
//is.read((char *)chunk.data(), chunk.size()-1);
|
||||
char ch;
|
||||
char *ptr= (char*)chunk.data();
|
||||
while(ct < chunk.size())
|
||||
{
|
||||
is.get(ch);
|
||||
ptr[ct]= ch;
|
||||
++ct;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char ch;
|
||||
int ct= 0;
|
||||
char *ptr= (char*)chunk.data();
|
||||
int sz= chunk.size();
|
||||
while(ct < sz)
|
||||
{
|
||||
is.get(ch);
|
||||
ptr[ct]= ch;
|
||||
++ct;
|
||||
}
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
std::istream &operator>>(std::istream &is, std::string &str)
|
||||
{
|
||||
std::ostringstream out;
|
||||
char ch;
|
||||
int ct= 0;
|
||||
do
|
||||
{
|
||||
is.get(ch);
|
||||
out.put(ch);
|
||||
++ct;
|
||||
} while (is.good() && ch != '\0');
|
||||
str.append(out.str());
|
||||
return is;
|
||||
}
|
||||
|
||||
std::istream &operator>>(std::istream &is, Protocol_chunk_string &str)
|
||||
{
|
||||
char ch;
|
||||
int ct= 0;
|
||||
int sz= str.m_str->size();
|
||||
for (ct=0; ct< sz && is.good(); ct++)
|
||||
{
|
||||
is.get(ch);
|
||||
str.m_str->at(ct)= ch;
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
std::istream &operator>>(std::istream &is, Protocol_chunk_string_len &lenstr)
|
||||
{
|
||||
boost::uint8_t len;
|
||||
std::string *str= lenstr.m_storage;
|
||||
Protocol_chunk<boost::uint8_t> proto_str_len(len);
|
||||
is >> proto_str_len;
|
||||
Protocol_chunk_string proto_str(*str, len);
|
||||
is >> proto_str;
|
||||
return is;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, Protocol &chunk)
|
||||
{
|
||||
if (!os.bad())
|
||||
os.write((const char *) chunk.data(),chunk.size());
|
||||
return os;
|
||||
}
|
||||
|
||||
Query_event *proto_query_event(std::istream &is, Log_event_header *header)
|
||||
{
|
||||
boost::uint8_t db_name_len;
|
||||
boost::uint16_t var_size;
|
||||
// Length of query stored in the payload.
|
||||
boost::uint32_t query_len;
|
||||
Query_event *qev=new Query_event(header);
|
||||
|
||||
Protocol_chunk<boost::uint32_t> proto_query_event_thread_id(qev->thread_id);
|
||||
Protocol_chunk<boost::uint32_t> proto_query_event_exec_time(qev->exec_time);
|
||||
Protocol_chunk<boost::uint8_t> proto_query_event_db_name_len(db_name_len);
|
||||
Protocol_chunk<boost::uint16_t> proto_query_event_error_code(qev->error_code);
|
||||
Protocol_chunk<boost::uint16_t> proto_query_event_var_size(var_size);
|
||||
|
||||
is >> proto_query_event_thread_id
|
||||
>> proto_query_event_exec_time
|
||||
>> proto_query_event_db_name_len
|
||||
>> proto_query_event_error_code
|
||||
>> proto_query_event_var_size;
|
||||
|
||||
//TODO : Implement it in a better way.
|
||||
|
||||
/*
|
||||
Query length =
|
||||
Total event length (header->event_length) -
|
||||
(
|
||||
(LOG_EVENT_HEADER_SIZE - 1) + //Shouldn't LOG_EVENT_HEADER_SIZE=19?
|
||||
Thread-id (pre-defined, 4) +
|
||||
Execution time (pre-defined, 4) +
|
||||
Placeholder to store database length (pre-defined, 1) +
|
||||
Error code (pre-defined, 2) +
|
||||
Placeholder to store length taken by status variable blk (pre-defined, 2) +
|
||||
Status variable block length (calculated, var_size) +
|
||||
Database name length (calculated, db_name_len) +
|
||||
Null terninator (pre-defined, 1) +
|
||||
)
|
||||
|
||||
which gives :
|
||||
*/
|
||||
|
||||
query_len= header->event_length - (LOG_EVENT_HEADER_SIZE + 13 + var_size +
|
||||
db_name_len);
|
||||
|
||||
qev->variables.reserve(var_size);
|
||||
Protocol_chunk_vector proto_payload(qev->variables, var_size);
|
||||
is >> proto_payload;
|
||||
|
||||
Protocol_chunk_string proto_query_event_db_name(qev->db_name,
|
||||
(unsigned long)db_name_len);
|
||||
|
||||
Protocol_chunk_string proto_query_event_query_str
|
||||
(qev->query, (unsigned long)query_len);
|
||||
|
||||
char zero_marker; // should always be 0;
|
||||
is >> proto_query_event_db_name
|
||||
>> zero_marker
|
||||
>> proto_query_event_query_str;
|
||||
// Following is not really required now,
|
||||
//qev->query.resize(qev->query.size() - 1); // Last character is a '\0' character.
|
||||
|
||||
return qev;
|
||||
}
|
||||
|
||||
Gtid_event *proto_gtid_event(std::istream &is, Log_event_header *header)
|
||||
{
|
||||
Gtid_event *gev=new Gtid_event(header);
|
||||
boost::uint32_t gtid_length=0;
|
||||
|
||||
if (header->type_code == GTID_EVENT_MARIADB) {
|
||||
Protocol_chunk<boost::uint32_t> proto_gtid_event_domain_id(gev->domain_id);
|
||||
gev->server_id = header->server_id;
|
||||
Protocol_chunk<boost::uint64_t> proto_gtid_event_sequence_number(gev->sequence_number);
|
||||
|
||||
// In MariaDB GTIDs are just sequence number followed by domain id
|
||||
is >> proto_gtid_event_sequence_number
|
||||
>> proto_gtid_event_domain_id;
|
||||
gev->m_gtid= Gtid(gev->domain_id, gev->server_id, gev->sequence_number);
|
||||
} else {
|
||||
// In MySQL GTIDs consists two parts SID and global sequence
|
||||
// number. SID is stored in encoded format, we will not try to
|
||||
// understand that. Global sequence number is more meaningfull.
|
||||
unsigned char gtid_data[MYSQL_GTID_ENCODED_SIZE+1];
|
||||
memset(gtid_data, 0, MYSQL_GTID_ENCODED_SIZE+1);
|
||||
is.read((char *)gtid_data, MYSQL_GTID_ENCODED_SIZE);
|
||||
unsigned char *buf = gtid_data;
|
||||
buf++; // commit flag, ignore
|
||||
memcpy(gev->m_mysql_gtid, (char *)buf, MYSQL_GTID_ENCODED_SIZE);
|
||||
gev->sequence_number = uint8korr(buf+16);
|
||||
|
||||
gev->m_gtid= Gtid(gev->m_mysql_gtid, gev->sequence_number);
|
||||
}
|
||||
|
||||
return gev;
|
||||
}
|
||||
|
||||
Rotate_event *proto_rotate_event(std::istream &is, Log_event_header *header)
|
||||
{
|
||||
Rotate_event *rev= new Rotate_event(header);
|
||||
|
||||
boost::uint32_t file_name_length= header->event_length - 7 - LOG_EVENT_HEADER_SIZE;
|
||||
|
||||
Protocol_chunk<boost::uint64_t > prot_position(rev->binlog_pos);
|
||||
Protocol_chunk_string prot_file_name(rev->binlog_file, file_name_length);
|
||||
is >> prot_position
|
||||
>> prot_file_name;
|
||||
|
||||
return rev;
|
||||
}
|
||||
|
||||
Incident_event *proto_incident_event(std::istream &is, Log_event_header *header)
|
||||
{
|
||||
Incident_event *incident= new Incident_event(header);
|
||||
Protocol_chunk<boost::uint8_t> proto_incident_code(incident->type);
|
||||
Protocol_chunk_string_len proto_incident_message(incident->message);
|
||||
|
||||
is >> proto_incident_code
|
||||
>> proto_incident_message;
|
||||
|
||||
return incident;
|
||||
}
|
||||
|
||||
Row_event *proto_rows_event(std::istream &is, Log_event_header *header)
|
||||
{
|
||||
Row_event *rev=new Row_event(header);
|
||||
|
||||
union
|
||||
{
|
||||
boost::uint64_t integer;
|
||||
boost::uint8_t bytes[6];
|
||||
} table_id;
|
||||
|
||||
table_id.integer=0L;
|
||||
Protocol_chunk<boost::uint8_t> proto_table_id(&table_id.bytes[0], 6);
|
||||
Protocol_chunk<boost::uint16_t> proto_flags(rev->flags);
|
||||
Protocol_chunk<boost::uint64_t> proto_column_len(rev->columns_len);
|
||||
proto_column_len.set_length_encoded_binary(true);
|
||||
|
||||
is >> proto_table_id
|
||||
>> proto_flags
|
||||
>> proto_column_len;
|
||||
|
||||
rev->table_id=table_id.integer;
|
||||
int used_column_len=(int) ((rev->columns_len + 7) / 8);
|
||||
Protocol_chunk_vector proto_used_columns(rev->used_columns, used_column_len);
|
||||
rev->null_bits_len= used_column_len;
|
||||
|
||||
is >> proto_used_columns;
|
||||
|
||||
if (header->type_code == UPDATE_ROWS_EVENT)
|
||||
{
|
||||
Protocol_chunk_vector proto_columns_before_image(rev->columns_before_image, used_column_len);
|
||||
is >> proto_columns_before_image;
|
||||
}
|
||||
|
||||
int bytes_read=proto_table_id.size() + proto_flags.size() + proto_column_len.size() + used_column_len;
|
||||
if (header->type_code == UPDATE_ROWS_EVENT)
|
||||
bytes_read+=used_column_len;
|
||||
|
||||
unsigned long row_len= header->event_length - bytes_read - LOG_EVENT_HEADER_SIZE + 1;
|
||||
//std::cout << "Bytes read: " << bytes_read << " Bytes expected: " << rev->row_len << std::endl;
|
||||
Protocol_chunk_vector proto_row(rev->row, row_len);
|
||||
is >> proto_row;
|
||||
|
||||
return rev;
|
||||
}
|
||||
|
||||
Int_var_event *proto_intvar_event(std::istream &is, Log_event_header *header)
|
||||
{
|
||||
Int_var_event *event= new Int_var_event(header);
|
||||
|
||||
Protocol_chunk<boost::uint8_t> proto_type(event->type);
|
||||
Protocol_chunk<boost::uint64_t> proto_value(event->value);
|
||||
is >> proto_type
|
||||
>> proto_value;
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
User_var_event *proto_uservar_event(std::istream &is, Log_event_header *header)
|
||||
{
|
||||
User_var_event *event= new User_var_event(header);
|
||||
|
||||
boost::uint32_t name_len;
|
||||
Protocol_chunk<boost::uint32_t> proto_name_len(name_len);
|
||||
|
||||
is >> proto_name_len;
|
||||
|
||||
Protocol_chunk_string proto_name(event->name, name_len);
|
||||
Protocol_chunk<boost::uint8_t> proto_null(event->is_null);
|
||||
|
||||
is >> proto_name >> proto_null;
|
||||
if (event->is_null)
|
||||
{
|
||||
event->type = User_var_event::STRING_TYPE;
|
||||
event->charset = 63; // Binary charset
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::uint32_t value_len;
|
||||
Protocol_chunk<boost::uint8_t> proto_type(event->type);
|
||||
Protocol_chunk<boost::uint32_t> proto_charset(event->charset);
|
||||
Protocol_chunk<boost::uint32_t> proto_val_len(value_len);
|
||||
is >> proto_type >> proto_charset >> proto_val_len;
|
||||
Protocol_chunk_string proto_value(event->value, value_len);
|
||||
is >> proto_value;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
Table_map_event *proto_table_map_event(std::istream &is, Log_event_header *header)
|
||||
{
|
||||
Table_map_event *tmev=new Table_map_event(header);
|
||||
boost::uint64_t columns_len= 0;
|
||||
boost::uint64_t metadata_len= 0;
|
||||
union
|
||||
{
|
||||
boost::uint64_t integer;
|
||||
boost::uint8_t bytes[6];
|
||||
} table_id;
|
||||
char zero_marker= 0;
|
||||
|
||||
table_id.integer=0L;
|
||||
Protocol_chunk<boost::uint8_t> proto_table_id(&table_id.bytes[0], 6);
|
||||
Protocol_chunk<boost::uint16_t> proto_flags(tmev->flags);
|
||||
Protocol_chunk_string_len proto_db_name(tmev->db_name);
|
||||
Protocol_chunk<boost::uint8_t> proto_marker(zero_marker); // Should be '\0'
|
||||
Protocol_chunk_string_len proto_table_name(tmev->table_name);
|
||||
Protocol_chunk<boost::uint64_t> proto_columns_len(columns_len);
|
||||
proto_columns_len.set_length_encoded_binary(true);
|
||||
|
||||
is >> proto_table_id
|
||||
>> proto_flags
|
||||
>> proto_db_name
|
||||
>> proto_marker
|
||||
>> proto_table_name
|
||||
>> proto_marker
|
||||
>> proto_columns_len;
|
||||
tmev->table_id=table_id.integer;
|
||||
Protocol_chunk_vector proto_columns(tmev->columns, columns_len);
|
||||
Protocol_chunk<boost::uint64_t> proto_metadata_len(metadata_len);
|
||||
proto_metadata_len.set_length_encoded_binary(true);
|
||||
|
||||
is >> proto_columns
|
||||
>> proto_metadata_len;
|
||||
Protocol_chunk_vector proto_metadata(tmev->metadata, (unsigned long)metadata_len);
|
||||
is >> proto_metadata;
|
||||
unsigned long null_bits_len=(int) ((tmev->columns.size() + 7) / 8);
|
||||
|
||||
Protocol_chunk_vector proto_null_bits(tmev->null_bits, null_bits_len);
|
||||
|
||||
is >> proto_null_bits;
|
||||
return tmev;
|
||||
}
|
||||
|
||||
std::istream &operator>>(std::istream &is, Protocol_chunk_vector &chunk)
|
||||
{
|
||||
unsigned long size= chunk.m_size;
|
||||
for(int i=0; i< size; i++)
|
||||
{
|
||||
char ch;
|
||||
is.get(ch);
|
||||
chunk.m_vec->push_back(ch);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
} } // end namespace mysql::system
|
180
replication_listener/src/resultset_iterator.cpp
Normal file
180
replication_listener/src/resultset_iterator.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "resultset_iterator.h"
|
||||
#include "protocol.h"
|
||||
#include "row_of_fields.h"
|
||||
|
||||
using namespace mysql;
|
||||
|
||||
namespace mysql {
|
||||
|
||||
Result_set::iterator Result_set::begin() { return iterator(this); }
|
||||
Result_set::iterator Result_set::end() { return iterator(); }
|
||||
Result_set::const_iterator Result_set::begin() const { return const_iterator(const_cast<Result_set *>(this)); }
|
||||
Result_set::const_iterator Result_set::end() const { return const_iterator(); }
|
||||
|
||||
void Result_set::digest_row_set()
|
||||
{
|
||||
unsigned long packet_length;
|
||||
unsigned char packet_no= 1;
|
||||
m_current_state= RESULT_HEADER;
|
||||
boost::asio::streambuf resultbuff;
|
||||
std::istream response_stream(&resultbuff);
|
||||
unsigned field_count= 0;
|
||||
try {
|
||||
do
|
||||
{
|
||||
/*
|
||||
* Get server response
|
||||
*/
|
||||
packet_length= system::proto_get_one_package(m_socket, resultbuff, &packet_no);
|
||||
|
||||
switch(m_current_state)
|
||||
{
|
||||
case RESULT_HEADER:
|
||||
system::digest_result_header(response_stream, m_field_count, m_extra);
|
||||
m_row_count= 0;
|
||||
m_current_state= FIELD_PACKETS;
|
||||
break;
|
||||
case FIELD_PACKETS:
|
||||
{
|
||||
Field_packet field;
|
||||
system::digest_field_packet(response_stream, field);
|
||||
m_field_types.assign(field_count,field);
|
||||
|
||||
if (++field_count == m_field_count)
|
||||
m_current_state= MARKER;
|
||||
}
|
||||
break;
|
||||
case MARKER:
|
||||
{
|
||||
char marker;
|
||||
response_stream >> marker;
|
||||
//assert(marker == 0xfe);
|
||||
system::digest_marker(response_stream);
|
||||
m_current_state= ROW_CONTENTS;
|
||||
}
|
||||
break;
|
||||
case ROW_CONTENTS:
|
||||
{
|
||||
bool is_eof= false;
|
||||
Row_of_fields row(0);
|
||||
system::digest_row_content(response_stream, m_field_count, row, m_storage, is_eof);
|
||||
if (is_eof)
|
||||
m_current_state= EOF_PACKET;
|
||||
else
|
||||
{
|
||||
m_rows.push_back(row);
|
||||
++m_row_count;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
} while (m_current_state != EOF_PACKET);
|
||||
} catch(boost::system::system_error e)
|
||||
{
|
||||
// TODO log error
|
||||
m_field_count= 0;
|
||||
m_row_count= 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace system {
|
||||
|
||||
void digest_result_header(std::istream &is, boost::uint64_t &field_count, boost::uint64_t extra)
|
||||
{
|
||||
Protocol_chunk<boost::uint64_t> proto_field_count(field_count);
|
||||
//Protocol_chunk<boost::uint64_t> proto_extra(extra);
|
||||
|
||||
proto_field_count.set_length_encoded_binary(true);
|
||||
//proto_extra.set_length_encoded_binary(true);
|
||||
|
||||
is >> proto_field_count;
|
||||
//>> proto_extra;
|
||||
}
|
||||
|
||||
void digest_field_packet(std::istream &is, Field_packet &field_packet)
|
||||
{
|
||||
Protocol_chunk_string_len proto_catalog(field_packet.catalog);
|
||||
Protocol_chunk_string_len proto_db(field_packet.db);
|
||||
Protocol_chunk_string_len proto_table(field_packet.table);
|
||||
Protocol_chunk_string_len proto_org_table(field_packet.org_table);
|
||||
Protocol_chunk_string_len proto_name(field_packet.name);
|
||||
Protocol_chunk_string_len proto_org_name(field_packet.org_name);
|
||||
Protocol_chunk<boost::uint8_t> proto_marker(field_packet.marker);
|
||||
Protocol_chunk<boost::uint16_t> proto_charsetnr(field_packet.charsetnr);
|
||||
Protocol_chunk<boost::uint32_t> proto_length(field_packet.length);
|
||||
Protocol_chunk<boost::uint8_t> proto_type(field_packet.type);
|
||||
Protocol_chunk<boost::uint16_t> proto_flags(field_packet.flags);
|
||||
Protocol_chunk<boost::uint8_t> proto_decimals(field_packet.decimals);
|
||||
Protocol_chunk<boost::uint16_t> proto_filler(field_packet.filler);
|
||||
//Protocol_chunk<boost::uint64_t> proto_default_value(field_packet.default_value);
|
||||
|
||||
is >> proto_catalog
|
||||
>> proto_db
|
||||
>> proto_table
|
||||
>> proto_org_table
|
||||
>> proto_name
|
||||
>> proto_org_name
|
||||
>> proto_marker
|
||||
>> proto_charsetnr
|
||||
>> proto_length
|
||||
>> proto_type
|
||||
>> proto_flags
|
||||
>> proto_decimals
|
||||
>> proto_filler;
|
||||
}
|
||||
|
||||
void digest_marker(std::istream &is)
|
||||
{
|
||||
struct st_eof_package eof;
|
||||
prot_parse_eof_message(is,eof);
|
||||
}
|
||||
|
||||
void digest_row_content(std::istream &is, int field_count, Row_of_fields &row, String_storage &storage, bool &is_eof)
|
||||
{
|
||||
boost::uint8_t size;
|
||||
Protocol_chunk<boost::uint8_t> proto_size(size);
|
||||
is >> proto_size;
|
||||
if (size == 0xfe)
|
||||
{
|
||||
/* EOF packet is detected and there are no more rows to be expeced. */
|
||||
is_eof= true;
|
||||
struct st_eof_package eof;
|
||||
prot_parse_eof_message(is, eof);
|
||||
return;
|
||||
}
|
||||
is.putback((char)size);
|
||||
for(int field_no=0; field_no < field_count; ++field_no)
|
||||
{
|
||||
std::string *storage= new std::string;
|
||||
|
||||
Protocol_chunk_string_len proto_value(*storage);
|
||||
is >> proto_value;
|
||||
|
||||
Value value(MYSQL_TYPE_VAR_STRING, storage->length(), storage->c_str());
|
||||
row.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
}} // end namespace system, mysql
|
51
replication_listener/src/row_of_fields.cpp
Normal file
51
replication_listener/src/row_of_fields.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 <vector>
|
||||
|
||||
#include "row_of_fields.h"
|
||||
#include <stdexcept>
|
||||
#include <boost/foreach.hpp>
|
||||
#include "value.h"
|
||||
|
||||
using namespace mysql;
|
||||
|
||||
Row_of_fields& Row_of_fields::operator=(const Row_of_fields &right)
|
||||
{
|
||||
if (size() != right.size())
|
||||
throw std::length_error("Row dimension doesn't match.");
|
||||
int i= 0;
|
||||
BOOST_FOREACH(Value value, right)
|
||||
{
|
||||
this->assign(++i, value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Row_of_fields& Row_of_fields::operator=(Row_of_fields &right)
|
||||
{
|
||||
if (size() != right.size())
|
||||
throw std::length_error("Row dimension doesn't match.");
|
||||
int i= 0;
|
||||
BOOST_FOREACH(Value value, right)
|
||||
{
|
||||
this->assign(++i, value);
|
||||
}
|
||||
return *this;
|
||||
}
|
1221
replication_listener/src/tcp_driver.cpp
Normal file
1221
replication_listener/src/tcp_driver.cpp
Normal file
File diff suppressed because it is too large
Load Diff
154
replication_listener/src/utilities.cpp
Normal file
154
replication_listener/src/utilities.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "utilities.h"
|
||||
|
||||
using namespace mysql;
|
||||
|
||||
namespace mysql {
|
||||
|
||||
int server_var_decoder (std::map<std::string, mysql::Value> *my_var_map,
|
||||
std::vector<boost::uint8_t> variables)
|
||||
{
|
||||
boost::uint8_t length, i;
|
||||
std::string name;
|
||||
mysql::system::enum_field_types field_type;
|
||||
/* To handle special case of 'terminating null byte'. */
|
||||
bool is_null_byte= 0;
|
||||
|
||||
|
||||
std::vector<boost::uint8_t>::iterator it= variables.begin();
|
||||
|
||||
while (it != variables.end())
|
||||
{
|
||||
switch (*it++)
|
||||
{
|
||||
case Q_FLAGS2_CODE:
|
||||
length= 4;
|
||||
name= "flag2";
|
||||
field_type= mysql::system::MYSQL_TYPE_LONG;
|
||||
break;
|
||||
case Q_SQL_MODE_CODE:
|
||||
length= 8;
|
||||
name= "sql_mode";
|
||||
field_type= mysql::system::MYSQL_TYPE_LONGLONG;
|
||||
break;
|
||||
case Q_CATALOG_CODE:
|
||||
length= *it++;
|
||||
name= "catalog_name_old";
|
||||
field_type= mysql::system::MYSQL_TYPE_VAR_STRING;
|
||||
is_null_byte= 1;
|
||||
break;
|
||||
case Q_AUTO_INCREMENT:
|
||||
length= 2;
|
||||
my_var_map->insert(std::make_pair
|
||||
("auto_increment_increment",
|
||||
mysql::Value(mysql::system::MYSQL_TYPE_SHORT,
|
||||
length, (char*) &(*it))));
|
||||
for (i= 0; i < length; i++)
|
||||
it++;
|
||||
|
||||
name= "auto_increment_offset";
|
||||
field_type= mysql::system::MYSQL_TYPE_SHORT;
|
||||
break;
|
||||
case Q_CHARSET_CODE:
|
||||
length= 2;
|
||||
my_var_map->insert(std::make_pair
|
||||
("character_set_client",
|
||||
mysql::Value(mysql::system::MYSQL_TYPE_SHORT,
|
||||
length, (char*) &(*it))));
|
||||
for (i= 0; i < length; i++)
|
||||
it++;
|
||||
|
||||
my_var_map->insert(std::make_pair
|
||||
("collation_connection",
|
||||
mysql::Value(mysql::system::MYSQL_TYPE_SHORT,
|
||||
length, (char*) &(*it))));
|
||||
for (i= 0; i < length; i++)
|
||||
it++;
|
||||
|
||||
name= "collation_server";
|
||||
field_type= mysql::system::MYSQL_TYPE_SHORT;
|
||||
break;
|
||||
case Q_TIME_ZONE_CODE:
|
||||
length= *it++;
|
||||
name= "time_zone";
|
||||
field_type= mysql::system::MYSQL_TYPE_VAR_STRING;
|
||||
break;
|
||||
case Q_CATALOG_NZ_CODE:
|
||||
length= *it++;
|
||||
name= "catalog_name";
|
||||
field_type= mysql::system::MYSQL_TYPE_VAR_STRING;
|
||||
break;
|
||||
case Q_LC_TIME_NAMES_CODE:
|
||||
length= 2;
|
||||
name= "lc_time_names";
|
||||
field_type= mysql::system::MYSQL_TYPE_SHORT;
|
||||
break;
|
||||
case Q_CHARSET_DATABASE_CODE:
|
||||
length= 2;
|
||||
name= "collation_database";
|
||||
field_type= mysql::system::MYSQL_TYPE_SHORT;
|
||||
break;
|
||||
case Q_TABLE_MAP_FOR_UPDATE_CODE:
|
||||
length= 8;
|
||||
name= "table_map_for_update";
|
||||
field_type= mysql::system::MYSQL_TYPE_LONGLONG;
|
||||
break;
|
||||
case Q_MASTER_DATA_WRITTEN_CODE:
|
||||
length= 4;
|
||||
name= "master_data_written";
|
||||
field_type= mysql::system::MYSQL_TYPE_LONG;
|
||||
break;
|
||||
case Q_INVOKER:
|
||||
length= *it++;
|
||||
my_var_map->insert(std::make_pair
|
||||
("user",
|
||||
mysql::Value(mysql::system::MYSQL_TYPE_VAR_STRING,
|
||||
length, (char*) &(*it))));
|
||||
for (i= 0; i < length; i++)
|
||||
it++;
|
||||
|
||||
length= *it++;
|
||||
name= "host";
|
||||
field_type= mysql::system::MYSQL_TYPE_VARCHAR;
|
||||
break;
|
||||
default:
|
||||
/* Unknown status variables. Error!! */
|
||||
return 1;
|
||||
} /* switch */
|
||||
my_var_map->insert(std::make_pair
|
||||
(name, mysql::Value(field_type, length,
|
||||
(char*) &(*it))));
|
||||
while (length --)
|
||||
++it;
|
||||
|
||||
/* Handle null termination byte. */
|
||||
if (is_null_byte)
|
||||
{
|
||||
++it;
|
||||
is_null_byte= 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} /* server_var_decoder() */
|
||||
|
||||
} /* mysql namespace */
|
||||
|
608
replication_listener/src/value.cpp
Normal file
608
replication_listener/src/value.cpp
Normal file
@ -0,0 +1,608 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 "value.h"
|
||||
#include "binlog_event.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iomanip>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#define DIG_PER_DEC1 9
|
||||
|
||||
using namespace mysql;
|
||||
using namespace mysql::system;
|
||||
namespace mysql {
|
||||
|
||||
static const int dig2bytes[DIG_PER_DEC1 + 1] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
|
||||
|
||||
int decimal_bin_size(int precision, int scale)
|
||||
{
|
||||
int intg = precision - scale;
|
||||
int intg0 = intg / DIG_PER_DEC1;
|
||||
int frac0 = scale / DIG_PER_DEC1;
|
||||
int intg0x = intg - intg0 * DIG_PER_DEC1;
|
||||
int frac0x = scale - frac0 * DIG_PER_DEC1;
|
||||
|
||||
return(
|
||||
intg0 * sizeof(boost::int32_t) + dig2bytes[intg0x] +
|
||||
frac0 * sizeof(boost::int32_t) + dig2bytes[frac0x]
|
||||
);
|
||||
}
|
||||
|
||||
int calc_field_size(unsigned char column_type, const unsigned char *field_ptr, boost::uint32_t metadata)
|
||||
{
|
||||
boost::uint32_t length;
|
||||
|
||||
switch (column_type) {
|
||||
case mysql::system::MYSQL_TYPE_VAR_STRING:
|
||||
/* This type is hijacked for result set types. */
|
||||
length= metadata;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_NEWDECIMAL:
|
||||
{
|
||||
int precision = (metadata & 0xff);
|
||||
int scale = metadata >> 8;
|
||||
length = decimal_bin_size(precision, scale);
|
||||
break;
|
||||
}
|
||||
case mysql::system::MYSQL_TYPE_DECIMAL:
|
||||
case mysql::system::MYSQL_TYPE_FLOAT:
|
||||
case mysql::system::MYSQL_TYPE_DOUBLE:
|
||||
length= metadata;
|
||||
break;
|
||||
/*
|
||||
The cases for SET and ENUM are include for completeness, however
|
||||
both are mapped to type MYSQL_TYPE_STRING and their real types
|
||||
are encoded in the field metadata.
|
||||
*/
|
||||
case mysql::system::MYSQL_TYPE_SET:
|
||||
case mysql::system::MYSQL_TYPE_ENUM:
|
||||
case mysql::system::MYSQL_TYPE_STRING:
|
||||
{
|
||||
//unsigned char type= metadata >> 8U;
|
||||
unsigned char type = metadata & 0xff;
|
||||
if ((type == mysql::system::MYSQL_TYPE_SET) || (type == mysql::system::MYSQL_TYPE_ENUM))
|
||||
{
|
||||
//length= metadata & 0x00ff;
|
||||
length = (metadata & 0xff00) >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
We are reading the actual size from the master_data record
|
||||
because this field has the actual lengh stored in the first
|
||||
byte.
|
||||
*/
|
||||
length= (unsigned int) *field_ptr+1;
|
||||
//DBUG_ASSERT(length != 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case mysql::system::MYSQL_TYPE_YEAR:
|
||||
case mysql::system::MYSQL_TYPE_TINY:
|
||||
length= 1;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_SHORT:
|
||||
length= 2;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_INT24:
|
||||
length= 3;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_LONG:
|
||||
length= 4;
|
||||
break;
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
length= 8;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_NULL:
|
||||
length= 0;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_NEWDATE:
|
||||
length= 3;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_DATE:
|
||||
case mysql::system::MYSQL_TYPE_TIME:
|
||||
length= 3;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_TIMESTAMP:
|
||||
length= 4;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_DATETIME:
|
||||
length= 8;
|
||||
break;
|
||||
case mysql::system::MYSQL_TYPE_BIT:
|
||||
{
|
||||
/*
|
||||
Decode the size of the bit field from the master.
|
||||
from_len is the length in bytes from the master
|
||||
from_bit_len is the number of extra bits stored in the master record
|
||||
If from_bit_len is not 0, add 1 to the length to account for accurate
|
||||
number of bytes needed.
|
||||
*/
|
||||
boost::uint32_t from_len= (metadata >> 8U) & 0x00ff;
|
||||
boost::uint32_t from_bit_len= metadata & 0x00ff;
|
||||
//DBUG_ASSERT(from_bit_len <= 7);
|
||||
length= from_len + ((from_bit_len > 0) ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case mysql::system::MYSQL_TYPE_VARCHAR:
|
||||
{
|
||||
length= metadata > 255 ? 2 : 1;
|
||||
length+= length == 1 ? (boost::uint32_t) *field_ptr : *((boost::uint16_t *)field_ptr);
|
||||
break;
|
||||
}
|
||||
case mysql::system::MYSQL_TYPE_TINY_BLOB:
|
||||
case mysql::system::MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case mysql::system::MYSQL_TYPE_LONG_BLOB:
|
||||
case mysql::system::MYSQL_TYPE_BLOB:
|
||||
case mysql::system::MYSQL_TYPE_GEOMETRY:
|
||||
{
|
||||
switch (metadata)
|
||||
{
|
||||
case 1:
|
||||
length= 1+ (boost::uint32_t) field_ptr[0];
|
||||
break;
|
||||
case 2:
|
||||
length= 2+ (boost::uint32_t) (*(boost::uint16_t *)(field_ptr) & 0xFFFF);
|
||||
break;
|
||||
case 3:
|
||||
// TODO make platform indep.
|
||||
length= 3+ (boost::uint32_t) (long) (*((boost::uint32_t *) (field_ptr)) & 0xFFFFFF);
|
||||
break;
|
||||
case 4:
|
||||
// TODO make platform indep.
|
||||
length= 4+ (boost::uint32_t) (long) *((boost::uint32_t *) (field_ptr));
|
||||
break;
|
||||
default:
|
||||
length= 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
length= ~(boost::uint32_t) 0;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
Value::Value(Value &val)
|
||||
{
|
||||
m_size= val.length();
|
||||
m_storage= val.storage();
|
||||
m_type= val.type();
|
||||
m_metadata= val.metadata();
|
||||
m_is_null= val.is_null();
|
||||
}
|
||||
*/
|
||||
|
||||
Value::Value(const Value& val)
|
||||
{
|
||||
m_size= val.m_size;
|
||||
m_storage= val.m_storage;
|
||||
m_type= val.m_type;
|
||||
m_metadata= val.m_metadata;
|
||||
m_is_null= val.m_is_null;
|
||||
}
|
||||
|
||||
Value &Value::operator=(const Value &val)
|
||||
{
|
||||
m_size= val.m_size;
|
||||
m_storage= val.m_storage;
|
||||
m_type= val.m_type;
|
||||
m_metadata= val.m_metadata;
|
||||
m_is_null= val.m_is_null;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Value::operator==(const Value &val) const
|
||||
{
|
||||
return (m_size == val.m_size) &&
|
||||
(m_storage == val.m_storage) &&
|
||||
(m_type == val.m_type) &&
|
||||
(m_metadata == val.m_metadata);
|
||||
}
|
||||
|
||||
bool Value::operator!=(const Value &val) const
|
||||
{
|
||||
return !operator==(val);
|
||||
}
|
||||
|
||||
char *Value::as_c_str(unsigned long &size) const
|
||||
{
|
||||
if (m_is_null || m_size == 0)
|
||||
{
|
||||
size= 0;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
Length encoded; First byte is length of string.
|
||||
*/
|
||||
int metadata_length= m_size > 251 ? 2: 1;
|
||||
/*
|
||||
Size is length of the character string; not of the entire storage
|
||||
*/
|
||||
size= m_size - metadata_length;
|
||||
|
||||
char *str = const_cast<char *>(m_storage + metadata_length);
|
||||
|
||||
if (m_type == mysql::system::MYSQL_TYPE_VARCHAR && m_metadata > 255) {
|
||||
str++;
|
||||
size--;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
unsigned char *Value::as_blob(unsigned long &size) const
|
||||
{
|
||||
if (m_is_null || m_size == 0)
|
||||
{
|
||||
size= 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Size was calculated during construction of the object and only inludes the
|
||||
size of the blob data, not the metadata part which also is stored in the
|
||||
storage. For blobs this part can be between 1-4 bytes long.
|
||||
*/
|
||||
size= m_size - m_metadata;
|
||||
|
||||
/*
|
||||
Adjust the storage pointer with the size of the metadata.
|
||||
*/
|
||||
return (unsigned char *)(m_storage + m_metadata);
|
||||
}
|
||||
|
||||
boost::int32_t Value::as_int32() const
|
||||
{
|
||||
if (m_is_null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
boost::uint32_t to_int;
|
||||
Protocol_chunk<boost::uint32_t> prot_integer(to_int);
|
||||
|
||||
buffer_source buff(m_storage, m_size);
|
||||
buff >> prot_integer;
|
||||
return to_int;
|
||||
}
|
||||
|
||||
boost::int8_t Value::as_int8() const
|
||||
{
|
||||
if (m_is_null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
boost::int8_t to_int;
|
||||
Protocol_chunk<boost::int8_t> prot_integer(to_int);
|
||||
|
||||
buffer_source buff(m_storage, m_size);
|
||||
buff >> prot_integer;
|
||||
return to_int;
|
||||
}
|
||||
|
||||
boost::int16_t Value::as_int16() const
|
||||
{
|
||||
if (m_is_null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
boost::int16_t to_int;
|
||||
Protocol_chunk<boost::int16_t> prot_integer(to_int);
|
||||
|
||||
buffer_source buff(m_storage, m_size);
|
||||
buff >> prot_integer;
|
||||
return to_int;
|
||||
}
|
||||
|
||||
boost::int64_t Value::as_int64() const
|
||||
{
|
||||
if (m_is_null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
boost::int64_t to_int;
|
||||
Protocol_chunk<boost::int64_t> prot_integer(to_int);
|
||||
|
||||
buffer_source buff(m_storage, m_size);
|
||||
buff >> prot_integer;
|
||||
return to_int;
|
||||
}
|
||||
|
||||
float Value::as_float() const
|
||||
{
|
||||
// TODO
|
||||
return *((const float *)storage());
|
||||
}
|
||||
|
||||
double Value::as_double() const
|
||||
{
|
||||
// TODO
|
||||
return *((const double *)storage());
|
||||
}
|
||||
|
||||
void Converter::to(std::string &str, const Value &val) const
|
||||
{
|
||||
if (val.is_null())
|
||||
{
|
||||
str= "(NULL)";
|
||||
return;
|
||||
}
|
||||
|
||||
switch(val.type())
|
||||
{
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
str= "not implemented";
|
||||
break;
|
||||
case MYSQL_TYPE_TINY:
|
||||
str= boost::lexical_cast<std::string>(static_cast<int>(val.as_int8()));
|
||||
break;
|
||||
case MYSQL_TYPE_SHORT:
|
||||
str= boost::lexical_cast<std::string>(val.as_int16());
|
||||
break;
|
||||
case MYSQL_TYPE_LONG:
|
||||
str= boost::lexical_cast<std::string>(val.as_int32());
|
||||
break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
{
|
||||
str= boost::str(boost::format("%d") % val.as_float());
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
str= boost::str(boost::format("%d") % val.as_double());
|
||||
break;
|
||||
case MYSQL_TYPE_NULL:
|
||||
str= "not implemented";
|
||||
break;
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
str= boost::lexical_cast<std::string>((boost::uint32_t)val.as_int32());
|
||||
break;
|
||||
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
str= boost::lexical_cast<std::string>(val.as_int64());
|
||||
break;
|
||||
case MYSQL_TYPE_INT24:
|
||||
str= "not implemented";
|
||||
break;
|
||||
case MYSQL_TYPE_DATE:
|
||||
{
|
||||
const char* val_storage = val.storage();
|
||||
unsigned int date_val = (val_storage[0] & 0xff) + ((val_storage[1] & 0xff) << 8) + ((val_storage[2] & 0xff) << 16);
|
||||
unsigned int date_year = date_val >> 9;
|
||||
date_val -= (date_year << 9);
|
||||
unsigned int date_month = date_val >> 5;
|
||||
unsigned int date_day = date_val - (date_month << 5);
|
||||
str = boost::str(boost::format("%04d-%02d-%02d") % date_year % date_month % date_day);
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
{
|
||||
boost::uint64_t timestamp= val.as_int64();
|
||||
unsigned long d= timestamp / 1000000;
|
||||
unsigned long t= timestamp % 1000000;
|
||||
std::ostringstream os;
|
||||
|
||||
os << std::setfill('0') << std::setw(4) << d / 10000
|
||||
<< std::setw(1) << '-'
|
||||
<< std::setw(2) << (d % 10000) / 100
|
||||
<< std::setw(1) << '-'
|
||||
<< std::setw(2) << d % 100
|
||||
<< std::setw(1) << ' '
|
||||
<< std::setw(2) << t / 10000
|
||||
<< std::setw(1) << ':'
|
||||
<< std::setw(2) << (t % 10000) / 100
|
||||
<< std::setw(1) << ':'
|
||||
<< std::setw(2) << t % 100;
|
||||
|
||||
str= os.str();
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_TIME:
|
||||
{
|
||||
const char* val_storage = val.storage();
|
||||
unsigned int time_val = (val_storage[0] & 0xff) + ((val_storage[1] & 0xff) << 8) + ((val_storage[2] & 0xff) << 16);
|
||||
unsigned int time_sec = time_val % 100;
|
||||
time_val -= time_sec;
|
||||
unsigned int time_min = (time_val % 10000) / 100;
|
||||
unsigned int time_hour = (time_val - time_min) / 10000;
|
||||
str = boost::str(boost::format("%02d:%02d:%02d") % time_hour % time_min % time_sec);
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_YEAR:
|
||||
{
|
||||
const char* val_storage = val.storage();
|
||||
unsigned int year_val = (val_storage[0] & 0xff);
|
||||
year_val = year_val > 0 ? (year_val + 1900) : 0;
|
||||
str = boost::str(boost::format("%04d") % year_val);
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_NEWDATE:
|
||||
str= "not implemented";
|
||||
break;
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
{
|
||||
unsigned long size;
|
||||
char *ptr= val.as_c_str(size);
|
||||
str.append(ptr, size);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
{
|
||||
str.append(val.storage(), val.length());
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_STRING:
|
||||
{
|
||||
unsigned char str_type = 0;
|
||||
|
||||
if (val.metadata()) {
|
||||
str_type = val.metadata() & 0xff;
|
||||
}
|
||||
|
||||
if (str_type == mysql::system::MYSQL_TYPE_SET) {
|
||||
str = "not implemented";
|
||||
break;
|
||||
} else if (str_type == mysql::system::MYSQL_TYPE_ENUM) {
|
||||
unsigned int val_storage = static_cast<unsigned int>(*val.storage());
|
||||
str = boost::str(boost::format("%u") % val_storage);
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned long size;
|
||||
char *ptr= val.as_c_str(size);
|
||||
str.append(ptr, size);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_BIT:
|
||||
str= "not implemented";
|
||||
break;
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
str= "not implemented";
|
||||
break;
|
||||
case MYSQL_TYPE_ENUM:
|
||||
str= "not implemented";
|
||||
break;
|
||||
case MYSQL_TYPE_SET:
|
||||
str= "not implemented";
|
||||
break;
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned char *ptr= val.as_blob(size);
|
||||
str.append((const char *)ptr, size);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
str= "not implemented";
|
||||
break;
|
||||
default:
|
||||
str= "not implemented";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Converter::to(float &out, const Value &val) const
|
||||
{
|
||||
switch(val.type())
|
||||
{
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
out= val.as_float();
|
||||
break;
|
||||
default:
|
||||
out= 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Converter::to(long &out, const Value &val) const
|
||||
{
|
||||
switch(val.type())
|
||||
{
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
// TODO
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY:
|
||||
out= val.as_int8();
|
||||
break;
|
||||
case MYSQL_TYPE_SHORT:
|
||||
out= val.as_int16();
|
||||
break;;
|
||||
case MYSQL_TYPE_LONG:
|
||||
out= (long)val.as_int32();
|
||||
break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
out= (long)val.as_double();
|
||||
case MYSQL_TYPE_NULL:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
out=(boost::uint32_t)val.as_int32();
|
||||
break;
|
||||
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
out= (long)val.as_int64();
|
||||
break;
|
||||
case MYSQL_TYPE_INT24:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_DATE:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_TIME:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
out= (long)val.as_int64();
|
||||
break;
|
||||
case MYSQL_TYPE_YEAR:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_NEWDATE:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_BIT:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_ENUM:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_SET:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
{
|
||||
std::string str;
|
||||
str.append(val.storage(), val.length());
|
||||
out= boost::lexical_cast<long>(str.c_str());
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_STRING:
|
||||
out= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
out= 0;
|
||||
break;
|
||||
default:
|
||||
out= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace mysql
|
19
replication_listener/tests/CMakeLists.txt
Normal file
19
replication_listener/tests/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# Right now, the tests are built using the static version of the
|
||||
# replication listener, but we need to decide which one to use.
|
||||
|
||||
set(MySQL_SERVER_TESTS test-basic)
|
||||
set(MySQL_BINLOG_TESTS replaybinlog replay_sys_vars)
|
||||
set(MySQL_SIMPLE_TESTS test-transport)
|
||||
|
||||
foreach(test ${MySQL_BINLOG_TESTS} ${MySQL_SERVER_TESTS} ${MySQL_SIMPLE_TESTS})
|
||||
message("Adding test ${test}")
|
||||
add_executable(${test} ${test}.cpp)
|
||||
target_link_libraries(${test} replication_static gtest)
|
||||
endforeach()
|
||||
|
||||
if(WITH_SERVER_TESTS)
|
||||
add_test(ServerTests ${MySQL_SERVER_TESTS})
|
||||
endif(WITH_SERVER_TESTS)
|
||||
add_test(BasicTests ${MySQL_SIMPLE_TESTS})
|
||||
add_test(BinlogTests ${MySQL_BINLOG_TESTS})
|
||||
|
533
replication_listener/tests/r/binlog_file_reader.result
Normal file
533
replication_listener/tests/r/binlog_file_reader.result
Normal file
@ -0,0 +1,533 @@
|
||||
#
|
||||
# Reading binlogs files.
|
||||
#
|
||||
Event type: Format_desc length: 110 next pos: 114
|
||||
Event type: Query length: 91 next pos: 205
|
||||
query= drop database if exists test db= test
|
||||
|
||||
Event type: Query length: 83 next pos: 288
|
||||
query= create database test db= test
|
||||
|
||||
Event type: Query length: 105 next pos: 393
|
||||
query= CREATE TABLE REPLICATION_LISTENER (c1 int) db= test
|
||||
|
||||
Event type: Query length: 115 next pos: 508
|
||||
query= CREATE TABLE t1 (c1 CHAR(3), c2 CHAR(1) DEFAULT 'a') db= test
|
||||
|
||||
Event type: Query length: 110 next pos: 686
|
||||
query= INSERT INTO t1 (c1) VALUES ('a'),('bb'),('ccc') db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 755
|
||||
Event type: Query length: 99 next pos: 922
|
||||
query= UPDATE t1 SET c1='aaaa' WHERE c1='a' db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 991
|
||||
Event type: Query length: 107 next pos: 1098
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(255) db= test
|
||||
|
||||
Event type: Query length: 111 next pos: 1277
|
||||
query= UPDATE t1 SET c1='bbbbbbbbbbbbbbb' WHERE c1='bb' db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 1346
|
||||
Event type: Query length: 105 next pos: 1451
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(1) db= test
|
||||
|
||||
Event type: Query length: 77 next pos: 1596
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 1665
|
||||
Event type: Query length: 104 next pos: 1769
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 107 next pos: 1876
|
||||
query= CREATE TABLE t1 (c1 INT, c2 INT DEFAULT '1') db= test
|
||||
|
||||
Event type: Query length: 105 next pos: 2049
|
||||
query= INSERT INTO t1 (c1) VALUES (1),(-12),(123) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 2118
|
||||
Event type: Query length: 101 next pos: 2287
|
||||
query= UPDATE t1 SET c1=2147483647 WHERE c1=1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 2356
|
||||
Event type: Query length: 111 next pos: 2535
|
||||
query= UPDATE t1 SET c1=-2147483648 WHERE c1=2147483647 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 2604
|
||||
Event type: Query length: 77 next pos: 2749
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 2818
|
||||
Event type: Query length: 104 next pos: 2922
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 117 next pos: 3039
|
||||
query= CREATE TABLE t1 (c1 SMALLINT, c2 SMALLINT DEFAULT '1') db= test
|
||||
|
||||
Event type: Query length: 105 next pos: 3212
|
||||
query= INSERT INTO t1 (c1) VALUES (1),(-12),(123) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 3281
|
||||
Event type: Query length: 96 next pos: 3445
|
||||
query= UPDATE t1 SET c1=32767 WHERE c1=1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 3514
|
||||
Event type: Query length: 101 next pos: 3683
|
||||
query= UPDATE t1 SET c1=-32768 WHERE c1=32767 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 3752
|
||||
Event type: Query length: 77 next pos: 3897
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 3966
|
||||
Event type: Query length: 104 next pos: 4070
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 115 next pos: 4185
|
||||
query= CREATE TABLE t1 (c1 TINYINT, c2 TINYINT DEFAULT '1') db= test
|
||||
|
||||
Event type: Query length: 105 next pos: 4358
|
||||
query= INSERT INTO t1 (c1) VALUES (1),(-12),(123) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 4427
|
||||
Event type: Query length: 94 next pos: 4589
|
||||
query= UPDATE t1 SET c1=127 WHERE c1=1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 4658
|
||||
Event type: Query length: 97 next pos: 4823
|
||||
query= UPDATE t1 SET c1=-128 WHERE c1=127 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 4892
|
||||
Event type: Query length: 77 next pos: 5037
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 5106
|
||||
Event type: Query length: 104 next pos: 5210
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 123 next pos: 5333
|
||||
query= CREATE TABLE t1 (c0 INT AUTO_INCREMENT PRIMARY KEY, c1 TEXT) db= test
|
||||
|
||||
Event type: Intvar length: 28 next pos: 5429
|
||||
Event type: Query length: 110 next pos: 5539
|
||||
query= INSERT INTO t1 (c1) VALUES ('a'),('bb'),('ccc') db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 5608
|
||||
Event type: Query length: 99 next pos: 5775
|
||||
query= UPDATE t1 SET c1='aaaa' WHERE c1='a' db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 5844
|
||||
Event type: Query length: 107 next pos: 5951
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(255) db= test
|
||||
|
||||
Event type: Query length: 111 next pos: 6130
|
||||
query= UPDATE t1 SET c1='bbbbbbbbbbbbbbb' WHERE c1='bb' db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 6199
|
||||
Event type: Query length: 105 next pos: 6304
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(1) db= test
|
||||
|
||||
Event type: Query length: 77 next pos: 6449
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 6518
|
||||
Event type: Query length: 102 next pos: 6620
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 TEXT db= test
|
||||
|
||||
Event type: Intvar length: 28 next pos: 6716
|
||||
Event type: Query length: 11106 next pos: 17822
|
||||
query= INSERT INTO t1 (c1) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaa') db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 17891
|
||||
Event type: Intvar length: 28 next pos: 17987
|
||||
Event type: Query length: 11106 next pos: 29093
|
||||
query= INSERT INTO t1 (c1) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaa') db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 29162
|
||||
Event type: Query length: 77 next pos: 29307
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 29376
|
||||
Event type: Query length: 104 next pos: 29480
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 93 next pos: 29573
|
||||
query= CREATE TABLE t1 (c1 TIMESTAMP) db= test
|
||||
|
||||
Event type: Query length: 116 next pos: 29765
|
||||
query= INSERT INTO t1 VALUES ("2010-05-18 14:17:59") db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 29842
|
||||
Event type: Query length: 77 next pos: 29987
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 30056
|
||||
Event type: Query length: 104 next pos: 30160
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 92 next pos: 30252
|
||||
query= CREATE TABLE t1 (c1 DATETIME) db= test
|
||||
|
||||
Event type: Query length: 108 next pos: 30428
|
||||
query= INSERT INTO t1 VALUES ("2005-05-18 14:17:59") db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 30497
|
||||
Event type: Query length: 77 next pos: 30642
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 30711
|
||||
Event type: Query length: 104 next pos: 30815
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 89 next pos: 30904
|
||||
query= CREATE TABLE t1 (c1 FLOAT) db= test
|
||||
|
||||
Event type: Query length: 116 next pos: 31088
|
||||
query= INSERT INTO t1 VALUES (1.0),(1.01),(-12.05),(115.321) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 31157
|
||||
Event type: Query length: 101 next pos: 31326
|
||||
query= UPDATE t1 SET c1=0.000001 WHERE c1=1.0 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 31395
|
||||
Event type: Query length: 77 next pos: 31540
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 31609
|
||||
Event type: Query length: 104 next pos: 31713
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 90 next pos: 31803
|
||||
query= CREATE TABLE t1 (c1 DOUBLE) db= test
|
||||
|
||||
Event type: Query length: 116 next pos: 31987
|
||||
query= INSERT INTO t1 VALUES (1.0),(1.01),(-12.05),(115.321) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 32056
|
||||
Event type: Query length: 106 next pos: 32230
|
||||
query= UPDATE t1 SET c1=0.00000000001 WHERE c1=1.0 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 32299
|
||||
Event type: Query length: 77 next pos: 32444
|
||||
query= DELETE FROM t1 db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 32513
|
||||
Event type: Query length: 104 next pos: 32617
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 122 next pos: 32739
|
||||
query= DROP TABLE `REPLICATION_LISTENER` /* generated by server */ db= test
|
||||
|
||||
Event type: Format_desc length: 94 next pos: 98
|
||||
Event type: Query length: 100 next pos: 198
|
||||
query= create table t1(a int) engine= innodb db= test
|
||||
|
||||
Event type: Query length: 101 next pos: 299
|
||||
query= create table t2(a int) engine= innodb db= mysql
|
||||
|
||||
Event type: Query length: 92 next pos: 460
|
||||
query= insert into t1 (a) values (1) db= test
|
||||
|
||||
Event type: Query length: 93 next pos: 553
|
||||
query= insert into t2 (a) values (1) db= mysql
|
||||
|
||||
Event type: User defined length: 0 next pos: 553
|
||||
Event type: Query length: 100 next pos: 680
|
||||
query= create table t3(a int) engine= innodb db= test
|
||||
|
||||
Event type: Query length: 101 next pos: 781
|
||||
query= create table t4(a int) engine= myisam db= mysql
|
||||
|
||||
Event type: Query length: 92 next pos: 942
|
||||
query= insert into t3 (a) values (2) db= test
|
||||
|
||||
Event type: Query length: 93 next pos: 1035
|
||||
query= insert into t4 (a) values (2) db= mysql
|
||||
|
||||
Event type: Query length: 72 next pos: 1107
|
||||
query= ROLLBACK db= mysql
|
||||
|
||||
Event type: Query length: 97 next pos: 1204
|
||||
query= create table t5(a int) engine= NDB db= test
|
||||
|
||||
Event type: Query length: 98 next pos: 1302
|
||||
query= create table t6(a int) engine= NDB db= mysql
|
||||
|
||||
Event type: Query length: 92 next pos: 1463
|
||||
query= insert into t5 (a) values (3) db= test
|
||||
|
||||
Event type: Query length: 93 next pos: 1556
|
||||
query= insert into t6 (a) values (3) db= mysql
|
||||
|
||||
Event type: User defined length: 0 next pos: 1626
|
||||
Event type: Rotate length: 44 next pos: 1670
|
||||
filename= master-bin.000002 pos= 4
|
||||
|
||||
Event type: Format_desc length: 102 next pos: 106
|
||||
Event type: Rotate length: 44 next pos: 0
|
||||
filename= master-bin.000003 pos= 4
|
||||
|
||||
Event type: Format_desc length: 102 next pos: 106
|
||||
Event type: Query length: 92 next pos: 266
|
||||
query= INSERT INTO db1.t1 VALUES(20) db= test
|
||||
|
||||
Event type: Query length: 84 next pos: 350
|
||||
query= SavePoint mixed_cases db= test
|
||||
|
||||
Event type: Query length: 115 next pos: 465
|
||||
query= INSERT INTO db1.t2 VALUES("in savepoint mixed_cases") db= db1
|
||||
|
||||
Event type: Query length: 91 next pos: 556
|
||||
query= INSERT INTO db1.t1 VALUES(40) db= db1
|
||||
|
||||
Event type: Query length: 86 next pos: 642
|
||||
query= ROLLBACK TO mixed_cases db= test
|
||||
|
||||
Event type: Query length: 108 next pos: 750
|
||||
query= INSERT INTO db1.t2 VALUES("after rollback to") db= db1
|
||||
|
||||
Event type: Query length: 91 next pos: 841
|
||||
query= INSERT INTO db1.t1 VALUES(50) db= db1
|
||||
|
||||
Event type: User defined length: 0 next pos: 841
|
||||
# End of test
|
980
replication_listener/tests/r/replication_listener.result
Normal file
980
replication_listener/tests/r/replication_listener.result
Normal file
@ -0,0 +1,980 @@
|
||||
use test;
|
||||
CREATE TABLE REPLICATION_LISTENER (c1 int);
|
||||
"*** Test CHAR"
|
||||
CREATE TABLE t1 (c1 CHAR(3), c2 CHAR(1) DEFAULT 'a');
|
||||
INSERT INTO t1 (c1) VALUES ('a'),('bb'),('ccc');
|
||||
UPDATE t1 SET c1='aaaa' WHERE c1='a';
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'c1' at row 1
|
||||
ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(255);
|
||||
UPDATE t1 SET c1='bbbbbbbbbbbbbbb' WHERE c1='bb';
|
||||
ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(1);
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'c1' at row 1
|
||||
Warning 1265 Data truncated for column 'c1' at row 2
|
||||
Warning 1265 Data truncated for column 'c1' at row 3
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
"*** Test INT"
|
||||
CREATE TABLE t1 (c1 INT, c2 INT DEFAULT '1');
|
||||
INSERT INTO t1 (c1) VALUES (1),(-12),(123);
|
||||
UPDATE t1 SET c1=2147483647 WHERE c1=1;
|
||||
UPDATE t1 SET c1=-2147483648 WHERE c1=2147483647;
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
"*** Test SMALLINT"
|
||||
CREATE TABLE t1 (c1 SMALLINT, c2 SMALLINT DEFAULT '1');
|
||||
INSERT INTO t1 (c1) VALUES (1),(-12),(123);
|
||||
UPDATE t1 SET c1=32767 WHERE c1=1;
|
||||
UPDATE t1 SET c1=-32768 WHERE c1=32767;
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
"*** Test TINYINT"
|
||||
CREATE TABLE t1 (c1 TINYINT, c2 TINYINT DEFAULT '1');
|
||||
INSERT INTO t1 (c1) VALUES (1),(-12),(123);
|
||||
UPDATE t1 SET c1=127 WHERE c1=1;
|
||||
UPDATE t1 SET c1=-128 WHERE c1=127;
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
"**** Test TEXT"
|
||||
CREATE TABLE t1 (c0 INT AUTO_INCREMENT PRIMARY KEY, c1 TEXT);
|
||||
INSERT INTO t1 (c1) VALUES ('a'),('bb'),('ccc');
|
||||
UPDATE t1 SET c1='aaaa' WHERE c1='a';
|
||||
ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(255);
|
||||
UPDATE t1 SET c1='bbbbbbbbbbbbbbb' WHERE c1='bb';
|
||||
ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(1);
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'c1' at row 1
|
||||
Warning 1265 Data truncated for column 'c1' at row 2
|
||||
Warning 1265 Data truncated for column 'c1' at row 3
|
||||
DELETE FROM t1;
|
||||
ALTER TABLE t1 CHANGE COLUMN c1 c1 TEXT;
|
||||
INSERT INTO t1 (c1) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaa');
|
||||
INSERT INTO t1 (c1) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaa');
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
"*** Testing TIMESTAMP"
|
||||
CREATE TABLE t1 (c1 TIMESTAMP);
|
||||
INSERT INTO t1 VALUES ("2010-05-18 14:17:59");
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
"*** Testing DATETIME"
|
||||
CREATE TABLE t1 (c1 DATETIME);
|
||||
INSERT INTO t1 VALUES ("2005-05-18 14:17:59");
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
"*** Testing FLOAT"
|
||||
CREATE TABLE t1 (c1 FLOAT);
|
||||
INSERT INTO t1 VALUES (1.0),(1.01),(-12.05),(115.321);
|
||||
UPDATE t1 SET c1=0.000001 WHERE c1=1.0;
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
"*** Testing DOUBLE"
|
||||
CREATE TABLE t1 (c1 DOUBLE);
|
||||
INSERT INTO t1 VALUES (1.0),(1.01),(-12.05),(115.321);
|
||||
UPDATE t1 SET c1=0.00000000001 WHERE c1=1.0;
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE REPLICATION_LISTENER;
|
||||
Event type: Incident length: 40 next pos: 4
|
||||
type= 175 message= Operation canceled
|
||||
|
||||
Event type: Rotate length: 43 next pos: 0
|
||||
filename= searchbin.000001 pos= 4
|
||||
|
||||
Event type: Format_desc length: 103 next pos: 107
|
||||
Event type: Query length: 105 next pos: 212
|
||||
query= CREATE TABLE REPLICATION_LISTENER (c1 int) db= test
|
||||
|
||||
Event type: Query length: 115 next pos: 327
|
||||
query= CREATE TABLE t1 (c1 CHAR(3), c2 CHAR(1) DEFAULT 'a') db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 488
|
||||
INSERT INTO test.t1 VALUES (a, a)
|
||||
INSERT INTO test.t1 VALUES (bb, a)
|
||||
INSERT INTO test.t1 VALUES (ccc, a)
|
||||
Event type: User defined length: 0 next pos: 713
|
||||
UPDATE test.t1 SET 0= aaa, 1= a WHERE 0= a AND 1= a LIMIT 1
|
||||
Event type: Query length: 107 next pos: 889
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(255) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 1058
|
||||
UPDATE test.t1 SET 0= bbbbbbbbbbbbbbb, 1= a WHERE 0= bb AND 1= a LIMIT 1
|
||||
Event type: Query length: 105 next pos: 1232
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(1) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 1390
|
||||
DELETE FROM test.t1 WHERE 0= a AND 1= a LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= b AND 1= a LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= c AND 1= a LIMIT 1
|
||||
Event type: Query length: 104 next pos: 1563
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 107 next pos: 1670
|
||||
query= CREATE TABLE t1 (c1 INT, c2 INT DEFAULT '1') db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 1836
|
||||
INSERT INTO test.t1 VALUES (1, 1)
|
||||
INSERT INTO test.t1 VALUES (-12, 1)
|
||||
INSERT INTO test.t1 VALUES (123, 1)
|
||||
Event type: User defined length: 0 next pos: 2063
|
||||
UPDATE test.t1 SET 0= 2147483647, 1= 1 WHERE 0= 1 AND 1= 1 LIMIT 1
|
||||
Event type: User defined length: 0 next pos: 2290
|
||||
UPDATE test.t1 SET 0= -2147483648, 1= 1 WHERE 0= 2147483647 AND 1= 1 LIMIT 1
|
||||
Event type: User defined length: 0 next pos: 2525
|
||||
DELETE FROM test.t1 WHERE 0= -2147483648 AND 1= 1 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= -12 AND 1= 1 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 123 AND 1= 1 LIMIT 1
|
||||
Event type: Query length: 104 next pos: 2698
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 117 next pos: 2815
|
||||
query= CREATE TABLE t1 (c1 SMALLINT, c2 SMALLINT DEFAULT '1') db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 2969
|
||||
INSERT INTO test.t1 VALUES (1, 1)
|
||||
INSERT INTO test.t1 VALUES (-12, 1)
|
||||
INSERT INTO test.t1 VALUES (123, 1)
|
||||
Event type: User defined length: 0 next pos: 3188
|
||||
UPDATE test.t1 SET 0= 32767, 1= 1 WHERE 0= 1 AND 1= 1 LIMIT 1
|
||||
Event type: User defined length: 0 next pos: 3407
|
||||
UPDATE test.t1 SET 0= -32768, 1= 1 WHERE 0= 32767 AND 1= 1 LIMIT 1
|
||||
Event type: User defined length: 0 next pos: 3630
|
||||
DELETE FROM test.t1 WHERE 0= -32768 AND 1= 1 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= -12 AND 1= 1 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 123 AND 1= 1 LIMIT 1
|
||||
Event type: Query length: 104 next pos: 3803
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 115 next pos: 3918
|
||||
query= CREATE TABLE t1 (c1 TINYINT, c2 TINYINT DEFAULT '1') db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 4066
|
||||
INSERT INTO test.t1 VALUES (1, 1)
|
||||
INSERT INTO test.t1 VALUES (-12, 1)
|
||||
INSERT INTO test.t1 VALUES (123, 1)
|
||||
Event type: User defined length: 0 next pos: 4281
|
||||
UPDATE test.t1 SET 0= 127, 1= 1 WHERE 0= 1 AND 1= 1 LIMIT 1
|
||||
Event type: User defined length: 0 next pos: 4496
|
||||
UPDATE test.t1 SET 0= -128, 1= 1 WHERE 0= 127 AND 1= 1 LIMIT 1
|
||||
Event type: User defined length: 0 next pos: 4713
|
||||
DELETE FROM test.t1 WHERE 0= -128 AND 1= 1 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= -12 AND 1= 1 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 123 AND 1= 1 LIMIT 1
|
||||
Event type: Query length: 104 next pos: 4886
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 123 next pos: 5009
|
||||
query= CREATE TABLE t1 (c0 INT AUTO_INCREMENT PRIMARY KEY, c1 TEXT) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 5176
|
||||
INSERT INTO test.t1 VALUES (1, 'a')
|
||||
INSERT INTO test.t1 VALUES (2, 'bb')
|
||||
INSERT INTO test.t1 VALUES (3, 'ccc')
|
||||
Event type: User defined length: 0 next pos: 5405
|
||||
UPDATE test.t1 SET 0= 1, 1= 'aaaa' WHERE 0= 1 AND 1= 'a' LIMIT 1
|
||||
Event type: Query length: 107 next pos: 5581
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(255) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 5752
|
||||
UPDATE test.t1 SET 0= 2, 1= bbbbbbbbbbbbbbb WHERE 0= 2 AND 1= bb LIMIT 1
|
||||
Event type: Query length: 105 next pos: 5926
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 CHAR(1) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 6088
|
||||
DELETE FROM test.t1 WHERE 0= 1 AND 1= a LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 2 AND 1= b LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 3 AND 1= c LIMIT 1
|
||||
Event type: Query length: 102 next pos: 6259
|
||||
query= ALTER TABLE t1 CHANGE COLUMN c1 c1 TEXT db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 17418
|
||||
INSERT INTO test.t1 VALUES (4, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaa')
|
||||
Event type: User defined length: 0 next pos: 28646
|
||||
INSERT INTO test.t1 VALUES (5, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaa')
|
||||
Event type: User defined length: 0 next pos: 50922
|
||||
DELETE FROM test.t1 WHERE 0= 4 AND 1= 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaa' LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 5 AND 1= 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaa' LIMIT 1
|
||||
Event type: Query length: 104 next pos: 51095
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 93 next pos: 51188
|
||||
query= CREATE TABLE t1 (c1 TIMESTAMP) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 51339
|
||||
INSERT INTO test.t1 VALUES (1274181479)
|
||||
Event type: User defined length: 0 next pos: 51559
|
||||
DELETE FROM test.t1 WHERE 0= 1274181479 LIMIT 1
|
||||
Event type: Query length: 104 next pos: 51732
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 92 next pos: 51824
|
||||
query= CREATE TABLE t1 (c1 DATETIME) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 51971
|
||||
INSERT INTO test.t1 VALUES (2005-05-18 14:17:59)
|
||||
Event type: User defined length: 0 next pos: 52187
|
||||
DELETE FROM test.t1 WHERE 0= 2005-05-18 14:17:59 LIMIT 1
|
||||
Event type: Query length: 104 next pos: 52360
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 89 next pos: 52449
|
||||
query= CREATE TABLE t1 (c1 FLOAT) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 52608
|
||||
INSERT INTO test.t1 VALUES (1)
|
||||
INSERT INTO test.t1 VALUES (1.01)
|
||||
INSERT INTO test.t1 VALUES (-12.05)
|
||||
INSERT INTO test.t1 VALUES (115.321)
|
||||
Event type: User defined length: 0 next pos: 52827
|
||||
UPDATE test.t1 SET 0= 1e-06 WHERE 0= 1 LIMIT 1
|
||||
Event type: User defined length: 0 next pos: 53055
|
||||
DELETE FROM test.t1 WHERE 0= 1e-06 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 1.01 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= -12.05 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 115.321 LIMIT 1
|
||||
Event type: Query length: 104 next pos: 53228
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 90 next pos: 53318
|
||||
query= CREATE TABLE t1 (c1 DOUBLE) db= test
|
||||
|
||||
Event type: User defined length: 0 next pos: 53493
|
||||
INSERT INTO test.t1 VALUES (1)
|
||||
INSERT INTO test.t1 VALUES (1.01)
|
||||
INSERT INTO test.t1 VALUES (-12.05)
|
||||
INSERT INTO test.t1 VALUES (115.321)
|
||||
Event type: User defined length: 0 next pos: 53720
|
||||
UPDATE test.t1 SET 0= 1e-11 WHERE 0= 1 LIMIT 1
|
||||
Event type: User defined length: 0 next pos: 53964
|
||||
DELETE FROM test.t1 WHERE 0= 1e-11 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 1.01 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= -12.05 LIMIT 1
|
||||
DELETE FROM test.t1 WHERE 0= 115.321 LIMIT 1
|
||||
Event type: Query length: 104 next pos: 54137
|
||||
query= DROP TABLE `t1` /* generated by server */ db= test
|
||||
|
||||
Event type: Query length: 122 next pos: 54259
|
||||
query= DROP TABLE `REPLICATION_LISTENER` /* generated by server */ db= test
|
||||
|
||||
"## End of binary log."
|
329
replication_listener/tests/r/sys_vars.result
Normal file
329
replication_listener/tests/r/sys_vars.result
Normal file
@ -0,0 +1,329 @@
|
||||
DROP DATABASE IF EXISTS `sys_var`;
|
||||
Warnings:
|
||||
Note 1008 Can't drop database 'sys_var'; database doesn't exist
|
||||
CREATE DATABASE `sys_var`;
|
||||
USE `sys_var`;
|
||||
CREATE TABLE t1 (c1 CHAR(3), c2 CHAR(1) DEFAULT 'a');
|
||||
INSERT INTO t1 (c1) VALUES ('a'),('bb'),('ccc');
|
||||
UPDATE t1 SET c1='aaaa' WHERE c1='a';
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'c1' at row 1
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
SET @@auto_increment_increment=19;
|
||||
SET @@auto_increment_offset=4;
|
||||
SET @@character_set_client='latin2';
|
||||
SET @@collation_connection='latin2_bin';
|
||||
SET @@collation_server='geostd8_general_ci';
|
||||
SET @@time_zone='Japan';
|
||||
SET @@lc_time_names='sv_SE';
|
||||
SET @@collation_database='geostd8_bin';
|
||||
CREATE TABLE t1 (c1 DATE);
|
||||
INSERT INTO t1 VALUES ('2006-01-01');
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
2006-01-01
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT PRIMARY KEY, c2 TEXT);
|
||||
INSERT INTO t1 (c1) VALUES ('a'),('bb'),('ccc');
|
||||
Warnings:
|
||||
Warning 1366 Incorrect integer value: 'a' for column 'c1' at row 1
|
||||
Warning 1366 Incorrect integer value: 'bb' for column 'c1' at row 2
|
||||
Warning 1366 Incorrect integer value: 'ccc' for column 'c1' at row 3
|
||||
SELECT * FROM t1;
|
||||
c1 c2
|
||||
4 NULL
|
||||
23 NULL
|
||||
42 NULL
|
||||
DROP TABLE t1;
|
||||
DROP DATABASE `sys_var`;
|
||||
Connected to server!!
|
||||
Pos = 4 Event_type = 26
|
||||
Pos = 0 Event_type = 4
|
||||
Pos = 114 Event_type = 15
|
||||
Pos = 213 Event_type = 2
|
||||
Query = DROP DATABASE IF EXISTS `sys_var` DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 0
|
||||
sql_mode = -453830021431164924
|
||||
----------
|
||||
|
||||
Pos = 304 Event_type = 2
|
||||
Query = CREATE DATABASE `sys_var` DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 0
|
||||
sql_mode = -453830021431164924
|
||||
----------
|
||||
|
||||
Pos = 422 Event_type = 2
|
||||
Query = CREATE TABLE t1 (c1 CHAR(3), c2 CHAR(1) DEFAULT 'a') DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566648
|
||||
sql_mode = -453830021430627274
|
||||
----------
|
||||
|
||||
Pos = 493 Event_type = 2
|
||||
Query = BEGIN DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566656
|
||||
sql_mode = -453830021430758090
|
||||
----------
|
||||
|
||||
Pos = 606 Event_type = 2
|
||||
Query = INSERT INTO t1 (c1) VALUES ('a'),('bb'),('ccc') DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566654
|
||||
sql_mode = -453830021430889162
|
||||
----------
|
||||
|
||||
Pos = 678 Event_type = 2
|
||||
Query = COMMIT DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566650
|
||||
sql_mode = -453830021431151306
|
||||
----------
|
||||
|
||||
Pos = 749 Event_type = 2
|
||||
Query = BEGIN DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566652
|
||||
sql_mode = -453830021431020234
|
||||
----------
|
||||
|
||||
Pos = 851 Event_type = 2
|
||||
Query = UPDATE t1 SET c1='aaaa' WHERE c1='a' DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566652
|
||||
sql_mode = -453830021431020234
|
||||
----------
|
||||
|
||||
Pos = 923 Event_type = 2
|
||||
Query = COMMIT DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566652
|
||||
sql_mode = -453830021431020234
|
||||
----------
|
||||
|
||||
Pos = 994 Event_type = 2
|
||||
Query = BEGIN DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566652
|
||||
sql_mode = -453830021431020234
|
||||
----------
|
||||
|
||||
Pos = 1074 Event_type = 2
|
||||
Query = DELETE FROM t1 DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566652
|
||||
sql_mode = -453830021431020234
|
||||
----------
|
||||
|
||||
Pos = 1146 Event_type = 2
|
||||
Query = COMMIT DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566652
|
||||
sql_mode = -453830021431020234
|
||||
----------
|
||||
|
||||
Pos = 1253 Event_type = 2
|
||||
Query = DROP TABLE `t1` /* generated by server */ DB = sys_var
|
||||
catalog_name = std
|
||||
character_set_client = 8
|
||||
collation_connection = 8
|
||||
collation_server = 8
|
||||
flag2 = 566652
|
||||
sql_mode = -453830021431020234
|
||||
----------
|
||||
|
||||
Pos = 1355 Event_type = 2
|
||||
Query = CREATE TABLE t1 (c1 DATE) DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 1437 Event_type = 2
|
||||
Query = BEGIN DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 1550 Event_type = 2
|
||||
Query = INSERT INTO t1 VALUES ('2006-01-01') DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 1633 Event_type = 2
|
||||
Query = COMMIT DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 1751 Event_type = 2
|
||||
Query = DROP TABLE `t1` /* generated by server */ DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 1888 Event_type = 2
|
||||
Query = CREATE TABLE t1 (c1 INT AUTO_INCREMENT PRIMARY KEY, c2 TEXT) DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 1970 Event_type = 2
|
||||
Query = BEGIN DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 1998 Event_type = 5
|
||||
Pos = 2122 Event_type = 2
|
||||
Query = INSERT INTO t1 (c1) VALUES ('a'),('bb'),('ccc') DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 2205 Event_type = 2
|
||||
Query = COMMIT DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 2323 Event_type = 2
|
||||
Query = DROP TABLE `t1` /* generated by server */ DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
Pos = 2423 Event_type = 2
|
||||
Query = DROP DATABASE `sys_var` DB = sys_var
|
||||
auto_increment_increment = 19
|
||||
auto_increment_offset = 4
|
||||
catalog_name = std
|
||||
character_set_client = 9
|
||||
collation_connection = 77
|
||||
collation_database = 93
|
||||
collation_server = 92
|
||||
flag2 = 0
|
||||
lc_time_names = 3
|
||||
sql_mode = -453830021430968318
|
||||
----------
|
||||
|
||||
"#End of binary log"
|
103
replication_listener/tests/replay_sys_vars.cpp
Normal file
103
replication_listener/tests/replay_sys_vars.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 <cstdlib>
|
||||
#include <boost/foreach.hpp>
|
||||
#include "binlog_api.h"
|
||||
#include "utilities.h"
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
mysql::Binary_log
|
||||
binlog(mysql::system::create_transport("mysql://root@127.0.0.1:13000"));
|
||||
|
||||
if (binlog.connect())
|
||||
{
|
||||
std::cerr << "Can't connect!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
std::cout << "Connected to server!!" << std::endl;
|
||||
|
||||
if (binlog.set_position(4) != ERR_OK)
|
||||
{
|
||||
std::cerr << "Can't reposition the binary log reader."
|
||||
<< std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Binary_log_event *event;
|
||||
|
||||
bool quit=false;
|
||||
while (!quit)
|
||||
{
|
||||
if (binlog.wait_for_next_event (&event))
|
||||
{
|
||||
quit= true;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "Pos = "
|
||||
<< event->header()->next_position
|
||||
<<" Event_type = "
|
||||
<< event->get_event_type()
|
||||
<< std::endl;
|
||||
|
||||
switch (event->header()->type_code)
|
||||
{
|
||||
case mysql::QUERY_EVENT:
|
||||
{
|
||||
const mysql::Query_event *qev= static_cast<const mysql::Query_event *>(event);
|
||||
std::cout << "Query = "
|
||||
<< qev->query
|
||||
<< " DB = "
|
||||
<< qev->db_name
|
||||
<< std::endl;
|
||||
std::map<std::string, mysql::Value> my_var_map;
|
||||
|
||||
if (server_var_decoder(&my_var_map, qev->variables))
|
||||
return (EXIT_FAILURE);
|
||||
|
||||
mysql::Converter converter;
|
||||
|
||||
typedef std::map<std::string, mysql::Value>::value_type my_pair;
|
||||
BOOST_FOREACH (my_pair &ref, my_var_map)
|
||||
{
|
||||
std::string value;
|
||||
converter.to(value, ref.second);
|
||||
std::cout << ref.first
|
||||
<< " = "
|
||||
<< value
|
||||
<< std::endl;
|
||||
}
|
||||
std::cout << "----------" << std::endl << std::endl;
|
||||
|
||||
if (qev->query.find("DROP DATABASE `sys_var`") != std::string::npos
|
||||
|| qev->query.find("DROP DATABASE sys_var") != std::string::npos)
|
||||
quit= true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
delete event;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
330
replication_listener/tests/replaybinlog.cpp
Normal file
330
replication_listener/tests/replaybinlog.cpp
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
|
||||
reserved.
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <boost/foreach.hpp>
|
||||
#include "binlog_api.h"
|
||||
|
||||
bool is_text_field(Value &val)
|
||||
{
|
||||
if (val.type() == mysql::system::MYSQL_TYPE_VARCHAR ||
|
||||
val.type() == mysql::system::MYSQL_TYPE_BLOB ||
|
||||
val.type() == mysql::system::MYSQL_TYPE_MEDIUM_BLOB ||
|
||||
val.type() == mysql::system::MYSQL_TYPE_LONG_BLOB)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void table_insert(const std::string& table_name, mysql::Row_of_fields &fields)
|
||||
{
|
||||
std::cout << "INSERT INTO "
|
||||
<< table_name
|
||||
<< " VALUES (";
|
||||
mysql::Row_of_fields::iterator field_it= fields.begin();
|
||||
mysql::Converter converter;
|
||||
do {
|
||||
/*
|
||||
Each row contains a vector of Value objects. The converter
|
||||
allows us to transform the value into another
|
||||
representation.
|
||||
*/
|
||||
std::string str;
|
||||
converter.to(str, *field_it);
|
||||
if (is_text_field(*field_it))
|
||||
std::cout << '\'';
|
||||
std::cout << str;
|
||||
if (is_text_field(*field_it))
|
||||
std::cout << '\'';
|
||||
++field_it;
|
||||
if (field_it != fields.end())
|
||||
std::cout << ", ";
|
||||
} while(field_it != fields.end());
|
||||
std::cout << ")" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void table_update(const std::string& table_name,
|
||||
mysql::Row_of_fields &old_fields, mysql::Row_of_fields &new_fields)
|
||||
{
|
||||
std::cout << "UPDATE "
|
||||
<< table_name
|
||||
<< " SET ";
|
||||
|
||||
int field_id= 0;
|
||||
mysql::Row_of_fields::iterator field_it= new_fields.begin();
|
||||
mysql::Converter converter;
|
||||
do {
|
||||
std::string str;
|
||||
converter.to(str, *field_it);
|
||||
std::cout << field_id << "= ";
|
||||
if (is_text_field(*field_it))
|
||||
std::cout << '\'';
|
||||
std::cout << str;
|
||||
if (is_text_field(*field_it))
|
||||
std::cout << '\'';
|
||||
++field_it;
|
||||
++field_id;
|
||||
if (field_it != new_fields.end())
|
||||
std::cout << ", ";
|
||||
} while(field_it != new_fields.end());
|
||||
std::cout << " WHERE ";
|
||||
field_it= old_fields.begin();
|
||||
field_id= 0;
|
||||
do {
|
||||
std::string str;
|
||||
converter.to(str, *field_it);
|
||||
std::cout << field_id << "= ";
|
||||
if (is_text_field(*field_it))
|
||||
std::cout << '\'';
|
||||
std::cout << str;
|
||||
if (is_text_field(*field_it))
|
||||
std::cout << '\'';
|
||||
++field_it;
|
||||
++field_id;
|
||||
if (field_it != old_fields.end())
|
||||
std::cout << " AND ";
|
||||
} while(field_it != old_fields.end());
|
||||
std::cout << " LIMIT 1" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void table_delete(const std::string& table_name, mysql::Row_of_fields &fields)
|
||||
{
|
||||
std::cout << "DELETE FROM "
|
||||
<< table_name
|
||||
<< " WHERE ";
|
||||
mysql::Row_of_fields::iterator field_it= fields.begin();
|
||||
int field_id= 0;
|
||||
mysql::Converter converter;
|
||||
do {
|
||||
|
||||
std::string str;
|
||||
converter.to(str, *field_it);
|
||||
std::cout << field_id << "= ";
|
||||
if (is_text_field(*field_it))
|
||||
std::cout << '\'';
|
||||
std::cout << str;
|
||||
if (is_text_field(*field_it))
|
||||
std::cout << '\'';
|
||||
++field_it;
|
||||
++field_id;
|
||||
if (field_it != fields.end())
|
||||
std::cout << " AND ";
|
||||
} while(field_it != fields.end());
|
||||
std::cout << " LIMIT 1" << std::endl;
|
||||
}
|
||||
|
||||
class Incident_handler : public mysql::Content_handler
|
||||
{
|
||||
public:
|
||||
Incident_handler() : mysql::Content_handler() {}
|
||||
|
||||
mysql::Binary_log_event *process_event(mysql::Incident_event *incident)
|
||||
{
|
||||
std::cout << "Event type: "
|
||||
<< mysql::system::get_event_type_str(incident->get_event_type())
|
||||
<< " length: " << incident->header()->event_length
|
||||
<< " next pos: " << incident->header()->next_position
|
||||
<< std::endl;
|
||||
std::cout << "type= "
|
||||
<< (unsigned)incident->type
|
||||
<< " message= "
|
||||
<< incident->message
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
/* Consume the event */
|
||||
delete incident;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class Replay_binlog : public mysql::Content_handler
|
||||
{
|
||||
public:
|
||||
Replay_binlog() : mysql::Content_handler() {}
|
||||
mysql::Binary_log_event *process_event(mysql::Binary_log_event *event)
|
||||
{
|
||||
if (event->get_event_type() != mysql::USER_DEFINED)
|
||||
return event;
|
||||
std::cout << "Event type: "
|
||||
<< mysql::system::get_event_type_str(event->get_event_type())
|
||||
<< " length: " << event->header()->event_length
|
||||
<< " next pos: " << event->header()->next_position
|
||||
<< std::endl;
|
||||
mysql::Transaction_log_event *trans= static_cast<mysql::Transaction_log_event *>(event);
|
||||
int row_count=0;
|
||||
/*
|
||||
The transaction event we created has aggregated all row events in an
|
||||
ordered list.
|
||||
*/
|
||||
BOOST_FOREACH(mysql::Binary_log_event * event, trans->m_events)
|
||||
{
|
||||
switch (event->get_event_type())
|
||||
{
|
||||
case mysql::WRITE_ROWS_EVENT:
|
||||
case mysql::DELETE_ROWS_EVENT:
|
||||
case mysql::UPDATE_ROWS_EVENT:
|
||||
mysql::Row_event *rev= static_cast<mysql::Row_event *>(event);
|
||||
boost::uint64_t table_id= rev->table_id;
|
||||
// BUG: will create a new event header if the table id doesn't exist.
|
||||
Binary_log_event * tmevent= trans->table_map()[table_id];
|
||||
mysql::Table_map_event *tm;
|
||||
if (tmevent != NULL)
|
||||
tm= static_cast<mysql::Table_map_event *>(tmevent);
|
||||
else
|
||||
{
|
||||
std::cout << "Table id "
|
||||
<< table_id
|
||||
<< " was not registered by any preceding table map event."
|
||||
<< std::endl;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
Each row event contains multiple rows and fields. The Row_iterator
|
||||
allows us to iterate one row at a time.
|
||||
*/
|
||||
mysql::Row_event_set rows(rev, tm);
|
||||
/*
|
||||
Create a fuly qualified table name
|
||||
*/
|
||||
std::ostringstream os;
|
||||
os << tm->db_name << '.' << tm->table_name;
|
||||
mysql::Row_event_set::iterator it= rows.begin();
|
||||
do {
|
||||
mysql::Row_of_fields fields= *it;
|
||||
|
||||
if (event->get_event_type() == mysql::WRITE_ROWS_EVENT)
|
||||
table_insert(os.str(),fields);
|
||||
if (event->get_event_type() == mysql::UPDATE_ROWS_EVENT)
|
||||
{
|
||||
++it;
|
||||
mysql::Row_of_fields fields2= *it;
|
||||
table_update(os.str(),fields,fields2);
|
||||
}
|
||||
if (event->get_event_type() == mysql::DELETE_ROWS_EVENT)
|
||||
table_delete(os.str(),fields);
|
||||
} while (++it != rows.end());
|
||||
} // end switch
|
||||
} // end BOOST_FOREACH
|
||||
/* Consume the event */
|
||||
delete trans;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr,"Usage:\n\treplaybinlog URL\n\nExample:\n\treplaybinlog mysql://root:mypasswd@127.0.0.1:3306\n\n");
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
mysql::Binary_log binlog(mysql::system::create_transport(argv[1]));
|
||||
|
||||
|
||||
/*
|
||||
Attach a custom event parser which produces user defined events
|
||||
*/
|
||||
mysql::Basic_transaction_parser transaction_parser;
|
||||
Incident_handler incident_hndlr;
|
||||
Replay_binlog replay_hndlr;
|
||||
|
||||
binlog.content_handler_pipeline()->push_back(&transaction_parser);
|
||||
binlog.content_handler_pipeline()->push_back(&incident_hndlr);
|
||||
binlog.content_handler_pipeline()->push_back(&replay_hndlr);
|
||||
|
||||
if (binlog.connect())
|
||||
{
|
||||
fprintf(stderr,"Can't connect to the master.\n");
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (binlog.set_position(4) != ERR_OK)
|
||||
{
|
||||
fprintf(stderr,"Can't reposition the binary log reader.\n");
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
Binary_log_event *event;
|
||||
|
||||
bool quit= false;
|
||||
while(!quit)
|
||||
{
|
||||
/*
|
||||
Pull events from the master. This is the heart beat of the event listener.
|
||||
*/
|
||||
if (binlog.wait_for_next_event(&event))
|
||||
{
|
||||
quit= true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
Print the event
|
||||
*/
|
||||
std::cout << "Event type: "
|
||||
<< mysql::system::get_event_type_str(event->get_event_type())
|
||||
<< " length: " << event->header()->event_length
|
||||
<< " next pos: " << event->header()->next_position
|
||||
<< std::endl;
|
||||
|
||||
/*
|
||||
Perform a special action based on event type
|
||||
*/
|
||||
|
||||
switch(event->header()->type_code)
|
||||
{
|
||||
case mysql::QUERY_EVENT:
|
||||
{
|
||||
const mysql::Query_event *qev= static_cast<const mysql::Query_event *>(event);
|
||||
std::cout << "query= "
|
||||
<< qev->query
|
||||
<< " db= "
|
||||
<< qev->db_name
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
if (qev->query.find("DROP TABLE REPLICATION_LISTENER") != std::string::npos ||
|
||||
qev->query.find("DROP TABLE `REPLICATION_LISTENER`") != std::string::npos)
|
||||
{
|
||||
quit= true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case mysql::ROTATE_EVENT:
|
||||
{
|
||||
mysql::Rotate_event *rot= static_cast<mysql::Rotate_event *>(event);
|
||||
std::cout << "filename= "
|
||||
<< rot->binlog_file.c_str()
|
||||
<< " pos= "
|
||||
<< rot->binlog_pos
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
} // end switch
|
||||
delete event;
|
||||
} // end loop
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
BIN
replication_listener/tests/std-data/binlog_savepoint.000001
Normal file
BIN
replication_listener/tests/std-data/binlog_savepoint.000001
Normal file
Binary file not shown.
BIN
replication_listener/tests/std-data/binlog_transaction.000001
Normal file
BIN
replication_listener/tests/std-data/binlog_transaction.000001
Normal file
Binary file not shown.
BIN
replication_listener/tests/std-data/searchbin.000001
Normal file
BIN
replication_listener/tests/std-data/searchbin.000001
Normal file
Binary file not shown.
12
replication_listener/tests/t/binlog_file_reader.test
Normal file
12
replication_listener/tests/t/binlog_file_reader.test
Normal file
@ -0,0 +1,12 @@
|
||||
-- source include/not_embedded.inc
|
||||
let $REPLICATION_LISTENER="<path-to-replaybinlog>";
|
||||
let $SAMPLE_BINLOG_FILES_DIR="<path-to-std-data>";
|
||||
|
||||
--echo #
|
||||
--echo # Reading binlogs files.
|
||||
--echo #
|
||||
--exec $REPLICATION_LISTENER file://$SAMPLE_BINLOG_FILES_DIR/searchbin.000001
|
||||
--exec $REPLICATION_LISTENER file://$SAMPLE_BINLOG_FILES_DIR/binlog_transaction.000001
|
||||
--exec $REPLICATION_LISTENER file://$SAMPLE_BINLOG_FILES_DIR/binlog_savepoint.000001
|
||||
|
||||
--echo # End of test
|
@ -0,0 +1 @@
|
||||
--log_bin=searchbin --binlog_format=row
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user