Skip to content

Commit 8a941ba

Browse files
MDEV-14168 Unconditionally allow ALGORITHM=INPLACE for setting a column NOT NULL
- Added two new test case for it.
1 parent a7852e3 commit 8a941ba

File tree

4 files changed

+269
-0
lines changed

4 files changed

+269
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
set @@sql_mode = 'STRICT_TRANS_TABLES';
2+
CREATE TABLE t1(f1 INT)ENGINE=INNODB;
3+
INSERT INTO t1 VALUES(NULL);
4+
SELECT * FROM t1;
5+
f1
6+
NULL
7+
ALTER TABLE t1 CHANGE f1 f1 INT NOT NULL;
8+
affected rows: 0
9+
info: Records: 0 Duplicates: 0 Warnings: 0
10+
SELECT * FROM t1;
11+
f1
12+
0
13+
DROP TABLE t1;
14+
CREATE TABLE t1(f1 CHAR(10))ENGINE=INNODB;
15+
INSERT INTO t1 VALUES(NULL);
16+
SELECT * FROM t1;
17+
f1
18+
NULL
19+
ALTER TABLE t1 CHANGE f1 f1 CHAR(10) NOT NULL;
20+
affected rows: 0
21+
info: Records: 0 Duplicates: 0 Warnings: 0
22+
SELECT * FROM t1;
23+
f1
24+
25+
DROP TABLE t1;
26+
CREATE TABLE t1(f1 VARCHAR(10))ENGINE=INNODB;
27+
INSERT INTO t1 VALUES(NULL);
28+
SELECT * FROM t1;
29+
f1
30+
NULL
31+
ALTER TABLE t1 CHANGE f1 f1 VARCHAR(20) NOT NULL;
32+
affected rows: 0
33+
info: Records: 0 Duplicates: 0 Warnings: 0
34+
SELECT * FROM t1;
35+
f1
36+
37+
DROP TABLE t1;
38+
CREATE TABLE t1(f1 TEXT)ENGINE=INNODB;
39+
INSERT INTO t1 VALUES(NULL);
40+
SELECT * FROM t1;
41+
f1
42+
NULL
43+
ALTER TABLE t1 CHANGE f1 f1 TEXT NOT NULL DEFAULT 'abc';
44+
affected rows: 0
45+
info: Records: 0 Duplicates: 0 Warnings: 0
46+
SELECT * FROM t1;
47+
f1
48+
abc
49+
DROP TABLE t1;
50+
CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, f3 INT)ENGINE=INNODB;
51+
INSERT INTO t1 VALUES(2, 2, NULL);
52+
SELECT * FROM t1;
53+
f1 f2 f3
54+
2 2 NULL
55+
ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2), ALGORITHM=INPLACE;
56+
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: cannot convert NULL to non-constant DEFAULT. Try ALGORITHM=COPY
57+
UPDATE t1 SET f3 = 0;
58+
SELECT * FROM t1;
59+
f1 f2 f3
60+
2 2 0
61+
ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2);
62+
affected rows: 1
63+
info: Records: 1 Duplicates: 0 Warnings: 0
64+
SELECT * FROM t1;
65+
f1 f2 f3
66+
2 2 0
67+
DROP TABLE t1;
68+
CREATE TABLE t1(f1 INT NOT NULL DEFAULT 0, b TINYINT)ENGINE=InnoDB;
69+
INSERT INTO t1 VALUES(10, NULL);
70+
SELECT * FROM t1;
71+
f1 b
72+
10 NULL
73+
ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0), algorithm=INPLACE;
74+
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: cannot convert NULL to non-constant DEFAULT. Try ALGORITHM=COPY
75+
DROP TABLE t1;
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB;
2+
INSERT INTO t1 VALUES(1, NULL);
3+
SET DEBUG_SYNC= 'row_merge_after_scan
4+
SIGNAL opened WAIT_FOR flushed';
5+
ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE;
6+
connect con1,localhost,root;
7+
SET DEBUG_SYNC= 'now WAIT_FOR opened';
8+
INSERT INTO t1 VALUES(2, NULL);
9+
SET DEBUG_SYNC= 'now SIGNAL flushed';
10+
connection default;
11+
ERROR 22004: Invalid use of NULL value
12+
SELECT * FROM t1;
13+
c1 c2
14+
1 NULL
15+
2 NULL
16+
UPDATE t1 SET c2 = 0 WHERE c1 = 2;
17+
SET DEBUG_SYNC= 'row_merge_after_scan
18+
SIGNAL opened WAIT_FOR flushed';
19+
# Alter ignore can convert the NULL values from
20+
# CONCURRENT DML to constants
21+
ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE;
22+
connection con1;
23+
SET DEBUG_SYNC= 'now WAIT_FOR opened';
24+
UPDATE t1 SET c2 = NULL WHERE c1 = 2;
25+
INSERT INTO t1 VALUES (3, NULL);
26+
SET DEBUG_SYNC= 'now SIGNAL flushed';
27+
connection default;
28+
SELECT * FROM t1;
29+
c1 c2
30+
1 2
31+
2 2
32+
3 2
33+
DROP TABLE t1;
34+
CREATE TABLE t1(c1 INT NOT NULL, c2 INT, c3 INT, PRIMARY KEY(c1))ENGINE=INNODB;
35+
INSERT INTO t1 VALUES(1, NULL, NULL);
36+
SET DEBUG_SYNC= 'row_merge_after_scan
37+
SIGNAL opened WAIT_FOR flushed';
38+
# Alter Successfully converts from null to not null
39+
ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE;
40+
connection con1;
41+
SET DEBUG_SYNC= 'now WAIT_FOR opened';
42+
UPDATE t1 SET c2= 2 WHERE c1 = 1;
43+
INSERT INTO t1 VALUES (2, 3, 4);
44+
SET DEBUG_SYNC= 'now SIGNAL flushed';
45+
connection default;
46+
SELECT * FROM t1;
47+
c1 c2 c3
48+
1 2 NULL
49+
2 3 4
50+
SET DEBUG_SYNC= 'row_merge_after_scan
51+
SIGNAL opened WAIT_FOR flushed';
52+
# Alter fails because concurrent dml inserts null value
53+
ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE;
54+
connection con1;
55+
SET DEBUG_SYNC= 'now WAIT_FOR opened';
56+
UPDATE t1 SET c3= 2 WHERE c1 = 2;
57+
INSERT INTO t1 VALUES (4, 3, NULL);
58+
SET DEBUG_SYNC= 'now SIGNAL flushed';
59+
connection default;
60+
ERROR 22004: Invalid use of NULL value
61+
SELECT * FROM t1;
62+
c1 c2 c3
63+
1 2 NULL
64+
2 3 2
65+
4 3 NULL
66+
DROP TABLE t1;
67+
disconnect con1;
68+
SET DEBUG_SYNC='RESET';
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--source include/have_innodb.inc
2+
set @@sql_mode = 'STRICT_TRANS_TABLES';
3+
4+
CREATE TABLE t1(f1 INT)ENGINE=INNODB;
5+
INSERT INTO t1 VALUES(NULL);
6+
SELECT * FROM t1;
7+
--enable_info
8+
ALTER TABLE t1 CHANGE f1 f1 INT NOT NULL;
9+
--disable_info
10+
SELECT * FROM t1;
11+
DROP TABLE t1;
12+
13+
CREATE TABLE t1(f1 CHAR(10))ENGINE=INNODB;
14+
INSERT INTO t1 VALUES(NULL);
15+
SELECT * FROM t1;
16+
--enable_info
17+
ALTER TABLE t1 CHANGE f1 f1 CHAR(10) NOT NULL;
18+
--disable_info
19+
SELECT * FROM t1;
20+
DROP TABLE t1;
21+
22+
CREATE TABLE t1(f1 VARCHAR(10))ENGINE=INNODB;
23+
INSERT INTO t1 VALUES(NULL);
24+
SELECT * FROM t1;
25+
--enable_info
26+
ALTER TABLE t1 CHANGE f1 f1 VARCHAR(20) NOT NULL;
27+
--disable_info
28+
SELECT * FROM t1;
29+
DROP TABLE t1;
30+
31+
CREATE TABLE t1(f1 TEXT)ENGINE=INNODB;
32+
INSERT INTO t1 VALUES(NULL);
33+
SELECT * FROM t1;
34+
--enable_info
35+
ALTER TABLE t1 CHANGE f1 f1 TEXT NOT NULL DEFAULT 'abc';
36+
--disable_info
37+
SELECT * FROM t1;
38+
DROP TABLE t1;
39+
40+
CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, f3 INT)ENGINE=INNODB;
41+
INSERT INTO t1 VALUES(2, 2, NULL);
42+
SELECT * FROM t1;
43+
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
44+
ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2), ALGORITHM=INPLACE;
45+
UPDATE t1 SET f3 = 0;
46+
SELECT * FROM t1;
47+
--enable_info
48+
ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2);
49+
--disable_info
50+
SELECT * FROM t1;
51+
DROP TABLE t1;
52+
53+
CREATE TABLE t1(f1 INT NOT NULL DEFAULT 0, b TINYINT)ENGINE=InnoDB;
54+
INSERT INTO t1 VALUES(10, NULL);
55+
SELECT * FROM t1;
56+
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
57+
ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0), algorithm=INPLACE;
58+
DROP TABLE t1;
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
--source include/have_innodb.inc
2+
--source include/have_debug.inc
3+
--source include/have_debug_sync.inc
4+
5+
CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB;
6+
INSERT INTO t1 VALUES(1, NULL);
7+
SET DEBUG_SYNC= 'row_merge_after_scan
8+
SIGNAL opened WAIT_FOR flushed';
9+
send ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE;
10+
connect (con1,localhost,root);
11+
SET DEBUG_SYNC= 'now WAIT_FOR opened';
12+
INSERT INTO t1 VALUES(2, NULL);
13+
SET DEBUG_SYNC= 'now SIGNAL flushed';
14+
connection default;
15+
--error ER_INVALID_USE_OF_NULL
16+
reap;
17+
SELECT * FROM t1;
18+
UPDATE t1 SET c2 = 0 WHERE c1 = 2;
19+
SET DEBUG_SYNC= 'row_merge_after_scan
20+
SIGNAL opened WAIT_FOR flushed';
21+
--echo # Alter ignore can convert the NULL values from
22+
--echo # CONCURRENT DML to constants
23+
send ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE;
24+
connection con1;
25+
SET DEBUG_SYNC= 'now WAIT_FOR opened';
26+
UPDATE t1 SET c2 = NULL WHERE c1 = 2;
27+
INSERT INTO t1 VALUES (3, NULL);
28+
SET DEBUG_SYNC= 'now SIGNAL flushed';
29+
connection default;
30+
reap;
31+
SELECT * FROM t1;
32+
DROP TABLE t1;
33+
34+
35+
CREATE TABLE t1(c1 INT NOT NULL, c2 INT, c3 INT, PRIMARY KEY(c1))ENGINE=INNODB;
36+
INSERT INTO t1 VALUES(1, NULL, NULL);
37+
SET DEBUG_SYNC= 'row_merge_after_scan
38+
SIGNAL opened WAIT_FOR flushed';
39+
--echo # Alter Successfully converts from null to not null
40+
41+
send ALTER TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE;
42+
43+
connection con1;
44+
SET DEBUG_SYNC= 'now WAIT_FOR opened';
45+
UPDATE t1 SET c2= 2 WHERE c1 = 1;
46+
INSERT INTO t1 VALUES (2, 3, 4);
47+
SET DEBUG_SYNC= 'now SIGNAL flushed';
48+
connection default;
49+
reap;
50+
SELECT * FROM t1;
51+
52+
SET DEBUG_SYNC= 'row_merge_after_scan
53+
SIGNAL opened WAIT_FOR flushed';
54+
--echo # Alter fails because concurrent dml inserts null value
55+
56+
send ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL DEFAULT 2, ALGORITHM=INPLACE;
57+
connection con1;
58+
SET DEBUG_SYNC= 'now WAIT_FOR opened';
59+
UPDATE t1 SET c3= 2 WHERE c1 = 2;
60+
INSERT INTO t1 VALUES (4, 3, NULL);
61+
SET DEBUG_SYNC= 'now SIGNAL flushed';
62+
connection default;
63+
--error ER_INVALID_USE_OF_NULL
64+
reap;
65+
SELECT * FROM t1;
66+
DROP TABLE t1;
67+
disconnect con1;
68+
SET DEBUG_SYNC='RESET';

0 commit comments

Comments
 (0)