1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-08 17:02:21 +03:00

WL#5151: Conversion between different types when replicating

Row-based replication requires the types of columns on the
master and slave to be approximately the same (some safe
conversions between strings are allowed), but does not
allow safe conversions between fields of similar types such
as TINYINT and INT.

This patch implement type conversions between similar fields
on the master and slave.

The conversions are controlled using a new variable
SLAVE_TYPE_CONVERSIONS of type SET('ALL_LOSSY','ALL_NON_LOSSY').

Non-lossy conversions are any conversions that do not run the
risk of losing any information, while lossy conversions can
potentially truncate the value. The column definitions are
checked to decide if the conversion is acceptable.

If neither conversion is enabled, it is required that the
definitions of the columns are identical on master and slave.

Conversion is done by creating an internal conversion table,
unpacking the master data into it, and then copy the data to
the real table on the slave.
This commit is contained in:
Mats Kindahl
2009-12-14 12:04:55 +01:00
parent c7a02cf807
commit c63df11f37
39 changed files with 2893 additions and 464 deletions

View File

@ -392,6 +392,7 @@ client/rpl_record_old.h
client/rpl_tblmap.h
client/rpl_tblmap.cc
client/rpl_utility.h
client/rpl_utility.cc
client/select_test
client/sql_string.cpp
client/ssl_test
@ -1142,6 +1143,7 @@ libmysqld/rpl_filter.cc
libmysqld/rpl_injector.cc
libmysqld/rpl_record.cc
libmysqld/rpl_record_old.cc
libmysqld/rpl_utility.cc
libmysqld/scheduler.cc
libmysqld/set_var.cc
libmysqld/simple-test

View File

@ -104,9 +104,10 @@ DEFS = -DMYSQL_CLIENT_NO_THREADS \
-DMYSQL_DATADIR="\"$(localstatedir)\""
sql_src=log_event.h mysql_priv.h rpl_constants.h \
rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
rpl_tblmap.h rpl_tblmap.cc \
log_event.cc my_decimal.h my_decimal.cc \
log_event_old.h log_event_old.cc \
rpl_utility.h rpl_utility.cc \
rpl_record_old.h rpl_record_old.cc
strings_src=decimal.c

View File

@ -2108,4 +2108,4 @@ int main(int argc, char** argv)
#include "my_decimal.cc"
#include "log_event.cc"
#include "log_event_old.cc"
#include "rpl_utility.cc"

View File

@ -55,7 +55,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
item_geofunc.cc item_subselect.cc item_row.cc\
item_xmlfunc.cc \
key.cc lock.cc log.cc sql_state.c \
log_event.cc rpl_record.cc \
log_event.cc rpl_record.cc rpl_utility.cc \
log_event_old.cc rpl_record_old.cc \
protocol.cc net_serv.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \

View File

@ -0,0 +1,52 @@
# Helper file to perform one insert of a value into a table with
# different types on master and slave. The file will insert the
# result into the type_conversions table *on the slave* to get a
# summary of failing and succeeding tests.
# Input:
# $source_type Type on the master
# $target_type Type on the slave
# $source_value Value on the master (inserted into the table)
# $target_value Value on the slave (expected value in the table
# on the slave)
# $can_convert True if conversion shall work, false if it
# shall generate an error
connection master;
disable_warnings;
DROP TABLE IF EXISTS t1;
enable_warnings;
eval CREATE TABLE t1 (a $source_type);
sync_slave_with_master;
eval ALTER TABLE t1 MODIFY a $target_type;
connection master;
eval INSERT INTO t1 VALUES($source_value);
if ($can_convert) {
sync_slave_with_master;
eval SELECT a = $target_value into @compare FROM t1;
eval INSERT INTO type_conversions SET
Source = "$source_type",
Target = "$target_type",
Flags = @@slave_type_conversions,
On_Master = $source_value,
Expected = $target_value,
Compare = @compare;
UPDATE type_conversions
SET On_Slave = (SELECT a FROM t1)
WHERE TestNo = LAST_INSERT_ID();
}
if (!$can_convert) {
connection slave;
wait_for_slave_to_stop;
let $error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
eval INSERT INTO type_conversions SET
Source = "$source_type",
Target = "$target_type",
Flags = @@slave_type_conversions,
On_Master = $source_value,
Error = "$error";
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;
}

View File

@ -36,6 +36,9 @@ sync_slave_with_master;
STOP SLAVE;
RESET SLAVE;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
eval CREATE TABLE t1 (a INT, b INT PRIMARY KEY, c CHAR(20),
d FLOAT DEFAULT '2.00',
e CHAR(4) DEFAULT 'TEST')
@ -62,6 +65,8 @@ SELECT * FROM t1 ORDER BY a;
sync_slave_with_master;
SELECT * FROM t1 ORDER BY a;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
--echo *** Drop t1 ***
connection master;
DROP TABLE t1;
@ -495,7 +500,7 @@ sync_slave_with_master;
--echo *** Create t11 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT,
eval CREATE TABLE t11 (a INT KEY, b BLOB, f INT,
c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE=$engine_type;
--echo *** Create t11 on Master ***

View File

@ -6,6 +6,7 @@
# First we test tables with only an index.
#
connection master;
eval CREATE TABLE t1 (C1 CHAR(1), C2 CHAR(1), INDEX (C1)$extra_index_t1) ENGINE = $type ;
SELECT * FROM t1;
sync_slave_with_master;
@ -156,6 +157,12 @@ SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5
# Testing special column types
#
if (`select char_length('$bit_field_special') > 0`) {
SET @saved_slave_type_conversions = @@SLAVE_TYPE_CONVERSIONS;
connection slave;
eval SET GLOBAL SLAVE_TYPE_CONVERSIONS = '$bit_field_special';
}
connection master;
eval CREATE TABLE t4 (C1 CHAR(1) PRIMARY KEY, B1 BIT(1), B2 BIT(1) NOT NULL DEFAULT 0, C2 CHAR(1) NOT NULL DEFAULT 'A') ENGINE = $type ;
@ -164,6 +171,10 @@ SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
sync_slave_with_master;
SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
if (`select char_length('$bit_field_special') > 0`) {
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
}
#
# Testing conflicting operations
#
@ -350,6 +361,10 @@ eval CREATE TABLE t7 (i INT NOT NULL,
c CHAR(255) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = $type ;
connection slave;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
--echo [expecting slave to replicate correctly]
connection master;
INSERT INTO t1 VALUES (1, "", 1);
@ -370,17 +385,9 @@ let $diff_table_1=master:test.t2;
let $diff_table_2=slave:test.t2;
source include/diff_tables.inc;
--echo [expecting slave to stop]
connection master;
INSERT INTO t3 VALUES (1, "", 1);
INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
connection master;
RESET MASTER;
connection slave;
@ -600,7 +607,15 @@ sync_slave_with_master;
connection master;
# Since t1 contain a bit field, we have to do this trick to handle InnoDB
if (`select char_length('$bit_field_special') > 0`) {
SET @saved_slave_type_conversions = @@SLAVE_TYPE_CONVERSIONS;
connection slave;
eval SET GLOBAL SLAVE_TYPE_CONVERSIONS = '$bit_field_special';
}
--disable_warnings
connection master;
eval CREATE TABLE t1 (a bit) ENGINE=$type;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
@ -645,6 +660,10 @@ UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
sync_slave_with_master;
if (`select char_length('$bit_field_special') > 0`) {
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
}
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;

View File

@ -0,0 +1,710 @@
# File containing different lossy and non-lossy type conversions.
# Integral conversion testing, we do not reduce the test using
# transitivity of conversions since the implementation is not using a
# transitivity strategy. Instead we do an exhaustive testing.
disable_query_log;
connection slave;
--let $conv = `select @@slave_type_conversions`
--echo **** Running tests with @@SLAVE_TYPE_CONVERSIONS = '$conv' ****
let $if_is_lossy = `SELECT FIND_IN_SET('ALL_LOSSY', @@SLAVE_TYPE_CONVERSIONS)`;
let $if_is_non_lossy = `SELECT FIND_IN_SET('ALL_NON_LOSSY', @@SLAVE_TYPE_CONVERSIONS)`;
let $source_type = BIT(1);
let $target_type = BIT(1);
let $source_value = b'1';
let $target_value = b'1';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type = DATE;
let $target_type = DATE;
let $source_value = '2009-11-21';
let $target_value = '2009-11-21';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type = ENUM('master','slave');
let $target_type = ENUM('master','slave');
let $source_value = 'master';
let $target_value = 'master';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type = CHAR(10);
let $target_type = ENUM('master','slave');
let $source_value = 'master';
let $target_value = 'master';
let $can_convert = 0;
source extra/rpl_tests/check_type.inc;
let $source_type = CHAR(10);
let $target_type = SET('master','slave');
let $source_value = 'master';
let $target_value = 'master';
let $can_convert = 0;
source extra/rpl_tests/check_type.inc;
let $source_type = ENUM('master','slave');
let $target_type = CHAR(10);
let $source_value = 'master';
let $target_value = 'master';
let $can_convert = 0;
source extra/rpl_tests/check_type.inc;
let $source_type = SET('master','slave');
let $target_type = CHAR(10);
let $source_value = 'master';
let $target_value = 'master';
let $can_convert = 0;
source extra/rpl_tests/check_type.inc;
let $source_type = SET('master','slave');
let $target_type = SET('master','slave');
let $source_value = '';
let $target_value = '';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type = SET('master','slave');
let $target_type = SET('master','slave');
let $source_value = 'master,slave';
let $target_value = 'master,slave';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type = TINYINT;
let $target_type = TINYINT;
let $source_value = 1;
let $target_value = 1;
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type = TINYINT;
let $target_type = SMALLINT;
let $source_value = 1;
let $target_value = 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TINYINT;
let $target_type= MEDIUMINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TINYINT;
let $target_type= INT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TINYINT;
let $target_type= BIGINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= SMALLINT;
let $target_type= TINYINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= SMALLINT;
let $target_type= TINYINT;
let $source_value= 1 << 9;
let $target_value= (1 << 7) - 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= SMALLINT;
let $target_type= TINYINT UNSIGNED;
let $source_value= 1 << 9;
let $target_value= (1 << 8) - 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= SMALLINT;
let $target_type= SMALLINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= SMALLINT;
let $target_type= MEDIUMINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= SMALLINT;
let $target_type= INT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= SMALLINT;
let $target_type= BIGINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMINT;
let $target_type= TINYINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMINT;
let $target_type= TINYINT;
let $source_value= 1 << 20;
let $target_value= (1 << 7) - 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMINT;
let $target_type= TINYINT UNSIGNED;
let $source_value= 1 << 20;
let $target_value= (1 << 8) - 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMINT;
let $target_type= SMALLINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMINT;
let $target_type= MEDIUMINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMINT;
let $target_type= INT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMINT;
let $target_type= BIGINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= INT;
let $target_type= TINYINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= INT;
let $target_type= TINYINT;
let $source_value= (1 << 30);
let $target_value= (1 << 7) - 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= INT;
let $target_type= TINYINT UNSIGNED;
let $source_value= (1 << 30);
let $target_value= (1 << 8) - 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= INT;
let $target_type= SMALLINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= INT;
let $target_type= MEDIUMINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= INT;
let $target_type= INT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= INT;
let $target_type= BIGINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIGINT;
let $target_type= TINYINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIGINT;
let $target_type= SMALLINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIGINT;
let $target_type= MEDIUMINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIGINT;
let $target_type= INT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIGINT;
let $target_type= BIGINT;
let $source_value= 1;
let $target_value= 1;
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= CHAR(20);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= CHAR(30);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= CHAR(10);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnood';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= VARCHAR(20);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= VARCHAR(30);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= VARCHAR(10);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnood';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= TINYTEXT;
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= TEXT;
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= MEDIUMTEXT;
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= CHAR(20);
let $target_type= LONGTEXT;
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= VARCHAR(20);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= VARCHAR(30);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= VARCHAR(10);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnood';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= CHAR(30);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= CHAR(10);
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnood';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= TINYTEXT;
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= TEXT;
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= MEDIUMTEXT;
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(20);
let $target_type= LONGTEXT;
let $source_value= 'Smoothnoodlemaps';
let $target_value= 'Smoothnoodlemaps';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $blob = `select repeat('abcd', 125)`;
let $truncated_blob = `select left('$blob', 255)`;
let $source_type= VARCHAR(500);
let $target_type= VARCHAR(500);
let $source_value= '$blob';
let $target_value= '$blob';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(500);
let $target_type= VARCHAR(510);
let $source_value= '$blob';
let $target_value= '$blob';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(500);
let $target_type= VARCHAR(255);
let $source_value= '$blob';
let $target_value= '$truncated_blob';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(500);
let $target_type= TINYTEXT;
let $source_value= '$blob';
let $target_value= '$truncated_blob';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(500);
let $target_type= TEXT;
let $source_value= '$blob';
let $target_value= '$blob';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(500);
let $target_type= MEDIUMTEXT;
let $source_value= '$blob';
let $target_value= '$blob';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= VARCHAR(500);
let $target_type= LONGTEXT;
let $source_value= '$blob';
let $target_value= '$blob';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $tiny_blob = `select repeat('tiny blob ', 25)`;
let $truncated_tiny_blob = `select left('$tiny_blob', 254)`;
let $source_type= TINYTEXT;
let $target_type= VARCHAR(500);
let $source_value= '$tiny_blob';
let $target_value= '$tiny_blob';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TEXT;
let $target_type= VARCHAR(500);
let $source_value= '$blob';
let $target_value= '$blob';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMTEXT;
let $target_type= VARCHAR(500);
let $source_value= '$blob';
let $target_value= '$blob';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= LONGTEXT;
let $target_type= VARCHAR(500);
let $source_value= '$blob';
let $target_value= '$blob';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TINYTEXT;
let $target_type= CHAR(255);
let $source_value= '$tiny_blob';
let $target_value= '$tiny_blob';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TINYTEXT;
let $target_type= CHAR(250);
let $source_value= '$tiny_blob';
let $target_value= left('$tiny_blob', 250);
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TEXT;
let $target_type= CHAR(255);
let $source_value= '$blob';
let $target_value= left('$blob', 255);
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= MEDIUMTEXT;
let $target_type= CHAR(255);
let $source_value= '$blob';
let $target_value= left('$blob', 255);
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= LONGTEXT;
let $target_type= CHAR(255);
let $source_value= '$blob';
let $target_value= left('$blob', 255);
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TINYTEXT;
let $target_type= TINYTEXT;
let $source_value= '$tiny_blob';
let $target_value= '$tiny_blob';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= TINYTEXT;
let $target_type= TEXT;
let $source_value= '$tiny_blob';
let $target_value= '$tiny_blob';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= TEXT;
let $target_type= TINYTEXT;
let $source_value= '$blob';
let $target_value= left('$blob',255);
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= DECIMAL(10,5);
let $source_value= 3.14159;
let $target_value= 3.14159;
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= DECIMAL(10,6);
let $source_value= 3.14159;
let $target_value= 3.141590;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= DECIMAL(11,5);
let $source_value= 3.14159;
let $target_value= 3.14159;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= DECIMAL(11,6);
let $source_value= 3.14159;
let $target_value= 3.141590;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= DECIMAL(10,4);
let $source_value= 3.14159;
let $target_value= 3.1416;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= DECIMAL(9,5);
let $source_value= 3.14159;
let $target_value= 3.14159;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= DECIMAL(9,4);
let $source_value= 3.14159;
let $target_value= 3.1416;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= FLOAT;
let $target_type= DECIMAL(10,5);
let $source_value= 3.15625;
let $target_value= 3.15625;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DOUBLE;
let $target_type= DECIMAL(10,5);
let $source_value= 3.15625;
let $target_value= 3.15625;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= FLOAT;
let $source_value= 3.15625;
let $target_value= 3.15625;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DECIMAL(10,5);
let $target_type= DOUBLE;
let $source_value= 3.15625;
let $target_value= 3.15625;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= FLOAT;
let $target_type= FLOAT;
let $source_value= 3.15625;
let $target_value= 3.15625;
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= DOUBLE;
let $target_type= DOUBLE;
let $source_value= 3.15625;
let $target_value= 3.15625;
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= FLOAT;
let $target_type= DOUBLE;
let $source_value= 3.15625;
let $target_value= 3.15625;
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= DOUBLE;
let $target_type= FLOAT;
let $source_value= 3.15625;
let $target_value= 3.15625;
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIT(5);
let $target_type= BIT(5);
let $source_value= b'11001';
let $target_value= b'11001';
let $can_convert = 1;
source extra/rpl_tests/check_type.inc;
let $source_type= BIT(5);
let $target_type= BIT(6);
let $source_value= b'11001';
let $target_value= b'11001';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIT(6);
let $target_type= BIT(5);
let $source_value= b'111001';
let $target_value= b'11111';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIT(5);
let $target_type= BIT(12);
let $source_value= b'11001';
let $target_value= b'11001';
let $can_convert = $if_is_non_lossy;
source extra/rpl_tests/check_type.inc;
let $source_type= BIT(12);
let $target_type= BIT(5);
let $source_value= b'101100111000';
let $target_value= b'11111';
let $can_convert = $if_is_lossy;
source extra/rpl_tests/check_type.inc;
disable_warnings;
source include/reset_master_and_slave.inc;
enable_warnings;
enable_query_log;

View File

@ -4,6 +4,8 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
CREATE DATABASE track;
USE track;
CREATE TABLE `visits` (
@ -65,5 +67,6 @@ visits_id myid src ip cc org ref time host entry visit_exit user_id visit_start
SELECT * FROM visits_events;
event_id visit_id timestamp src data visits_events_id
20000 21231038 2007-09-18 03:59:02 Downloads/MySQL-4.1/mysql-4.1.12a-win32.zip 33712207
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
DROP DATABASE track;
End of 5.1 tests

View File

@ -9,6 +9,8 @@ DROP TABLE IF EXISTS t1;
*** Create "wider" table on slave ***
STOP SLAVE;
RESET SLAVE;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
CREATE TABLE t1 (
a float (47),
b double (143,9),
@ -177,3 +179,4 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
*** Cleanup ***
DROP TABLE t1;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;

View File

@ -9,6 +9,8 @@ call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051");
*** On Slave ***
STOP SLAVE;
RESET SLAVE;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
CREATE TABLE t1 (a INT, b INT PRIMARY KEY, c CHAR(20),
d FLOAT DEFAULT '2.00',
e CHAR(4) DEFAULT 'TEST')
@ -32,6 +34,7 @@ a b c d e
1 2 TEXAS 2 TEST
2 1 AUSTIN 2 TEST
3 4 QA 2 TEST
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
*** Drop t1 ***
DROP TABLE t1;
*** Create t2 on slave ***
@ -73,8 +76,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 2 of table 'test.t2' cannot be converted from type 'char(10)' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -91,8 +94,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t2' cannot be converted from type 'char(10)' to type 'char(5)'
STOP SLAVE;
RESET SLAVE;
SELECT * FROM t2 ORDER BY a;
@ -140,8 +143,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3
Last_Errno 1641
Last_Error Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -158,8 +161,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t3 ***
@ -202,8 +205,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3
Last_Errno 1641
Last_Error Column 0 of table 'test.t4' cannot be converted from type 'decimal(8,2)' to type 'int(11)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -220,8 +223,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t4' cannot be converted from type 'decimal(8,2)' to type 'int(11)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t4 ***
@ -264,8 +267,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246
Last_Errno 1641
Last_Error Column 1 of table 'test.t5' cannot be converted from type 'varchar(6)' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -282,8 +285,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246
Last_SQL_Errno 1641
Last_SQL_Error Column 1 of table 'test.t5' cannot be converted from type 'varchar(6)' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t5 ***
@ -325,8 +328,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3
Last_Errno 1641
Last_Error Column 1 of table 'test.t6' cannot be converted from type 'varchar(6)' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -343,8 +346,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3
Last_SQL_Errno 1641
Last_SQL_Error Column 1 of table 'test.t6' cannot be converted from type 'varchar(6)' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=3;
*** Drop t6 ***
DROP TABLE t6;
@ -493,8 +496,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5
Last_Errno 1641
Last_Error Column 2 of table 'test.t10' cannot be converted from type 'char(5)' to type 'double'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -511,8 +514,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t10' cannot be converted from type 'char(5)' to type 'double'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t10 ***
@ -520,7 +523,7 @@ DROP TABLE t10;
*** Create t11 on slave ***
STOP SLAVE;
RESET SLAVE;
CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT,
CREATE TABLE t11 (a INT KEY, b BLOB, f INT,
c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='InnoDB';
*** Create t11 on Master ***
CREATE TABLE t11 (a INT PRIMARY KEY, b BLOB, c VARCHAR(254)
@ -554,8 +557,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252
Last_Errno 1641
Last_Error Column 2 of table 'test.t11' cannot be converted from type 'varchar(254)' to type 'int(11)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -572,8 +575,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t11' cannot be converted from type 'varchar(254)' to type 'int(11)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t11 ***
@ -944,8 +947,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2
Last_Errno 1641
Last_Error Column 0 of table 'test.t17' cannot be converted from type 'bigint' to type 'smallint(6)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -962,8 +965,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t17' cannot be converted from type 'bigint' to type 'smallint(6)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
** DROP table t17 ***

View File

@ -9,6 +9,8 @@ call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051");
*** On Slave ***
STOP SLAVE;
RESET SLAVE;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
CREATE TABLE t1 (a INT, b INT PRIMARY KEY, c CHAR(20),
d FLOAT DEFAULT '2.00',
e CHAR(4) DEFAULT 'TEST')
@ -32,6 +34,7 @@ a b c d e
1 2 TEXAS 2 TEST
2 1 AUSTIN 2 TEST
3 4 QA 2 TEST
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
*** Drop t1 ***
DROP TABLE t1;
*** Create t2 on slave ***
@ -73,8 +76,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 2 of table 'test.t2' cannot be converted from type 'char(10)' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -91,8 +94,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t2' cannot be converted from type 'char(10)' to type 'char(5)'
STOP SLAVE;
RESET SLAVE;
SELECT * FROM t2 ORDER BY a;
@ -140,8 +143,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3
Last_Errno 1641
Last_Error Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -158,8 +161,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 252, test.t3 has type 3
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t3 ***
@ -202,8 +205,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3
Last_Errno 1641
Last_Error Column 0 of table 'test.t4' cannot be converted from type 'decimal(8,2)' to type 'int(11)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -220,8 +223,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 246, test.t4 has type 3
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t4' cannot be converted from type 'decimal(8,2)' to type 'int(11)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t4 ***
@ -264,8 +267,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246
Last_Errno 1641
Last_Error Column 1 of table 'test.t5' cannot be converted from type 'varchar(6)' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -282,8 +285,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 5 type mismatch - received type 4, test.t5 has type 246
Last_SQL_Errno 1641
Last_SQL_Error Column 1 of table 'test.t5' cannot be converted from type 'varchar(6)' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t5 ***
@ -325,8 +328,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3
Last_Errno 1641
Last_Error Column 1 of table 'test.t6' cannot be converted from type 'varchar(6)' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -343,8 +346,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 3 type mismatch - received type 16, test.t6 has type 3
Last_SQL_Errno 1641
Last_SQL_Error Column 1 of table 'test.t6' cannot be converted from type 'varchar(6)' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=3;
*** Drop t6 ***
DROP TABLE t6;
@ -493,8 +496,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5
Last_Errno 1641
Last_Error Column 2 of table 'test.t10' cannot be converted from type 'char(5)' to type 'double'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -511,8 +514,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 254, test.t10 has type 5
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t10' cannot be converted from type 'char(5)' to type 'double'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t10 ***
@ -520,7 +523,7 @@ DROP TABLE t10;
*** Create t11 on slave ***
STOP SLAVE;
RESET SLAVE;
CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT,
CREATE TABLE t11 (a INT KEY, b BLOB, f INT,
c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE='MyISAM';
*** Create t11 on Master ***
CREATE TABLE t11 (a INT PRIMARY KEY, b BLOB, c VARCHAR(254)
@ -554,8 +557,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252
Last_Errno 1641
Last_Error Column 2 of table 'test.t11' cannot be converted from type 'varchar(254)' to type 'int(11)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -572,8 +575,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 15, test.t11 has type 252
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t11' cannot be converted from type 'varchar(254)' to type 'int(11)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Drop t11 ***
@ -944,8 +947,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2
Last_Errno 1641
Last_Error Column 0 of table 'test.t17' cannot be converted from type 'bigint' to type 'smallint(6)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -962,8 +965,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 8, test.t17 has type 2
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t17' cannot be converted from type 'bigint' to type 'smallint(6)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
** DROP table t17 ***

View File

@ -563,8 +563,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_Errno 1641
Last_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -581,8 +581,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -638,8 +638,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_Errno 1641
Last_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -656,8 +656,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -1704,8 +1704,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_Errno 1641
Last_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -1722,8 +1722,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -1779,8 +1779,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_Errno 1641
Last_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -1797,8 +1797,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -2845,8 +2845,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_Errno 1641
Last_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -2863,8 +2863,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -2920,8 +2920,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_Errno 1641
Last_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -2938,8 +2938,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;

View File

@ -563,8 +563,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_Errno 1641
Last_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -581,8 +581,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -638,8 +638,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_Errno 1641
Last_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -656,8 +656,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -1704,8 +1704,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_Errno 1641
Last_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -1722,8 +1722,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -1779,8 +1779,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_Errno 1641
Last_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -1797,8 +1797,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -2845,8 +2845,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_Errno 1641
Last_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -2863,8 +2863,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 5, test.t10 has type 254
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -2920,8 +2920,8 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_Errno 1641
Last_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -2938,8 +2938,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 252, test.t11 has type 15
Last_SQL_Errno 1641
Last_SQL_Error Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;

View File

@ -476,6 +476,8 @@ ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
CREATE TABLE t7 (i INT NOT NULL,
c CHAR(255) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = 'MYISAM' ;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
[expecting slave to replicate correctly]
INSERT INTO t1 VALUES (1, "", 1);
INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2);
@ -484,11 +486,7 @@ Comparing tables master:test.t1 and slave:test.t1
INSERT INTO t2 VALUES (1, "", 1);
INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2);
Comparing tables master:test.t2 and slave:test.t2
[expecting slave to stop]
INSERT INTO t3 VALUES (1, "", 1);
INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
Last_SQL_Error
Table definition on master and slave does not match: Column 1 size mismatch - master has size 384, test.t3 on slave has size 49. Master's column size should be <= the slave's column size.
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
RESET MASTER;
STOP SLAVE;
RESET SLAVE;
@ -501,7 +499,7 @@ Comparing tables master:test.t4 and slave:test.t4
INSERT INTO t5 VALUES (1, "", 1);
INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2);
Last_SQL_Error
Table definition on master and slave does not match: Column 1 size mismatch - master has size 765, test.t5 on slave has size 49. Master's column size should be <= the slave's column size.
Column 1 of table 'test.t5' cannot be converted from type 'char(255)' to type 'char(16)'
RESET MASTER;
STOP SLAVE;
RESET SLAVE;
@ -510,7 +508,7 @@ START SLAVE;
INSERT INTO t6 VALUES (1, "", 1);
INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2);
Last_SQL_Error
Table definition on master and slave does not match: Column 1 size mismatch - master has size 765, test.t6 on slave has size 385. Master's column size should be <= the slave's column size.
Column 1 of table 'test.t6' cannot be converted from type 'char(255)' to type 'char(128)'
RESET MASTER;
STOP SLAVE;
RESET SLAVE;

View File

@ -354,6 +354,8 @@ X Q 5 7 R 49 X Y 2 S 1
X Q 5 7 R 49 X Z 2 S 2
X Q 5 9 R 81 X Y 2 S 1
X Q 5 9 R 81 X Z 2 S 2
SET @saved_slave_type_conversions = @@SLAVE_TYPE_CONVERSIONS;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_LOSSY';
CREATE TABLE t4 (C1 CHAR(1) PRIMARY KEY, B1 BIT(1), B2 BIT(1) NOT NULL DEFAULT 0, C2 CHAR(1) NOT NULL DEFAULT 'A') ENGINE = 'INNODB' ;
INSERT INTO t4 SET C1 = 1;
SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
@ -362,6 +364,7 @@ C1 HEX(B1) HEX(B2)
SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
C1 HEX(B1) HEX(B2)
1 NULL 0
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
CREATE TABLE t7 (C1 INT PRIMARY KEY, C2 INT) ENGINE = 'INNODB' ;
--- on slave: original values ---
INSERT INTO t7 VALUES (1,3), (2,6), (3,9);
@ -476,6 +479,8 @@ ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
CREATE TABLE t7 (i INT NOT NULL,
c CHAR(255) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = 'INNODB' ;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
[expecting slave to replicate correctly]
INSERT INTO t1 VALUES (1, "", 1);
INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2);
@ -484,11 +489,7 @@ Comparing tables master:test.t1 and slave:test.t1
INSERT INTO t2 VALUES (1, "", 1);
INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2);
Comparing tables master:test.t2 and slave:test.t2
[expecting slave to stop]
INSERT INTO t3 VALUES (1, "", 1);
INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
Last_SQL_Error
Table definition on master and slave does not match: Column 1 size mismatch - master has size 384, test.t3 on slave has size 49. Master's column size should be <= the slave's column size.
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
RESET MASTER;
STOP SLAVE;
RESET SLAVE;
@ -501,7 +502,7 @@ Comparing tables master:test.t4 and slave:test.t4
INSERT INTO t5 VALUES (1, "", 1);
INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2);
Last_SQL_Error
Table definition on master and slave does not match: Column 1 size mismatch - master has size 765, test.t5 on slave has size 49. Master's column size should be <= the slave's column size.
Column 1 of table 'test.t5' cannot be converted from type 'char(255)' to type 'char(16)'
RESET MASTER;
STOP SLAVE;
RESET SLAVE;
@ -510,7 +511,7 @@ START SLAVE;
INSERT INTO t6 VALUES (1, "", 1);
INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2);
Last_SQL_Error
Table definition on master and slave does not match: Column 1 size mismatch - master has size 765, test.t6 on slave has size 385. Master's column size should be <= the slave's column size.
Column 1 of table 'test.t6' cannot be converted from type 'char(255)' to type 'char(128)'
RESET MASTER;
STOP SLAVE;
RESET SLAVE;
@ -597,6 +598,8 @@ UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
SET @saved_slave_type_conversions = @@SLAVE_TYPE_CONVERSIONS;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_LOSSY';
CREATE TABLE t1 (a bit) ENGINE='INNODB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
@ -637,5 +640,6 @@ DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;

View File

@ -37,8 +37,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 10, test.t1 on slave has size 3. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'decimal(20,10)' to type 'decimal(5,2)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -55,8 +55,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 10, test.t1 on slave has size 3. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'decimal(20,10)' to type 'decimal(5,2)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -91,8 +91,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 12, test.t1 on slave has size 12. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'decimal(27,18)' to type 'decimal(27,9)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -109,8 +109,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 12, test.t1 on slave has size 12. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'decimal(27,18)' to type 'decimal(27,9)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -145,8 +145,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 10, test.t1 on slave has size 3. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'decimal(20,10)' to type 'decimal(5,2)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -163,8 +163,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 10, test.t1 on slave has size 3. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'decimal(20,10)' to type 'decimal(5,2)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -200,8 +200,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 5, test.t1 has type 4
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'double' to type 'float'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -218,8 +218,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 5, test.t1 has type 4
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'double' to type 'float'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -255,8 +255,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 8, test.t1 on slave has size 1. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'bit(8)' to type 'bit(5)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -273,8 +273,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 8, test.t1 on slave has size 1. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'bit(8)' to type 'bit(5)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -309,8 +309,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 2. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'bit(5)' to type 'bit(11)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -327,8 +327,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 2. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'bit(5)' to type 'bit(11)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -364,8 +364,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 1. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'set' to type 'set('4')'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -382,8 +382,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 1. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'set' to type 'set('4')'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -419,8 +419,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 20, test.t1 on slave has size 11. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'char(20)' to type 'char(10)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -437,8 +437,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 20, test.t1 on slave has size 11. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'char(20)' to type 'char(10)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -505,8 +505,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 1. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'enum' to type 'enum('44','54')'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -523,8 +523,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 1. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'enum' to type 'enum('44','54')'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -560,8 +560,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2000, test.t1 on slave has size 100. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'varchar(2000)' to type 'varchar(100)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -578,8 +578,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2000, test.t1 on slave has size 100. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'varchar(2000)' to type 'varchar(100)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -614,8 +614,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 200, test.t1 on slave has size 10. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'varchar(200)' to type 'varchar(10)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -632,8 +632,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 200, test.t1 on slave has size 10. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'varchar(200)' to type 'varchar(10)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -668,8 +668,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2000, test.t1 on slave has size 1000. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'varchar(2000)' to type 'varchar(1000)'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -686,8 +686,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2000, test.t1 on slave has size 1000. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'varchar(2000)' to type 'varchar(1000)'
SELECT COUNT(*) FROM t1;
COUNT(*)
0
@ -723,8 +723,8 @@ Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 4, test.t1 on slave has size 1. Master's column size should be <= the slave's column size.
Last_Errno 1641
Last_Error Column 0 of table 'test.t1' cannot be converted from type 'tinyblob' to type 'tinyblob'
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@ -741,8 +741,8 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1535
Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 4, test.t1 on slave has size 1. Master's column size should be <= the slave's column size.
Last_SQL_Errno 1641
Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'tinyblob' to type 'tinyblob'
SELECT COUNT(*) FROM t1;
COUNT(*)
0

View File

@ -216,7 +216,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Errno 1641
Last_Error <Last_Error>
Skip_Counter 0
Exec_Master_Log_Pos #
@ -234,7 +234,7 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno <Last_IO_Errno>
Last_IO_Error <Last_IO_Error>
Last_SQL_Errno 1535
Last_SQL_Errno 1641
Last_SQL_Error <Last_SQL_Error>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -259,7 +259,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Errno 1641
Last_Error <Last_Error>
Skip_Counter 0
Exec_Master_Log_Pos #
@ -277,7 +277,7 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno <Last_IO_Errno>
Last_IO_Error <Last_IO_Error>
Last_SQL_Errno 1535
Last_SQL_Errno 1641
Last_SQL_Error <Last_SQL_Error>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -302,7 +302,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Errno 1641
Last_Error <Last_Error>
Skip_Counter 0
Exec_Master_Log_Pos #
@ -320,7 +320,7 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno <Last_IO_Errno>
Last_IO_Error <Last_IO_Error>
Last_SQL_Errno 1535
Last_SQL_Errno 1641
Last_SQL_Error <Last_SQL_Error>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;

View File

@ -216,7 +216,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Errno 1641
Last_Error <Last_Error>
Skip_Counter 0
Exec_Master_Log_Pos #
@ -234,7 +234,7 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno <Last_IO_Errno>
Last_IO_Error <Last_IO_Error>
Last_SQL_Errno 1535
Last_SQL_Errno 1641
Last_SQL_Error <Last_SQL_Error>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -259,7 +259,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Errno 1641
Last_Error <Last_Error>
Skip_Counter 0
Exec_Master_Log_Pos #
@ -277,7 +277,7 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno <Last_IO_Errno>
Last_IO_Error <Last_IO_Error>
Last_SQL_Errno 1535
Last_SQL_Errno 1641
Last_SQL_Error <Last_SQL_Error>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
@ -302,7 +302,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1535
Last_Errno 1641
Last_Error <Last_Error>
Skip_Counter 0
Exec_Master_Log_Pos #
@ -320,7 +320,7 @@ Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno <Last_IO_Errno>
Last_IO_Error <Last_IO_Error>
Last_SQL_Errno 1535
Last_SQL_Errno 1641
Last_SQL_Error <Last_SQL_Error>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;

View File

@ -0,0 +1,466 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set @saved_slave_type_conversions = @@global.slave_type_conversions;
CREATE TABLE type_conversions (
TestNo INT AUTO_INCREMENT PRIMARY KEY,
Source TEXT,
Target TEXT,
Flags TEXT,
On_Master TEXT,
On_Slave TEXT,
Expected TEXT,
Compare INT,
Error TEXT);
SELECT @@global.slave_type_conversions;
@@global.slave_type_conversions
SET GLOBAL SLAVE_TYPE_CONVERSIONS='';
SELECT @@global.slave_type_conversions;
@@global.slave_type_conversions
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY';
SELECT @@global.slave_type_conversions;
@@global.slave_type_conversions
ALL_NON_LOSSY
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY';
SELECT @@global.slave_type_conversions;
@@global.slave_type_conversions
ALL_LOSSY
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY';
SELECT @@global.slave_type_conversions;
@@global.slave_type_conversions
ALL_LOSSY,ALL_NON_LOSSY
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY,NONEXISTING_BIT';
ERROR 42000: Variable 'slave_type_conversions' can't be set to the value of 'NONEXISTING_BIT'
SELECT @@global.slave_type_conversions;
@@global.slave_type_conversions
ALL_LOSSY,ALL_NON_LOSSY
SET GLOBAL SLAVE_TYPE_CONVERSIONS='';
**** Running tests with @@SLAVE_TYPE_CONVERSIONS = '' ****
**** Resetting master and slave ****
include/stop_slave.inc
RESET SLAVE;
RESET MASTER;
include/start_slave.inc
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY';
**** Running tests with @@SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY' ****
**** Resetting master and slave ****
include/stop_slave.inc
RESET SLAVE;
RESET MASTER;
include/start_slave.inc
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY';
**** Running tests with @@SLAVE_TYPE_CONVERSIONS = 'ALL_LOSSY' ****
**** Resetting master and slave ****
include/stop_slave.inc
RESET SLAVE;
RESET MASTER;
include/start_slave.inc
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY';
**** Running tests with @@SLAVE_TYPE_CONVERSIONS = 'ALL_LOSSY,ALL_NON_LOSSY' ****
**** Resetting master and slave ****
include/stop_slave.inc
RESET SLAVE;
RESET MASTER;
include/start_slave.inc
**** Result of conversions ****
Source_Type Target_Type All_Type_Conversion_Flags Value_On_Slave
BIT(1) BIT(1) <Correct value>
DATE DATE <Correct value>
ENUM('master',' ENUM('master',' <Correct value>
CHAR(10) ENUM('master',' <Correct error>
CHAR(10) SET('master','s <Correct error>
ENUM('master',' CHAR(10) <Correct error>
SET('master','s CHAR(10) <Correct error>
SET('master','s SET('master','s <Correct value>
SET('master','s SET('master','s <Correct value>
TINYINT TINYINT <Correct value>
TINYINT SMALLINT <Correct error>
TINYINT MEDIUMINT <Correct error>
TINYINT INT <Correct error>
TINYINT BIGINT <Correct error>
SMALLINT TINYINT <Correct error>
SMALLINT TINYINT <Correct error>
SMALLINT TINYINT UNSIGNE <Correct error>
SMALLINT SMALLINT <Correct value>
SMALLINT MEDIUMINT <Correct error>
SMALLINT INT <Correct error>
SMALLINT BIGINT <Correct error>
MEDIUMINT TINYINT <Correct error>
MEDIUMINT TINYINT <Correct error>
MEDIUMINT TINYINT UNSIGNE <Correct error>
MEDIUMINT SMALLINT <Correct error>
MEDIUMINT MEDIUMINT <Correct value>
MEDIUMINT INT <Correct error>
MEDIUMINT BIGINT <Correct error>
INT TINYINT <Correct error>
INT TINYINT <Correct error>
INT TINYINT UNSIGNE <Correct error>
INT SMALLINT <Correct error>
INT MEDIUMINT <Correct error>
INT INT <Correct value>
INT BIGINT <Correct error>
BIGINT TINYINT <Correct error>
BIGINT SMALLINT <Correct error>
BIGINT MEDIUMINT <Correct error>
BIGINT INT <Correct error>
BIGINT BIGINT <Correct value>
CHAR(20) CHAR(20) <Correct value>
CHAR(20) CHAR(30) <Correct error>
CHAR(20) CHAR(10) <Correct error>
CHAR(20) VARCHAR(20) <Correct error>
CHAR(20) VARCHAR(30) <Correct error>
CHAR(20) VARCHAR(10) <Correct error>
CHAR(20) TINYTEXT <Correct error>
CHAR(20) TEXT <Correct error>
CHAR(20) MEDIUMTEXT <Correct error>
CHAR(20) LONGTEXT <Correct error>
VARCHAR(20) VARCHAR(20) <Correct value>
VARCHAR(20) VARCHAR(30) <Correct error>
VARCHAR(20) VARCHAR(10) <Correct error>
VARCHAR(20) CHAR(30) <Correct error>
VARCHAR(20) CHAR(10) <Correct error>
VARCHAR(20) TINYTEXT <Correct error>
VARCHAR(20) TEXT <Correct error>
VARCHAR(20) MEDIUMTEXT <Correct error>
VARCHAR(20) LONGTEXT <Correct error>
VARCHAR(500) VARCHAR(500) <Correct value>
VARCHAR(500) VARCHAR(510) <Correct error>
VARCHAR(500) VARCHAR(255) <Correct error>
VARCHAR(500) TINYTEXT <Correct error>
VARCHAR(500) TEXT <Correct error>
VARCHAR(500) MEDIUMTEXT <Correct error>
VARCHAR(500) LONGTEXT <Correct error>
TINYTEXT VARCHAR(500) <Correct error>
TEXT VARCHAR(500) <Correct error>
MEDIUMTEXT VARCHAR(500) <Correct error>
LONGTEXT VARCHAR(500) <Correct error>
TINYTEXT CHAR(255) <Correct error>
TINYTEXT CHAR(250) <Correct error>
TEXT CHAR(255) <Correct error>
MEDIUMTEXT CHAR(255) <Correct error>
LONGTEXT CHAR(255) <Correct error>
TINYTEXT TINYTEXT <Correct value>
TINYTEXT TEXT <Correct error>
TEXT TINYTEXT <Correct error>
DECIMAL(10,5) DECIMAL(10,5) <Correct value>
DECIMAL(10,5) DECIMAL(10,6) <Correct error>
DECIMAL(10,5) DECIMAL(11,5) <Correct error>
DECIMAL(10,5) DECIMAL(11,6) <Correct error>
DECIMAL(10,5) DECIMAL(10,4) <Correct error>
DECIMAL(10,5) DECIMAL(9,5) <Correct error>
DECIMAL(10,5) DECIMAL(9,4) <Correct error>
FLOAT DECIMAL(10,5) <Correct error>
DOUBLE DECIMAL(10,5) <Correct error>
DECIMAL(10,5) FLOAT <Correct error>
DECIMAL(10,5) DOUBLE <Correct error>
FLOAT FLOAT <Correct value>
DOUBLE DOUBLE <Correct value>
FLOAT DOUBLE <Correct error>
DOUBLE FLOAT <Correct error>
BIT(5) BIT(5) <Correct value>
BIT(5) BIT(6) <Correct error>
BIT(6) BIT(5) <Correct error>
BIT(5) BIT(12) <Correct error>
BIT(12) BIT(5) <Correct error>
BIT(1) BIT(1) ALL_NON_LOSSY <Correct value>
DATE DATE ALL_NON_LOSSY <Correct value>
ENUM('master',' ENUM('master',' ALL_NON_LOSSY <Correct value>
CHAR(10) ENUM('master',' ALL_NON_LOSSY <Correct error>
CHAR(10) SET('master','s ALL_NON_LOSSY <Correct error>
ENUM('master',' CHAR(10) ALL_NON_LOSSY <Correct error>
SET('master','s CHAR(10) ALL_NON_LOSSY <Correct error>
SET('master','s SET('master','s ALL_NON_LOSSY <Correct value>
SET('master','s SET('master','s ALL_NON_LOSSY <Correct value>
TINYINT TINYINT ALL_NON_LOSSY <Correct value>
TINYINT SMALLINT ALL_NON_LOSSY <Correct value>
TINYINT MEDIUMINT ALL_NON_LOSSY <Correct value>
TINYINT INT ALL_NON_LOSSY <Correct value>
TINYINT BIGINT ALL_NON_LOSSY <Correct value>
SMALLINT TINYINT ALL_NON_LOSSY <Correct error>
SMALLINT TINYINT ALL_NON_LOSSY <Correct error>
SMALLINT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error>
SMALLINT SMALLINT ALL_NON_LOSSY <Correct value>
SMALLINT MEDIUMINT ALL_NON_LOSSY <Correct value>
SMALLINT INT ALL_NON_LOSSY <Correct value>
SMALLINT BIGINT ALL_NON_LOSSY <Correct value>
MEDIUMINT TINYINT ALL_NON_LOSSY <Correct error>
MEDIUMINT TINYINT ALL_NON_LOSSY <Correct error>
MEDIUMINT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error>
MEDIUMINT SMALLINT ALL_NON_LOSSY <Correct error>
MEDIUMINT MEDIUMINT ALL_NON_LOSSY <Correct value>
MEDIUMINT INT ALL_NON_LOSSY <Correct value>
MEDIUMINT BIGINT ALL_NON_LOSSY <Correct value>
INT TINYINT ALL_NON_LOSSY <Correct error>
INT TINYINT ALL_NON_LOSSY <Correct error>
INT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error>
INT SMALLINT ALL_NON_LOSSY <Correct error>
INT MEDIUMINT ALL_NON_LOSSY <Correct error>
INT INT ALL_NON_LOSSY <Correct value>
INT BIGINT ALL_NON_LOSSY <Correct value>
BIGINT TINYINT ALL_NON_LOSSY <Correct error>
BIGINT SMALLINT ALL_NON_LOSSY <Correct error>
BIGINT MEDIUMINT ALL_NON_LOSSY <Correct error>
BIGINT INT ALL_NON_LOSSY <Correct error>
BIGINT BIGINT ALL_NON_LOSSY <Correct value>
CHAR(20) CHAR(20) ALL_NON_LOSSY <Correct value>
CHAR(20) CHAR(30) ALL_NON_LOSSY <Correct value>
CHAR(20) CHAR(10) ALL_NON_LOSSY <Correct error>
CHAR(20) VARCHAR(20) ALL_NON_LOSSY <Correct value>
CHAR(20) VARCHAR(30) ALL_NON_LOSSY <Correct value>
CHAR(20) VARCHAR(10) ALL_NON_LOSSY <Correct error>
CHAR(20) TINYTEXT ALL_NON_LOSSY <Correct value>
CHAR(20) TEXT ALL_NON_LOSSY <Correct value>
CHAR(20) MEDIUMTEXT ALL_NON_LOSSY <Correct value>
CHAR(20) LONGTEXT ALL_NON_LOSSY <Correct value>
VARCHAR(20) VARCHAR(20) ALL_NON_LOSSY <Correct value>
VARCHAR(20) VARCHAR(30) ALL_NON_LOSSY <Correct value>
VARCHAR(20) VARCHAR(10) ALL_NON_LOSSY <Correct error>
VARCHAR(20) CHAR(30) ALL_NON_LOSSY <Correct value>
VARCHAR(20) CHAR(10) ALL_NON_LOSSY <Correct error>
VARCHAR(20) TINYTEXT ALL_NON_LOSSY <Correct value>
VARCHAR(20) TEXT ALL_NON_LOSSY <Correct value>
VARCHAR(20) MEDIUMTEXT ALL_NON_LOSSY <Correct value>
VARCHAR(20) LONGTEXT ALL_NON_LOSSY <Correct value>
VARCHAR(500) VARCHAR(500) ALL_NON_LOSSY <Correct value>
VARCHAR(500) VARCHAR(510) ALL_NON_LOSSY <Correct value>
VARCHAR(500) VARCHAR(255) ALL_NON_LOSSY <Correct error>
VARCHAR(500) TINYTEXT ALL_NON_LOSSY <Correct error>
VARCHAR(500) TEXT ALL_NON_LOSSY <Correct value>
VARCHAR(500) MEDIUMTEXT ALL_NON_LOSSY <Correct value>
VARCHAR(500) LONGTEXT ALL_NON_LOSSY <Correct value>
TINYTEXT VARCHAR(500) ALL_NON_LOSSY <Correct value>
TEXT VARCHAR(500) ALL_NON_LOSSY <Correct error>
MEDIUMTEXT VARCHAR(500) ALL_NON_LOSSY <Correct error>
LONGTEXT VARCHAR(500) ALL_NON_LOSSY <Correct error>
TINYTEXT CHAR(255) ALL_NON_LOSSY <Correct value>
TINYTEXT CHAR(250) ALL_NON_LOSSY <Correct error>
TEXT CHAR(255) ALL_NON_LOSSY <Correct error>
MEDIUMTEXT CHAR(255) ALL_NON_LOSSY <Correct error>
LONGTEXT CHAR(255) ALL_NON_LOSSY <Correct error>
TINYTEXT TINYTEXT ALL_NON_LOSSY <Correct value>
TINYTEXT TEXT ALL_NON_LOSSY <Correct value>
TEXT TINYTEXT ALL_NON_LOSSY <Correct error>
DECIMAL(10,5) DECIMAL(10,5) ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(10,6) ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(11,5) ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(11,6) ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(10,4) ALL_NON_LOSSY <Correct error>
DECIMAL(10,5) DECIMAL(9,5) ALL_NON_LOSSY <Correct error>
DECIMAL(10,5) DECIMAL(9,4) ALL_NON_LOSSY <Correct error>
FLOAT DECIMAL(10,5) ALL_NON_LOSSY <Correct error>
DOUBLE DECIMAL(10,5) ALL_NON_LOSSY <Correct error>
DECIMAL(10,5) FLOAT ALL_NON_LOSSY <Correct error>
DECIMAL(10,5) DOUBLE ALL_NON_LOSSY <Correct error>
FLOAT FLOAT ALL_NON_LOSSY <Correct value>
DOUBLE DOUBLE ALL_NON_LOSSY <Correct value>
FLOAT DOUBLE ALL_NON_LOSSY <Correct value>
DOUBLE FLOAT ALL_NON_LOSSY <Correct error>
BIT(5) BIT(5) ALL_NON_LOSSY <Correct value>
BIT(5) BIT(6) ALL_NON_LOSSY <Correct value>
BIT(6) BIT(5) ALL_NON_LOSSY <Correct error>
BIT(5) BIT(12) ALL_NON_LOSSY <Correct value>
BIT(12) BIT(5) ALL_NON_LOSSY <Correct error>
BIT(1) BIT(1) ALL_LOSSY <Correct value>
DATE DATE ALL_LOSSY <Correct value>
ENUM('master',' ENUM('master',' ALL_LOSSY <Correct value>
CHAR(10) ENUM('master',' ALL_LOSSY <Correct error>
CHAR(10) SET('master','s ALL_LOSSY <Correct error>
ENUM('master',' CHAR(10) ALL_LOSSY <Correct error>
SET('master','s CHAR(10) ALL_LOSSY <Correct error>
SET('master','s SET('master','s ALL_LOSSY <Correct value>
SET('master','s SET('master','s ALL_LOSSY <Correct value>
TINYINT TINYINT ALL_LOSSY <Correct value>
TINYINT SMALLINT ALL_LOSSY <Correct error>
TINYINT MEDIUMINT ALL_LOSSY <Correct error>
TINYINT INT ALL_LOSSY <Correct error>
TINYINT BIGINT ALL_LOSSY <Correct error>
SMALLINT TINYINT ALL_LOSSY <Correct value>
SMALLINT TINYINT ALL_LOSSY <Correct value>
SMALLINT TINYINT UNSIGNE ALL_LOSSY <Correct value>
SMALLINT SMALLINT ALL_LOSSY <Correct value>
SMALLINT MEDIUMINT ALL_LOSSY <Correct error>
SMALLINT INT ALL_LOSSY <Correct error>
SMALLINT BIGINT ALL_LOSSY <Correct error>
MEDIUMINT TINYINT ALL_LOSSY <Correct value>
MEDIUMINT TINYINT ALL_LOSSY <Correct value>
MEDIUMINT TINYINT UNSIGNE ALL_LOSSY <Correct value>
MEDIUMINT SMALLINT ALL_LOSSY <Correct value>
MEDIUMINT MEDIUMINT ALL_LOSSY <Correct value>
MEDIUMINT INT ALL_LOSSY <Correct error>
MEDIUMINT BIGINT ALL_LOSSY <Correct error>
INT TINYINT ALL_LOSSY <Correct value>
INT TINYINT ALL_LOSSY <Correct value>
INT TINYINT UNSIGNE ALL_LOSSY <Correct value>
INT SMALLINT ALL_LOSSY <Correct value>
INT MEDIUMINT ALL_LOSSY <Correct value>
INT INT ALL_LOSSY <Correct value>
INT BIGINT ALL_LOSSY <Correct error>
BIGINT TINYINT ALL_LOSSY <Correct value>
BIGINT SMALLINT ALL_LOSSY <Correct value>
BIGINT MEDIUMINT ALL_LOSSY <Correct value>
BIGINT INT ALL_LOSSY <Correct value>
BIGINT BIGINT ALL_LOSSY <Correct value>
CHAR(20) CHAR(20) ALL_LOSSY <Correct value>
CHAR(20) CHAR(30) ALL_LOSSY <Correct error>
CHAR(20) CHAR(10) ALL_LOSSY <Correct value>
CHAR(20) VARCHAR(20) ALL_LOSSY <Correct error>
CHAR(20) VARCHAR(30) ALL_LOSSY <Correct error>
CHAR(20) VARCHAR(10) ALL_LOSSY <Correct value>
CHAR(20) TINYTEXT ALL_LOSSY <Correct error>
CHAR(20) TEXT ALL_LOSSY <Correct error>
CHAR(20) MEDIUMTEXT ALL_LOSSY <Correct error>
CHAR(20) LONGTEXT ALL_LOSSY <Correct error>
VARCHAR(20) VARCHAR(20) ALL_LOSSY <Correct value>
VARCHAR(20) VARCHAR(30) ALL_LOSSY <Correct error>
VARCHAR(20) VARCHAR(10) ALL_LOSSY <Correct value>
VARCHAR(20) CHAR(30) ALL_LOSSY <Correct error>
VARCHAR(20) CHAR(10) ALL_LOSSY <Correct value>
VARCHAR(20) TINYTEXT ALL_LOSSY <Correct error>
VARCHAR(20) TEXT ALL_LOSSY <Correct error>
VARCHAR(20) MEDIUMTEXT ALL_LOSSY <Correct error>
VARCHAR(20) LONGTEXT ALL_LOSSY <Correct error>
VARCHAR(500) VARCHAR(500) ALL_LOSSY <Correct value>
VARCHAR(500) VARCHAR(510) ALL_LOSSY <Correct error>
VARCHAR(500) VARCHAR(255) ALL_LOSSY <Correct value>
VARCHAR(500) TINYTEXT ALL_LOSSY <Correct value>
VARCHAR(500) TEXT ALL_LOSSY <Correct error>
VARCHAR(500) MEDIUMTEXT ALL_LOSSY <Correct error>
VARCHAR(500) LONGTEXT ALL_LOSSY <Correct error>
TINYTEXT VARCHAR(500) ALL_LOSSY <Correct error>
TEXT VARCHAR(500) ALL_LOSSY <Correct value>
MEDIUMTEXT VARCHAR(500) ALL_LOSSY <Correct value>
LONGTEXT VARCHAR(500) ALL_LOSSY <Correct value>
TINYTEXT CHAR(255) ALL_LOSSY <Correct error>
TINYTEXT CHAR(250) ALL_LOSSY <Correct value>
TEXT CHAR(255) ALL_LOSSY <Correct value>
MEDIUMTEXT CHAR(255) ALL_LOSSY <Correct value>
LONGTEXT CHAR(255) ALL_LOSSY <Correct value>
TINYTEXT TINYTEXT ALL_LOSSY <Correct value>
TINYTEXT TEXT ALL_LOSSY <Correct error>
TEXT TINYTEXT ALL_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(10,5) ALL_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(10,6) ALL_LOSSY <Correct error>
DECIMAL(10,5) DECIMAL(11,5) ALL_LOSSY <Correct error>
DECIMAL(10,5) DECIMAL(11,6) ALL_LOSSY <Correct error>
DECIMAL(10,5) DECIMAL(10,4) ALL_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(9,5) ALL_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(9,4) ALL_LOSSY <Correct value>
FLOAT DECIMAL(10,5) ALL_LOSSY <Correct value>
DOUBLE DECIMAL(10,5) ALL_LOSSY <Correct value>
DECIMAL(10,5) FLOAT ALL_LOSSY <Correct value>
DECIMAL(10,5) DOUBLE ALL_LOSSY <Correct value>
FLOAT FLOAT ALL_LOSSY <Correct value>
DOUBLE DOUBLE ALL_LOSSY <Correct value>
FLOAT DOUBLE ALL_LOSSY <Correct error>
DOUBLE FLOAT ALL_LOSSY <Correct value>
BIT(5) BIT(5) ALL_LOSSY <Correct value>
BIT(5) BIT(6) ALL_LOSSY <Correct error>
BIT(6) BIT(5) ALL_LOSSY <Correct value>
BIT(5) BIT(12) ALL_LOSSY <Correct error>
BIT(12) BIT(5) ALL_LOSSY <Correct value>
BIT(1) BIT(1) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DATE DATE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
ENUM('master',' ENUM('master',' ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(10) ENUM('master',' ALL_LOSSY,ALL_NON_LOSSY <Correct error>
CHAR(10) SET('master','s ALL_LOSSY,ALL_NON_LOSSY <Correct error>
ENUM('master',' CHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct error>
SET('master','s CHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct error>
SET('master','s SET('master','s ALL_LOSSY,ALL_NON_LOSSY <Correct value>
SET('master','s SET('master','s ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
SMALLINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
SMALLINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
SMALLINT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
SMALLINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
SMALLINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
SMALLINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
SMALLINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMINT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
INT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
INT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
INT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
INT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
INT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
INT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
INT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIGINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIGINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIGINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIGINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIGINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) CHAR(20) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) CHAR(30) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) CHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) VARCHAR(20) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) VARCHAR(30) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) VARCHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) MEDIUMTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
CHAR(20) LONGTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) VARCHAR(20) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) VARCHAR(30) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) VARCHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) CHAR(30) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) CHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) MEDIUMTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(20) LONGTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(500) VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(500) VARCHAR(510) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(500) VARCHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(500) TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(500) TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(500) MEDIUMTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
VARCHAR(500) LONGTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYTEXT VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TEXT VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMTEXT VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
LONGTEXT VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYTEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYTEXT CHAR(250) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
MEDIUMTEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
LONGTEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYTEXT TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TINYTEXT TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
TEXT TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(10,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(10,6) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(11,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(11,6) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(10,4) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(9,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DECIMAL(9,4) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
FLOAT DECIMAL(10,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DOUBLE DECIMAL(10,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) FLOAT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DECIMAL(10,5) DOUBLE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
FLOAT FLOAT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DOUBLE DOUBLE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
FLOAT DOUBLE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DOUBLE FLOAT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIT(5) BIT(5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIT(5) BIT(6) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIT(6) BIT(5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIT(5) BIT(12) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
BIT(12) BIT(5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
DROP TABLE type_conversions;
DROP TABLE t1;
set global slave_type_conversions = @saved_slave_type_conversions;

View File

@ -1,5 +1,8 @@
source include/master-slave.inc;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
CREATE DATABASE track;
USE track;
@ -130,7 +133,10 @@ VALUES ('3m3l4rhs6do0sf5p1i9lr94g928a272v', '', '', INET_ATON('71.118.124.98'),
SELECT * FROM visits;
SELECT * FROM visits_events;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
# Cleanup
DROP DATABASE track;
sync_slave_with_master;
--echo End of 5.1 tests

View File

@ -18,6 +18,9 @@ sync_slave_with_master;
STOP SLAVE;
RESET SLAVE;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
eval CREATE TABLE t1 (
a float (47),
b double (143,9),
@ -217,4 +220,6 @@ connection master;
DROP TABLE t1;
sync_slave_with_master;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
# END 5.1 Test Case

View File

@ -2,6 +2,8 @@
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
connection slave;
let $bit_field_special = ALL_LOSSY;
let $type= 'INNODB' ;
let $extra_index= ;
-- source extra/rpl_tests/rpl_row_basic.test

View File

@ -0,0 +1,69 @@
--source include/have_binlog_format_row.inc
--source include/master-slave.inc
connection slave;
set @saved_slave_type_conversions = @@global.slave_type_conversions;
CREATE TABLE type_conversions (
TestNo INT AUTO_INCREMENT PRIMARY KEY,
Source TEXT,
Target TEXT,
Flags TEXT,
On_Master TEXT,
On_Slave TEXT,
Expected TEXT,
Compare INT,
Error TEXT);
SELECT @@global.slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='';
SELECT @@global.slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY';
SELECT @@global.slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY';
SELECT @@global.slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY';
SELECT @@global.slave_type_conversions;
--error ER_WRONG_VALUE_FOR_VAR
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY,NONEXISTING_BIT';
SELECT @@global.slave_type_conversions;
# Checking strict interpretation of type conversions
connection slave;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='';
source extra/rpl_tests/type_conversions.test;
# Checking lossy integer type conversions
connection slave;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY';
source extra/rpl_tests/type_conversions.test;
# Checking non-lossy integer type conversions
connection slave;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY';
source extra/rpl_tests/type_conversions.test;
# Checking all type conversions
connection slave;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY';
source extra/rpl_tests/type_conversions.test;
connection slave;
--echo **** Result of conversions ****
disable_query_log;
SELECT RPAD(Source, 15, ' ') AS Source_Type,
RPAD(Target, 15, ' ') AS Target_Type,
RPAD(Flags, 25, ' ') AS All_Type_Conversion_Flags,
IF(Compare IS NULL AND Error IS NOT NULL, '<Correct error>',
IF(Compare, '<Correct value>',
CONCAT("'", On_Slave, "' != '", Expected, "'")))
AS Value_On_Slave
FROM type_conversions;
enable_query_log;
DROP TABLE type_conversions;
connection master;
DROP TABLE t1;
sync_slave_with_master;
set global slave_type_conversions = @saved_slave_type_conversions;

View File

@ -59,6 +59,8 @@ const char field_separator=',';
#define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
#define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
/*
Rules for merging different types of fields in UNION
@ -996,6 +998,21 @@ test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend)
}
/**
Template function to compare two objects.
*/
namespace {
template <class A_type, class B_type>
int compare(A_type a, B_type b)
{
if (a < b)
return -1;
if (b < a)
return 1;
return 0;
}
}
/**
Detect Item_result by given field type of UNION merge result.
@ -1367,22 +1384,46 @@ bool Field::send_binary(Protocol *protocol)
/**
Check to see if field size is compatible with destination.
This method is used in row-based replication to verify that the slave's
field size is less than or equal to the master's field size. The
encoded field metadata (from the master or source) is decoded and compared
to the size of this field (the slave or destination).
This method is used in row-based replication to verify that the
slave's field size is less than or equal to the master's field
size. The encoded field metadata (from the master or source) is
decoded and compared to the size of this field (the slave or
destination).
@note
The comparison is made so that if the source data (from the master)
is less than the target data (on the slave), -1 is returned in @c
<code>*order_var</code>. This implies that a conversion is
necessary, but that it is lossy and can result in truncation of the
value.
If the source data is strictly greater than the target data, 1 is
returned in <code>*order_var</code>. This implies that the source
type can is contained in the target type and that a conversion is
necessary but is non-lossy.
If no conversion is required to fit the source type in the target
type, 0 is returned in <code>*order_var</code>.
@param field_metadata Encoded size in field metadata
@param order_var Pointer to variable where the order
between the source field and this field
will be returned.
@retval 0 if this field's size is < the source field's size
@retval 1 if this field's size is >= the source field's size
@return @c true if this field's size is compatible with the
master's field size, @c false otherwise.
*/
int Field::compatible_field_size(uint field_metadata,
const Relay_log_info *rli_arg __attribute__((unused)))
bool Field::compatible_field_size(uint field_metadata,
Relay_log_info *rli_arg __attribute__((unused)),
int *order_var)
{
uint const source_size= pack_length_from_metadata(field_metadata);
uint const destination_size= row_pack_length();
return (source_size <= destination_size);
DBUG_PRINT("debug", ("real_type: %d, source_size: %u, destination_size: %u",
real_type(), source_size, destination_size));
*order_var = compare(source_size, destination_size);
return true;
}
@ -2907,33 +2948,15 @@ uint Field_new_decimal::pack_length_from_metadata(uint field_metadata)
}
/**
Check to see if field size is compatible with destination.
This method is used in row-based replication to verify that the slave's
field size is less than or equal to the master's field size. The
encoded field metadata (from the master or source) is decoded and compared
to the size of this field (the slave or destination).
@param field_metadata Encoded size in field metadata
@retval 0 if this field's size is < the source field's size
@retval 1 if this field's size is >= the source field's size
*/
int Field_new_decimal::compatible_field_size(uint field_metadata,
const Relay_log_info * __attribute__((unused)))
bool Field_new_decimal::compatible_field_size(uint field_metadata,
Relay_log_info * __attribute__((unused)),
int *order_var)
{
int compatible= 0;
uint const source_precision= (field_metadata >> 8U) & 0x00ff;
uint const source_decimal= field_metadata & 0x00ff;
uint const source_size= my_decimal_get_binary_size(source_precision,
source_decimal);
uint const destination_size= row_pack_length();
compatible= (source_size <= destination_size);
if (compatible)
compatible= (source_precision <= precision) &&
(source_decimal <= decimals());
return (compatible);
int order= compare(source_precision, precision);
*order_var= order != 0 ? order : compare(source_decimal, dec);
return true;
}
@ -6707,8 +6730,10 @@ check_field_for_37426(const void *param_arg)
}
#endif
int Field_string::compatible_field_size(uint field_metadata,
const Relay_log_info *rli_arg)
bool
Field_string::compatible_field_size(uint field_metadata,
Relay_log_info *rli_arg,
int *order_var)
{
#ifdef HAVE_REPLICATION
const Check_field_param check_param = { this };
@ -6716,7 +6741,7 @@ int Field_string::compatible_field_size(uint field_metadata,
check_field_for_37426, &check_param))
return FALSE; // Not compatible field sizes
#endif
return Field::compatible_field_size(field_metadata, rli_arg);
return Field::compatible_field_size(field_metadata, rli_arg, order_var);
}
@ -6778,6 +6803,8 @@ uchar *Field_string::pack(uchar *to, const uchar *from,
{
uint length= min(field_length,max_length);
uint local_char_length= max_length/field_charset->mbmaxlen;
DBUG_PRINT("debug", ("Packing field '%s' - length: %u ", field_name, length));
if (length > local_char_length)
local_char_length= my_charpos(field_charset, from, from+length,
local_char_length);
@ -7625,6 +7652,7 @@ Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
cs),
packlength(blob_pack_length)
{
DBUG_ASSERT(blob_pack_length <= 4); // Only pack lengths 1-4 supported currently
flags|= BLOB_FLAG;
share->blob_fields++;
/* TODO: why do not fill table->s->blob_field array here? */
@ -8035,8 +8063,10 @@ int Field_blob::key_cmp(const uchar *a,const uchar *b)
*/
int Field_blob::do_save_field_metadata(uchar *metadata_ptr)
{
DBUG_ENTER("Field_blob::do_save_field_metadata");
*metadata_ptr= pack_length_no_ptr();
return 1;
DBUG_PRINT("debug", ("metadata: %u (pack_length_no_ptr)", *metadata_ptr));
DBUG_RETURN(1);
}
@ -8977,6 +9007,9 @@ Field_bit::Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7),
bytes_in_rec(len_arg / 8)
{
DBUG_ENTER("Field_bit::Field_bit");
DBUG_PRINT("enter", ("ptr_arg: %p, null_ptr_arg: %p, len_arg: %u, bit_len: %u, bytes_in_rec: %u",
ptr_arg, null_ptr_arg, len_arg, bit_len, bytes_in_rec));
flags|= UNSIGNED_FLAG;
/*
Ensure that Field::eq() can distinguish between two different bit fields.
@ -8984,6 +9017,7 @@ Field_bit::Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
*/
if (!null_ptr_arg)
null_bit= bit_ofs_arg;
DBUG_VOID_RETURN;
}
@ -9268,9 +9302,12 @@ uint Field_bit::get_key_image(uchar *buff, uint length, imagetype type_arg)
*/
int Field_bit::do_save_field_metadata(uchar *metadata_ptr)
{
DBUG_ENTER("Field_bit::do_save_field_metadata");
DBUG_PRINT("debug", ("bit_len: %d, bytes_in_rec: %d",
bit_len, bytes_in_rec));
*metadata_ptr= bit_len;
*(metadata_ptr + 1)= bytes_in_rec;
return 2;
DBUG_RETURN(2);
}
@ -9295,34 +9332,20 @@ uint Field_bit::pack_length_from_metadata(uint field_metadata)
}
/**
Check to see if field size is compatible with destination.
This method is used in row-based replication to verify that the slave's
field size is less than or equal to the master's field size. The
encoded field metadata (from the master or source) is decoded and compared
to the size of this field (the slave or destination).
@param field_metadata Encoded size in field metadata
@retval 0 if this field's size is < the source field's size
@retval 1 if this field's size is >= the source field's size
*/
int Field_bit::compatible_field_size(uint field_metadata,
const Relay_log_info * __attribute__((unused)))
bool
Field_bit::compatible_field_size(uint field_metadata,
Relay_log_info * __attribute__((unused)),
int *order_var)
{
int compatible= 0;
uint const source_size= pack_length_from_metadata(field_metadata);
uint const destination_size= row_pack_length();
uint const from_bit_len= field_metadata & 0x00ff;
uint const from_len= (field_metadata >> 8U) & 0x00ff;
if ((bit_len == 0) || (from_bit_len == 0))
compatible= (source_size <= destination_size);
else if (from_bit_len > bit_len)
compatible= (from_len < bytes_in_rec);
else
compatible= ((from_bit_len <= bit_len) && (from_len <= bytes_in_rec));
return (compatible);
DBUG_ENTER("Field_bit::compatible_field_size");
DBUG_ASSERT((field_metadata >> 16) == 0);
uint const from_bit_len=
8 * (field_metadata >> 8) + (field_metadata & 0xff);
uint const to_bit_len= max_display_length();
DBUG_PRINT("debug", ("from_bit_len: %u, to_bit_len: %u",
from_bit_len, to_bit_len));
*order_var= compare(from_bit_len, to_bit_len);
DBUG_RETURN(TRUE);
}
@ -9388,8 +9411,15 @@ const uchar *
Field_bit::unpack(uchar *to, const uchar *from, uint param_data,
bool low_byte_first __attribute__((unused)))
{
DBUG_ENTER("Field_bit::unpack");
DBUG_PRINT("enter", ("to: %p, from: %p, param_data: 0x%x",
to, from, param_data));
DBUG_PRINT("debug", ("bit_ptr: %p, bit_len: %u, bit_ofs: %u",
bit_ptr, bit_len, bit_ofs));
uint const from_len= (param_data >> 8U) & 0x00ff;
uint const from_bit_len= param_data & 0x00ff;
DBUG_PRINT("debug", ("from_len: %u, from_bit_len: %u",
from_len, from_bit_len));
/*
If the parameter data is zero (i.e., undefined), or if the master
and slave have the same sizes, then use the old unpack() method.
@ -9410,7 +9440,7 @@ Field_bit::unpack(uchar *to, const uchar *from, uint param_data,
from++;
}
memcpy(to, from, bytes_in_rec);
return from + bytes_in_rec;
DBUG_RETURN(from + bytes_in_rec);
}
/*
@ -9436,7 +9466,7 @@ Field_bit::unpack(uchar *to, const uchar *from, uint param_data,
bitmap_set_bit(table->write_set,field_index);
store(value, new_len, system_charset_info);
my_afree(value);
return from + len;
DBUG_RETURN(from + len);
}
@ -9564,8 +9594,11 @@ void Create_field::create_length_to_internal_length(void)
*/
void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
uint32 length_arg, uint32 decimals_arg,
bool maybe_null, bool is_unsigned)
bool maybe_null, bool is_unsigned,
uint pack_length)
{
DBUG_ENTER("Create_field::init_for_tmp_table");
field_name= "";
sql_type= sql_type_arg;
char_length= length= length_arg;;
@ -9573,10 +9606,92 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
interval= 0;
charset= &my_charset_bin;
geom_type= Field::GEOM_GEOMETRY;
pack_flag= (FIELDFLAG_NUMBER |
((decimals_arg & FIELDFLAG_MAX_DEC) << FIELDFLAG_DEC_SHIFT) |
(maybe_null ? FIELDFLAG_MAYBE_NULL : 0) |
(is_unsigned ? 0 : FIELDFLAG_DECIMAL));
DBUG_PRINT("enter", ("sql_type: %d, length: %u, pack_length: %u",
sql_type_arg, length_arg, pack_length));
/*
These pack flags are crafted to get it correctly through the
branches of make_field().
*/
switch (sql_type_arg)
{
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_SET:
pack_flag= 0;
break;
case MYSQL_TYPE_GEOMETRY:
pack_flag= FIELDFLAG_GEOM;
break;
case MYSQL_TYPE_ENUM:
pack_flag= FIELDFLAG_INTERVAL;
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
pack_flag= FIELDFLAG_DECIMAL | FIELDFLAG_NUMBER |
(decimals_arg & FIELDFLAG_MAX_DEC) << FIELDFLAG_DEC_SHIFT;
break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
pack_flag= FIELDFLAG_BLOB;
break;
case MYSQL_TYPE_BIT:
pack_flag= FIELDFLAG_NUMBER | FIELDFLAG_TREAT_BIT_AS_CHAR;
break;
default:
pack_flag= FIELDFLAG_NUMBER;
break;
}
/*
Set the pack flag correctly for the blob-like types. This sets the
packtype to something that make_field can use. If the pack type is
not set correctly, the packlength will be reeeeally wierd (like
129 or so).
*/
switch (sql_type_arg)
{
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_GEOMETRY:
// If you are going to use the above types, you have to pass a
// pack_length as parameter. Assert that is really done.
DBUG_ASSERT(pack_length != ~0U);
pack_flag|= pack_length_to_packflag(pack_length);
break;
default:
/* Nothing */
break;
}
pack_flag|=
(maybe_null ? FIELDFLAG_MAYBE_NULL : 0) |
(is_unsigned ? 0 : FIELDFLAG_DECIMAL);
DBUG_PRINT("debug", ("pack_flag: %s%s%s%s%s, pack_type: %d",
FLAGSTR(pack_flag, FIELDFLAG_BINARY),
FLAGSTR(pack_flag, FIELDFLAG_NUMBER),
FLAGSTR(pack_flag, FIELDFLAG_INTERVAL),
FLAGSTR(pack_flag, FIELDFLAG_GEOM),
FLAGSTR(pack_flag, FIELDFLAG_BLOB),
f_packtype(pack_flag)));
DBUG_VOID_RETURN;
}
@ -10073,6 +10188,14 @@ Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length,
default: break;
}
DBUG_PRINT("debug", ("field_type: %d, field_length: %u, interval: %p, pack_flag: %s%s%s%s%s",
field_type, field_length, interval,
FLAGSTR(pack_flag, FIELDFLAG_BINARY),
FLAGSTR(pack_flag, FIELDFLAG_INTERVAL),
FLAGSTR(pack_flag, FIELDFLAG_NUMBER),
FLAGSTR(pack_flag, FIELDFLAG_PACK),
FLAGSTR(pack_flag, FIELDFLAG_BLOB)));
if (f_is_alpha(pack_flag))
{
if (!f_is_packed(pack_flag))

View File

@ -164,22 +164,13 @@ public:
table, which is located on disk).
*/
virtual uint32 pack_length_in_rec() const { return pack_length(); }
virtual int compatible_field_size(uint field_metadata,
const Relay_log_info *);
virtual bool compatible_field_size(uint metadata, Relay_log_info *rli,
int *order);
virtual uint pack_length_from_metadata(uint field_metadata)
{ return field_metadata; }
/*
This method is used to return the size of the data in a row-based
replication row record. The default implementation of returning 0 is
designed to allow fields that do not use metadata to return TRUE (1)
from compatible_field_size() which uses this function in the comparison.
The default value for field metadata for fields that do not have
metadata is 0. Thus, 0 == 0 means the fields are compatible in size.
Note: While most classes that override this method return pack_length(),
the classes Field_string, Field_varstring, and Field_blob return
field_length + 1, field_length, and pack_length_no_ptr() respectfully.
*/
{
DBUG_ENTER("Field::pack_length_from_metadata");
DBUG_RETURN(field_metadata);
}
virtual uint row_pack_length() { return 0; }
virtual int save_field_metadata(uchar *first_byte)
{ return do_save_field_metadata(first_byte); }
@ -636,6 +627,13 @@ public:
int store_decimal(const my_decimal *);
my_decimal *val_decimal(my_decimal *);
uint is_equal(Create_field *new_field);
uint row_pack_length() { return pack_length(); }
uint32 pack_length_from_metadata(uint field_metadata) {
uint32 length= pack_length();
DBUG_PRINT("result", ("pack_length_from_metadata(%d): %u",
field_metadata, length));
return length;
}
int check_int(CHARSET_INFO *cs, const char *str, int length,
const char *int_end, int error);
bool get_int(CHARSET_INFO *cs, const char *from, uint len,
@ -806,8 +804,8 @@ public:
uint32 pack_length() const { return (uint32) bin_size; }
uint pack_length_from_metadata(uint field_metadata);
uint row_pack_length() { return pack_length(); }
int compatible_field_size(uint field_metadata,
const Relay_log_info *rli);
bool compatible_field_size(uint field_metadata, Relay_log_info *rli,
int *order_var);
uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
@ -1501,9 +1499,9 @@ public:
return row_pack_length();
return (((field_metadata >> 4) & 0x300) ^ 0x300) + (field_metadata & 0x00ff);
}
int compatible_field_size(uint field_metadata,
const Relay_log_info *rli);
uint row_pack_length() { return (field_length + 1); }
bool compatible_field_size(uint field_metadata, Relay_log_info *rli,
int *order_var);
uint row_pack_length() { return field_length; }
int pack_cmp(const uchar *a,const uchar *b,uint key_length,
my_bool insert_or_update);
int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update);
@ -1965,8 +1963,8 @@ public:
uint pack_length_from_metadata(uint field_metadata);
uint row_pack_length()
{ return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); }
int compatible_field_size(uint field_metadata,
const Relay_log_info *rli);
bool compatible_field_size(uint metadata, Relay_log_info *rli,
int *order_var);
void sql_type(String &str) const;
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);
@ -2069,7 +2067,8 @@ public:
/* Init for a tmp table field. To be extended if need be. */
void init_for_tmp_table(enum_field_types sql_type_arg,
uint32 max_length, uint32 decimals,
bool maybe_null, bool is_unsigned);
bool maybe_null, bool is_unsigned,
uint pack_length = ~0U);
bool init(THD *thd, char *field_name, enum_field_types type, char *length,
char *decimals, uint type_modifier, Item *default_value,

View File

@ -29,7 +29,6 @@
#include "rpl_rli.h"
#include "rpl_mi.h"
#include "rpl_filter.h"
#include "rpl_utility.h"
#include "rpl_record.h"
#include <my_dir.h>
@ -37,6 +36,7 @@
#include <base64.h>
#include <my_bitmap.h>
#include "rpl_utility.h"
#define log_cs &my_charset_latin1
@ -7309,11 +7309,18 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
*/
{
DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
rli->tables_to_lock));
RPL_TABLE_LIST *ptr= rli->tables_to_lock;
for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
{
if (ptr->m_tabledef.compatible_with(rli, ptr->table))
TABLE *conv_table;
if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
ptr->table, &conv_table))
{
DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
ptr->table->s->db.str,
ptr->table->s->table_name.str));
/*
We should not honour --slave-skip-errors at this point as we are
having severe errors which should not be skiped.
@ -7324,12 +7331,17 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
DBUG_RETURN(ERR_BAD_TABLE_DEF);
}
DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
" - conv_table: %p",
ptr->table->s->db.str,
ptr->table->s->table_name.str, conv_table));
ptr->m_conv_table= conv_table;
}
}
/*
... and then we add all the tables to the table map and remove
them from tables to lock.
... and then we add all the tables to the table map and but keep
them in the tables to lock list.
We also invalidate the query cache for all the tables, since
they will now be changed.
@ -7825,7 +7837,10 @@ int Table_map_log_event::save_field_metadata()
DBUG_ENTER("Table_map_log_event::save_field_metadata");
int index= 0;
for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
{
DBUG_PRINT("debug", ("field_type: %d", m_coltype[i]));
index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
}
DBUG_RETURN(index);
}
#endif /* !defined(MYSQL_CLIENT) */

View File

@ -107,14 +107,24 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
RPL_TABLE_LIST *ptr= rli->tables_to_lock;
for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
{
if (ptr->m_tabledef.compatible_with(rli, ptr->table))
TABLE *conv_table;
if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
ptr->table, &conv_table))
{
DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
ptr->table->s->db.str,
ptr->table->s->table_name.str));
mysql_unlock_tables(thd, thd->lock);
thd->lock= 0;
thd->is_slave_error= 1;
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
DBUG_RETURN(Old_rows_log_event::ERR_BAD_TABLE_DEF);
}
DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
" - conv_table: %p",
ptr->table->s->db.str,
ptr->table->s->table_name.str, conv_table));
ptr->m_conv_table= conv_table;
}
}
@ -1578,7 +1588,9 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
RPL_TABLE_LIST *ptr= rli->tables_to_lock;
for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
{
if (ptr->m_tabledef.compatible_with(rli, ptr->table))
TABLE *conv_table;
if (ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
ptr->table, &conv_table))
{
mysql_unlock_tables(thd, thd->lock);
thd->lock= 0;
@ -1586,12 +1598,14 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
DBUG_RETURN(ERR_BAD_TABLE_DEF);
}
ptr->m_conv_table= conv_table;
}
}
/*
... and then we add all the tables to the table map and remove
them from tables to lock.
... and then we add all the tables to the table map but keep
them in the tables to lock list.
We also invalidate the query cache for all the tables, since
they will now be changed.

View File

@ -1998,6 +1998,7 @@ extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
extern my_bool opt_slave_compressed_protocol, use_temp_pool;
extern ulong slave_exec_mode_options;
extern ulong slave_type_conversions_options;
extern my_bool opt_readonly, lower_case_file_system;
extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth;

View File

@ -525,6 +525,8 @@ ulong open_files_limit, max_binlog_size, max_relay_log_size;
ulong slave_net_timeout, slave_trans_retries;
ulong slave_exec_mode_options;
const char *slave_exec_mode_str= "STRICT";
ulong slave_type_conversions_options;
const char *slave_type_conversions_default= "";
ulong thread_cache_size=0, thread_pool_size= 0;
ulong binlog_cache_size=0;
ulonglong max_binlog_cache_size=0;
@ -5690,6 +5692,7 @@ enum options_mysqld
#endif /* defined(ENABLED_DEBUG_SYNC) */
OPT_OLD_MODE,
OPT_SLAVE_EXEC_MODE,
OPT_SLAVE_TYPE_CONVERSIONS,
OPT_GENERAL_LOG_FILE,
OPT_SLOW_QUERY_LOG_FILE,
OPT_IGNORE_BUILTIN_INNODB
@ -6413,6 +6416,15 @@ replicating a LOAD DATA INFILE command.",
{"slave-exec-mode", OPT_SLAVE_EXEC_MODE,
"Modes for how replication events should be executed. Legal values are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, replication will not stop for operations that are idempotent. In STRICT mode, replication will stop on any unexpected difference between the master and the slave.",
(uchar**) &slave_exec_mode_str, (uchar**) &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"slave-type-conversions", OPT_SLAVE_TYPE_CONVERSIONS,
"Set of slave type conversions that are enabled. Legal values are:"
" ALL_LOSSY to enable lossy conversions and"
" ALL_NON_LOSSY to enable non-lossy conversions."
" If the variable is assigned the empty set, no conversions are"
" allowed and it is expected that the types match exactly.",
(uchar**) &slave_type_conversions_default,
(uchar**) &slave_type_conversions_default,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"slow-query-log", OPT_SLOW_LOG,
"Enable|disable slow query log", (uchar**) &opt_slow_log,
@ -7671,6 +7683,11 @@ static int mysql_init_variables(void)
slave_exec_mode_options= (uint)
find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL,
&error);
/* Slave type conversions */
slave_type_conversions_options= 0;
slave_type_conversions_options=
find_bit_type_or_exit(slave_type_conversions_default, &slave_type_conversions_typelib,
NULL, &error);
if (error)
return 1;
opt_specialflag= SPECIAL_ENGLISH;
@ -7900,6 +7917,12 @@ mysqld_get_one_option(int optid,
if (error)
return 1;
break;
case OPT_SLAVE_TYPE_CONVERSIONS:
slave_type_conversions_options= (uint)
find_bit_type_or_exit(argument, &slave_type_conversions_typelib, "", &error);
if (error)
return 1;
break;
#endif
case OPT_SAFEMALLOC_MEM_LIMIT:
#if !defined(DBUG_OFF) && defined(SAFEMALLOC)

View File

@ -104,10 +104,10 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
#endif
pack_ptr= field->pack(pack_ptr, field->ptr + offset,
field->max_data_length(), TRUE);
DBUG_PRINT("debug", ("field: %s; pack_ptr: 0x%lx;"
DBUG_PRINT("debug", ("field: %s; real_type: %d, pack_ptr: 0x%lx;"
" pack_ptr':0x%lx; bytes: %d",
field->field_name, (ulong) old_pack_ptr,
(ulong) pack_ptr,
field->field_name, field->real_type(),
(ulong) old_pack_ptr, (ulong) pack_ptr,
(int) (pack_ptr - old_pack_ptr)));
}
@ -201,10 +201,30 @@ unpack_row(Relay_log_info const *rli,
// The "current" null bits
unsigned int null_bits= *null_ptr++;
uint i= 0;
table_def *tabledef= ((Relay_log_info*)rli)->get_tabledef(table);
table_def *tabledef;
TABLE *conv_table;
bool table_found= rli->get_table_data(table, &tabledef, &conv_table);
DBUG_PRINT("debug", ("Table data: table_found: %d, tabldef: %p, conv_table: %p",
table_found, tabledef, conv_table));
DBUG_ASSERT(table_found);
if (!table_found)
return HA_ERR_GENERIC;
for (field_ptr= begin_ptr ; field_ptr < end_ptr && *field_ptr ; ++field_ptr)
{
Field *const f= *field_ptr;
/*
If there is a conversion table, we pick up the field pointer to
the conversion table. If the conversion table or the field
pointer is NULL, no conversions are necessary.
*/
Field *conv_field=
conv_table ? conv_table->field[field_ptr - begin_ptr] : NULL;
Field *const f=
conv_field ? conv_field : *field_ptr;
DBUG_PRINT("debug", ("Conversion %srequired for field '%s' (#%d)",
conv_field ? "" : "not ",
(*field_ptr)->field_name, field_ptr - begin_ptr));
DBUG_ASSERT(f != NULL);
/*
No need to bother about columns that does not exist: they have
@ -247,6 +267,39 @@ unpack_row(Relay_log_info const *rli,
(int) (pack_ptr - old_pack_ptr)));
}
/*
If conv_field is set, then we are doing a conversion. In this
case, we have unpacked the master data to the conversion
table, so we need to copy the value stored in the conversion
table into the final table and do the conversion at the same time.
*/
if (conv_field)
{
Copy_field copy;
#ifndef DBUG_OFF
char source_buf[MAX_FIELD_WIDTH];
char value_buf[MAX_FIELD_WIDTH];
String source_type(source_buf, sizeof(source_buf), system_charset_info);
String value_string(value_buf, sizeof(value_buf), system_charset_info);
conv_field->sql_type(source_type);
conv_field->val_str(&value_string);
DBUG_PRINT("debug", ("Copying field '%s' of type '%s' with value '%s'",
(*field_ptr)->field_name,
source_type.c_ptr(), value_string.c_ptr()));
#endif
copy.set(*field_ptr, f, TRUE);
(*copy.do_copy)(&copy);
#ifndef DBUG_OFF
char target_buf[MAX_FIELD_WIDTH];
String target_type(target_buf, sizeof(target_buf), system_charset_info);
(*field_ptr)->sql_type(target_type);
(*field_ptr)->val_str(&value_string);
DBUG_PRINT("debug", ("Value of field '%s' of type '%s' is now '%s'",
(*field_ptr)->field_name,
target_type.c_ptr(), value_string.c_ptr()));
#endif
}
null_mask <<= 1;
}
i++;

View File

@ -314,13 +314,21 @@ public:
uint tables_to_lock_count; /* RBR: Count of tables to lock */
table_mapping m_table_map; /* RBR: Mapping table-id to table */
inline table_def *get_tabledef(TABLE *tbl)
bool get_table_data(TABLE *table_arg, table_def **tabledef_var, TABLE **conv_table_var) const
{
table_def *td= 0;
for (TABLE_LIST *ptr= tables_to_lock; ptr && !td; ptr= ptr->next_global)
if (ptr->table == tbl)
td= &((RPL_TABLE_LIST *)ptr)->m_tabledef;
return (td);
DBUG_ASSERT(tabledef_var && conv_table_var);
for (TABLE_LIST *ptr= tables_to_lock ; ptr != NULL ; ptr= ptr->next_global)
if (ptr->table == table_arg)
{
*tabledef_var= &static_cast<RPL_TABLE_LIST*>(ptr)->m_tabledef;
*conv_table_var= static_cast<RPL_TABLE_LIST*>(ptr)->m_conv_table;
DBUG_PRINT("debug", ("Fetching table data for table %s.%s:"
" tabledef: %p, conv_table: %p",
table_arg->s->db.str, table_arg->s->table_name.str,
*tabledef_var, *conv_table_var));
return true;
}
return false;
}
/*

View File

@ -14,8 +14,184 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "rpl_utility.h"
#ifndef MYSQL_CLIENT
#include "rpl_rli.h"
/**
Template function to compare two objects.
*/
namespace {
template <class Type>
int compare(Type a, Type b)
{
if (a < b)
return -1;
if (b < a)
return 1;
return 0;
}
}
/**
Max value for an unsigned integer of 'bits' bits.
The somewhat contorted expression is to avoid overflow.
*/
uint32 uint_max(int bits) {
return (((1UL << (bits - 1)) - 1) << 1) | 1;
}
/**
Compute the maximum display length of a field.
@param sql_type Type of the field
@param metadata The metadata from the master for the field.
@return Maximum length of the field in bytes.
*/
static uint32
max_display_length_for_field(enum_field_types sql_type, unsigned int metadata)
{
DBUG_PRINT("debug", ("sql_type: %d, metadata: 0x%x", sql_type, metadata));
DBUG_ASSERT(metadata >> 16 == 0);
switch (sql_type) {
case MYSQL_TYPE_NEWDECIMAL:
return metadata >> 8;
case MYSQL_TYPE_FLOAT:
return 12;
case MYSQL_TYPE_DOUBLE:
return 22;
case MYSQL_TYPE_SET:
case MYSQL_TYPE_ENUM:
return metadata & 0x00ff;
case MYSQL_TYPE_STRING:
{
uchar type= metadata >> 8;
if (type == MYSQL_TYPE_SET || type == MYSQL_TYPE_ENUM)
return metadata & 0xff;
else
/* This is taken from Field_string::unpack. */
return (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff);
}
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_TINY:
return 4;
case MYSQL_TYPE_SHORT:
return 6;
case MYSQL_TYPE_INT24:
return 9;
case MYSQL_TYPE_LONG:
return 11;
#ifdef HAVE_LONG_LONG
case MYSQL_TYPE_LONGLONG:
return 20;
#endif
case MYSQL_TYPE_NULL:
return 0;
case MYSQL_TYPE_NEWDATE:
return 3;
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
return 3;
case MYSQL_TYPE_TIMESTAMP:
return 4;
case MYSQL_TYPE_DATETIME:
return 8;
case 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
*/
uint from_len= (metadata >> 8U) & 0x00ff;
uint from_bit_len= metadata & 0x00ff;
DBUG_ASSERT(from_bit_len <= 7);
return 8 * from_len + from_bit_len;
}
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_VARCHAR:
return metadata;
/*
The actual length for these types does not really matter since
they are used to calc_pack_length, which ignores the given
length for these types.
Since we want this to be accurate for other uses, we return the
maximum size in bytes of these BLOBs.
*/
case MYSQL_TYPE_TINY_BLOB:
return uint_max(1 * 8);
case MYSQL_TYPE_MEDIUM_BLOB:
return uint_max(3 * 8);
case MYSQL_TYPE_BLOB:
/*
For the blob type, Field::real_type() lies and say that all
blobs are of type MYSQL_TYPE_BLOB. In that case, we have to look
at the length instead to decide what the max display size is.
*/
return uint_max(metadata * 8);
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_GEOMETRY:
return uint_max(4 * 8);
default:
return ~(uint32) 0;
}
}
/*
Compare the pack lengths of a source field (on the master) and a
target field (on the slave).
@param field Target field.
@param type Source field type.
@param metadata Source field metadata.
@retval -1 The length of the source field is smaller than the target field.
@retval 0 The length of the source and target fields are the same.
@retval 1 The length of the source field is greater than the target field.
*/
int compare_lengths(Field *field, enum_field_types source_type, uint16 metadata)
{
DBUG_ENTER("compare_lengths");
size_t const source_length=
max_display_length_for_field(source_type, metadata);
size_t const target_length= field->max_display_length();
DBUG_PRINT("debug", ("source_length: %lu, source_type: %u,"
" target_length: %lu, target_type: %u",
(unsigned long) source_length, source_type,
(unsigned long) target_length, field->real_type()));
int result= compare(source_length, target_length);
DBUG_PRINT("result", ("%d", result));
DBUG_RETURN(result);
}
/*********************************************************************
* table_def member definitions *
*********************************************************************/
@ -169,58 +345,698 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
return length;
}
/*
/**
*/
void show_sql_type(enum_field_types type, uint16 metadata, String *str)
{
DBUG_ENTER("show_sql_type");
DBUG_PRINT("enter", ("type: %d, metadata: 0x%x", type, metadata));
switch (type)
{
case MYSQL_TYPE_TINY:
str->set_ascii(STRING_WITH_LEN("tinyint"));
break;
case MYSQL_TYPE_SHORT:
str->set_ascii(STRING_WITH_LEN("smallint"));
break;
case MYSQL_TYPE_LONG:
str->set_ascii(STRING_WITH_LEN("int"));
break;
case MYSQL_TYPE_FLOAT:
str->set_ascii(STRING_WITH_LEN("float"));
break;
case MYSQL_TYPE_DOUBLE:
str->set_ascii(STRING_WITH_LEN("double"));
break;
case MYSQL_TYPE_NULL:
str->set_ascii(STRING_WITH_LEN("null"));
break;
case MYSQL_TYPE_TIMESTAMP:
str->set_ascii(STRING_WITH_LEN("timestamp"));
break;
case MYSQL_TYPE_LONGLONG:
str->set_ascii(STRING_WITH_LEN("bigint"));
break;
case MYSQL_TYPE_INT24:
str->set_ascii(STRING_WITH_LEN("mediumint"));
break;
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE:
str->set_ascii(STRING_WITH_LEN("date"));
break;
case MYSQL_TYPE_TIME:
str->set_ascii(STRING_WITH_LEN("time"));
break;
case MYSQL_TYPE_DATETIME:
str->set_ascii(STRING_WITH_LEN("datetime"));
break;
case MYSQL_TYPE_YEAR:
str->set_ascii(STRING_WITH_LEN("year"));
break;
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_VARCHAR:
{
CHARSET_INFO *cs= str->charset();
uint32 length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"varchar(%u)", metadata);
str->length(length);
}
break;
case MYSQL_TYPE_BIT:
{
CHARSET_INFO *cs= str->charset();
int bit_length= (metadata >> 8) + (metadata & 0xFF);
uint32 length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"bit(%d)", bit_length);
str->length(length);
}
break;
case MYSQL_TYPE_DECIMAL:
{
CHARSET_INFO *cs= str->charset();
uint32 length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"decimal(%d,?)", metadata);
str->length(length);
}
break;
case MYSQL_TYPE_NEWDECIMAL:
{
CHARSET_INFO *cs= str->charset();
uint32 length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"decimal(%d,%d)", metadata >> 8, metadata & 0xff);
str->length(length);
}
break;
case MYSQL_TYPE_ENUM:
str->set_ascii(STRING_WITH_LEN("enum"));
break;
case MYSQL_TYPE_SET:
str->set_ascii(STRING_WITH_LEN("set"));
break;
case MYSQL_TYPE_BLOB:
/*
Field::real_type() lies regarding the actual type of a BLOB, so
it is necessary to check the pack length to figure out what kind
of blob it really is.
*/
switch (get_blob_type_from_length(metadata))
{
case MYSQL_TYPE_TINY_BLOB:
str->set_ascii(STRING_WITH_LEN("tinyblob"));
break;
case MYSQL_TYPE_MEDIUM_BLOB:
str->set_ascii(STRING_WITH_LEN("mediumblob"));
break;
case MYSQL_TYPE_LONG_BLOB:
str->set_ascii(STRING_WITH_LEN("longblob"));
break;
case MYSQL_TYPE_BLOB:
str->set_ascii(STRING_WITH_LEN("blob"));
break;
default:
DBUG_ASSERT(0);
break;
}
break;
case MYSQL_TYPE_STRING:
{
/*
This is taken from Field_string::unpack.
*/
CHARSET_INFO *cs= str->charset();
uint bytes= (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff);
uint32 length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
"char(%d)", bytes / cs->mbmaxlen);
str->length(length);
}
break;
case MYSQL_TYPE_GEOMETRY:
str->set_ascii(STRING_WITH_LEN("geometry"));
break;
default:
str->set_ascii(STRING_WITH_LEN("<unknown type>"));
}
DBUG_VOID_RETURN;
}
/**
Check the order variable and print errors if the order is not
acceptable according to the current settings.
*/
bool is_conversion_ok(int order, Relay_log_info *rli)
{
DBUG_ENTER("is_conversion_ok");
bool allow_non_lossy=
bit_is_set(slave_type_conversions_options, SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY);
bool allow_lossy=
bit_is_set(slave_type_conversions_options, SLAVE_TYPE_CONVERSIONS_ALL_LOSSY);
DBUG_PRINT("enter", ("order: %d, flags:%s%s", order,
allow_non_lossy ? " ALL_NON_LOSSY" : "",
allow_lossy ? " ALL_LOSSY" : ""));
if (order < 0 && !allow_non_lossy)
{
/* !!! Add error message saying that non-lossy conversions need to be allowed. */
DBUG_RETURN(false);
}
if (order > 0 && !allow_lossy)
{
/* !!! Add error message saying that lossy conversions need to be allowed. */
DBUG_RETURN(false);
}
DBUG_RETURN(true);
}
/**
Can a type potentially be converted to another type?
This function check if the types are convertible and what
conversion is required.
If conversion is not possible, and error is printed.
If conversion is possible:
- *order will be set to -1 if source type is smaller than target
type and a non-lossy conversion can be required. This includes
the case where the field types are different but types could
actually be converted in either direction.
- *order will be set to 0 if no conversion is required.
- *order will be set to 1 if the source type is strictly larger
than the target type and that conversion is potentially lossy.
@param[in] field Target field
@param[in] type Source field type
@param[in] metadata Source field metadata
@param[in] rli Relay log info (for error reporting)
@param[out] order Order between source field and target field
@return @c true if conversion is possible according to the current
settings, @c false if conversion is not possible according to the
current setting.
*/
static bool
can_convert_field_to(Field *field,
enum_field_types source_type, uint16 metadata,
Relay_log_info *rli, int *order_var)
{
DBUG_ENTER("can_convert_field_to");
#ifndef DBUG_OFF
char field_type_buf[MAX_FIELD_WIDTH];
String field_type(field_type_buf, sizeof(field_type_buf), field->charset());
field->sql_type(field_type);
DBUG_PRINT("enter", ("field_type: %s, target_type: %d, source_type: %d, source_metadata: 0x%x",
field_type.c_ptr(), field->real_type(), source_type, metadata));
#endif
/*
If the real type is the same, we need to check the metadata to
decide if conversions are allowed.
*/
if (field->real_type() == source_type)
{
DBUG_PRINT("debug", ("Base types are identical, doing field size comparison"));
if (field->compatible_field_size(metadata, rli, order_var))
DBUG_RETURN(is_conversion_ok(*order_var, rli));
else
DBUG_RETURN(false);
}
else if (!slave_type_conversions_options)
DBUG_RETURN(false);
/*
Here, from and to will always be different. Since the types are
different, we cannot use the compatible_field_size() function, but
have to rely on hard-coded max-sizes for fields.
*/
DBUG_PRINT("debug", ("Base types are different, checking conversion"));
switch (source_type) // Source type (on master)
{
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
switch (field->real_type())
{
case MYSQL_TYPE_NEWDECIMAL:
/*
Then the other type is either FLOAT, DOUBLE, or old style
DECIMAL, so we require lossy conversion.
*/
*order_var= 1;
DBUG_RETURN(is_conversion_ok(*order_var, rli));
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
{
if (source_type == MYSQL_TYPE_NEWDECIMAL ||
source_type == MYSQL_TYPE_DECIMAL)
*order_var = 1; // Always require lossy conversions
else
*order_var= compare_lengths(field, source_type, metadata);
DBUG_ASSERT(*order_var != 0);
DBUG_RETURN(is_conversion_ok(*order_var, rli));
}
default:
DBUG_RETURN(false);
}
break;
/*
The length comparison check will do the correct job of comparing
the field lengths (in bytes) of two integer types.
*/
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG:
switch (field->real_type())
{
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG:
*order_var= compare_lengths(field, source_type, metadata);
DBUG_ASSERT(*order_var != 0);
DBUG_RETURN(is_conversion_ok(*order_var, rli));
default:
DBUG_RETURN(false);
}
break;
/*
Since source and target type is different, and it is not possible
to convert bit types to anything else, this will return false.
*/
case MYSQL_TYPE_BIT:
DBUG_RETURN(false);
/*
If all conversions are disabled, it is not allowed to convert
between these types. Since the TEXT vs. BINARY is distinguished by
the charset, and the charset is not replicated, we cannot
currently distinguish between , e.g., TEXT and BLOB.
*/
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_VARCHAR:
switch (field->real_type())
{
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_VARCHAR:
*order_var= compare_lengths(field, source_type, metadata);
/*
Here we know that the types are different, so if the order
gives that they do not require any conversion, we still need
to have non-lossy conversion enabled to allow conversion
between different (string) types of the same length.
*/
if (*order_var == 0)
*order_var= -1;
DBUG_RETURN(is_conversion_ok(*order_var, rli));
default:
DBUG_RETURN(false);
}
break;
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
DBUG_RETURN(false);
}
DBUG_RETURN(false); // To keep GCC happy
}
/**
Is the definition compatible with a table?
This function will compare the master table with an existing table
on the slave and see if they are compatible with respect to the
current settings of @c SLAVE_TYPE_CONVERSIONS.
If the tables are compatible and conversions are required, @c
*tmp_table_var will be set to a virtual temporary table with field
pointers for the fields that require conversions. This allow simple
checking of whether a conversion are to be applied or not.
If tables are compatible, but no conversions are necessary, @c
*tmp_table_var will be set to NULL.
@param rli_arg[in]
Relay log info, for error reporting.
@param table[in]
Table to compare with
@param tmp_table_var[out]
Virtual temporary table for performing conversions, if necessary.
@retval true Master table is compatible with slave table.
@retval false Master table is not compatible with slave table.
*/
int
table_def::compatible_with(Relay_log_info const *rli_arg, TABLE *table)
bool
table_def::compatible_with(THD *thd, Relay_log_info *rli,
TABLE *table, TABLE **conv_table_var)
const
{
/*
We only check the initial columns for the tables.
*/
uint const cols_to_check= min(table->s->fields, size());
int error= 0;
Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
TABLE_SHARE const *const tsh= table->s;
TABLE *tmp_table= NULL;
for (uint col= 0 ; col < cols_to_check ; ++col)
{
Field *const field= table->field[col];
if (field->type() != type(col))
int order;
if (can_convert_field_to(field, type(col), field_metadata(col), rli, &order))
{
DBUG_ASSERT(col < size() && col < tsh->fields);
DBUG_ASSERT(tsh->db.str && tsh->table_name.str);
error= 1;
char buf[256];
my_snprintf(buf, sizeof(buf), "Column %d type mismatch - "
"received type %d, %s.%s has type %d",
col, type(col), tsh->db.str, tsh->table_name.str,
field->type());
rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF,
ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf);
DBUG_PRINT("debug", ("Checking column %d -"
" field '%s' can be converted - order: %d",
col, field->field_name, order));
DBUG_ASSERT(order >= -1 && order <= 1);
/*
If order is not 0, a conversion is required, so we need to set
up the conversion table.
*/
if (order != 0 && tmp_table == NULL)
{
/*
This will create the full table with all fields. This is
necessary to ge the correct field lengths for the record.
*/
tmp_table= create_conversion_table(thd, rli, table);
if (tmp_table == NULL)
return false;
/*
Clear all fields up to, but not including, this column.
*/
for (unsigned int i= 0; i < col; ++i)
tmp_table->field[i]= NULL;
}
if (order == 0 && tmp_table != NULL)
tmp_table->field[col]= NULL;
}
/*
Check the slave's field size against that of the master.
*/
if (!error &&
!field->compatible_field_size(field_metadata(col), rli_arg))
else
{
error= 1;
char buf[256];
my_snprintf(buf, sizeof(buf), "Column %d size mismatch - "
"master has size %d, %s.%s on slave has size %d."
" Master's column size should be <= the slave's "
"column size.", col,
field->pack_length_from_metadata(m_field_metadata[col]),
tsh->db.str, tsh->table_name.str,
field->row_pack_length());
rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF,
ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf);
DBUG_PRINT("debug", ("Checking column %d -"
" field '%s' can not be converted",
col, field->field_name));
DBUG_ASSERT(col < size() && col < table->s->fields);
DBUG_ASSERT(table->s->db.str && table->s->table_name.str);
const char *db_name= table->s->db.str;
const char *tbl_name= table->s->table_name.str;
char source_buf[MAX_FIELD_WIDTH];
char target_buf[MAX_FIELD_WIDTH];
String source_type(source_buf, sizeof(source_buf), field->charset());
String target_type(target_buf, sizeof(target_buf), field->charset());
show_sql_type(type(col), field_metadata(col), &source_type);
field->sql_type(target_type);
rli->report(ERROR_LEVEL, ER_SLAVE_CONVERSION_FAILED,
ER(ER_SLAVE_CONVERSION_FAILED),
col, db_name, tbl_name,
source_type.c_ptr(), target_type.c_ptr());
return false;
}
}
return error;
#ifndef DBUG_OFF
if (tmp_table)
{
for (unsigned int col= 0; col < tmp_table->s->fields; ++col)
if (tmp_table->field[col])
{
char source_buf[MAX_FIELD_WIDTH];
char target_buf[MAX_FIELD_WIDTH];
String source_type(source_buf, sizeof(source_buf), table->field[col]->charset());
String target_type(target_buf, sizeof(target_buf), table->field[col]->charset());
tmp_table->field[col]->sql_type(source_type);
table->field[col]->sql_type(target_type);
DBUG_PRINT("debug", ("Field %s - conversion required."
" Source type: '%s', Target type: '%s'",
tmp_table->field[col]->field_name,
source_type.c_ptr(), target_type.c_ptr()));
}
}
#endif
*conv_table_var= tmp_table;
return true;
}
/**
Create a conversion table.
If the function is unable to create the conversion table, an error
will be printed and NULL will be returned.
@return Pointer to conversion table, or NULL if unable to create
conversion table.
*/
TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE *target_table) const
{
DBUG_ENTER("table_def::create_conversion_table");
List<Create_field> field_list;
for (uint col= 0 ; col < size() ; ++col)
{
Create_field *field_def=
(Create_field*) alloc_root(thd->mem_root, sizeof(Create_field));
if (field_list.push_back(field_def))
DBUG_RETURN(NULL);
uint decimals= 0;
TYPELIB* interval= NULL;
uint pack_length= 0;
uint32 max_length=
max_display_length_for_field(type(col), field_metadata(col));
switch(type(col))
{
int precision;
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
interval= static_cast<Field_enum*>(target_table->field[col])->typelib;
pack_length= field_metadata(col) & 0x00ff;
break;
case MYSQL_TYPE_NEWDECIMAL:
/*
The display length of a DECIMAL type is not the same as the
length that should be supplied to make_field, so we correct
the length here.
*/
precision= field_metadata(col) >> 8;
decimals= field_metadata(col) & 0x00ff;
max_length=
my_decimal_precision_to_length(precision, decimals, FALSE);
break;
case MYSQL_TYPE_DECIMAL:
precision= field_metadata(col);
decimals= static_cast<Field_num*>(target_table->field[col])->dec;
max_length= field_metadata(col);
break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_GEOMETRY:
pack_length= field_metadata(col) & 0x00ff;
break;
default:
break;
}
DBUG_PRINT("debug", ("sql_type: %d, target_field: '%s', max_length: %d, decimals: %d,"
" maybe_null: %d, unsigned_flag: %d, pack_length: %u",
type(col), target_table->field[col]->field_name,
max_length, decimals, TRUE, FALSE, pack_length));
field_def->init_for_tmp_table(type(col),
max_length,
decimals,
maybe_null(col), // maybe_null
FALSE, // unsigned_flag
pack_length);
field_def->charset= target_table->field[col]->charset();
field_def->interval= interval;
}
TABLE *conv_table= create_virtual_tmp_table(thd, field_list);
if (conv_table == NULL)
rli->report(ERROR_LEVEL, ER_SLAVE_CANT_CREATE_CONVERSION,
ER(ER_SLAVE_CANT_CREATE_CONVERSION),
target_table->s->db.str,
target_table->s->table_name.str);
DBUG_RETURN(conv_table);
}
#endif /* MYSQL_CLIENT */
table_def::table_def(unsigned char *types, ulong size,
uchar *field_metadata, int metadata_size,
uchar *null_bitmap)
: m_size(size), m_type(0), m_field_metadata_size(metadata_size),
m_field_metadata(0), m_null_bits(0), m_memory(NULL)
{
m_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
&m_type, size,
&m_field_metadata,
size * sizeof(uint16),
&m_null_bits, (size + 7) / 8,
NULL);
bzero(m_field_metadata, size * sizeof(uint16));
if (m_type)
memcpy(m_type, types, size);
else
m_size= 0;
/*
Extract the data from the table map into the field metadata array
iff there is field metadata. The variable metadata_size will be
0 if we are replicating from an older version server since no field
metadata was written to the table map. This can also happen if
there were no fields in the master that needed extra metadata.
*/
if (m_size && metadata_size)
{
int index= 0;
for (unsigned int i= 0; i < m_size; i++)
{
switch (m_type[i]) {
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_FLOAT:
{
/*
These types store a single byte.
*/
m_field_metadata[i]= field_metadata[index];
index++;
break;
}
case MYSQL_TYPE_SET:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_STRING:
{
uint16 x= field_metadata[index++] << 8U; // real_type
x+= field_metadata[index++]; // pack or field length
m_field_metadata[i]= x;
break;
}
case MYSQL_TYPE_BIT:
{
uint16 x= field_metadata[index++];
x = x + (field_metadata[index++] << 8U);
m_field_metadata[i]= x;
break;
}
case MYSQL_TYPE_VARCHAR:
{
/*
These types store two bytes.
*/
char *ptr= (char *)&field_metadata[index];
m_field_metadata[i]= uint2korr(ptr);
index= index + 2;
break;
}
case MYSQL_TYPE_NEWDECIMAL:
{
uint16 x= field_metadata[index++] << 8U; // precision
x+= field_metadata[index++]; // decimals
m_field_metadata[i]= x;
break;
}
default:
m_field_metadata[i]= 0;
break;
}
}
}
if (m_size && null_bitmap)
memcpy(m_null_bits, null_bitmap, (m_size + 7) / 8);
}
table_def::~table_def()
{
my_free(m_memory, MYF(0));
#ifndef DBUG_OFF
m_type= 0;
m_size= 0;
#endif
}

View File

@ -21,6 +21,7 @@
#endif
#include "mysql_priv.h"
#include "mysql_com.h"
class Relay_log_info;
@ -43,116 +44,19 @@ class Relay_log_info;
class table_def
{
public:
/**
Convenience declaration of the type of the field type data in a
table map event.
*/
typedef unsigned char field_type;
/**
Constructor.
@param types Array of types
@param types Array of types, each stored as a byte
@param size Number of elements in array 'types'
@param field_metadata Array of extra information about fields
@param metadata_size Size of the field_metadata array
@param null_bitmap The bitmap of fields that can be null
*/
table_def(field_type *types, ulong size, uchar *field_metadata,
int metadata_size, uchar *null_bitmap)
: m_size(size), m_type(0), m_field_metadata_size(metadata_size),
m_field_metadata(0), m_null_bits(0), m_memory(NULL)
{
m_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
&m_type, size,
&m_field_metadata,
size * sizeof(uint16),
&m_null_bits, (size + 7) / 8,
NULL);
table_def(unsigned char *types, ulong size, uchar *field_metadata,
int metadata_size, uchar *null_bitmap);
bzero(m_field_metadata, size * sizeof(uint16));
if (m_type)
memcpy(m_type, types, size);
else
m_size= 0;
/*
Extract the data from the table map into the field metadata array
iff there is field metadata. The variable metadata_size will be
0 if we are replicating from an older version server since no field
metadata was written to the table map. This can also happen if
there were no fields in the master that needed extra metadata.
*/
if (m_size && metadata_size)
{
int index= 0;
for (unsigned int i= 0; i < m_size; i++)
{
switch (m_type[i]) {
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_FLOAT:
{
/*
These types store a single byte.
*/
m_field_metadata[i]= field_metadata[index];
index++;
break;
}
case MYSQL_TYPE_SET:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_STRING:
{
uint16 x= field_metadata[index++] << 8U; // real_type
x+= field_metadata[index++]; // pack or field length
m_field_metadata[i]= x;
break;
}
case MYSQL_TYPE_BIT:
{
uint16 x= field_metadata[index++];
x = x + (field_metadata[index++] << 8U);
m_field_metadata[i]= x;
break;
}
case MYSQL_TYPE_VARCHAR:
{
/*
These types store two bytes.
*/
char *ptr= (char *)&field_metadata[index];
m_field_metadata[i]= uint2korr(ptr);
index= index + 2;
break;
}
case MYSQL_TYPE_NEWDECIMAL:
{
uint16 x= field_metadata[index++] << 8U; // precision
x+= field_metadata[index++]; // decimals
m_field_metadata[i]= x;
break;
}
default:
m_field_metadata[i]= 0;
break;
}
}
}
if (m_size && null_bitmap)
memcpy(m_null_bits, null_bitmap, (m_size + 7) / 8);
}
~table_def() {
my_free(m_memory, MYF(0));
#ifndef DBUG_OFF
m_type= 0;
m_size= 0;
#endif
}
~table_def();
/**
Return the number of fields there is type data for.
@ -171,10 +75,40 @@ public:
<code>index</code>. Currently, only the type identifier is
returned.
*/
field_type type(ulong index) const
enum_field_types type(ulong index) const
{
DBUG_ASSERT(index < m_size);
return m_type[index];
/*
If the source type is MYSQL_TYPE_STRING, it can in reality be
either MYSQL_TYPE_STRING, MYSQL_TYPE_ENUM, or MYSQL_TYPE_SET, so
we might need to modify the type to get the real type.
*/
enum_field_types source_type= static_cast<enum_field_types>(m_type[index]);
uint16 source_metadata= m_field_metadata[index];
switch (source_type)
{
case MYSQL_TYPE_STRING:
{
int real_type= source_metadata >> 8;
if (real_type == MYSQL_TYPE_ENUM || real_type == MYSQL_TYPE_SET)
source_type= static_cast<enum_field_types>(real_type);
break;
}
/*
This type has not been used since before row-based replication,
so we can safely assume that it really is MYSQL_TYPE_NEWDATE.
*/
case MYSQL_TYPE_DATE:
source_type= MYSQL_TYPE_NEWDATE;
break;
default:
/* Do nothing */
break;
}
return source_type;
}
@ -226,23 +160,58 @@ public:
with it.
A table definition is compatible with a table if:
- the columns types of the table definition is a (not
necessarily proper) prefix of the column type of the table, or
- the other way around
- The columns types of the table definition is a (not
necessarily proper) prefix of the column type of the table.
- The other way around.
- Each column on the master that also exists on the slave can be
converted according to the current settings of @c
SLAVE_TYPE_CONVERSIONS.
@param thd
@param rli Pointer to relay log info
@param table Pointer to table to compare with.
@param[out] tmp_table_var Pointer to temporary table for holding
conversion table.
@retval 1 if the table definition is not compatible with @c table
@retval 0 if the table definition is compatible with @c table
*/
#ifndef MYSQL_CLIENT
int compatible_with(Relay_log_info const *rli, TABLE *table) const;
bool compatible_with(THD *thd, Relay_log_info *rli, TABLE *table,
TABLE **conv_table_var) const;
/**
Create a virtual in-memory temporary table structure.
The table structure has records and field array so that a row can
be unpacked into the record for further processing.
In the virtual table, each field that requires conversion will
have a non-NULL value, while fields that do not require
conversion will have a NULL value.
Some information that is missing in the events, such as the
character set for string types, are taken from the table that the
field is going to be pushed into, so the target table that the data
eventually need to be pushed into need to be supplied.
@param thd Thread to allocate memory from.
@param rli Relay log info structure, for error reporting.
@param target_table Target table for fields.
@return A pointer to a temporary table with memory allocated in the
thread's memroot, NULL if the table could not be created
*/
TABLE *create_conversion_table(THD *thd, Relay_log_info *rli, TABLE *target_table) const;
#endif
private:
ulong m_size; // Number of elements in the types array
field_type *m_type; // Array of type descriptors
unsigned char *m_type; // Array of type descriptors
uint m_field_metadata_size;
uint16 *m_field_metadata;
uchar *m_null_bits;
@ -260,6 +229,7 @@ struct RPL_TABLE_LIST
{
bool m_tabledef_valid;
table_def m_tabledef;
TABLE *m_conv_table;
};

View File

@ -92,6 +92,33 @@ TYPELIB delay_key_write_typelib=
delay_key_write_type_names, NULL
};
/**
SLAVE_TYPE_CONVERSIONS variable.
Definition is equivalent to
@code
SET('ALL_NON_LOSSY', 'ALL_LOSSY')
@endcode
*/
const char *slave_type_conversions_type_name[]= {
"ALL_LOSSY",
"ALL_NON_LOSSY",
NullS
};
unsigned int slave_type_conversions_type_length[]= {
sizeof("ALL_LOSSY")-1,
sizeof("ALL_NON_LOSSY")-1,
0
};
TYPELIB slave_type_conversions_typelib=
{
array_elements(slave_type_conversions_type_name)-1, "",
slave_type_conversions_type_name,
slave_type_conversions_type_length
};
const char *slave_exec_mode_names[]=
{ "STRICT", "IDEMPOTENT", NullS };
static const unsigned int slave_exec_mode_names_len[]=
@ -580,6 +607,12 @@ static sys_var_set_slave_mode slave_exec_mode(&vars,
&slave_exec_mode_options,
&slave_exec_mode_typelib,
0);
static sys_var_set slave_type_conversions(&vars,
"slave_type_conversions",
&slave_type_conversions_options,
&slave_type_conversions_typelib,
0);
static sys_var_long_ptr sys_slow_launch_time(&vars, "slow_launch_time",
&slow_launch_time);
static sys_var_thd_ulong sys_sort_buffer(&vars, "sort_buffer_size",
@ -1261,7 +1294,6 @@ bool sys_var_thd_binlog_format::check(THD *thd, set_var *var) {
return result;
}
bool sys_var_thd_binlog_format::is_readonly() const
{
/*

View File

@ -32,6 +32,7 @@ typedef struct my_locale_st MY_LOCALE;
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib,
optimizer_switch_typelib, slave_exec_mode_typelib;
extern TYPELIB slave_type_conversions_typelib;
typedef int (*sys_check_func)(THD *, set_var *);
typedef bool (*sys_update_func)(THD *, set_var *);

View File

@ -6213,3 +6213,8 @@ ER_DEBUG_SYNC_TIMEOUT
ER_DEBUG_SYNC_HIT_LIMIT
eng "debug sync point hit limit reached"
ger "Debug Sync Point Hit Limit erreicht"
ER_SLAVE_CONVERSION_FAILED
eng "Column %d of table '%-.192s.%-.192s' cannot be converted from type '%-.32s' to type '%-.32s'"
ER_SLAVE_CANT_CREATE_CONVERSION
eng "Can't create conversion table for table '%-.192s.%-.192s'"

View File

@ -86,6 +86,12 @@ enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT,
SLAVE_EXEC_MODE_IDEMPOTENT,
SLAVE_EXEC_MODE_LAST_BIT};
enum enum_slave_type_conversions {
SLAVE_TYPE_CONVERSIONS_ALL_LOSSY,
SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY,
SLAVE_TYPE_CONVERSIONS_COUNT
};
enum enum_mark_columns
{ MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE};

View File

@ -10462,6 +10462,18 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
null_bit= 1;
}
}
if (cur_field->type() == MYSQL_TYPE_BIT &&
cur_field->key_type() == HA_KEYTYPE_BIT)
{
/* This is a Field_bit since key_type is HA_KEYTYPE_BIT */
static_cast<Field_bit*>(cur_field)->set_bit_ptr(null_pos, null_bit);
null_bit+= cur_field->field_length & 7;
if (null_bit > 7)
{
null_pos++;
null_bit-= 8;
}
}
cur_field->reset();
field_pos+= cur_field->pack_length();