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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
67909baa
Commit
67909baa
authored
May 08, 2006
by
mats@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL#3259 (RBR with more columns on slave than on master):
Added support for UPDATE. Some minor fixes.
parent
89df5b6b
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
828 additions
and
105 deletions
+828
-105
mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
+42
-22
mysql-test/r/rpl_row_tabledefs_2myisam.result
mysql-test/r/rpl_row_tabledefs_2myisam.result
+50
-18
mysql-test/r/rpl_row_tabledefs_3innodb.result
mysql-test/r/rpl_row_tabledefs_3innodb.result
+286
-0
mysql-test/r/rpl_row_tabledefs_7ndb.result
mysql-test/r/rpl_row_tabledefs_7ndb.result
+286
-0
mysql-test/t/rpl_row_tabledefs_2myisam.test
mysql-test/t/rpl_row_tabledefs_2myisam.test
+0
-0
mysql-test/t/rpl_row_tabledefs_3innodb.test
mysql-test/t/rpl_row_tabledefs_3innodb.test
+9
-0
sql/field.cc
sql/field.cc
+32
-0
sql/field.h
sql/field.h
+19
-0
sql/log_event.cc
sql/log_event.cc
+104
-65
No files found.
mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
View file @
67909baa
...
...
@@ -3,7 +3,14 @@
# Consider making these part of the basic RBR tests.
connection
slave
;
connection
master
;
--
disable_warnings
--
disable_query_log
DROP
TABLE
IF
EXISTS
t1_int
,
t1_bit
,
t1_char
,
t1_nodef
;
DROP
TABLE
IF
EXISTS
t2
,
t3
,
t4
,
t5
,
t6
,
t9
;
--
enable_query_log
--
enable_warnings
sync_slave_with_master
;
STOP
SLAVE
;
SET
GLOBAL
SQL_MODE
=
'STRICT_ALL_TABLES'
;
START
SLAVE
;
...
...
@@ -26,8 +33,12 @@ sync_slave_with_master;
# On the slave, we add one INT column last in table 't1_int',
ALTER
TABLE
t1_int
ADD
x
INT
DEFAULT
42
;
# ... and add one BIT column last in table 't1_bit',
ALTER
TABLE
t1_bit
ADD
x
BIT
(
3
)
DEFAULT
b
'011'
;
# ... and add BIT columns last in table 't1_bit' to ensure that we
# have at least one extra null byte on the slave,
ALTER
TABLE
t1_bit
ADD
x
BIT
(
3
)
DEFAULT
b
'011'
,
ADD
y
BIT
(
5
)
DEFAULT
b
'10101'
,
ADD
z
BIT
(
2
)
DEFAULT
b
'10'
;
# ... and add one CHAR column last in table 't1_char',
ALTER
TABLE
t1_char
ADD
x
CHAR
(
20
)
DEFAULT
'Just a test'
;
# ... and add one non-nullable INT column last in table 't1_text'
...
...
@@ -44,9 +55,9 @@ ALTER TABLE t6 MODIFY c FLOAT;
# 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
);
INSERT
INTO
t1_char
VALUES
(
2
,
4
,
'Foo is a bar'
);
INSERT
INTO
t1_bit
VALUES
(
2
,
4
,
b
'1
01'
);
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'
);
--
echo
****
On
Master
****
connection
master
;
...
...
@@ -62,7 +73,21 @@ SELECT * FROM t1_char;
--
echo
****
On
Slave
****
sync_slave_with_master
;
SELECT
a
,
b
,
x
FROM
t1_int
;
SELECT
a
,
b
,
HEX
(
x
)
FROM
t1_bit
;
SELECT
a
,
b
,
HEX
(
x
),
HEX
(
y
),
HEX
(
z
)
FROM
t1_bit
;
SELECT
a
,
b
,
x
FROM
t1_char
;
--
echo
****
On
Master
****
connection
master
;
UPDATE
t1_int
SET
b
=
2
*
b
WHERE
a
=
2
;
UPDATE
t1_char
SET
b
=
2
*
b
WHERE
a
=
2
;
UPDATE
t1_bit
SET
b
=
2
*
b
WHERE
a
=
2
;
SELECT
*
FROM
t1_int
;
SELECT
*
FROM
t1_bit
;
SELECT
*
FROM
t1_char
;
--
echo
****
On
Slave
****
sync_slave_with_master
;
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
...
...
@@ -76,9 +101,8 @@ INSERT INTO t1_nodef VALUES (1,2);
connection
slave
;
wait_for_slave_to_stop
;
--
replace_result
$MASTER_MYPORT
MASTER_PORT
--
replace_column
1
# 8 # 9 # 23 # 33 #
--
vertical_results
SHOW
SLAVE
STATUS
;
--
replace_column
1
# 7 # 8 # 9 # 22 # 23 # 33 #
--
query_vertical
SHOW
SLAVE
STATUS
SET
GLOBAL
SQL_SLAVE_SKIP_COUNTER
=
2
;
START
SLAVE
;
...
...
@@ -91,9 +115,8 @@ INSERT INTO t2 VALUES (2,4);
connection
slave
;
wait_for_slave_to_stop
;
--
replace_result
$MASTER_MYPORT
MASTER_PORT
--
replace_column
1
# 8 # 9 # 23 # 33 #
--
vertical_results
SHOW
SLAVE
STATUS
;
--
replace_column
1
# 7 # 8 # 9 # 22 # 23 # 33 #
--
query_vertical
SHOW
SLAVE
STATUS
SET
GLOBAL
SQL_SLAVE_SKIP_COUNTER
=
2
;
START
SLAVE
;
...
...
@@ -106,9 +129,8 @@ INSERT INTO t4 VALUES (4);
connection
slave
;
wait_for_slave_to_stop
;
--
replace_result
$MASTER_MYPORT
MASTER_PORT
--
replace_column
1
# 8 # 9 # 23 # 33 #
--
vertical_results
SHOW
SLAVE
STATUS
;
--
replace_column
1
# 7 # 8 # 9 # 22 # 23 # 33 #
--
query_vertical
SHOW
SLAVE
STATUS
SET
GLOBAL
SQL_SLAVE_SKIP_COUNTER
=
2
;
START
SLAVE
;
...
...
@@ -121,9 +143,8 @@ INSERT INTO t5 VALUES (5,10,25);
connection
slave
;
wait_for_slave_to_stop
;
--
replace_result
$MASTER_MYPORT
MASTER_PORT
--
replace_column
1
# 8 # 9 # 23 # 33 #
--
vertical_results
SHOW
SLAVE
STATUS
;
--
replace_column
1
# 7 # 8 # 9 # 22 # 23 # 33 #
--
query_vertical
SHOW
SLAVE
STATUS
SET
GLOBAL
SQL_SLAVE_SKIP_COUNTER
=
2
;
START
SLAVE
;
...
...
@@ -136,9 +157,8 @@ INSERT INTO t6 VALUES (6,12,36);
connection
slave
;
wait_for_slave_to_stop
;
--
replace_result
$MASTER_MYPORT
MASTER_PORT
--
replace_column
1
# 8 # 9 # 23 # 33 #
--
vertical_results
SHOW
SLAVE
STATUS
;
--
replace_column
1
# 7 # 8 # 9 # 22 # 23 # 33 #
--
query_vertical
SHOW
SLAVE
STATUS
SET
GLOBAL
SQL_SLAVE_SKIP_COUNTER
=
2
;
START
SLAVE
;
...
...
mysql-test/r/rpl_row_tabledefs.result
→
mysql-test/r/rpl_row_tabledefs
_2myisam
.result
View file @
67909baa
...
...
@@ -18,16 +18,19 @@ CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='MyISAM';
CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='MyISAM';
CREATE TABLE t9 (a INT) ENGINE='MyISAM';
ALTER TABLE t1_int ADD x INT DEFAULT 42;
ALTER TABLE t1_bit ADD x BIT(3) DEFAULT b'011';
ALTER TABLE t1_bit
ADD x BIT(3) DEFAULT b'011',
ADD y BIT(5) DEFAULT b'10101',
ADD z BIT(2) DEFAULT b'10';
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
ALTER TABLE t1_nodef ADD x INT NOT NULL;
ALTER TABLE t2 DROP b;
ALTER TABLE t4 MODIFY a FLOAT;
ALTER TABLE t5 MODIFY b FLOAT;
ALTER TABLE t6 MODIFY c FLOAT;
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'1
01');
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');
**** On Master ****
INSERT INTO t1_int VALUES (1,2);
INSERT INTO t1_int VALUES (2,5);
...
...
@@ -52,14 +55,43 @@ SELECT a,b,x FROM t1_int;
a b x
2 5 4711
1 2 42
SELECT a,b,HEX(x) FROM t1_bit;
a b HEX(x)
2 5 5
1 2 3
SELECT a,b,HEX(x)
,HEX(y),HEX(z)
FROM t1_bit;
a b HEX(x)
HEX(y) HEX(z)
2 5 5
1C 1
1 2 3
15 2
SELECT a,b,x FROM t1_char;
a b x
2 5 Foo is a bar
1 2 Just a test
**** On Master ****
UPDATE t1_int SET b=2*b WHERE a=2;
UPDATE t1_char SET b=2*b WHERE a=2;
UPDATE t1_bit SET b=2*b WHERE a=2;
SELECT * FROM t1_int;
a b
1 2
2 10
SELECT * FROM t1_bit;
a b
1 2
2 10
SELECT * FROM t1_char;
a b
1 2
2 10
**** On Slave ****
SELECT a,b,x FROM t1_int;
a b x
2 10 4711
1 2 42
SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit;
a b HEX(x) HEX(y) HEX(z)
2 10 5 1C 1
1 2 3 15 2
SELECT a,b,x FROM t1_char;
a b x
2 10 Foo is a bar
1 2 Just a test
INSERT INTO t9 VALUES (2);
INSERT INTO t1_nodef VALUES (1,2);
SHOW SLAVE STATUS;
...
...
@@ -69,7 +101,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos
1934
Read_Master_Log_Pos
#
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
...
...
@@ -84,7 +116,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 1364
Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef
Skip_Counter 0
Exec_Master_Log_Pos
1850
Exec_Master_Log_Pos
#
Relay_Log_Space #
Until_Condition None
Until_Log_File
...
...
@@ -107,7 +139,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos
2085
Read_Master_Log_Pos
#
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
...
...
@@ -122,7 +154,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns
Skip_Counter 0
Exec_Master_Log_Pos
2007
Exec_Master_Log_Pos
#
Relay_Log_Space #
Until_Condition None
Until_Log_File
...
...
@@ -145,7 +177,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos
2231
Read_Master_Log_Pos
#
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
...
...
@@ -160,7 +192,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4
Skip_Counter 0
Exec_Master_Log_Pos
2158
Exec_Master_Log_Pos
#
Relay_Log_Space #
Until_Condition None
Until_Log_File
...
...
@@ -183,7 +215,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos
2387
Read_Master_Log_Pos
#
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
...
...
@@ -198,7 +230,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4
Skip_Counter 0
Exec_Master_Log_Pos
2304
Exec_Master_Log_Pos
#
Relay_Log_Space #
Until_Condition None
Until_Log_File
...
...
@@ -221,7 +253,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos
2543
Read_Master_Log_Pos
#
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
...
...
@@ -236,7 +268,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4
Skip_Counter 0
Exec_Master_Log_Pos
2460
Exec_Master_Log_Pos
#
Relay_Log_Space #
Until_Condition None
Until_Log_File
...
...
mysql-test/r/rpl_row_tabledefs_3innodb.result
0 → 100644
View file @
67909baa
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;
STOP SLAVE;
SET GLOBAL SQL_MODE='STRICT_ALL_TABLES';
START SLAVE;
CREATE TABLE t1_int (a INT PRIMARY KEY, b INT) ENGINE='InnoDB';
CREATE TABLE t1_bit (a INT PRIMARY KEY, b INT) ENGINE='InnoDB';
CREATE TABLE t1_char (a INT PRIMARY KEY, b INT) ENGINE='InnoDB';
CREATE TABLE t1_nodef (a INT PRIMARY KEY, b INT) ENGINE='InnoDB';
CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE='InnoDB';
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 t9 (a INT) ENGINE='InnoDB';
ALTER TABLE t1_int ADD x INT DEFAULT 42;
ALTER TABLE t1_bit
ADD x BIT(3) DEFAULT b'011',
ADD y BIT(5) DEFAULT b'10101',
ADD z BIT(2) DEFAULT b'10';
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
ALTER TABLE t1_nodef ADD x INT NOT NULL;
ALTER TABLE t2 DROP b;
ALTER TABLE t4 MODIFY a FLOAT;
ALTER TABLE t5 MODIFY b FLOAT;
ALTER TABLE t6 MODIFY c FLOAT;
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');
**** On Master ****
INSERT INTO t1_int VALUES (1,2);
INSERT INTO t1_int VALUES (2,5);
INSERT INTO t1_bit VALUES (1,2);
INSERT INTO t1_bit VALUES (2,5);
INSERT INTO t1_char VALUES (1,2);
INSERT INTO t1_char VALUES (2,5);
SELECT * FROM t1_int;
a b
1 2
2 5
SELECT * FROM t1_bit;
a b
1 2
2 5
SELECT * FROM t1_char;
a b
1 2
2 5
**** On Slave ****
SELECT a,b,x FROM t1_int;
a b x
2 5 4711
1 2 42
SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit;
a b HEX(x) HEX(y) HEX(z)
2 5 5 1C 1
1 2 3 15 2
SELECT a,b,x FROM t1_char;
a b x
2 5 Foo is a bar
1 2 Just a test
**** On Master ****
UPDATE t1_int SET b=2*b WHERE a=2;
UPDATE t1_char SET b=2*b WHERE a=2;
UPDATE t1_bit SET b=2*b WHERE a=2;
SELECT * FROM t1_int;
a b
1 2
2 10
SELECT * FROM t1_bit;
a b
1 2
2 10
SELECT * FROM t1_char;
a b
1 2
2 10
**** On Slave ****
SELECT a,b,x FROM t1_int;
a b x
2 10 4711
1 2 42
SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit;
a b HEX(x) HEX(y) HEX(z)
2 10 5 1C 1
1 2 3 15 2
SELECT a,b,x FROM t1_char;
a b x
2 10 Foo is a bar
1 2 Just a test
INSERT INTO t9 VALUES (2);
INSERT INTO t1_nodef VALUES (1,2);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (2);
INSERT INTO t2 VALUES (2,4);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (4);
INSERT INTO t4 VALUES (4);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (5);
INSERT INTO t5 VALUES (5,10,25);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (6);
INSERT INTO t6 VALUES (6,12,36);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef;
DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9;
mysql-test/r/rpl_row_tabledefs_7ndb.result
0 → 100644
View file @
67909baa
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;
STOP SLAVE;
SET GLOBAL SQL_MODE='STRICT_ALL_TABLES';
START SLAVE;
CREATE TABLE t1_int (a INT PRIMARY KEY, b INT) ENGINE='NDB';
CREATE TABLE t1_bit (a INT PRIMARY KEY, b INT) ENGINE='NDB';
CREATE TABLE t1_char (a INT PRIMARY KEY, b INT) ENGINE='NDB';
CREATE TABLE t1_nodef (a INT PRIMARY KEY, b INT) ENGINE='NDB';
CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE='NDB';
CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE='NDB';
CREATE TABLE t4 (a INT) ENGINE='NDB';
CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='NDB';
CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='NDB';
CREATE TABLE t9 (a INT) ENGINE='NDB';
ALTER TABLE t1_int ADD x INT DEFAULT 42;
ALTER TABLE t1_bit
ADD x BIT(3) DEFAULT b'011',
ADD y BIT(5) DEFAULT b'10101',
ADD z BIT(2) DEFAULT b'10';
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
ALTER TABLE t1_nodef ADD x INT NOT NULL;
ALTER TABLE t2 DROP b;
ALTER TABLE t4 MODIFY a FLOAT;
ALTER TABLE t5 MODIFY b FLOAT;
ALTER TABLE t6 MODIFY c FLOAT;
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');
**** On Master ****
INSERT INTO t1_int VALUES (1,2);
INSERT INTO t1_int VALUES (2,5);
INSERT INTO t1_bit VALUES (1,2);
INSERT INTO t1_bit VALUES (2,5);
INSERT INTO t1_char VALUES (1,2);
INSERT INTO t1_char VALUES (2,5);
SELECT * FROM t1_int;
a b
1 2
2 5
SELECT * FROM t1_bit;
a b
1 2
2 5
SELECT * FROM t1_char;
a b
1 2
2 5
**** On Slave ****
SELECT a,b,x FROM t1_int;
a b x
1 2 42
2 5 42
SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit;
a b HEX(x) HEX(y) HEX(z)
1 2 3 15 2
2 5 3 15 2
SELECT a,b,x FROM t1_char;
a b x
1 2 Just a test
2 5 Just a test
**** On Master ****
UPDATE t1_int SET b=2*b WHERE a=2;
UPDATE t1_char SET b=2*b WHERE a=2;
UPDATE t1_bit SET b=2*b WHERE a=2;
SELECT * FROM t1_int;
a b
1 2
2 10
SELECT * FROM t1_bit;
a b
1 2
2 10
SELECT * FROM t1_char;
a b
1 2
2 10
**** On Slave ****
SELECT a,b,x FROM t1_int;
a b x
1 2 42
2 10 42
SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit;
a b HEX(x) HEX(y) HEX(z)
1 2 3 15 2
2 10 3 15 2
SELECT a,b,x FROM t1_char;
a b x
1 2 Just a test
2 10 Just a test
INSERT INTO t9 VALUES (2);
INSERT INTO t1_nodef VALUES (1,2);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (2);
INSERT INTO t2 VALUES (2,4);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (4);
INSERT INTO t4 VALUES (4);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (5);
INSERT INTO t5 VALUES (5,10,25);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (6);
INSERT INTO t6 VALUES (6,12,36);
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 No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1514
Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4
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 #
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef;
DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9;
mysql-test/t/rpl_row_tabledefs.test
→
mysql-test/t/rpl_row_tabledefs
_2myisam
.test
View file @
67909baa
File moved
mysql-test/t/rpl_row_tabledefs_3innodb.test
0 → 100644
View file @
67909baa
--
source
include
/
have_binlog_format_row
.
inc
--
source
include
/
have_innodb
.
inc
--
source
include
/
master
-
slave
.
inc
let
$engine_type
=
'InnoDB'
;
--
source
extra
/
rpl_tests
/
rpl_row_tabledefs
.
test
sql/field.cc
View file @
67909baa
...
...
@@ -1237,6 +1237,14 @@ uint Field::offset()
}
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
;
}
void
Field
::
copy_from_tmp
(
int
row_offset
)
{
memcpy
(
ptr
,
ptr
+
row_offset
,
pack_length
());
...
...
@@ -8012,6 +8020,30 @@ Field_bit::Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
}
my_size_t
Field_bit
::
do_last_null_byte
()
const
{
/*
Code elsewhere is assuming that bytes are 8 bits, so I'm using
that value instead of the correct one: CHAR_BIT.
REFACTOR SUGGESTION (Matz): Change to use the correct number of
bits. On systems with CHAR_BIT > 8 (not very common), the storage
will lose the extra bits.
*/
DBUG_PRINT
(
"debug"
,
(
"bit_ofs=%d, bit_len=%d, bit_ptr=%p"
,
bit_ofs
,
bit_len
,
bit_ptr
));
uchar
*
result
;
if
(
bit_len
==
0
)
result
=
null_ptr
;
else
if
(
bit_ofs
+
bit_len
>
8
)
result
=
bit_ptr
+
1
;
else
result
=
bit_ptr
;
return
result
?
(
byte
*
)
result
-
table
->
record
[
0
]
+
1
:
0
;
}
Field
*
Field_bit
::
new_key_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
char
*
new_ptr
,
uchar
*
new_null_ptr
,
...
...
sql/field.h
View file @
67909baa
...
...
@@ -212,6 +212,19 @@ public:
{
if
(
null_ptr
)
null_ptr
[
row_offset
]
&=
(
uchar
)
~
null_bit
;
}
inline
bool
maybe_null
(
void
)
{
return
null_ptr
!=
0
||
table
->
maybe_null
;
}
inline
bool
real_maybe_null
(
void
)
{
return
null_ptr
!=
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.
*/
my_size_t
last_null_byte
()
const
{
my_size_t
bytes
=
do_last_null_byte
();
DBUG_PRINT
(
"debug"
,
(
"last_null_byte() ==> %d"
,
bytes
));
DBUG_ASSERT
(
bytes
<=
table
->
s
->
null_bytes
);
return
bytes
;
}
virtual
void
make_field
(
Send_field
*
);
virtual
void
sort_string
(
char
*
buff
,
uint
length
)
=
0
;
virtual
bool
optimize_range
(
uint
idx
,
uint
part
);
...
...
@@ -371,6 +384,9 @@ public:
friend
class
Item_sum_min
;
friend
class
Item_sum_max
;
friend
class
Item_func_group_concat
;
private:
virtual
my_size_t
do_last_null_byte
()
const
;
};
...
...
@@ -1399,6 +1415,9 @@ public:
Field
::
move_field_offset
(
ptr_diff
);
bit_ptr
=
ADD_TO_PTR
(
bit_ptr
,
ptr_diff
,
uchar
*
);
}
private:
virtual
my_size_t
do_last_null_byte
()
const
;
};
...
...
sql/log_event.cc
View file @
67909baa
...
...
@@ -5270,16 +5270,28 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
*/
static
int
unpack_row
(
RELAY_LOG_INFO
*
rli
,
TABLE
*
table
,
uint
colcnt
,
byte
*
record
,
TABLE
*
table
,
uint
co
nst
co
lcnt
,
byte
*
record
,
char
const
*
row
,
MY_BITMAP
const
*
cols
,
char
const
**
row_end
,
ulong
*
master_reclength
)
{
DBUG_ASSERT
(
record
&&
row
);
MY_BITMAP
*
write_set
=
table
->
file
->
write_set
;
my_size_t
const
n_null_bytes
=
table
->
s
->
null_bytes
;
my_ptrdiff_t
const
offset
=
record
-
(
byte
*
)
table
->
record
[
0
];
memcpy
(
record
,
row
,
n_null_bytes
);
// [1]
my_size_t
master_null_bytes
=
table
->
s
->
null_bytes
;
if
(
colcnt
!=
table
->
s
->
fields
)
{
Field
**
fptr
=
&
table
->
field
[
colcnt
-
1
];
do
master_null_bytes
=
(
*
fptr
)
->
last_null_byte
();
while
(
master_null_bytes
==
0
&&
fptr
--
>
table
->
field
);
if
(
master_null_bytes
==
0
)
master_null_bytes
=
table
->
s
->
null_bytes
;
}
DBUG_ASSERT
(
master_null_bytes
<=
table
->
s
->
null_bytes
);
memcpy
(
record
,
row
,
master_null_bytes
);
// [1]
int
error
=
0
;
bitmap_set_all
(
write_set
);
...
...
@@ -5287,14 +5299,12 @@ unpack_row(RELAY_LOG_INFO *rli,
Field
**
const
begin_ptr
=
table
->
field
;
Field
**
field_ptr
;
{
char
const
*
ptr
=
row
+
n_null_bytes
;
for
(
field_ptr
=
begin_ptr
;
*
field_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
(
colcnt
==
0
)
break
;
--
colcnt
;
if
(
bitmap_is_set
(
cols
,
field_ptr
-
begin_ptr
))
{
/* Field...::unpack() cannot return 0 */
...
...
@@ -6190,7 +6200,7 @@ int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
int
error
;
error
=
unpack_row
(
rli
,
table
,
m_width
,
(
byte
*
)
table
->
record
[
0
],
table
,
m_width
,
table
->
record
[
0
],
row_start
,
&
m_cols
,
row_end
,
&
m_master_reclength
);
#ifndef DBUG_OFF
print_column_values
(
"Unpacked value"
,
thd
,
table
);
...
...
@@ -6241,6 +6251,79 @@ namespace {
}
/*
Copy "extra" columns from record[1] to record[0].
Copy the extra fields that are not present on the master but are
present on the slave from record[1] to record[0]. This is used
after fetching a record that are to be updated, either inside
replace_record() or as part of executing an update_row().
*/
static
int
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
],
master_fields
,
master_reclength
,
table
->
s
->
fields
,
table
->
s
->
reclength
));
if
(
master_reclength
<
table
->
s
->
reclength
)
bmove_align
(
table
->
record
[
0
]
+
master_reclength
,
table
->
record
[
1
]
+
master_reclength
,
table
->
s
->
reclength
-
master_reclength
);
/*
Bit columns are special. We iterate over all the remaining
columns and copy the "extra" bits to the new record. This is
not a very good solution: it should be refactored on
opportunity.
REFACTORING SUGGESTION (Matz). Introduce a member function
similar to move_field_offset() called copy_field_offset() to
copy field values and implement it for all Field subclasses. Use
this function to copy data from the found record to the record
that are going to be inserted.
The copy_field_offset() function need to be a virtual function,
which in this case will prevent copying an entire range of
fields efficiently.
*/
{
Field
**
field_ptr
=
table
->
field
+
master_fields
;
for
(
;
*
field_ptr
;
++
field_ptr
)
{
/*
Set the null bit according to the values in record[1]
*/
if
((
*
field_ptr
)
->
maybe_null
()
&&
(
*
field_ptr
)
->
is_null_in_record
(
reinterpret_cast
<
uchar
*>
(
table
->
record
[
1
])))
(
*
field_ptr
)
->
set_null
();
else
(
*
field_ptr
)
->
set_notnull
();
/*
Do the extra work for special columns.
*/
switch
((
*
field_ptr
)
->
real_type
())
{
default:
/* Nothing to do */
break
;
case
FIELD_TYPE_BIT
:
Field_bit
*
f
=
static_cast
<
Field_bit
*>
(
*
field_ptr
);
my_ptrdiff_t
const
offset
=
table
->
record
[
1
]
-
table
->
record
[
0
];
uchar
const
bits
=
get_rec_bits
(
f
->
bit_ptr
+
offset
,
f
->
bit_ofs
,
f
->
bit_len
);
set_rec_bits
(
bits
,
f
->
bit_ptr
,
f
->
bit_ofs
,
f
->
bit_len
);
break
;
}
}
}
return
0
;
// All OK
}
/*
Replace the provided record in the database.
...
...
@@ -6327,54 +6410,7 @@ replace_record(THD *thd, TABLE *table,
First we copy the columns into table->record[0] that are not
present on the master from table->record[1], if there are any.
*/
DBUG_PRINT
(
"info"
,
(
"Copying to %p from offset %u to %u"
,
table
->
record
[
0
],
master_reclength
,
table
->
s
->
reclength
));
#ifndef DBUG_OFF
print_column_values
(
"After copy value"
,
thd
,
table
);
#endif
if
(
master_reclength
<
table
->
s
->
reclength
)
bmove_align
(
table
->
record
[
0
]
+
master_reclength
,
table
->
record
[
1
]
+
master_reclength
,
table
->
s
->
reclength
-
master_reclength
);
/*
Bit columns are special. We iterate over all the remaining
columns and copy the "extra" bits to the new record. This is
not a very good solution: it should be refactored on
opportunity.
REFACTORING SUGGESTION (Matz). Introduce a member function
similar to move_field_offset() called copy_field_offset() to
copy field values and implement it for all Field subclasses. Use
this function to copy data from the found record to the record
that are going to be inserted.
The copy_field_offset() function need to be a virtual function,
which in this case will prevent copying an entire range of
fields efficiently.
*/
{
Field
**
field_ptr
=
table
->
field
+
master_fields
;
for
(
;
*
field_ptr
;
++
field_ptr
)
{
switch
((
*
field_ptr
)
->
real_type
())
{
default:
/* Nothing to do */
break
;
case
FIELD_TYPE_BIT
:
Field_bit
*
f
=
static_cast
<
Field_bit
*>
(
*
field_ptr
);
my_ptrdiff_t
const
offset
=
table
->
record
[
1
]
-
table
->
record
[
0
];
uchar
const
bits
=
get_rec_bits
(
f
->
bit_ptr
+
offset
,
f
->
bit_ofs
,
f
->
bit_len
);
set_rec_bits
(
bits
,
f
->
bit_ptr
,
f
->
bit_ofs
,
f
->
bit_len
);
break
;
}
}
}
copy_extra_record_fields
(
table
,
master_reclength
,
master_fields
);
/*
REPLACE is defined as either INSERT or DELETE + INSERT. If
...
...
@@ -6887,17 +6923,20 @@ int Update_rows_log_event::do_exec_row(TABLE *table)
example, the partition engine).
Since find_and_fetch_row() puts the fetched record (i.e., the old
record) in record[0], we have to move it out of the way and into
record[1]. After that, we can put the new record (i.e., the after
image) into record[0].
record) in record[1], we can keep it there. We put the new record
(i.e., the after image) into record[0], and copy the fields that
are on the slave (i.e., in record[1]) into record[0], effectively
overwriting the default values that where put there by the
unpack_row() function.
*/
bmove_align
(
table
->
record
[
1
],
table
->
record
[
0
],
table
->
s
->
reclength
);
bmove_align
(
table
->
record
[
0
],
m_after_image
,
table
->
s
->
reclength
);
copy_extra_record_fields
(
table
,
m_master_reclength
,
m_width
);
/*
Now we should have the right row to update. The old row (the one
we're looking for) has to be in record[1] and the new row has to
be in record[0] for all storage engines to work correctly.
Now we have the right row to update. The old row (the one we're
looking for) is in record[1] and the new row has is in record[0].
We also have copied the original values already in the slave's
database into the after image delivered from the master.
*/
error
=
table
->
file
->
ha_update_row
(
table
->
record
[
1
],
table
->
record
[
0
]);
...
...
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