Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
ca50d070
Commit
ca50d070
authored
Sep 13, 2006
by
mats@romeo.(none)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL#3259 (RBR with more columns on slave than master):
Incorporating changes from review. Fixing one bug that surfaced.
parent
f480cb0d
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
441 additions
and
62 deletions
+441
-62
mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
+66
-2
mysql-test/r/rpl_row_tabledefs_2myisam.result
mysql-test/r/rpl_row_tabledefs_2myisam.result
+100
-5
mysql-test/r/rpl_row_tabledefs_3innodb.result
mysql-test/r/rpl_row_tabledefs_3innodb.result
+96
-1
mysql-test/t/disabled.def
mysql-test/t/disabled.def
+0
-1
sql/field.cc
sql/field.cc
+8
-2
sql/field.h
sql/field.h
+28
-3
sql/log_event.cc
sql/log_event.cc
+72
-38
sql/rpl_utility.cc
sql/rpl_utility.cc
+0
-5
sql/rpl_utility.h
sql/rpl_utility.h
+71
-5
No files found.
mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
View file @
ca50d070
...
...
@@ -25,6 +25,8 @@ eval CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type;
eval
CREATE
TABLE
t4
(
a
INT
)
ENGINE
=
$engine_type
;
eval
CREATE
TABLE
t5
(
a
INT
,
b
INT
,
c
INT
)
ENGINE
=
$engine_type
;
eval
CREATE
TABLE
t6
(
a
INT
,
b
INT
,
c
INT
)
ENGINE
=
$engine_type
;
eval
CREATE
TABLE
t7
(
a
INT
NOT
NULL
)
ENGINE
=
$engine_type
;
eval
CREATE
TABLE
t8
(
a
INT
NOT
NULL
)
ENGINE
=
$engine_type
;
# Table used to detect that slave is running
eval
CREATE
TABLE
t9
(
a
INT
)
ENGINE
=
$engine_type
;
...
...
@@ -53,6 +55,17 @@ ALTER TABLE t5 MODIFY b FLOAT;
# ... change the type of the last column of table 't6'
ALTER
TABLE
t6
MODIFY
c
FLOAT
;
# ... add one byte worth of null bytes to the table on the slave
ALTER
TABLE
t7
ADD
e1
INT
,
ADD
e2
INT
,
ADD
e3
INT
,
ADD
e4
INT
,
ADD
e5
INT
,
ADD
e6
INT
,
ADD
e7
INT
,
ADD
e8
INT
;
# ... add 8 columns that are nullable: t8 will not be entirely
# nullable and have no null bits (just an X bit)
ALTER
TABLE
t8
ADD
e1
INT
NOT
NULL
DEFAULT
0
,
ADD
e2
INT
NOT
NULL
DEFAULT
0
,
ADD
e3
INT
NOT
NULL
DEFAULT
0
,
ADD
e4
INT
NOT
NULL
DEFAULT
0
,
ADD
e5
INT
NOT
NULL
DEFAULT
0
,
ADD
e6
INT
NOT
NULL
DEFAULT
0
,
ADD
e7
INT
NOT
NULL
DEFAULT
0
,
ADD
e8
INT
NOT
NULL
DEFAULT
0
;
# Insert some values for tables on slave side. These should not be
# modified when the row from the master is applied.
INSERT
INTO
t1_int
VALUES
(
2
,
4
,
4711
);
...
...
@@ -90,7 +103,7 @@ SELECT a,b,x FROM t1_int;
SELECT
a
,
b
,
HEX
(
x
),
HEX
(
y
),
HEX
(
z
)
FROM
t1_bit
;
SELECT
a
,
b
,
x
FROM
t1_char
;
# Each of these should generate an error and stop the slave
# Each of these
inserts
should generate an error and stop the slave
connection
master
;
INSERT
INTO
t9
VALUES
(
2
);
...
...
@@ -162,9 +175,60 @@ wait_for_slave_to_stop;
SET
GLOBAL
SQL_SLAVE_SKIP_COUNTER
=
2
;
START
SLAVE
;
connection
master
;
INSERT
INTO
t9
VALUES
(
6
);
sync_slave_with_master
;
--
replace_result
$MASTER_MYPORT
MASTER_PORT
--
replace_column
1
# 7 # 8 # 9 # 22 # 23 # 33 #
--
query_vertical
SHOW
SLAVE
STATUS
# Testing some tables extra field that can be null and cannot be null
# (but have default values)
connection
master
;
INSERT
INTO
t7
VALUES
(
1
),(
2
),(
3
);
INSERT
INTO
t8
VALUES
(
1
),(
2
),(
3
);
SELECT
*
FROM
t7
;
SELECT
*
FROM
t8
;
sync_slave_with_master
;
SELECT
*
FROM
t7
;
SELECT
*
FROM
t8
;
# We will now try to update and then delete a row on the master where
# the extra field on the slave does not have a default value. This
# update should not generate an error even though there is no default
# for the extra column.
--
echo
****
On
Master
****
connection
master
;
TRUNCATE
t1_nodef
;
SET
SQL_LOG_BIN
=
0
;
INSERT
INTO
t1_nodef
VALUES
(
1
,
2
);
INSERT
INTO
t1_nodef
VALUES
(
2
,
4
);
SET
SQL_LOG_BIN
=
1
;
--
echo
****
On
Slave
****
connection
slave
;
INSERT
INTO
t1_nodef
VALUES
(
1
,
2
,
3
);
INSERT
INTO
t1_nodef
VALUES
(
2
,
4
,
6
);
--
echo
****
On
Master
****
connection
master
;
UPDATE
t1_nodef
SET
b
=
2
*
b
WHERE
a
=
1
;
SELECT
*
FROM
t1_nodef
;
--
echo
****
On
Slave
****
sync_slave_with_master
;
SELECT
*
FROM
t1_nodef
;
--
echo
****
On
Master
****
connection
master
;
DELETE
FROM
t1_nodef
WHERE
a
=
2
;
SELECT
*
FROM
t1_nodef
;
--
echo
****
On
Slave
****
sync_slave_with_master
;
SELECT
*
FROM
t1_nodef
;
--
echo
****
Cleanup
****
connection
master
;
--
disable_warnings
DROP
TABLE
IF
EXISTS
t1_int
,
t1_bit
,
t1_char
,
t1_nodef
;
DROP
TABLE
IF
EXISTS
t2
,
t3
,
t4
,
t5
,
t6
,
t9
;
DROP
TABLE
IF
EXISTS
t2
,
t3
,
t4
,
t5
,
t6
,
t
7
,
t8
,
t
9
;
--
enable_warnings
sync_slave_with_master
;
mysql-test/r/rpl_row_tabledefs_2myisam.result
View file @
ca50d070
...
...
@@ -16,6 +16,8 @@ CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE='MyISAM';
CREATE TABLE t4 (a INT) ENGINE='MyISAM';
CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='MyISAM';
CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='MyISAM';
CREATE TABLE t7 (a INT NOT NULL) ENGINE='MyISAM';
CREATE TABLE t8 (a INT NOT NULL) ENGINE='MyISAM';
CREATE TABLE t9 (a INT) ENGINE='MyISAM';
ALTER TABLE t1_int ADD x INT DEFAULT 42;
ALTER TABLE t1_bit
...
...
@@ -28,6 +30,12 @@ ALTER TABLE t2 DROP b;
ALTER TABLE t4 MODIFY a FLOAT;
ALTER TABLE t5 MODIFY b FLOAT;
ALTER TABLE t6 MODIFY c FLOAT;
ALTER TABLE t7 ADD e1 INT, ADD e2 INT, ADD e3 INT, ADD e4 INT,
ADD e5 INT, ADD e6 INT, ADD e7 INT, ADD e8 INT;
ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0,
ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0,
ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0,
ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0;
INSERT INTO t1_int VALUES (2, 4, 4711);
INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar');
INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01');
...
...
@@ -151,7 +159,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 15
14
Last_Errno 15
22
Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns
Skip_Counter 0
Exec_Master_Log_Pos #
...
...
@@ -189,7 +197,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 15
14
Last_Errno 15
22
Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4
Skip_Counter 0
Exec_Master_Log_Pos #
...
...
@@ -227,7 +235,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 15
14
Last_Errno 15
22
Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4
Skip_Counter 0
Exec_Master_Log_Pos #
...
...
@@ -265,7 +273,7 @@ Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 15
14
Last_Errno 15
22
Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4
Skip_Counter 0
Exec_Master_Log_Pos #
...
...
@@ -282,5 +290,92 @@ Master_SSL_Key
Seconds_Behind_Master #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (6);
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos #
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
INSERT INTO t7 VALUES (1),(2),(3);
INSERT INTO t8 VALUES (1),(2),(3);
SELECT * FROM t7;
a
1
2
3
SELECT * FROM t8;
a
1
2
3
SELECT * FROM t7;
a e1 e2 e3 e4 e5 e6 e7 e8
1 NULL NULL NULL NULL NULL NULL NULL NULL
2 NULL NULL NULL NULL NULL NULL NULL NULL
3 NULL NULL NULL NULL NULL NULL NULL NULL
SELECT * FROM t8;
a e1 e2 e3 e4 e5 e6 e7 e8
1 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0
**** On Master ****
TRUNCATE t1_nodef;
SET SQL_LOG_BIN=0;
INSERT INTO t1_nodef VALUES (1,2);
INSERT INTO t1_nodef VALUES (2,4);
SET SQL_LOG_BIN=1;
**** On Slave ****
INSERT INTO t1_nodef VALUES (1,2,3);
INSERT INTO t1_nodef VALUES (2,4,6);
**** On Master ****
UPDATE t1_nodef SET b=2*b WHERE a=1;
SELECT * FROM t1_nodef;
a b
1 4
2 4
**** On Slave ****
SELECT * FROM t1_nodef;
a b x
1 4 3
2 4 6
**** On Master ****
DELETE FROM t1_nodef WHERE a=2;
SELECT * FROM t1_nodef;
a b
1 4
**** On Slave ****
SELECT * FROM t1_nodef;
a b x
1 4 3
**** Cleanup ****
DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef;
DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9;
DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t
7,t8,t
9;
mysql-test/r/rpl_row_tabledefs_3innodb.result
View file @
ca50d070
...
...
@@ -16,6 +16,8 @@ CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE='InnoDB';
CREATE TABLE t4 (a INT) ENGINE='InnoDB';
CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='InnoDB';
CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='InnoDB';
CREATE TABLE t7 (a INT NOT NULL) ENGINE='InnoDB';
CREATE TABLE t8 (a INT NOT NULL) ENGINE='InnoDB';
CREATE TABLE t9 (a INT) ENGINE='InnoDB';
ALTER TABLE t1_int ADD x INT DEFAULT 42;
ALTER TABLE t1_bit
...
...
@@ -28,6 +30,12 @@ ALTER TABLE t2 DROP b;
ALTER TABLE t4 MODIFY a FLOAT;
ALTER TABLE t5 MODIFY b FLOAT;
ALTER TABLE t6 MODIFY c FLOAT;
ALTER TABLE t7 ADD e1 INT, ADD e2 INT, ADD e3 INT, ADD e4 INT,
ADD e5 INT, ADD e6 INT, ADD e7 INT, ADD e8 INT;
ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0,
ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0,
ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0,
ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0;
INSERT INTO t1_int VALUES (2, 4, 4711);
INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar');
INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01');
...
...
@@ -282,5 +290,92 @@ Master_SSL_Key
Seconds_Behind_Master #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (6);
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos #
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
INSERT INTO t7 VALUES (1),(2),(3);
INSERT INTO t8 VALUES (1),(2),(3);
SELECT * FROM t7;
a
1
2
3
SELECT * FROM t8;
a
1
2
3
SELECT * FROM t7;
a e1 e2 e3 e4 e5 e6 e7 e8
1 NULL NULL NULL NULL NULL NULL NULL NULL
2 NULL NULL NULL NULL NULL NULL NULL NULL
3 NULL NULL NULL NULL NULL NULL NULL NULL
SELECT * FROM t8;
a e1 e2 e3 e4 e5 e6 e7 e8
1 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0
**** On Master ****
TRUNCATE t1_nodef;
SET SQL_LOG_BIN=0;
INSERT INTO t1_nodef VALUES (1,2);
INSERT INTO t1_nodef VALUES (2,4);
SET SQL_LOG_BIN=1;
**** On Slave ****
INSERT INTO t1_nodef VALUES (1,2,3);
INSERT INTO t1_nodef VALUES (2,4,6);
**** On Master ****
UPDATE t1_nodef SET b=2*b WHERE a=1;
SELECT * FROM t1_nodef;
a b
1 4
2 4
**** On Slave ****
SELECT * FROM t1_nodef;
a b x
1 4 3
2 4 6
**** On Master ****
DELETE FROM t1_nodef WHERE a=2;
SELECT * FROM t1_nodef;
a b
1 4
**** On Slave ****
SELECT * FROM t1_nodef;
a b x
1 4 3
**** Cleanup ****
DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef;
DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9;
DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t
7,t8,t
9;
mysql-test/t/disabled.def
View file @
ca50d070
...
...
@@ -36,7 +36,6 @@ rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly
rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed
rpl_row_inexist_tbl : BUG#18948 2006-03-09 mats Disabled since patch makes this test wait forever
rpl_sp : BUG#16456 2006-02-16 jmiller
rpl_sp_effects : BUG#19862 2006-08-22 mats Bug appear to be fixed
rpl_until : BUG#15886 2006-02-16 jmiller Unstable test case
sp-goto : BUG#18949 2006-02-16 jmiller GOTO is currently is disabled - will be fixed in the future
mysqldump : BUG#18078 2006-03-10 lars
...
...
sql/field.cc
View file @
ca50d070
...
...
@@ -1261,7 +1261,10 @@ my_size_t
Field
::
do_last_null_byte
()
const
{
DBUG_ASSERT
(
null_ptr
==
NULL
||
(
byte
*
)
null_ptr
>=
table
->
record
[
0
]);
return
null_ptr
?
(
byte
*
)
null_ptr
-
table
->
record
[
0
]
+
1
:
0
;
if
(
null_ptr
)
return
(
byte
*
)
null_ptr
-
table
->
record
[
0
]
+
1
;
else
return
LAST_NULL_BYTE_UNDEF
;
}
...
...
@@ -8196,7 +8199,10 @@ Field_bit::do_last_null_byte() const
else
result
=
bit_ptr
;
return
result
?
(
byte
*
)
result
-
table
->
record
[
0
]
+
1
:
0
;
if
(
result
)
return
(
byte
*
)
result
-
table
->
record
[
0
]
+
1
;
else
return
LAST_NULL_BYTE_UNDEF
;
}
Field
*
Field_bit
::
new_key_field
(
MEM_ROOT
*
root
,
...
...
sql/field.h
View file @
ca50d070
...
...
@@ -208,10 +208,24 @@ class Field
inline
bool
maybe_null
(
void
)
{
return
null_ptr
!=
0
||
table
->
maybe_null
;
}
inline
bool
real_maybe_null
(
void
)
{
return
null_ptr
!=
0
;
}
enum
{
LAST_NULL_BYTE_UNDEF
=
0
};
/*
Return a pointer to the last byte of the null bytes where the
field conceptually is placed. In the case that the field does not
use any bits of the null bytes, a null pointer is returned.
Find the position of the last null byte for the field.
SYNOPSIS
last_null_byte()
DESCRIPTION
Return a pointer to the last byte of the null bytes where the
field conceptually is placed.
RETURN VALUE
The position of the last null byte relative to the beginning of
the record. If the field does not use any bits of the null
bytes, the value 0 (LAST_NULL_BYTE_UNDEF) is returned.
*/
my_size_t
last_null_byte
()
const
{
my_size_t
bytes
=
do_last_null_byte
();
...
...
@@ -384,6 +398,17 @@ class Field
friend
class
Item_func_group_concat
;
private:
/*
Primitive for implementing last_null_byte().
SYNOPSIS
do_last_null_byte()
DESCRIPTION
Primitive for the implementation of the last_null_byte()
function. This represents the inheritance interface and can be
overridden by subclasses.
*/
virtual
my_size_t
do_last_null_byte
()
const
;
};
...
...
sql/log_event.cc
View file @
ca50d070
...
...
@@ -5304,7 +5304,7 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
row_end Pointer to variable that will hold the value of the
one-after-end position for the row
master_reclength
Pointer to variable that will
hold
the length of the
Pointer to variable that will
be set to
the length of the
record on the master side
rw_set Pointer to bitmap that holds either the read_set or the
write_set of the table
...
...
@@ -5317,13 +5317,22 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
At most 'colcnt' columns are read: if the table is larger than
that, the remaining fields are not filled in.
RETURN VALUE
Error code, or zero if no error. The following error codes can
be returned:
ER_NO_DEFAULT_FOR_FIELD
Returned if one of the fields existing on the slave but not on
the master does not have a default value (and isn't nullable)
*/
static
int
unpack_row
(
RELAY_LOG_INFO
*
rli
,
TABLE
*
table
,
uint
const
colcnt
,
byte
*
record
,
char
const
*
row
,
MY_BITMAP
const
*
cols
,
char
const
**
row_end
,
ulong
*
master_reclength
,
MY_BITMAP
*
const
rw_set
)
MY_BITMAP
*
const
rw_set
,
Log_event_type
const
event_type
)
{
DBUG_ASSERT
(
record
&&
row
);
my_ptrdiff_t
const
offset
=
record
-
(
byte
*
)
table
->
record
[
0
];
...
...
@@ -5334,10 +5343,20 @@ unpack_row(RELAY_LOG_INFO *rli,
Field
**
fptr
=
&
table
->
field
[
colcnt
-
1
];
do
master_null_bytes
=
(
*
fptr
)
->
last_null_byte
();
while
(
master_null_bytes
==
0
&&
fptr
--
>
table
->
field
);
while
(
master_null_bytes
==
Field
::
LAST_NULL_BYTE_UNDEF
&&
fptr
--
>
table
->
field
);
/*
If master_null_bytes is LAST_NULL_BYTE_UNDEF (0) at this time,
there were no nullable fields nor BIT fields at all in the
columns that are common to the master and the slave. In that
case, there is only one null byte holding the X bit.
if
(
master_null_bytes
==
0
)
master_null_bytes
=
table
->
s
->
null_bytes
;
OBSERVE! There might still be nullable columns following the
common columns, so table->s->null_bytes might be greater than 1.
*/
if
(
master_null_bytes
==
Field
::
LAST_NULL_BYTE_UNDEF
)
master_null_bytes
=
1
;
}
DBUG_ASSERT
(
master_null_bytes
<=
table
->
s
->
null_bytes
);
...
...
@@ -5348,31 +5367,29 @@ unpack_row(RELAY_LOG_INFO *rli,
Field
**
const
begin_ptr
=
table
->
field
;
Field
**
field_ptr
;
char
const
*
ptr
=
row
+
master_null_bytes
;
Field
**
const
end_ptr
=
begin_ptr
+
colcnt
;
for
(
field_ptr
=
begin_ptr
;
field_ptr
<
end_ptr
;
++
field_ptr
)
{
char
const
*
ptr
=
row
+
master_null_bytes
;
Field
**
const
end_ptr
=
begin_ptr
+
colcnt
;
for
(
field_ptr
=
begin_ptr
;
field_ptr
<
end_ptr
;
++
field_ptr
)
{
Field
*
const
f
=
*
field_ptr
;
if
(
bitmap_is_set
(
cols
,
field_ptr
-
begin_ptr
))
{
ptr
=
f
->
unpack
(
f
->
ptr
+
offset
,
ptr
);
/* Field...::unpack() cannot return 0 */
DBUG_ASSERT
(
ptr
!=
NULL
);
}
else
bitmap_clear_bit
(
rw_set
,
field_ptr
-
begin_ptr
);
}
Field
*
const
f
=
*
field_ptr
;
*
row_end
=
ptr
;
if
(
master_reclength
)
if
(
bitmap_is_set
(
cols
,
field_ptr
-
begin_ptr
))
{
if
(
*
field_ptr
)
*
master_reclength
=
(
*
field_ptr
)
->
ptr
-
(
char
*
)
table
->
record
[
0
];
else
*
master_reclength
=
table
->
s
->
reclength
;
ptr
=
f
->
unpack
(
f
->
ptr
+
offset
,
ptr
);
/* Field...::unpack() cannot return 0 */
DBUG_ASSERT
(
ptr
!=
NULL
);
}
else
bitmap_clear_bit
(
rw_set
,
field_ptr
-
begin_ptr
);
}
*
row_end
=
ptr
;
if
(
master_reclength
)
{
if
(
*
field_ptr
)
*
master_reclength
=
(
*
field_ptr
)
->
ptr
-
(
char
*
)
table
->
record
[
0
];
else
*
master_reclength
=
table
->
s
->
reclength
;
}
/*
...
...
@@ -5381,16 +5398,26 @@ unpack_row(RELAY_LOG_INFO *rli,
it was not there already. We iterate over all remaining columns,
even if there were an error, to get as many error messages as
possible. We are still able to return a pointer to the next row,
so wedo that.
so redo that.
This generation of error messages is only relevant when inserting
new rows.
*/
for
(
;
*
field_ptr
;
++
field_ptr
)
{
if
((
*
field_ptr
)
->
flags
&
(
NOT_NULL_FLAG
|
NO_DEFAULT_VALUE_FLAG
))
uint32
const
mask
=
NOT_NULL_FLAG
|
NO_DEFAULT_VALUE_FLAG
;
DBUG_PRINT
(
"debug"
,
(
"flags = 0x%x, mask = 0x%x, flags & mask = 0x%x"
,
(
*
field_ptr
)
->
flags
,
mask
,
(
*
field_ptr
)
->
flags
&
mask
));
if
(
event_type
==
WRITE_ROWS_EVENT
&&
((
*
field_ptr
)
->
flags
&
mask
)
==
mask
)
{
slave_print_msg
(
ERROR_LEVEL
,
rli
,
ER_NO_DEFAULT_FOR_FIELD
,
slave_print_msg
(
ERROR_LEVEL
,
rli
,
ER_NO_DEFAULT_FOR_FIELD
,
"Field `%s` of table `%s`.`%s` "
"has no default value and cannot be NULL"
,
(
*
field_ptr
)
->
field_name
,
table
->
s
->
db
.
str
,
(
*
field_ptr
)
->
field_name
,
table
->
s
->
db
.
str
,
table
->
s
->
table_name
.
str
);
error
=
ER_NO_DEFAULT_FOR_FIELD
;
}
...
...
@@ -5562,8 +5589,8 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
{
char
const
*
row_end
=
NULL
;
if
((
error
=
do_prepare_row
(
thd
,
rli
,
table
,
row_start
,
&
row_end
)))
break
;
// We should
to the after-row operation even in the
// case of error
break
;
// We should
perform the after-row operation even in
//
the
case of error
DBUG_ASSERT
(
row_end
!=
NULL
);
// cannot happen
DBUG_ASSERT
(
row_end
<=
(
const
char
*
)
m_rows_end
);
...
...
@@ -6224,7 +6251,7 @@ int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
error
=
unpack_row
(
rli
,
table
,
m_width
,
table
->
record
[
0
],
row_start
,
&
m_cols
,
row_end
,
&
m_master_reclength
,
table
->
write_set
);
table
->
write_set
,
WRITE_ROWS_EVENT
);
bitmap_copy
(
table
->
read_set
,
table
->
write_set
);
return
error
;
}
...
...
@@ -6285,10 +6312,17 @@ copy_extra_record_fields(TABLE *table,
my_size_t
master_reclength
,
my_ptrdiff_t
master_fields
)
{
DBUG_PRINT
(
"info"
,
(
"Copying to %p from field %d at offset %u to field %d at offset %u"
,
table
->
record
[
0
],
DBUG_PRINT
(
"info"
,
(
"Copying to %p "
"from field %d at offset %u "
"to field %d at offset %u"
,
table
->
record
[
0
],
master_fields
,
master_reclength
,
table
->
s
->
fields
,
table
->
s
->
reclength
));
/*
Copying the extra fields of the slave that does not exist on
master into record[0] (which are basically the default values).
*/
DBUG_ASSERT
(
master_reclength
<=
table
->
s
->
reclength
);
if
(
master_reclength
<
table
->
s
->
reclength
)
bmove_align
(
table
->
record
[
0
]
+
master_reclength
,
table
->
record
[
1
]
+
master_reclength
,
...
...
@@ -6771,7 +6805,7 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
error
=
unpack_row
(
rli
,
table
,
m_width
,
table
->
record
[
0
],
row_start
,
&
m_cols
,
row_end
,
&
m_master_reclength
,
table
->
read_set
);
table
->
read_set
,
DELETE_ROWS_EVENT
);
/*
If we will access rows using the random access method, m_key will
be set to NULL, so we do not need to make a key copy in that case.
...
...
@@ -6914,13 +6948,13 @@ int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
error
=
unpack_row
(
rli
,
table
,
m_width
,
table
->
record
[
0
],
row_start
,
&
m_cols
,
row_end
,
&
m_master_reclength
,
table
->
read_set
);
table
->
read_set
,
UPDATE_ROWS_EVENT
);
row_start
=
*
row_end
;
/* m_after_image is the after image for the update */
error
=
unpack_row
(
rli
,
table
,
m_width
,
m_after_image
,
row_start
,
&
m_cols
,
row_end
,
&
m_master_reclength
,
table
->
write_set
);
table
->
write_set
,
UPDATE_ROWS_EVENT
);
/*
If we will access rows using the random access method, m_key will
...
...
sql/rpl_utility.cc
View file @
ca50d070
...
...
@@ -107,11 +107,6 @@ field_length_from_packed(enum_field_types const field_type,
/*
Is the definition compatible with a table?
Compare the definition with a table to see if it is compatible 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
*/
int
table_def
::
compatible_with
(
RELAY_LOG_INFO
*
rli
,
TABLE
*
table
)
...
...
sql/rpl_utility.h
View file @
ca50d070
...
...
@@ -32,29 +32,95 @@ field_length_from_packed(enum_field_types const field_type,
RESPONSIBILITIES
- Extract table definition data from the table map event
- Extract
and decode
table definition data from the table map event
- Check if table definition in table map is compatible with table
definition on slave
DESCRIPTION
Currently, the only field type data available is an array of the
type operators that are present in the table map event.
TODO
Add type operands to this structure to allow detection of
difference between, e.g., BIT(5) and BIT(10).
*/
class
table_def
{
public:
/*
Convenience declaration of the type of the field type data in a
table map event.
*/
typedef
unsigned
char
field_type
;
table_def
(
field_type
*
t
,
my_size_t
s
)
:
m_type
(
t
),
m_size
(
s
)
/*
Constructor.
SYNOPSIS
table_def()
types Array of types
size Number of elements in array 'types'
*/
table_def
(
field_type
*
types
,
my_size_t
size
)
:
m_type
(
types
),
m_size
(
size
)
{
}
/*
Return the number of fields there is type data for.
SYNOPSIS
size()
RETURN VALUE
The number of fields that there is type data for.
*/
my_size_t
size
()
const
{
return
m_size
;
}
/*
Return a representation of the type data for one field.
SYNOPSIS
type()
i Field index to return data for
RETURN VALUE
Will return a representation of the type data for field
'i'. Currently, only the type identifier is returned.
*/
field_type
type
(
my_ptrdiff_t
i
)
const
{
return
m_type
[
i
];
}
/*
Decide if the table definition is compatible with a table.
SYNOPSIS
compatible_with()
rli Pointer to relay log info
table Pointer to table to compare with.
DESCRIPTION
Compare the definition with a table to see if it is compatible
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
RETURN VALUE
1 if the table definition is not compatible with 'table'
0 if the table definition is compatible with 'table'
*/
int
compatible_with
(
RELAY_LOG_INFO
*
rli
,
TABLE
*
table
)
const
;
private:
my_size_t
m_size
;
field_type
*
m_type
;
my_size_t
m_size
;
// Number of elements in the types array
field_type
*
m_type
;
// Array of type descriptors
};
#endif
/* RPL_UTILITY_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment