Details
-
Bug
-
Status: Closed (View Workflow)
-
Minor
-
Resolution: Not a Bug
-
10.6.18
-
None
Description
We have stumbled into an inconsistency in the way alter table behaves when trying to drop a column and readd it in same alter statement - a perfectly legit operation, but please see below.
This works:
mariadb-test-0-0-prod [test]> show create table testtable\G
|
*************************** 1. row ***************************
|
Table: testtable
|
Create Table: CREATE TABLE `testtable` (
|
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
`col1` int(11) DEFAULT NULL,
|
`col1b` int(11) DEFAULT NULL,
|
`col2` int(11) NOT NULL,
|
PRIMARY KEY (`id`)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
1 row in set (0.000 sec)
|
|
mariadb-test-0-0-prod [test]> alter table testtable drop column col1b, add column col1b int not null after col1;
|
Query OK, 0 rows affected (0.002 sec)
|
Records: 0 Duplicates: 0 Warnings: 0
|
|
mariadb-test-0-0-prod [test]> show create table testtable\G
|
*************************** 1. row ***************************
|
Table: testtable
|
Create Table: CREATE TABLE `testtable` (
|
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
`col1` int(11) DEFAULT NULL,
|
`col1b` int(11) NOT NULL,
|
`col2` int(11) NOT NULL,
|
PRIMARY KEY (`id`)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
1 row in set (0.000 sec)
|
This does not work and the column is dropped with just a warning:
mariadb-test-0-0-prod [test]> alter table testtable drop column if exists col1b, add column if not exists col1b int not null after col1;
|
Query OK, 0 rows affected, 1 warning (0.002 sec)
|
Records: 0 Duplicates: 0 Warnings: 1
|
|
mariadb-test-0-0-prod [test]> show warnings;
|
+-------+------+-------------------------------+
|
| Level | Code | Message |
|
+-------+------+-------------------------------+
|
| Note | 1060 | Duplicate column name 'col1b' |
|
+-------+------+-------------------------------+
|
1 row in set (0.000 sec)
|
|
mariadb-test-0-0-prod [test]> show create table testtable\G
|
*************************** 1. row ***************************
|
Table: testtable
|
Create Table: CREATE TABLE `testtable` (
|
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
`col1` int(11) DEFAULT NULL,
|
`col2` int(11) NOT NULL,
|
PRIMARY KEY (`id`)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
1 row in set (0.000 sec)
|
|
It looks to me that the IF NOT EXISTS check is done before the whole alter runs, hence the column addition fails even if the former part of the alter has indeed dropped the column.
The existence check should be done after the previous alter steps are executed, and not before altering the table.
Also, the fact that we only get a warning is a problem per se, as the column is dropped but not recreated.
ALTER TABLE converts the table atomically from a structure A to a structure B, it does not execute individual sub-commands sequentially. If you want them to be executed sequentially, one after the other, you can do them in separate ALTER TABLE statements, but this will be, of course, slower.