github.com/dolthub/go-mysql-server@v0.18.0/enginetest/queries/alter_table_queries.go (about) 1 // Copyright 2023 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package queries 16 17 import ( 18 "github.com/dolthub/vitess/go/mysql" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 "github.com/dolthub/go-mysql-server/sql/analyzer/analyzererrors" 22 "github.com/dolthub/go-mysql-server/sql/plan" 23 "github.com/dolthub/go-mysql-server/sql/types" 24 ) 25 26 var AlterTableScripts = []ScriptTest{ 27 { 28 Name: "multi alter with invalid schemas", 29 SetUpScript: []string{ 30 "CREATE TABLE t(a int primary key)", 31 }, 32 Assertions: []ScriptTestAssertion{ 33 { 34 Query: "alter table t add column b varchar(16383)", 35 ExpectedErr: analyzererrors.ErrInvalidRowLength, 36 }, 37 { 38 // 1 char = 4 bytes with default collation 39 Query: "alter table t add column b varchar(16000), add column c varchar(16000)", 40 ExpectedErr: analyzererrors.ErrInvalidRowLength, 41 }, 42 { 43 Query: "alter table t add column b varchar(16000), add column c varchar(10)", 44 Expected: []sql.Row{{types.NewOkResult(0)}}, 45 }, 46 }, 47 }, 48 { 49 Name: "variety of alter column statements in a single statement", 50 SetUpScript: []string{ 51 "CREATE TABLE t32(pk BIGINT PRIMARY KEY, v1 int, v2 int, v3 int default (v1), toRename int)", 52 `alter table t32 add column v4 int after pk, 53 drop column v2, modify v1 varchar(100) not null, 54 alter column v3 set default 100, rename column toRename to newName`, 55 "CREATE TABLE t32_2(pk BIGINT PRIMARY KEY, v1 int, v2 int, v3 int)", 56 `alter table t32_2 drop v1, add v1 int`, 57 "CREATE TABLE t32_3(pk BIGINT PRIMARY KEY, v1 int, v2 int, v3 int)", 58 `alter table t32_3 rename column v1 to v5, add v1 int`, 59 }, 60 Assertions: []ScriptTestAssertion{ 61 { 62 Query: "SHOW FULL COLUMNS FROM t32", 63 // | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | 64 Expected: []sql.Row{ 65 {"pk", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 66 {"v4", "int", nil, "YES", "", "NULL", "", "", ""}, 67 {"v1", "varchar(100)", "utf8mb4_0900_bin", "NO", "", "NULL", "", "", ""}, 68 {"v3", "int", nil, "YES", "", "100", "", "", ""}, 69 {"newName", "int", nil, "YES", "", "NULL", "", "", ""}, 70 }, 71 }, 72 { 73 Query: "SHOW FULL COLUMNS FROM t32_2", 74 Expected: []sql.Row{ 75 {"pk", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 76 {"v2", "int", nil, "YES", "", "NULL", "", "", ""}, 77 {"v3", "int", nil, "YES", "", "NULL", "", "", ""}, 78 {"v1", "int", nil, "YES", "", "NULL", "", "", ""}, 79 }, 80 }, 81 { 82 Query: "SHOW FULL COLUMNS FROM t32_3", 83 Expected: []sql.Row{ 84 {"pk", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 85 {"v5", "int", nil, "YES", "", "NULL", "", "", ""}, 86 {"v2", "int", nil, "YES", "", "NULL", "", "", ""}, 87 {"v3", "int", nil, "YES", "", "NULL", "", "", ""}, 88 {"v1", "int", nil, "YES", "", "NULL", "", "", ""}, 89 }, 90 }, 91 { 92 Query: "alter table t32 add column vnew int, drop column vnew", 93 ExpectedErr: sql.ErrTableColumnNotFound, 94 }, 95 { 96 Query: "alter table t32 rename column v3 to v5, drop column v5", 97 ExpectedErr: sql.ErrTableColumnNotFound, 98 }, 99 { 100 Query: "alter table t32 rename column v3 to v5, drop column v3", 101 ExpectedErr: sql.ErrTableColumnNotFound, 102 }, 103 }, 104 }, 105 { 106 Name: "mix of alter column, add and drop constraints in one statement", 107 SetUpScript: []string{ 108 "CREATE TABLE t33(pk BIGINT PRIMARY KEY, v1 int, v2 int)", 109 `alter table t33 add column v4 int after pk, 110 drop column v2, add constraint v1gt0 check (v1 > 0)`, 111 }, 112 Assertions: []ScriptTestAssertion{ 113 { 114 Query: "SHOW FULL COLUMNS FROM t33", 115 // | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | 116 Expected: []sql.Row{ 117 {"pk", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 118 {"v4", "int", nil, "YES", "", "NULL", "", "", ""}, 119 {"v1", "int", nil, "YES", "", "NULL", "", "", ""}, 120 }, 121 }, 122 { 123 Query: "SELECT * FROM information_schema.CHECK_CONSTRAINTS", 124 Expected: []sql.Row{ 125 {"def", "mydb", "v1gt0", "(v1 > 0)"}, 126 }, 127 }, 128 }, 129 }, 130 { 131 // This script relies on setup.Pk_tablesData 132 Name: "Error queries", 133 Assertions: []ScriptTestAssertion{ 134 { 135 Query: "ALTER TABLE one_pk_two_idx MODIFY COLUMN v1 BIGINT DEFAULT (pk) AFTER v3", 136 ExpectedErr: sql.ErrTableColumnNotFound, 137 }, 138 { 139 Query: "ALTER TABLE one_pk_two_idx ADD COLUMN v4 BIGINT DEFAULT (pk) AFTER v3", 140 ExpectedErr: sql.ErrTableColumnNotFound, 141 }, 142 { 143 Query: "ALTER TABLE one_pk_two_idx ADD COLUMN v3 BIGINT DEFAULT 5, RENAME COLUMN v3 to v4", 144 ExpectedErr: sql.ErrTableColumnNotFound, 145 }, 146 { 147 Query: "ALTER TABLE one_pk_two_idx ADD COLUMN v3 BIGINT DEFAULT 5, modify column v3 bigint default null", 148 ExpectedErr: sql.ErrTableColumnNotFound, 149 }, 150 }, 151 }, 152 { 153 // https://github.com/dolthub/dolt/issues/6206 154 Name: "alter table containing column default value expressions", 155 SetUpScript: []string{ 156 "create table t (pk int primary key, col1 timestamp(6) default current_timestamp(), col2 varchar(1000), index idx1 (pk, col1));", 157 }, 158 Assertions: []ScriptTestAssertion{ 159 { 160 Query: "alter table t alter column col2 DROP DEFAULT;", 161 Expected: []sql.Row{{types.NewOkResult(0)}}, 162 }, 163 { 164 Query: "show create table t;", 165 Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `pk` int NOT NULL,\n `col1` timestamp(6) DEFAULT CURRENT_TIMESTAMP,\n `col2` varchar(1000),\n PRIMARY KEY (`pk`),\n KEY `idx1` (`pk`,`col1`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 166 }, 167 { 168 Query: "alter table t alter column col2 SET DEFAULT 'FOO!';", 169 Expected: []sql.Row{{types.NewOkResult(0)}}, 170 }, 171 { 172 Query: "show create table t;", 173 Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `pk` int NOT NULL,\n `col1` timestamp(6) DEFAULT CURRENT_TIMESTAMP,\n `col2` varchar(1000) DEFAULT 'FOO!',\n PRIMARY KEY (`pk`),\n KEY `idx1` (`pk`,`col1`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 174 }, 175 { 176 Query: "alter table t drop index idx1;", 177 Expected: []sql.Row{{types.NewOkResult(0)}}, 178 }, 179 }, 180 }, 181 { 182 Name: "drop column drops check constraint", 183 SetUpScript: []string{ 184 "create table t34 (i bigint primary key, s varchar(20))", 185 "ALTER TABLE t34 ADD COLUMN j int", 186 "ALTER TABLE t34 ADD CONSTRAINT test_check CHECK (j < 12345)", 187 "ALTER TABLE t34 DROP COLUMN j", 188 }, 189 Assertions: []ScriptTestAssertion{ 190 { 191 Query: "show create table t34", 192 Expected: []sql.Row{{"t34", "CREATE TABLE `t34` (\n" + 193 " `i` bigint NOT NULL,\n" + 194 " `s` varchar(20),\n" + 195 " PRIMARY KEY (`i`)\n" + 196 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 197 }, 198 }, 199 }, 200 { 201 Name: "drop check as part of alter block", 202 SetUpScript: []string{ 203 "create table t42 (i bigint primary key, j int, CONSTRAINT check1 CHECK (j < 12345), CONSTRAINT check2 CHECK (j > 0))", 204 "ALTER TABLE t42 ADD COLUMN s varchar(20), drop check check1", 205 }, 206 Assertions: []ScriptTestAssertion{ 207 { 208 Query: "show create table t42", 209 Expected: []sql.Row{{"t42", 210 "CREATE TABLE `t42` (\n" + 211 " `i` bigint NOT NULL,\n" + 212 " `j` int,\n" + 213 " `s` varchar(20),\n" + 214 " PRIMARY KEY (`i`),\n" + 215 " CONSTRAINT `check2` CHECK ((`j` > 0))\n" + 216 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 217 }, 218 }, 219 }, 220 { 221 Name: "drop constraint as part of alter block", 222 SetUpScript: []string{ 223 "create table t42 (i bigint primary key, j int, CONSTRAINT check1 CHECK (j < 12345), CONSTRAINT check2 CHECK (j > 0))", 224 "ALTER TABLE t42 ADD COLUMN s varchar(20), drop constraint check1", 225 }, 226 Assertions: []ScriptTestAssertion{ 227 { 228 Query: "show create table t42", 229 Expected: []sql.Row{{"t42", 230 "CREATE TABLE `t42` (\n" + 231 " `i` bigint NOT NULL,\n" + 232 " `j` int,\n" + 233 " `s` varchar(20),\n" + 234 " PRIMARY KEY (`i`),\n" + 235 " CONSTRAINT `check2` CHECK ((`j` > 0))\n" + 236 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 237 }, 238 }, 239 }, 240 { 241 Name: "drop column drops all relevant check constraints", 242 SetUpScript: []string{ 243 "create table t42 (i bigint primary key, s varchar(20))", 244 "ALTER TABLE t42 ADD COLUMN j int", 245 "ALTER TABLE t42 ADD CONSTRAINT check1 CHECK (j < 12345)", 246 "ALTER TABLE t42 ADD CONSTRAINT check2 CHECK (j > 0)", 247 "ALTER TABLE t42 DROP COLUMN j", 248 }, 249 Assertions: []ScriptTestAssertion{ 250 { 251 Query: "show create table t42", 252 Expected: []sql.Row{{"t42", "CREATE TABLE `t42` (\n" + 253 " `i` bigint NOT NULL,\n" + 254 " `s` varchar(20),\n" + 255 " PRIMARY KEY (`i`)\n" + 256 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 257 }, 258 }, 259 }, 260 { 261 Name: "drop column drops correct check constraint", 262 SetUpScript: []string{ 263 "create table t41 (i bigint primary key, s varchar(20))", 264 "ALTER TABLE t41 ADD COLUMN j int", 265 "ALTER TABLE t41 ADD COLUMN k int", 266 "ALTER TABLE t41 ADD CONSTRAINT j_check CHECK (j < 12345)", 267 "ALTER TABLE t41 ADD CONSTRAINT k_check CHECK (k < 123)", 268 "ALTER TABLE t41 DROP COLUMN j", 269 }, 270 Assertions: []ScriptTestAssertion{ 271 { 272 Query: "show create table t41", 273 Expected: []sql.Row{{"t41", "CREATE TABLE `t41` (\n" + 274 " `i` bigint NOT NULL,\n" + 275 " `s` varchar(20),\n" + 276 " `k` int,\n" + 277 " PRIMARY KEY (`i`),\n" + 278 " CONSTRAINT `k_check` CHECK ((`k` < 123))\n" + 279 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 280 }, 281 }, 282 }, 283 { 284 Name: "drop column does not drop when referenced in constraint with other column", 285 SetUpScript: []string{ 286 "create table t43 (i bigint primary key, s varchar(20))", 287 "ALTER TABLE t43 ADD COLUMN j int", 288 "ALTER TABLE t43 ADD COLUMN k int", 289 "ALTER TABLE t43 ADD CONSTRAINT test_check CHECK (j < k)", 290 }, 291 Assertions: []ScriptTestAssertion{ 292 { 293 Query: "alter table t43 drop column j", 294 ExpectedErr: sql.ErrCheckConstraintInvalidatedByColumnAlter, 295 }, 296 { 297 Query: "show create table t43", 298 Expected: []sql.Row{{"t43", "CREATE TABLE `t43` (\n" + 299 " `i` bigint NOT NULL,\n" + 300 " `s` varchar(20),\n" + 301 " `j` int,\n" + 302 " `k` int,\n" + 303 " PRIMARY KEY (`i`),\n" + 304 " CONSTRAINT `test_check` CHECK ((`j` < `k`))\n" + 305 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 306 }, 307 }, 308 }, 309 { 310 Name: "drop column preserves indexes", 311 SetUpScript: []string{ 312 "create table t35 (i bigint primary key, s varchar(20), s2 varchar(20))", 313 "ALTER TABLE t35 ADD unique key test_key (s)", 314 "ALTER TABLE t35 DROP COLUMN s2", 315 }, 316 Assertions: []ScriptTestAssertion{ 317 { 318 Query: "show create table t35", 319 Expected: []sql.Row{{"t35", "CREATE TABLE `t35` (\n" + 320 " `i` bigint NOT NULL,\n" + 321 " `s` varchar(20),\n" + 322 " PRIMARY KEY (`i`),\n" + 323 " UNIQUE KEY `test_key` (`s`)\n" + 324 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 325 }, 326 }, 327 }, 328 { 329 Name: "drop column prevents foreign key violations", 330 SetUpScript: []string{ 331 "create table t36 (i bigint primary key, j varchar(20))", 332 "create table t37 (i bigint primary key, j varchar(20))", 333 "ALTER TABLE t36 ADD key (j)", 334 "ALTER TABLE t37 ADD constraint fk_36 foreign key (j) references t36(j)", 335 }, 336 Assertions: []ScriptTestAssertion{ 337 { 338 Query: "alter table t37 drop column j", 339 ExpectedErr: sql.ErrForeignKeyDropColumn, 340 }, 341 }, 342 }, 343 { 344 Name: "disable keys / enable keys", 345 SetUpScript: []string{ 346 "CREATE TABLE t33(pk BIGINT PRIMARY KEY, v1 int, v2 int)", 347 `alter table t33 add column v4 int after pk, 348 drop column v2, add constraint v1gt0 check (v1 > 0)`, 349 }, 350 Assertions: []ScriptTestAssertion{ 351 { 352 Query: "ALTER TABLE t33 DISABLE KEYS", 353 SkipResultsCheck: true, 354 ExpectedWarning: mysql.ERNotSupportedYet, 355 ExpectedWarningsCount: 1, 356 }, 357 { 358 Query: "ALTER TABLE t33 ENABLE KEYS", 359 SkipResultsCheck: true, 360 ExpectedWarning: mysql.ERNotSupportedYet, 361 ExpectedWarningsCount: 1, 362 }, 363 }, 364 }, 365 { 366 Name: "adding a unique constraint errors if violations exist", 367 SetUpScript: []string{ 368 "CREATE TABLE t38 (pk int PRIMARY KEY, col1 int)", 369 "INSERT INTO t38 VALUES (1, 1)", 370 "INSERT INTO t38 VALUES (2, 2)", 371 "INSERT INTO t38 VALUES (3, NULL)", 372 "INSERT INTO t38 VALUES (4, NULL)", 373 374 "CREATE TABLE t39 (pk int PRIMARY KEY, col1 int, col2 int)", 375 "INSERT INTO t39 VALUES (1, 1, 1)", 376 "INSERT INTO t39 VALUES (2, 1, 2)", 377 "INSERT INTO t39 VALUES (3, 2, 1)", 378 "INSERT INTO t39 VALUES (4, 1, NULL)", 379 "INSERT INTO t39 VALUES (5, 1, NULL)", 380 "INSERT INTO t39 VALUES (6, NULL, 1)", 381 "INSERT INTO t39 VALUES (7, NULL, 1)", 382 "INSERT INTO t39 VALUES (8, NULL, NULL)", 383 "INSERT INTO t39 VALUES (9, NULL, NULL)", 384 }, 385 Assertions: []ScriptTestAssertion{ 386 { 387 Query: "ALTER TABLE t38 ADD UNIQUE u_col1 (col1)", 388 Expected: []sql.Row{{types.NewOkResult(0)}}, 389 }, 390 { 391 Query: "ALTER TABLE t39 ADD UNIQUE u_col1_col2 (col1, col2)", 392 Expected: []sql.Row{{types.NewOkResult(0)}}, 393 }, 394 { 395 Query: "ALTER TABLE t38 DROP INDEX u_col1;", 396 Expected: []sql.Row{{types.NewOkResult(0)}}, 397 }, 398 { 399 Query: "INSERT INTO t38 VALUES (5, 1);", 400 Expected: []sql.Row{{types.NewOkResult(1)}}, 401 }, 402 { 403 Query: "ALTER TABLE t38 ADD UNIQUE u_col1 (col1)", 404 ExpectedErr: sql.ErrUniqueKeyViolation, 405 }, 406 { 407 Query: "show create table t38;", 408 Expected: []sql.Row{{"t38", "CREATE TABLE `t38` (\n" + 409 " `pk` int NOT NULL,\n" + 410 " `col1` int,\n" + 411 " PRIMARY KEY (`pk`)\n" + 412 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 413 }, 414 { 415 Query: "ALTER TABLE t39 DROP INDEX u_col1_col2;", 416 Expected: []sql.Row{{types.NewOkResult(0)}}, 417 }, 418 { 419 Query: "INSERT INTO t39 VALUES (10, 1, 1);", 420 Expected: []sql.Row{{types.NewOkResult(1)}}, 421 }, 422 { 423 Query: "ALTER TABLE t39 ADD UNIQUE u_col1_col2 (col1, col2)", 424 ExpectedErr: sql.ErrUniqueKeyViolation, 425 }, 426 { 427 Query: "show create table t39;", 428 Expected: []sql.Row{{"t39", "CREATE TABLE `t39` (\n" + 429 " `pk` int NOT NULL,\n" + 430 " `col1` int,\n" + 431 " `col2` int,\n" + 432 " PRIMARY KEY (`pk`)\n" + 433 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 434 }, 435 }, 436 }, 437 { 438 Name: "ALTER TABLE remove AUTO_INCREMENT", 439 SetUpScript: []string{ 440 "CREATE TABLE t40 (pk int AUTO_INCREMENT PRIMARY KEY, val int)", 441 "INSERT into t40 VALUES (1, 1), (NULL, 2), (NULL, 3)", 442 }, 443 Assertions: []ScriptTestAssertion{ 444 { 445 Query: "ALTER TABLE t40 MODIFY COLUMN pk int", 446 Expected: []sql.Row{{types.NewOkResult(0)}}, 447 }, 448 { 449 Query: "describe t40", 450 Expected: []sql.Row{ 451 {"pk", "int", "NO", "PRI", "NULL", ""}, 452 {"val", "int", "YES", "", "NULL", ""}, 453 }, 454 }, 455 { 456 Query: "INSERT INTO t40 VALUES (NULL, 4)", 457 ExpectedErr: sql.ErrInsertIntoNonNullableProvidedNull, 458 }, 459 { 460 Query: "drop table t40", 461 Expected: []sql.Row{{types.NewOkResult(0)}}, 462 }, 463 { 464 Query: "CREATE TABLE t40 (pk int AUTO_INCREMENT PRIMARY KEY, val int)", 465 Expected: []sql.Row{{types.NewOkResult(0)}}, 466 }, 467 { 468 Query: "INSERT INTO t40 VALUES (NULL, 1)", 469 Expected: []sql.Row{{types.OkResult{ 470 RowsAffected: 1, 471 InsertID: 1, 472 }}}, 473 }, 474 { 475 Query: "SELECT * FROM t40", 476 Expected: []sql.Row{{1, 1}}, 477 }, 478 }, 479 }, 480 { 481 Name: "add column unique index", 482 SetUpScript: []string{ 483 "CREATE TABLE t1 (i bigint primary key, s varchar(20))", 484 "INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c')", 485 }, 486 Assertions: []ScriptTestAssertion{ 487 { 488 Query: "alter table t1 add column j int unique", 489 Expected: []sql.Row{{types.NewOkResult(0)}}, 490 }, 491 { 492 Query: "show create table t1", 493 Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + 494 " `i` bigint NOT NULL,\n" + 495 " `s` varchar(20),\n" + 496 " `j` int,\n" + 497 " PRIMARY KEY (`i`),\n" + 498 " UNIQUE KEY `j` (`j`)\n" + 499 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 500 }, 501 }, 502 }, 503 { 504 Name: "multi-alter ddl column errors", 505 SetUpScript: []string{ 506 "create table tbl_i (i int primary key)", 507 "create table tbl_ij (i int primary key, j int)", 508 }, 509 Assertions: []ScriptTestAssertion{ 510 { 511 Query: "alter table tbl_i add column j int, drop column j", 512 ExpectedErr: sql.ErrTableColumnNotFound, 513 }, 514 { 515 Query: "alter table tbl_i add column j int, rename column j to k;", 516 ExpectedErr: sql.ErrTableColumnNotFound, 517 }, 518 { 519 Query: "alter table tbl_i add column j int, modify column j varchar(10)", 520 ExpectedErr: sql.ErrTableColumnNotFound, 521 }, 522 { 523 Query: "alter table tbl_ij drop column j, rename column j to k;", 524 ExpectedErr: sql.ErrTableColumnNotFound, 525 }, 526 { 527 Query: "alter table tbl_ij drop column k, rename column j to k;", 528 ExpectedErr: sql.ErrTableColumnNotFound, 529 }, 530 { 531 Query: "alter table tbl_i add index(j), add column j int;", 532 ExpectedErr: sql.ErrKeyColumnDoesNotExist, 533 }, 534 }, 535 }, 536 { 537 Name: "Add column and make unique in separate clauses", 538 SetUpScript: []string{ 539 "create table t (c1 int primary key, c2 int, c3 int)", 540 "insert into t values (1, 1, 1), (2, 2, 2), (3, 3, 3)", 541 }, 542 Assertions: []ScriptTestAssertion{ 543 { 544 Query: "alter table t add column c4 int null, add unique index uniq(c4)", 545 Expected: []sql.Row{ 546 {types.NewOkResult(0)}, 547 }, 548 }, 549 { 550 Query: "show create table t", 551 Expected: []sql.Row{sql.Row{"t", 552 "CREATE TABLE `t` (\n" + 553 " `c1` int NOT NULL,\n" + 554 " `c2` int,\n" + 555 " `c3` int,\n" + 556 " `c4` int,\n" + 557 " PRIMARY KEY (`c1`),\n" + 558 " UNIQUE KEY `uniq` (`c4`)\n" + 559 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 560 }, 561 { 562 Query: "select * from t", 563 Expected: []sql.Row{ 564 {1, 1, 1, nil}, 565 {2, 2, 2, nil}, 566 {3, 3, 3, nil}, 567 }, 568 }, 569 }, 570 }, 571 { 572 Name: "ALTER TABLE does not change column collations", 573 SetUpScript: []string{ 574 "CREATE TABLE test1 (v1 VARCHAR(200), v2 ENUM('a'), v3 SET('a'));", 575 "CREATE TABLE test2 (v1 VARCHAR(200), v2 ENUM('a'), v3 SET('a')) COLLATE=utf8mb4_general_ci;", 576 "CREATE TABLE test3 (v1 VARCHAR(200) COLLATE utf8mb4_general_ci, v2 ENUM('a'), v3 SET('a') CHARACTER SET utf8mb3) COLLATE=utf8mb4_general_ci", 577 "CREATE TABLE test4 (v1 VARCHAR(200) COLLATE utf8mb4_0900_ai_ci, v2 ENUM('a') COLLATE utf8mb4_general_ci, v3 SET('a') COLLATE utf8mb4_unicode_ci) COLLATE=utf8mb4_bin;", 578 }, 579 Assertions: []ScriptTestAssertion{ 580 { 581 Query: "SHOW CREATE TABLE test1", 582 Expected: []sql.Row{{"test1", 583 "CREATE TABLE `test1` (\n" + 584 " `v1` varchar(200),\n" + 585 " `v2` enum('a'),\n" + 586 " `v3` set('a')\n" + 587 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 588 }, 589 { 590 Query: "SHOW CREATE TABLE test2", 591 Expected: []sql.Row{{"test2", 592 "CREATE TABLE `test2` (\n" + 593 " `v1` varchar(200),\n" + 594 " `v2` enum('a'),\n" + 595 " `v3` set('a')\n" + 596 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"}}, 597 }, 598 { 599 Query: "SHOW CREATE TABLE test3", 600 Expected: []sql.Row{{"test3", 601 "CREATE TABLE `test3` (\n" + 602 " `v1` varchar(200),\n" + 603 " `v2` enum('a'),\n" + 604 " `v3` set('a') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci\n" + 605 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"}}, 606 }, 607 { 608 Query: "SHOW CREATE TABLE test4", 609 Expected: []sql.Row{{"test4", 610 "CREATE TABLE `test4` (\n" + 611 " `v1` varchar(200) COLLATE utf8mb4_0900_ai_ci,\n" + 612 " `v2` enum('a') COLLATE utf8mb4_general_ci,\n" + 613 " `v3` set('a') COLLATE utf8mb4_unicode_ci\n" + 614 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"}}, 615 }, 616 { 617 Query: "ALTER TABLE test1 COLLATE utf8mb4_general_ci;", 618 Expected: []sql.Row{{types.NewOkResult(0)}}, 619 }, 620 { 621 Query: "ALTER TABLE test2 COLLATE utf8mb4_0900_bin;", 622 Expected: []sql.Row{{types.NewOkResult(0)}}, 623 }, 624 { 625 Query: "ALTER TABLE test3 COLLATE utf8mb4_0900_bin;", 626 Expected: []sql.Row{{types.NewOkResult(0)}}, 627 }, 628 { 629 Query: "ALTER TABLE test4 COLLATE utf8mb4_unicode_ci;", 630 Expected: []sql.Row{{types.NewOkResult(0)}}, 631 }, 632 { 633 Query: "SHOW CREATE TABLE test1", 634 Expected: []sql.Row{{"test1", 635 "CREATE TABLE `test1` (\n" + 636 " `v1` varchar(200) COLLATE utf8mb4_0900_bin,\n" + 637 " `v2` enum('a') COLLATE utf8mb4_0900_bin,\n" + 638 " `v3` set('a') COLLATE utf8mb4_0900_bin\n" + 639 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"}}, 640 }, 641 { 642 Query: "SHOW CREATE TABLE test2", 643 Expected: []sql.Row{{"test2", 644 "CREATE TABLE `test2` (\n" + 645 " `v1` varchar(200) COLLATE utf8mb4_general_ci,\n" + 646 " `v2` enum('a') COLLATE utf8mb4_general_ci,\n" + 647 " `v3` set('a') COLLATE utf8mb4_general_ci\n" + 648 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 649 }, 650 { 651 Query: "SHOW CREATE TABLE test3", 652 Expected: []sql.Row{{"test3", 653 "CREATE TABLE `test3` (\n" + 654 " `v1` varchar(200) COLLATE utf8mb4_general_ci,\n" + 655 " `v2` enum('a') COLLATE utf8mb4_general_ci,\n" + 656 " `v3` set('a') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci\n" + 657 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 658 }, 659 { 660 Query: "SHOW CREATE TABLE test4", 661 Expected: []sql.Row{{"test4", 662 "CREATE TABLE `test4` (\n" + 663 " `v1` varchar(200) COLLATE utf8mb4_0900_ai_ci,\n" + 664 " `v2` enum('a') COLLATE utf8mb4_general_ci,\n" + 665 " `v3` set('a')\n" + 666 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"}}, 667 }, 668 }, 669 }, 670 { 671 Name: "ALTER TABLE ... ALTER ADD CHECK / DROP CHECK", 672 SetUpScript: []string{ 673 "CREATE TABLE test (pk BIGINT PRIMARY KEY, v1 BIGINT NOT NULL DEFAULT 88);", 674 }, 675 Assertions: []ScriptTestAssertion{ 676 { 677 Query: "ALTER TABLE test ADD CONSTRAINT cx CHECK (v1 < 100)", 678 Expected: []sql.Row{{types.NewOkResult(0)}}, 679 }, 680 { 681 Query: "ALTER TABLE test DROP CHECK cx, ADD CHECK (v1 < 50)", 682 Expected: []sql.Row{{types.NewOkResult(0)}}, 683 }, 684 { 685 Query: "INSERT INTO test VALUES (1, 99)", 686 ExpectedErr: sql.ErrCheckConstraintViolated, 687 }, 688 { 689 Query: "INSERT INTO test VALUES (2, 2)", 690 Expected: []sql.Row{{types.NewOkResult(1)}}, 691 }, 692 }, 693 }, 694 { 695 Name: "ALTER TABLE AUTO INCREMENT no-ops on table with no original auto increment key", 696 SetUpScript: []string{ 697 "CREATE table test (pk int primary key)", 698 "ALTER TABLE `test` auto_increment = 2;", 699 "INSERT INTO test VALUES (1)", 700 }, 701 Assertions: []ScriptTestAssertion{ 702 { 703 Query: "SELECT * FROM test", 704 Expected: []sql.Row{{1}}, 705 }, 706 }, 707 }, 708 { 709 Name: "ALTER TABLE MODIFY column with UNIQUE KEY", 710 SetUpScript: []string{ 711 "CREATE table test (pk int primary key, uk int unique)", 712 "ALTER TABLE `test` MODIFY column uk int auto_increment", 713 }, 714 Assertions: []ScriptTestAssertion{ 715 { 716 Query: "describe test", 717 Expected: []sql.Row{ 718 {"pk", "int", "NO", "PRI", "NULL", ""}, 719 {"uk", "int", "YES", "UNI", "NULL", "auto_increment"}, 720 }, 721 }, 722 }, 723 }, 724 { 725 Name: "ALTER TABLE MODIFY column making UNIQUE", 726 SetUpScript: []string{ 727 "CREATE table test (pk int primary key, uk int)", 728 "ALTER TABLE `test` MODIFY column uk int unique", 729 }, 730 Assertions: []ScriptTestAssertion{ 731 { 732 Query: "INSERT INTO test VALUES (1, 1), (2, 1)", 733 ExpectedErr: sql.ErrUniqueKeyViolation, 734 }, 735 }, 736 }, 737 { 738 Name: "ALTER TABLE MODIFY column with KEY", 739 SetUpScript: []string{ 740 "CREATE table test (pk int primary key, mk int, index (mk))", 741 "ALTER TABLE `test` MODIFY column mk int auto_increment", 742 }, 743 Assertions: []ScriptTestAssertion{ 744 { 745 Query: "describe test", 746 Expected: []sql.Row{ 747 {"pk", "int", "NO", "PRI", "NULL", ""}, 748 {"mk", "int", "YES", "MUL", "NULL", "auto_increment"}, 749 }, 750 }, 751 }, 752 }, 753 { 754 Name: "ALTER TABLE AUTO INCREMENT no-ops on table with no original auto increment key", 755 SetUpScript: []string{ 756 "CREATE table test (pk int primary key)", 757 "ALTER TABLE `test` auto_increment = 2;", 758 "INSERT INTO test VALUES (1)", 759 }, 760 Assertions: []ScriptTestAssertion{ 761 { 762 Query: "SELECT * FROM test", 763 Expected: []sql.Row{{1}}, 764 }, 765 }, 766 }, 767 { 768 Name: "Identifier lengths", 769 SetUpScript: []string{ 770 "create table t1 (a int primary key, b int)", 771 "create table parent (a int primary key)", 772 }, 773 Assertions: []ScriptTestAssertion{ 774 { 775 // 64 characters 776 Query: "alter table t1 rename to abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl", 777 Expected: []sql.Row{{types.NewOkResult(0)}}, 778 }, 779 { 780 // reset name 781 Query: "alter table abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl rename to t1", 782 Expected: []sql.Row{{types.NewOkResult(0)}}, 783 }, 784 { 785 // 65 characters 786 Query: "alter table t1 rename to abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm", 787 ExpectedErr: sql.ErrInvalidIdentifier, 788 }, 789 { 790 // 64 characters 791 Query: "alter table t1 rename column a to abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl", 792 Expected: []sql.Row{{types.NewOkResult(0)}}, 793 }, 794 { 795 // reset name 796 Query: "alter table t1 rename column abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl to a", 797 Expected: []sql.Row{{types.NewOkResult(0)}}, 798 }, 799 { 800 // 65 characters 801 Query: "alter table t1 rename column a to abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm", 802 ExpectedErr: sql.ErrInvalidIdentifier, 803 }, 804 { 805 // 64 characters 806 Query: "alter table t1 add constraint abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl check (a > 0)", 807 Expected: []sql.Row{{types.NewOkResult(0)}}, 808 }, 809 { 810 // 65 characters 811 Query: "alter table t1 add constraint abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm check (a > 0)", 812 ExpectedErr: sql.ErrInvalidIdentifier, 813 }, 814 { 815 // 64 characters 816 Query: "alter table t1 add constraint abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk0 foreign key(a) references parent(a)", 817 Expected: []sql.Row{{types.NewOkResult(0)}}, 818 }, 819 { 820 // 65 characters 821 Query: "alter table t1 add constraint abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm foreign key(a) references parent(a)", 822 ExpectedErr: sql.ErrInvalidIdentifier, 823 }, 824 { 825 // 64 characters 826 Query: "alter table t1 add constraint abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk1 unique key(a)", 827 Expected: []sql.Row{{types.NewOkResult(0)}}, 828 }, 829 { 830 // 65 characters 831 Query: "alter table t1 add constraint abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm unique key(a)", 832 ExpectedErr: sql.ErrInvalidIdentifier, 833 }, 834 { 835 // 64 characters 836 Query: "alter table t1 rename index abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk1 to abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk2", 837 Expected: []sql.Row{{types.NewOkResult(0)}}, 838 }, 839 { 840 // 65 characters 841 Query: "alter table t1 rename index abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk2 to abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm", 842 ExpectedErr: sql.ErrInvalidIdentifier, 843 }, 844 { 845 // 64 characters 846 Query: "alter table t1 add column abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk2 int", 847 Expected: []sql.Row{{types.NewOkResult(0)}}, 848 }, 849 { 850 // 65 characters 851 Query: "alter table t1 add column abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm int", 852 ExpectedErr: sql.ErrInvalidIdentifier, 853 }, 854 { 855 // 64 characters 856 Query: "alter table t1 change column abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk2 abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk3 int", 857 Expected: []sql.Row{{types.NewOkResult(0)}}, 858 }, 859 { 860 // 65 characters 861 Query: "alter table t1 change column abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk3 abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm int", 862 ExpectedErr: sql.ErrInvalidIdentifier, 863 }, 864 { 865 // 64 characters 866 Query: "alter table t1 add index abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk3 (b)", 867 Expected: []sql.Row{{types.NewOkResult(0)}}, 868 }, 869 { 870 // 65 characters 871 Query: "alter table t1 add index abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm (b)", 872 ExpectedErr: sql.ErrInvalidIdentifier, 873 }, 874 { 875 // test of the same in an alter block 876 Query: "alter table t1 add column d int, add index abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm (b)", 877 ExpectedErr: sql.ErrInvalidIdentifier, 878 }, 879 }, 880 }, 881 { 882 Name: "Add a column with the same case-insensitive name", 883 SetUpScript: []string{ 884 "create table t1 (abc int primary key, def int)", 885 }, 886 Assertions: []ScriptTestAssertion{ 887 { 888 Query: "alter table t1 add column ABC int", 889 ExpectedErr: sql.ErrColumnExists, 890 }, 891 }, 892 }, 893 { 894 Name: "Prefix index with same columns as another index", 895 SetUpScript: []string{ 896 "CREATE table t (pk int primary key, col1 varchar(100));", 897 "INSERT into t values (1, '100'), (2, '200');", 898 "alter table t add unique index idx1 (col1);", 899 }, 900 Assertions: []ScriptTestAssertion{ 901 { 902 Query: "alter table t add index idx2 (col1(10));", 903 Expected: []sql.Row{{types.NewOkResult(0)}}, 904 }, 905 { 906 Query: "show create table t", 907 Expected: []sql.Row{{"t", 908 "CREATE TABLE `t` (\n" + 909 " `pk` int NOT NULL,\n" + 910 " `col1` varchar(100),\n" + 911 " PRIMARY KEY (`pk`),\n" + 912 " UNIQUE KEY `idx1` (`col1`),\n" + 913 " KEY `idx2` (`col1`(10))\n" + 914 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 915 }, 916 }, 917 }, 918 } 919 920 var RenameTableScripts = []ScriptTest{ 921 { 922 Name: "simple rename table", 923 Assertions: []ScriptTestAssertion{ 924 { 925 Query: "RENAME TABLE mytable TO newTableName", 926 Expected: []sql.Row{{types.NewOkResult(0)}}, 927 }, 928 { 929 Query: "SELECT COUNT(*) FROM mytable", 930 ExpectedErr: sql.ErrTableNotFound, 931 }, 932 { 933 Query: "SELECT COUNT(*) FROM newTableName", 934 Expected: []sql.Row{{3}}, 935 }, 936 }, 937 }, 938 { 939 Name: "rename multiple tables in one stmt", 940 Assertions: []ScriptTestAssertion{ 941 { 942 Query: "RENAME TABLE othertable to othertable2, newTableName to mytable", 943 Expected: []sql.Row{{types.NewOkResult(0)}}, 944 }, 945 { 946 Query: "SELECT COUNT(*) FROM othertable", 947 ExpectedErr: sql.ErrTableNotFound, 948 }, 949 { 950 Query: "SELECT COUNT(*) FROM newTableName", 951 ExpectedErr: sql.ErrTableNotFound, 952 }, 953 { 954 Query: "SELECT COUNT(*) FROM mytable", 955 Expected: []sql.Row{{3}}, 956 }, 957 { 958 Query: "SELECT COUNT(*) FROM othertable2", 959 Expected: []sql.Row{{3}}, 960 }, 961 }, 962 }, 963 { 964 Name: "error cases", 965 Assertions: []ScriptTestAssertion{ 966 { 967 Query: "ALTER TABLE not_exist RENAME foo", 968 ExpectedErr: sql.ErrTableNotFound, 969 }, 970 { 971 Query: "ALTER TABLE emptytable RENAME niltable", 972 ExpectedErr: sql.ErrTableAlreadyExists, 973 }, 974 }, 975 }, 976 } 977 978 var AlterTableAddAutoIncrementScripts = []ScriptTest{ 979 { 980 Name: "Add primary key column with auto increment", 981 SetUpScript: []string{ 982 "CREATE TABLE t1 (i int, j int);", 983 "insert into t1 values (1,1), (2,2), (3,3)", 984 }, 985 Assertions: []ScriptTestAssertion{ 986 { 987 Query: "alter table t1 add column pk int primary key auto_increment;", 988 Expected: []sql.Row{{types.NewOkResult(0)}}, 989 }, 990 { 991 Query: "show create table t1", 992 Expected: []sql.Row{{"t1", 993 "CREATE TABLE `t1` (\n" + 994 " `i` int,\n" + 995 " `j` int,\n" + 996 " `pk` int NOT NULL AUTO_INCREMENT,\n" + 997 " PRIMARY KEY (`pk`)\n" + 998 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 999 }, 1000 { 1001 Query: "select pk from t1 order by pk", 1002 Expected: []sql.Row{ 1003 {1}, {2}, {3}, 1004 }, 1005 }, 1006 }, 1007 }, 1008 { 1009 Name: "Add primary key column with auto increment, first", 1010 SetUpScript: []string{ 1011 "CREATE TABLE t1 (i int, j int);", 1012 "insert into t1 values (1,1), (2,2), (3,3)", 1013 }, 1014 Assertions: []ScriptTestAssertion{ 1015 { 1016 Query: "alter table t1 add column pk int primary key", 1017 ExpectedErr: sql.ErrPrimaryKeyViolation, 1018 }, 1019 { 1020 Query: "alter table t1 add column pk int primary key auto_increment first", 1021 Expected: []sql.Row{{types.NewOkResult(0)}}, 1022 }, 1023 { 1024 Query: "show create table t1", 1025 Expected: []sql.Row{{"t1", 1026 "CREATE TABLE `t1` (\n" + 1027 " `pk` int NOT NULL AUTO_INCREMENT,\n" + 1028 " `i` int,\n" + 1029 " `j` int,\n" + 1030 " PRIMARY KEY (`pk`)\n" + 1031 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1032 }, 1033 { 1034 Query: "select pk from t1 order by pk", 1035 Expected: []sql.Row{ 1036 {1}, {2}, {3}, 1037 }, 1038 }, 1039 }, 1040 }, 1041 { 1042 Name: "add column auto_increment, non primary key", 1043 SetUpScript: []string{ 1044 "CREATE TABLE t1 (i bigint primary key, s varchar(20))", 1045 "INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c')", 1046 }, 1047 Assertions: []ScriptTestAssertion{ 1048 { 1049 Query: "alter table t1 add column j int auto_increment unique", 1050 Expected: []sql.Row{{types.NewOkResult(0)}}, 1051 }, 1052 { 1053 Query: "show create table t1", 1054 Expected: []sql.Row{{"t1", 1055 "CREATE TABLE `t1` (\n" + 1056 " `i` bigint NOT NULL,\n" + 1057 " `s` varchar(20),\n" + 1058 " `j` int AUTO_INCREMENT,\n" + 1059 " PRIMARY KEY (`i`),\n" + 1060 " UNIQUE KEY `j` (`j`)\n" + 1061 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1062 }, 1063 { 1064 Query: "select * from t1 order by i", 1065 Expected: []sql.Row{ 1066 {1, "a", 1}, 1067 {2, "b", 2}, 1068 {3, "c", 3}, 1069 }, 1070 }, 1071 }, 1072 }, 1073 { 1074 Name: "add column auto_increment, non key", 1075 SetUpScript: []string{ 1076 "CREATE TABLE t1 (i bigint primary key, s varchar(20))", 1077 "INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c')", 1078 }, 1079 Assertions: []ScriptTestAssertion{ 1080 { 1081 Query: "alter table t1 add column j int auto_increment", 1082 ExpectedErr: sql.ErrInvalidAutoIncCols, 1083 }, 1084 }, 1085 }, 1086 } 1087 1088 var AddDropPrimaryKeyScripts = []ScriptTest{ 1089 { 1090 Name: "Add primary key", 1091 SetUpScript: []string{ 1092 "create table t1 (i int, j int)", 1093 "insert into t1 values (1,1), (1,2), (1,3)", 1094 }, 1095 Assertions: []ScriptTestAssertion{ 1096 { 1097 Query: "alter table t1 add primary key (i)", 1098 ExpectedErr: sql.ErrPrimaryKeyViolation, 1099 }, 1100 { 1101 Query: "show create table t1", 1102 Expected: []sql.Row{{"t1", 1103 "CREATE TABLE `t1` (\n" + 1104 " `i` int,\n" + 1105 " `j` int\n" + 1106 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1107 }, 1108 { 1109 Query: "alter table t1 add primary key (i, j)", 1110 Expected: []sql.Row{{types.NewOkResult(0)}}, 1111 }, 1112 { 1113 Query: "show create table t1", 1114 Expected: []sql.Row{{"t1", 1115 "CREATE TABLE `t1` (\n" + 1116 " `i` int NOT NULL,\n" + 1117 " `j` int NOT NULL,\n" + 1118 " PRIMARY KEY (`i`,`j`)\n" + 1119 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1120 }, 1121 }, 1122 }, 1123 { 1124 Name: "Drop primary key for table with multiple primary key columns", 1125 SetUpScript: []string{ 1126 "create table t1 (pk varchar(20), v varchar(20) default (concat(pk, '-foo')), primary key (pk, v))", 1127 "insert into t1 values ('a1', 'a2'), ('a2', 'a3'), ('a3', 'a4')", 1128 }, 1129 Assertions: []ScriptTestAssertion{ 1130 { 1131 Query: "select * from t1 order by pk", 1132 Expected: []sql.Row{ 1133 {"a1", "a2"}, 1134 {"a2", "a3"}, 1135 {"a3", "a4"}, 1136 }, 1137 }, 1138 { 1139 Query: "alter table t1 drop primary key", 1140 Expected: []sql.Row{{types.NewOkResult(0)}}, 1141 }, 1142 { 1143 Query: "select * from t1 order by pk", 1144 Expected: []sql.Row{ 1145 {"a1", "a2"}, 1146 {"a2", "a3"}, 1147 {"a3", "a4"}, 1148 }, 1149 }, 1150 { 1151 Query: "insert into t1 values ('a1', 'a2')", 1152 Expected: []sql.Row{{types.NewOkResult(1)}}, 1153 }, 1154 { 1155 Query: "select * from t1 order by pk", 1156 Expected: []sql.Row{ 1157 {"a1", "a2"}, 1158 {"a1", "a2"}, 1159 {"a2", "a3"}, 1160 {"a3", "a4"}, 1161 }, 1162 }, 1163 { 1164 Query: "alter table t1 add primary key (pk, v)", 1165 ExpectedErr: sql.ErrPrimaryKeyViolation, 1166 }, 1167 { 1168 Query: "delete from t1 where pk = 'a1' limit 1", 1169 Expected: []sql.Row{{types.NewOkResult(1)}}, 1170 }, 1171 { 1172 Query: "alter table t1 add primary key (pk, v)", 1173 Expected: []sql.Row{{types.NewOkResult(0)}}, 1174 }, 1175 { 1176 Query: "show create table t1", 1177 Expected: []sql.Row{{"t1", 1178 "CREATE TABLE `t1` (\n" + 1179 " `pk` varchar(20) NOT NULL,\n" + 1180 " `v` varchar(20) NOT NULL DEFAULT (concat(`pk`,'-foo')),\n" + 1181 " PRIMARY KEY (`pk`,`v`)\n" + 1182 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1183 }, 1184 { 1185 Query: "alter table t1 drop primary key", 1186 Expected: []sql.Row{{types.NewOkResult(0)}}, 1187 }, 1188 { 1189 Query: "alter table t1 add index myidx (v)", 1190 Expected: []sql.Row{{types.NewOkResult(0)}}, 1191 }, 1192 { 1193 Query: "alter table t1 add primary key (pk)", 1194 Expected: []sql.Row{{types.NewOkResult(0)}}, 1195 }, 1196 { 1197 Query: "insert into t1 values ('a4', 'a3')", 1198 Expected: []sql.Row{{types.NewOkResult(1)}}, 1199 }, 1200 { 1201 Query: "show create table t1", 1202 Expected: []sql.Row{{"t1", 1203 "CREATE TABLE `t1` (\n" + 1204 " `pk` varchar(20) NOT NULL,\n" + 1205 " `v` varchar(20) NOT NULL DEFAULT (concat(`pk`,'-foo')),\n" + 1206 " PRIMARY KEY (`pk`),\n" + 1207 " KEY `myidx` (`v`)\n" + 1208 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1209 }, 1210 { 1211 Query: "select * from t1 where v = 'a3' order by pk", 1212 Expected: []sql.Row{ 1213 {"a2", "a3"}, 1214 {"a4", "a3"}, 1215 }, 1216 }, 1217 { 1218 Query: "alter table t1 drop primary key", 1219 Expected: []sql.Row{{types.NewOkResult(0)}}, 1220 }, 1221 { 1222 Query: "truncate t1", 1223 Expected: []sql.Row{{types.NewOkResult(4)}}, 1224 }, 1225 { 1226 Query: "alter table t1 drop index myidx", 1227 Expected: []sql.Row{{types.NewOkResult(0)}}, 1228 }, 1229 { 1230 Query: "alter table t1 add primary key (pk, v)", 1231 Expected: []sql.Row{{types.NewOkResult(0)}}, 1232 }, 1233 { 1234 Query: "insert into t1 values ('a1', 'a2'), ('a2', 'a3'), ('a3', 'a4')", 1235 Expected: []sql.Row{{types.NewOkResult(3)}}, 1236 }, 1237 }, 1238 }, 1239 { 1240 Name: "Drop primary key for table with multiple primary key columns, add smaller primary key in same statement", 1241 SetUpScript: []string{ 1242 "create table t1 (pk varchar(20), v varchar(20) default (concat(pk, '-foo')), primary key (pk, v))", 1243 "insert into t1 values ('a1', 'a2'), ('a2', 'a3'), ('a3', 'a4')", 1244 }, 1245 Assertions: []ScriptTestAssertion{ 1246 { 1247 Query: "ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (v)", 1248 Expected: []sql.Row{{types.NewOkResult(0)}}, 1249 }, 1250 { 1251 Query: "INSERT INTO t1 (pk, v) values ('a100', 'a3')", 1252 ExpectedErr: sql.ErrPrimaryKeyViolation, 1253 }, 1254 { 1255 Query: "alter table t1 drop primary key", 1256 Expected: []sql.Row{{types.NewOkResult(0)}}, 1257 }, 1258 { 1259 Query: "ALTER TABLE t1 ADD PRIMARY KEY (pk, v), DROP PRIMARY KEY", 1260 Expected: []sql.Row{{types.NewOkResult(0)}}, 1261 }, 1262 { 1263 Query: "show create table t1", 1264 Expected: []sql.Row{{"t1", 1265 "CREATE TABLE `t1` (\n" + 1266 " `pk` varchar(20) NOT NULL,\n" + 1267 " `v` varchar(20) NOT NULL DEFAULT (concat(`pk`,'-foo'))\n" + 1268 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1269 }, 1270 }, 1271 }, 1272 { 1273 Name: "No database selected", 1274 SetUpScript: []string{ 1275 "create database newdb", 1276 "create table newdb.tab1 (pk int, c1 int)", 1277 "ALTER TABLE newdb.tab1 ADD PRIMARY KEY (pk)", 1278 }, 1279 Assertions: []ScriptTestAssertion{ 1280 { 1281 Query: "SHOW CREATE TABLE newdb.tab1", 1282 Expected: []sql.Row{{"tab1", 1283 "CREATE TABLE `tab1` (\n" + 1284 " `pk` int NOT NULL,\n" + 1285 " `c1` int,\n" + 1286 " PRIMARY KEY (`pk`)\n" + 1287 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1288 }, 1289 { 1290 Query: "alter table newdb.tab1 drop primary key", 1291 Expected: []sql.Row{{types.NewOkResult(0)}}, 1292 }, 1293 { 1294 Query: "SHOW CREATE TABLE newdb.tab1", 1295 Expected: []sql.Row{{"tab1", 1296 "CREATE TABLE `tab1` (\n" + 1297 " `pk` int NOT NULL,\n" + 1298 " `c1` int\n" + 1299 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1300 }, 1301 }, 1302 }, 1303 { 1304 Name: "Drop primary key auto increment", 1305 SetUpScript: []string{ 1306 "CREATE TABLE test(pk int AUTO_INCREMENT PRIMARY KEY, val int)", 1307 }, 1308 Assertions: []ScriptTestAssertion{ 1309 { 1310 Query: "ALTER TABLE test DROP PRIMARY KEY", 1311 ExpectedErr: sql.ErrWrongAutoKey, 1312 }, 1313 { 1314 Query: "ALTER TABLE test modify pk int", 1315 Expected: []sql.Row{{types.NewOkResult(0)}}, 1316 }, 1317 { 1318 Query: "SHOW CREATE TABLE test", 1319 Expected: []sql.Row{{"test", 1320 "CREATE TABLE `test` (\n" + 1321 " `pk` int NOT NULL,\n" + 1322 " `val` int,\n" + 1323 " PRIMARY KEY (`pk`)\n" + 1324 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1325 }, 1326 { 1327 Query: "ALTER TABLE test drop primary key", 1328 Expected: []sql.Row{{types.NewOkResult(0)}}, 1329 }, 1330 { 1331 Query: "SHOW CREATE TABLE test", 1332 Expected: []sql.Row{{"test", 1333 "CREATE TABLE `test` (\n" + 1334 " `pk` int NOT NULL,\n" + 1335 " `val` int\n" + 1336 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1337 }, 1338 { 1339 Query: "INSERT INTO test VALUES (1, 1), (NULL, 1)", 1340 ExpectedErr: sql.ErrInsertIntoNonNullableProvidedNull, 1341 }, 1342 { 1343 Query: "INSERT INTO test VALUES (2, 2), (3, 3)", 1344 Expected: []sql.Row{{types.NewOkResult(2)}}, 1345 }, 1346 { 1347 Query: "SELECT * FROM test ORDER BY pk", 1348 Expected: []sql.Row{ 1349 {2, 2}, 1350 {3, 3}, 1351 }, 1352 }, 1353 }, 1354 }, 1355 { 1356 Name: "Drop auto-increment primary key with supporting unique index", 1357 SetUpScript: []string{ 1358 "create table t (id int primary key AUTO_INCREMENT, c1 varchar(255));", 1359 "insert into t (c1) values ('one');", 1360 }, 1361 Assertions: []ScriptTestAssertion{ 1362 { 1363 // Without a supporting index, we can't drop the PK because of the auto_increment property 1364 Query: "ALTER TABLE t DROP PRIMARY KEY;", 1365 ExpectedErr: sql.ErrWrongAutoKey, 1366 }, 1367 { 1368 // Adding a unique index on the pk column allows us to drop the PK 1369 Query: "ALTER TABLE t ADD UNIQUE KEY id (id);", 1370 Expected: []sql.Row{{types.NewOkResult(0)}}, 1371 }, 1372 { 1373 Query: "ALTER TABLE t DROP PRIMARY KEY;", 1374 Expected: []sql.Row{{types.NewOkResult(0)}}, 1375 }, 1376 { 1377 Query: "show create table t;", 1378 Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `id` int NOT NULL AUTO_INCREMENT,\n `c1` varchar(255),\n UNIQUE KEY `id` (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1379 }, 1380 { 1381 Query: "insert into t (c1) values('two');", 1382 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 2}}}, 1383 }, 1384 { 1385 Query: "select * from t;", 1386 Expected: []sql.Row{{1, "one"}, {2, "two"}}, 1387 }, 1388 }, 1389 }, 1390 { 1391 Name: "Drop auto-increment primary key with supporting non-unique index", 1392 SetUpScript: []string{ 1393 "create table t (id int primary key AUTO_INCREMENT, c1 varchar(255));", 1394 "insert into t (c1) values ('one');", 1395 }, 1396 Assertions: []ScriptTestAssertion{ 1397 { 1398 // Without a supporting index, we cannot drop the PK 1399 Query: "ALTER TABLE t DROP PRIMARY KEY;", 1400 ExpectedErr: sql.ErrWrongAutoKey, 1401 }, 1402 { 1403 // Adding an index on the PK columns allows us to drop the PK 1404 Query: "ALTER TABLE t ADD KEY id (id);", 1405 Expected: []sql.Row{{types.NewOkResult(0)}}, 1406 }, 1407 { 1408 Query: "ALTER TABLE t DROP PRIMARY KEY;", 1409 Expected: []sql.Row{{types.NewOkResult(0)}}, 1410 }, 1411 { 1412 Query: "show create table t;", 1413 Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `id` int NOT NULL AUTO_INCREMENT,\n `c1` varchar(255),\n KEY `id` (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1414 }, 1415 { 1416 Query: "insert into t (c1) values('two');", 1417 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 2}}}, 1418 }, 1419 { 1420 Query: "select * from t;", 1421 Expected: []sql.Row{{1, "one"}, {2, "two"}}, 1422 }, 1423 }, 1424 }, 1425 { 1426 Name: "Drop multi-column, auto-increment primary key with supporting non-unique index", 1427 SetUpScript: []string{ 1428 "create table t (id1 int AUTO_INCREMENT, id2 int not null, c1 varchar(255), primary key (id1, id2));", 1429 "insert into t (id2, c1) values (-1, 'one');", 1430 }, 1431 Assertions: []ScriptTestAssertion{ 1432 { 1433 Query: "ALTER TABLE t DROP PRIMARY KEY;", 1434 ExpectedErr: sql.ErrWrongAutoKey, 1435 }, 1436 { 1437 // Adding an index that doesn't start with the auto_increment column doesn't allow us to drop the PK 1438 Query: "ALTER TABLE t ADD KEY c1id1 (c1, id1);", 1439 Expected: []sql.Row{{types.NewOkResult(0)}}, 1440 }, 1441 { 1442 Query: "ALTER TABLE t DROP PRIMARY KEY;", 1443 ExpectedErr: sql.ErrWrongAutoKey, 1444 }, 1445 { 1446 // Adding a supporting key (i.e the first column is the auto_increment column) allows us to drop the PK 1447 Query: "ALTER TABLE t ADD KEY id1c1 (id1, c1);", 1448 Expected: []sql.Row{{types.NewOkResult(0)}}, 1449 }, 1450 { 1451 Query: "ALTER TABLE t DROP PRIMARY KEY;", 1452 Expected: []sql.Row{{types.NewOkResult(0)}}, 1453 }, 1454 { 1455 Query: "insert into t (id2, c1) values(-2, 'two');", 1456 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 2}}}, 1457 }, 1458 { 1459 Query: "select * from t;", 1460 Expected: []sql.Row{{1, -1, "one"}, {2, -2, "two"}}, 1461 }, 1462 { 1463 Query: "show create table t;", 1464 Expected: []sql.Row{{"t", "CREATE TABLE `t` (\n `id1` int NOT NULL AUTO_INCREMENT,\n `id2` int NOT NULL,\n `c1` varchar(255),\n KEY `c1id1` (`c1`,`id1`),\n KEY `id1c1` (`id1`,`c1`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, 1465 }, 1466 }, 1467 }, 1468 } 1469 1470 var AddColumnScripts = []ScriptTest{ 1471 { 1472 Name: "column at end with default", 1473 Assertions: []ScriptTestAssertion{ 1474 { 1475 Query: "ALTER TABLE mytable ADD COLUMN i2 INT COMMENT 'hello' default 42", 1476 Expected: []sql.Row{{types.NewOkResult(0)}}, 1477 }, 1478 { 1479 Query: "SHOW FULL COLUMNS FROM mytable", 1480 // | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | 1481 // TODO: missing privileges 1482 Expected: []sql.Row{ 1483 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 1484 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "UNI", "NULL", "", "", "column s"}, 1485 {"i2", "int", nil, "YES", "", "42", "", "", "hello"}, 1486 }, 1487 }, 1488 { 1489 Query: "SELECT * FROM mytable ORDER BY i;", 1490 Expected: []sql.Row{ 1491 sql.NewRow(int64(1), "first row", int32(42)), 1492 sql.NewRow(int64(2), "second row", int32(42)), 1493 sql.NewRow(int64(3), "third row", int32(42)), 1494 }, 1495 }, 1496 }, 1497 }, 1498 { 1499 Name: "in middle, no default", 1500 Assertions: []ScriptTestAssertion{ 1501 { 1502 Query: "ALTER TABLE mytable ADD COLUMN s2 TEXT COMMENT 'hello' AFTER i;", 1503 Expected: []sql.Row{{types.NewOkResult(0)}}, 1504 }, 1505 { 1506 Query: "SHOW FULL COLUMNS FROM mytable", 1507 Expected: []sql.Row{ 1508 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 1509 {"s2", "text", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "hello"}, 1510 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "UNI", "NULL", "", "", "column s"}, 1511 {"i2", "int", nil, "YES", "", "42", "", "", "hello"}, 1512 }, 1513 }, 1514 { 1515 Query: "SELECT * FROM mytable ORDER BY i;", 1516 Expected: []sql.Row{ 1517 sql.NewRow(int64(1), nil, "first row", int32(42)), 1518 sql.NewRow(int64(2), nil, "second row", int32(42)), 1519 sql.NewRow(int64(3), nil, "third row", int32(42)), 1520 }, 1521 }, 1522 { 1523 Query: "insert into mytable values (4, 's2', 'fourth row', 11);", 1524 Expected: []sql.Row{{types.NewOkResult(1)}}, 1525 }, 1526 { 1527 Query: "update mytable set s2 = 'updated s2' where i2 = 42;", 1528 Expected: []sql.Row{{types.OkResult{RowsAffected: 3, Info: plan.UpdateInfo{Matched: 3, Updated: 3}}}}, 1529 }, 1530 { 1531 Query: "SELECT * FROM mytable ORDER BY i;", 1532 Expected: []sql.Row{ 1533 sql.NewRow(int64(1), "updated s2", "first row", int32(42)), 1534 sql.NewRow(int64(2), "updated s2", "second row", int32(42)), 1535 sql.NewRow(int64(3), "updated s2", "third row", int32(42)), 1536 sql.NewRow(int64(4), "s2", "fourth row", int32(11)), 1537 }, 1538 }, 1539 }, 1540 }, 1541 { 1542 Name: "first with default", 1543 Assertions: []ScriptTestAssertion{ 1544 { 1545 Query: "ALTER TABLE mytable ADD COLUMN s3 VARCHAR(25) COMMENT 'hello' default 'yay' FIRST", 1546 Expected: []sql.Row{{types.NewOkResult(0)}}, 1547 }, 1548 { 1549 Query: "SHOW FULL COLUMNS FROM mytable", 1550 Expected: []sql.Row{ 1551 {"s3", "varchar(25)", "utf8mb4_0900_bin", "YES", "", "'yay'", "", "", "hello"}, 1552 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 1553 {"s2", "text", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "hello"}, 1554 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "UNI", "NULL", "", "", "column s"}, 1555 {"i2", "int", nil, "YES", "", "42", "", "", "hello"}, 1556 }, 1557 }, 1558 { 1559 Query: "SELECT * FROM mytable ORDER BY i;", 1560 Expected: []sql.Row{ 1561 sql.NewRow("yay", int64(1), "updated s2", "first row", int32(42)), 1562 sql.NewRow("yay", int64(2), "updated s2", "second row", int32(42)), 1563 sql.NewRow("yay", int64(3), "updated s2", "third row", int32(42)), 1564 sql.NewRow("yay", int64(4), "s2", "fourth row", int32(11)), 1565 }, 1566 }, 1567 }, 1568 }, 1569 { 1570 Name: "middle, no default, non null", 1571 Assertions: []ScriptTestAssertion{ 1572 { 1573 Query: "ALTER TABLE mytable ADD COLUMN s4 VARCHAR(1) not null after s3", 1574 Expected: []sql.Row{{types.NewOkResult(0)}}, 1575 }, 1576 { 1577 Query: "SHOW FULL COLUMNS FROM mytable", 1578 Expected: []sql.Row{ 1579 {"s3", "varchar(25)", "utf8mb4_0900_bin", "YES", "", "'yay'", "", "", "hello"}, 1580 {"s4", "varchar(1)", "utf8mb4_0900_bin", "NO", "", "NULL", "", "", ""}, 1581 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 1582 {"s2", "text", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "hello"}, 1583 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "UNI", "NULL", "", "", "column s"}, 1584 {"i2", "int", nil, "YES", "", "42", "", "", "hello"}, 1585 }, 1586 }, 1587 { 1588 Query: "SELECT * FROM mytable ORDER BY i;", 1589 Expected: []sql.Row{ 1590 sql.NewRow("yay", "", int64(1), "updated s2", "first row", int32(42)), 1591 sql.NewRow("yay", "", int64(2), "updated s2", "second row", int32(42)), 1592 sql.NewRow("yay", "", int64(3), "updated s2", "third row", int32(42)), 1593 sql.NewRow("yay", "", int64(4), "s2", "fourth row", int32(11)), 1594 }, 1595 }, 1596 }, 1597 }, 1598 { 1599 Name: "multiple in one statement", 1600 Assertions: []ScriptTestAssertion{ 1601 { 1602 Query: "ALTER TABLE mytable ADD COLUMN s5 VARCHAR(26), ADD COLUMN s6 VARCHAR(27)", 1603 Expected: []sql.Row{{types.NewOkResult(0)}}, 1604 }, 1605 { 1606 Query: "SHOW FULL COLUMNS FROM mytable", 1607 Expected: []sql.Row{ 1608 {"s3", "varchar(25)", "utf8mb4_0900_bin", "YES", "", "'yay'", "", "", "hello"}, 1609 {"s4", "varchar(1)", "utf8mb4_0900_bin", "NO", "", "NULL", "", "", ""}, 1610 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 1611 {"s2", "text", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "hello"}, 1612 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "UNI", "NULL", "", "", "column s"}, 1613 {"i2", "int", nil, "YES", "", "42", "", "", "hello"}, 1614 {"s5", "varchar(26)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", ""}, 1615 {"s6", "varchar(27)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", ""}, 1616 }, 1617 }, 1618 { 1619 Query: "SELECT * FROM mytable ORDER BY i;", 1620 Expected: []sql.Row{ 1621 sql.NewRow("yay", "", int64(1), "updated s2", "first row", int32(42), nil, nil), 1622 sql.NewRow("yay", "", int64(2), "updated s2", "second row", int32(42), nil, nil), 1623 sql.NewRow("yay", "", int64(3), "updated s2", "third row", int32(42), nil, nil), 1624 sql.NewRow("yay", "", int64(4), "s2", "fourth row", int32(11), nil, nil), 1625 }, 1626 }, 1627 }, 1628 }, 1629 { 1630 Name: "error cases", 1631 Assertions: []ScriptTestAssertion{ 1632 { 1633 Query: "ALTER TABLE not_exist ADD COLUMN i2 INT COMMENT 'hello'", 1634 ExpectedErr: sql.ErrTableNotFound, 1635 }, 1636 { 1637 Query: "ALTER TABLE mytable ADD COLUMN b BIGINT COMMENT 'ok' AFTER not_exist", 1638 ExpectedErr: sql.ErrTableColumnNotFound, 1639 }, 1640 { 1641 Query: "ALTER TABLE mytable ADD COLUMN i BIGINT COMMENT 'ok'", 1642 ExpectedErr: sql.ErrColumnExists, 1643 }, 1644 { 1645 Query: "ALTER TABLE mytable ADD COLUMN b INT NOT NULL DEFAULT 'yes'", 1646 ExpectedErr: sql.ErrIncompatibleDefaultType, 1647 }, 1648 { 1649 Query: "ALTER TABLE mytable ADD COLUMN c int, add c int", 1650 ExpectedErr: sql.ErrColumnExists, 1651 }, 1652 }, 1653 }, 1654 } 1655 1656 var RenameColumnScripts = []ScriptTest{ 1657 { 1658 Name: "error cases", 1659 Assertions: []ScriptTestAssertion{ 1660 { 1661 Query: "ALTER TABLE mytable RENAME COLUMN i2 TO iX", 1662 ExpectedErr: sql.ErrTableColumnNotFound, 1663 }, 1664 { 1665 Query: "ALTER TABLE mytable RENAME COLUMN i TO iX, RENAME COLUMN iX TO i2", 1666 ExpectedErr: sql.ErrTableColumnNotFound, 1667 }, 1668 { 1669 Query: "ALTER TABLE mytable RENAME COLUMN i TO iX, RENAME COLUMN i TO i2", 1670 ExpectedErr: sql.ErrTableColumnNotFound, 1671 }, 1672 { 1673 Query: "ALTER TABLE mytable RENAME COLUMN i TO S", 1674 ExpectedErr: sql.ErrColumnExists, 1675 }, 1676 { 1677 Query: "ALTER TABLE mytable RENAME COLUMN i TO n, RENAME COLUMN s TO N", 1678 ExpectedErr: sql.ErrColumnExists, 1679 }, 1680 }, 1681 }, 1682 { 1683 Name: "simple rename column", 1684 Assertions: []ScriptTestAssertion{ 1685 { 1686 Query: "ALTER TABLE mytable RENAME COLUMN i TO i2, RENAME COLUMN s TO s2", 1687 Expected: []sql.Row{{types.NewOkResult(0)}}, 1688 }, 1689 { 1690 Query: "SHOW FULL COLUMNS FROM mytable", 1691 Expected: []sql.Row{ 1692 {"i2", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 1693 {"s2", "varchar(20)", "utf8mb4_0900_bin", "NO", "UNI", "NULL", "", "", "column s"}, 1694 }, 1695 }, 1696 { 1697 Query: "select * from mytable order by i2 limit 1", 1698 Expected: []sql.Row{ 1699 {1, "first row"}, 1700 }, 1701 }, 1702 }, 1703 }, 1704 { 1705 Name: "rename column preserves table checks", 1706 SetUpScript: []string{ 1707 "ALTER TABLE mytable ADD CONSTRAINT test_check CHECK (i2 < 12345)", 1708 }, 1709 Assertions: []ScriptTestAssertion{ 1710 { 1711 Query: "ALTER TABLE mytable RENAME COLUMN i2 TO i3", 1712 ExpectedErr: sql.ErrCheckConstraintInvalidatedByColumnAlter, 1713 }, 1714 { 1715 Query: "ALTER TABLE mytable RENAME COLUMN s2 TO s3", 1716 Expected: []sql.Row{{types.NewOkResult(0)}}, 1717 }, 1718 { 1719 Query: `SELECT TC.CONSTRAINT_NAME, CC.CHECK_CLAUSE, TC.ENFORCED 1720 FROM information_schema.TABLE_CONSTRAINTS TC, information_schema.CHECK_CONSTRAINTS CC 1721 WHERE TABLE_SCHEMA = 'mydb' AND TABLE_NAME = 'mytable' AND TC.TABLE_SCHEMA = CC.CONSTRAINT_SCHEMA AND TC.CONSTRAINT_NAME = CC.CONSTRAINT_NAME AND TC.CONSTRAINT_TYPE = 'CHECK';`, 1722 Expected: []sql.Row{{"test_check", "(i2 < 12345)", "YES"}}, 1723 }, 1724 }, 1725 }, 1726 } 1727 1728 var ModifyColumnScripts = []ScriptTest{ 1729 { 1730 Name: "column at end with default", 1731 Assertions: []ScriptTestAssertion{ 1732 { 1733 Query: "ALTER TABLE mytable MODIFY COLUMN i bigint NOT NULL COMMENT 'modified'", 1734 Expected: []sql.Row{{types.NewOkResult(0)}}, 1735 }, 1736 { 1737 Query: "SHOW FULL COLUMNS FROM mytable /* 1 */", 1738 Expected: []sql.Row{ 1739 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", "modified"}, 1740 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "", "NULL", "", "", "column s"}, 1741 }, 1742 }, 1743 { 1744 Query: "ALTER TABLE mytable MODIFY COLUMN i TINYINT NOT NULL COMMENT 'yes' AFTER s", 1745 Expected: []sql.Row{{types.NewOkResult(0)}}, 1746 }, 1747 { 1748 Query: "SHOW FULL COLUMNS FROM mytable /* 2 */", 1749 Expected: []sql.Row{ 1750 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "", "NULL", "", "", "column s"}, 1751 {"i", "tinyint", nil, "NO", "PRI", "NULL", "", "", "yes"}, 1752 }, 1753 }, 1754 { 1755 Query: "ALTER TABLE mytable MODIFY COLUMN i BIGINT NOT NULL COMMENT 'ok' FIRST", 1756 Expected: []sql.Row{{types.NewOkResult(0)}}, 1757 }, 1758 { 1759 Query: "SHOW FULL COLUMNS FROM mytable /* 3 */", 1760 Expected: []sql.Row{ 1761 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", "ok"}, 1762 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "", "NULL", "", "", "column s"}, 1763 }, 1764 }, 1765 { 1766 Query: "ALTER TABLE mytable MODIFY COLUMN s VARCHAR(20) NULL COMMENT 'changed'", 1767 Expected: []sql.Row{{types.NewOkResult(0)}}, 1768 }, 1769 { 1770 Query: "SHOW FULL COLUMNS FROM mytable /* 4 */", 1771 Expected: []sql.Row{ 1772 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", "ok"}, 1773 {"s", "varchar(20)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "changed"}, 1774 }, 1775 }, 1776 }, 1777 }, 1778 { 1779 Name: "auto increment attribute", 1780 SetUpScript: []string{}, 1781 Assertions: []ScriptTestAssertion{ 1782 { 1783 Query: "ALTER TABLE mytable MODIFY i BIGINT auto_increment", 1784 Expected: []sql.Row{{types.NewOkResult(0)}}, 1785 }, 1786 { 1787 Query: "SHOW FULL COLUMNS FROM mytable /* 1 */", 1788 Expected: []sql.Row{ 1789 {"i", "bigint", nil, "NO", "PRI", "NULL", "auto_increment", "", ""}, 1790 {"s", "varchar(20)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "changed"}, 1791 }, 1792 }, 1793 { 1794 Query: "insert into mytable (s) values ('new row')", 1795 }, 1796 { 1797 Query: "ALTER TABLE mytable add column i2 bigint auto_increment", 1798 ExpectedErr: sql.ErrInvalidAutoIncCols, 1799 }, 1800 { 1801 Query: "alter table mytable add column i2 bigint", 1802 }, 1803 { 1804 Query: "ALTER TABLE mytable modify column i2 bigint auto_increment", 1805 ExpectedErr: sql.ErrInvalidAutoIncCols, 1806 }, 1807 { 1808 Query: "SHOW FULL COLUMNS FROM mytable /* 2 */", 1809 Expected: []sql.Row{ 1810 {"i", "bigint", nil, "NO", "PRI", "NULL", "auto_increment", "", ""}, 1811 {"s", "varchar(20)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "changed"}, 1812 {"i2", "bigint", nil, "YES", "", "NULL", "", "", ""}, 1813 }, 1814 }, 1815 { 1816 Query: "ALTER TABLE mytable MODIFY COLUMN i BIGINT NOT NULL COMMENT 'ok' FIRST", 1817 Expected: []sql.Row{{types.NewOkResult(0)}}, 1818 }, 1819 { 1820 Query: "SHOW FULL COLUMNS FROM mytable /* 3 */", 1821 Expected: []sql.Row{ 1822 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", "ok"}, 1823 {"s", "varchar(20)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "changed"}, 1824 {"i2", "bigint", nil, "YES", "", "NULL", "", "", ""}, 1825 }, 1826 }, 1827 { 1828 Query: "ALTER TABLE mytable MODIFY COLUMN s VARCHAR(20) NULL COMMENT 'changed'", 1829 Expected: []sql.Row{{types.NewOkResult(0)}}, 1830 }, 1831 { 1832 Query: "SHOW FULL COLUMNS FROM mytable /* 4 */", 1833 Expected: []sql.Row{ 1834 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", "ok"}, 1835 {"s", "varchar(20)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "changed"}, 1836 {"i2", "bigint", nil, "YES", "", "NULL", "", "", ""}, 1837 }, 1838 }, 1839 }, 1840 }, 1841 { 1842 Name: "error cases", 1843 SetUpScript: []string{}, 1844 Assertions: []ScriptTestAssertion{ 1845 { 1846 Query: "ALTER TABLE mytable MODIFY not_exist BIGINT NOT NULL COMMENT 'ok' FIRST", 1847 ExpectedErr: sql.ErrTableColumnNotFound, 1848 }, 1849 { 1850 Query: "ALTER TABLE mytable MODIFY i BIGINT NOT NULL COMMENT 'ok' AFTER not_exist", 1851 ExpectedErr: sql.ErrTableColumnNotFound, 1852 }, 1853 { 1854 Query: "ALTER TABLE not_exist MODIFY COLUMN i INT NOT NULL COMMENT 'hello'", 1855 ExpectedErr: sql.ErrTableNotFound, 1856 }, 1857 { 1858 Query: "ALTER TABLE mytable ADD COLUMN b INT NOT NULL DEFAULT 'yes'", 1859 ExpectedErr: sql.ErrIncompatibleDefaultType, 1860 }, 1861 { 1862 Query: "ALTER TABLE mytable ADD COLUMN c int, add c int", 1863 ExpectedErr: sql.ErrColumnExists, 1864 }, 1865 }, 1866 }, 1867 } 1868 1869 var DropColumnScripts = []ScriptTest{ 1870 { 1871 Name: "drop last column", 1872 SetUpScript: []string{ 1873 "ALTER TABLE mytable DROP COLUMN s", 1874 }, 1875 Assertions: []ScriptTestAssertion{ 1876 { 1877 Query: "SHOW FULL COLUMNS FROM mytable", 1878 Expected: []sql.Row{{"i", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}}, 1879 }, 1880 { 1881 Query: "select * from mytable order by i", 1882 Expected: []sql.Row{{1}, {2}, {3}}, 1883 }, 1884 }, 1885 }, 1886 { 1887 Name: "drop first column", 1888 SetUpScript: []string{ 1889 "CREATE TABLE t1 (a int, b varchar(10), c bigint, k bigint primary key)", 1890 "insert into t1 values (1, 'abc', 2, 3), (4, 'def', 5, 6)", 1891 }, 1892 Assertions: []ScriptTestAssertion{ 1893 { 1894 Query: "ALTER TABLE t1 DROP COLUMN a", 1895 Expected: []sql.Row{{types.NewOkResult(0)}}, 1896 }, 1897 { 1898 Query: "SHOW FULL COLUMNS FROM t1", 1899 Expected: []sql.Row{ 1900 {"b", "varchar(10)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", ""}, 1901 {"c", "bigint", nil, "YES", "", "NULL", "", "", ""}, 1902 {"k", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 1903 }, 1904 }, 1905 { 1906 Query: "SELECT * FROM t1 ORDER BY b", 1907 Expected: []sql.Row{ 1908 {"abc", 2, 3}, 1909 {"def", 5, 6}, 1910 }, 1911 }, 1912 }, 1913 }, 1914 { 1915 Name: "drop middle column", 1916 SetUpScript: []string{ 1917 "CREATE TABLE t2 (a int, b varchar(10), c bigint, k bigint primary key)", 1918 "insert into t2 values (1, 'abc', 2, 3), (4, 'def', 5, 6)", 1919 }, 1920 Assertions: []ScriptTestAssertion{ 1921 { 1922 Query: "ALTER TABLE t2 DROP COLUMN b", 1923 Expected: []sql.Row{{types.NewOkResult(0)}}, 1924 }, 1925 { 1926 Query: "SHOW FULL COLUMNS FROM t2", 1927 Expected: []sql.Row{ 1928 {"a", "int", nil, "YES", "", "NULL", "", "", ""}, 1929 {"c", "bigint", nil, "YES", "", "NULL", "", "", ""}, 1930 {"k", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 1931 }, 1932 }, 1933 { 1934 Query: "SELECT * FROM t2 ORDER BY c", 1935 Expected: []sql.Row{ 1936 {1, 2, 3}, 1937 {4, 5, 6}, 1938 }, 1939 }, 1940 }, 1941 }, 1942 { 1943 // TODO: primary key column drops not well supported yet 1944 Name: "drop primary key column", 1945 SetUpScript: []string{ 1946 "CREATE TABLE t3 (a int primary key, b varchar(10), c bigint)", 1947 "insert into t3 values (1, 'abc', 2), (3, 'def', 4)", 1948 }, 1949 Assertions: []ScriptTestAssertion{ 1950 { 1951 Skip: true, 1952 Query: "ALTER TABLE t3 DROP COLUMN a", 1953 Expected: []sql.Row{{types.NewOkResult(0)}}, 1954 }, 1955 { 1956 Skip: true, 1957 Query: "SHOW FULL COLUMNS FROM t3", 1958 Expected: []sql.Row{ 1959 {"b", "varchar(10)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", ""}, 1960 {"c", "bigint", nil, "YES", "", "NULL", "", "", ""}, 1961 }, 1962 }, 1963 { 1964 Skip: true, 1965 Query: "SELECT * FROM t3 ORDER BY b", 1966 Expected: []sql.Row{ 1967 {"abc", 2}, 1968 {"def", 4}, 1969 }, 1970 }, 1971 }, 1972 }, 1973 { 1974 Name: "error cases", 1975 SetUpScript: []string{ 1976 "create table t4 (a int primary key, b int, c int default (b+10))", 1977 }, 1978 Assertions: []ScriptTestAssertion{ 1979 { 1980 Query: "ALTER TABLE not_exist DROP COLUMN s", 1981 ExpectedErr: sql.ErrTableNotFound, 1982 }, 1983 { 1984 Query: "ALTER TABLE mytable DROP COLUMN s", 1985 ExpectedErr: sql.ErrTableColumnNotFound, 1986 }, 1987 { 1988 Query: "ALTER TABLE t4 DROP COLUMN b", 1989 ExpectedErr: sql.ErrDropColumnReferencedInDefault, 1990 }, 1991 }, 1992 }, 1993 } 1994 1995 var DropColumnKeylessTablesScripts = []ScriptTest{ 1996 { 1997 Name: "drop last column", 1998 SetUpScript: []string{ 1999 "create table t0 (i bigint, s varchar(20))", 2000 }, 2001 Assertions: []ScriptTestAssertion{ 2002 { 2003 Query: "ALTER TABLE t0 DROP COLUMN s", 2004 Expected: []sql.Row{{types.NewOkResult(0)}}, 2005 }, 2006 { 2007 Query: "SHOW FULL COLUMNS FROM t0", 2008 Expected: []sql.Row{{"i", "bigint", nil, "YES", "", "NULL", "", "", ""}}, 2009 }, 2010 }, 2011 }, 2012 { 2013 Name: "drop first column", 2014 SetUpScript: []string{ 2015 "CREATE TABLE t1 (a int, b varchar(10), c bigint)", 2016 "insert into t1 values (1, 'abc', 2), (4, 'def', 5)", 2017 }, 2018 Assertions: []ScriptTestAssertion{ 2019 { 2020 Query: "ALTER TABLE t1 DROP COLUMN a", 2021 Expected: []sql.Row{{types.NewOkResult(0)}}, 2022 }, 2023 { 2024 Query: "SHOW FULL COLUMNS FROM t1", 2025 Expected: []sql.Row{{"b", "varchar(10)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", ""}, {"c", "bigint", nil, "YES", "", "NULL", "", "", ""}}, 2026 }, 2027 { 2028 Query: "SELECT * FROM t1 ORDER BY b", 2029 Expected: []sql.Row{ 2030 {"abc", 2}, 2031 {"def", 5}, 2032 }, 2033 }, 2034 }, 2035 }, 2036 { 2037 Name: "drop middle column", 2038 SetUpScript: []string{ 2039 "CREATE TABLE t2 (a int, b varchar(10), c bigint)", 2040 "insert into t2 values (1, 'abc', 2), (4, 'def', 5)", 2041 }, 2042 Assertions: []ScriptTestAssertion{ 2043 { 2044 Query: "ALTER TABLE t2 DROP COLUMN b", 2045 Expected: []sql.Row{{types.NewOkResult(0)}}, 2046 }, 2047 { 2048 Query: "SHOW FULL COLUMNS FROM t2", 2049 Expected: []sql.Row{{"a", "int", nil, "YES", "", "NULL", "", "", ""}, {"c", "bigint", nil, "YES", "", "NULL", "", "", ""}}, 2050 }, 2051 { 2052 Query: "SELECT * FROM t2 ORDER BY c", 2053 Expected: []sql.Row{ 2054 {1, 2}, 2055 {4, 5}, 2056 }, 2057 }, 2058 }, 2059 }, 2060 { 2061 Name: "error cases", 2062 SetUpScript: []string{}, 2063 Assertions: []ScriptTestAssertion{ 2064 { 2065 Query: "ALTER TABLE not_exist DROP COLUMN s", 2066 ExpectedErr: sql.ErrTableNotFound, 2067 }, 2068 { 2069 Query: "ALTER TABLE t0 DROP COLUMN s", 2070 ExpectedErr: sql.ErrTableColumnNotFound, 2071 }, 2072 { 2073 Query: "SELECT * FROM t2 ORDER BY c", 2074 Expected: []sql.Row{ 2075 {1, 2}, 2076 {4, 5}, 2077 }, 2078 }, 2079 }, 2080 }, 2081 }