1# 2# Tests of foreign keys that need a debug build or debug_sync feature. 3# 4 5--source include/have_debug.inc 6--source include/have_debug_sync.inc 7# Some parts of the test require enabled binary log. 8--source include/have_log_bin.inc 9 10SET @saved_binlog_format= @@SESSION.binlog_format; 11 12SET SESSION debug= '+d,skip_dd_table_access_check'; 13SET @@foreign_key_checks= DEFAULT; 14 15--echo # 16--echo # WL#6929: Move FOREIGN KEY constraints to the global data dictionary 17--echo # 18 19--echo # Test coverage for foreign key name generation. Should be removed 20--echo # or rewritten when WL#7141 is pushed. 21 22CREATE TABLE t1(a INT PRIMARY KEY); 23CREATE TABLE t2(a INT PRIMARY KEY); 24CREATE TABLE t3(a INT PRIMARY KEY, b INT, c INT); 25 26ALTER TABLE t3 ADD FOREIGN KEY (b) REFERENCES t1(a); 27# InnoDB generated name (until after WL#6599) 28SHOW CREATE TABLE t3; 29# Server generated name (until after WL#6599) 30SELECT fk.name FROM mysql.foreign_keys AS fk, mysql.tables AS t 31WHERE fk.table_id = t.id AND t.name = 't3'; 32 33ALTER TABLE t3 ADD FOREIGN KEY (c) REFERENCES t1(a); 34# InnoDB generated name (until after WL#6599) 35SHOW CREATE TABLE t3; 36# Server generated name (until after WL#6599) 37SELECT fk.name FROM mysql.foreign_keys AS fk, mysql.tables AS t 38WHERE fk.table_id = t.id AND t.name = 't3'; 39 40ALTER TABLE t3 ADD FOREIGN KEY (b) REFERENCES t1(a); 41# InnoDB generated name (until after WL#6599) 42SHOW CREATE TABLE t3; 43# Server generated name (until after WL#6599) 44SELECT fk.name FROM mysql.foreign_keys AS fk, mysql.tables AS t 45WHERE fk.table_id = t.id AND t.name = 't3'; 46 47ALTER TABLE t3 DROP FOREIGN KEY t3_ibfk_1; 48# InnoDB generated name (until after WL#6599) 49SHOW CREATE TABLE t3; 50# Server generated name (until after WL#6599) 51SELECT fk.name FROM mysql.foreign_keys AS fk, mysql.tables AS t 52WHERE fk.table_id = t.id AND t.name = 't3'; 53 54ALTER TABLE t3 ADD FOREIGN KEY (b) REFERENCES t1(a); 55# InnoDB generated name (until after WL#6599) 56SHOW CREATE TABLE t3; 57# Server generated name (until after WL#6599) 58SELECT fk.name FROM mysql.foreign_keys AS fk, mysql.tables AS t 59WHERE fk.table_id = t.id AND t.name = 't3'; 60 61DROP TABLE t3, t2, t1; 62 63CREATE TABLE t1(a INT PRIMARY KEY); 64CREATE TABLE name567890123456789012345678901234567890123456789012345678901234(a INT PRIMARY KEY, b INT); 65 66--error ER_TOO_LONG_IDENT 67ALTER TABLE name567890123456789012345678901234567890123456789012345678901234 68ADD FOREIGN KEY(b) REFERENCES t1(a); 69 70DROP TABLE name567890123456789012345678901234567890123456789012345678901234, t1; 71 72 73--echo # 74--echo # WL#6049: Meta data locking for foreign keys. 75--echo # 76 77--echo # 78--echo # Normal CT will set the FK unique constraint name. 79--echo # 80 81CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER, 82 UNIQUE KEY my_key (j)); 83CREATE TABLE child(pk INTEGER PRIMARY KEY, fk INTEGER, 84 FOREIGN KEY (fk) REFERENCES parent(j)); 85SELECT unique_constraint_name FROM mysql.foreign_keys 86 WHERE referenced_table_name LIKE 'parent'; 87 88DROP TABLES child, parent; 89 90--echo # 91--echo # CT introducing a missing parent will update the FK unique constraint name in the child. 92--echo # 93 94SET @@foreign_key_checks= 0; 95CREATE TABLE child(pk INTEGER PRIMARY KEY, fk INTEGER, 96 FOREIGN KEY (fk) REFERENCES parent(j)); 97 98--echo # An index is created for the FK, but the unique constraint name is NULL. 99SELECT name FROM mysql.indexes 100 WHERE table_id = (SELECT id from mysql.tables WHERE name LIKE 'child'); 101SELECT unique_constraint_name FROM mysql.foreign_keys 102 WHERE referenced_table_name LIKE 'parent'; 103 104CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER, 105 UNIQUE KEY my_key (j)); 106SET @@foreign_key_checks= 1; 107 108--echo # After creating the parent, the unique constraint name is updated. 109SELECT unique_constraint_name FROM mysql.foreign_keys 110 WHERE referenced_table_name LIKE 'parent'; 111 112DROP TABLES child, parent; 113 114--echo # 115--echo # CTL does not copy FKs from the source table. 116--echo # 117 118CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER, 119 UNIQUE KEY my_key (j)); 120CREATE TABLE child(pk INTEGER PRIMARY KEY, fk INTEGER, 121 FOREIGN KEY (fk) REFERENCES parent(j)); 122SELECT unique_constraint_name FROM mysql.foreign_keys 123 WHERE referenced_table_name LIKE 'parent'; 124 125CREATE TABLE child_copy LIKE child; 126 127--echo ## The index is re-created for the new table. 128SELECT name FROM mysql.indexes 129 WHERE table_id = (SELECT id from mysql.tables WHERE name LIKE 'child'); 130SELECT name FROM mysql.indexes 131 WHERE table_id = (SELECT id from mysql.tables WHERE name LIKE 'child_copy'); 132 133--echo ## ... but not the constraint. 134SELECT unique_constraint_name FROM mysql.foreign_keys 135 WHERE referenced_table_name LIKE 'parent'; 136 137DROP TABLES child, child_copy, parent; 138 139--echo # 140--echo # CTL introducing a missing parent will update the FK in the child. 141--echo # 142 143SET @@foreign_key_checks= 0; 144CREATE TABLE child(pk INTEGER PRIMARY KEY, fk INTEGER, 145 FOREIGN KEY (fk) REFERENCES parent(j)); 146 147--echo ## An index is created for the FK, but the unique constraint name is NULL. 148SELECT name FROM mysql.indexes 149 WHERE table_id = (SELECT id from mysql.tables WHERE name LIKE 'parent'); 150SELECT unique_constraint_name FROM mysql.foreign_keys 151 WHERE referenced_table_name LIKE 'parent'; 152 153CREATE TABLE parent_base(pk INTEGER PRIMARY KEY, j INTEGER, 154 UNIQUE KEY my_key (j)); 155CREATE TABLE parent LIKE parent_base; 156SET @@foreign_key_checks= 1; 157 158--echo ## After creating the parent, the unique constraint name is updated. 159SELECT unique_constraint_name FROM mysql.foreign_keys 160 WHERE referenced_table_name LIKE 'parent'; 161 162DROP TABLE child, parent_base, parent; 163 164--echo # 165--echo # CTS will update the unique constraint name in its FK info. 166--echo # 167 168CREATE TABLE source(pk INTEGER PRIMARY KEY, j INTEGER); 169INSERT INTO source VALUES (1, 1); 170 171CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER, 172 UNIQUE KEY my_key(j)); 173INSERT INTO parent VALUES (2, 1); 174 175SET @@SESSION.binlog_format=STATEMENT; 176CREATE TABLE child(pk INTEGER PRIMARY KEY, fk INTEGER, 177 FOREIGN KEY (fk) REFERENCES parent(j)) AS SELECT pk, j AS fk FROM source; 178SET SESSION binlog_format= @saved_binlog_format; 179SELECT * FROM child; 180 181--echo ## An index is created for the FK, and the unique constraint name is updated. 182SELECT name FROM mysql.indexes 183 WHERE table_id = (SELECT id from mysql.tables WHERE name LIKE 'child'); 184SELECT unique_constraint_name FROM mysql.foreign_keys 185 WHERE referenced_table_name LIKE 'parent'; 186 187DROP TABLES source, child, parent; 188 189--echo # 190--echo # CTS introducing a missing parent will update the FK in the child. 191--echo # 192 193SET @@foreign_key_checks= 0; 194CREATE TABLE source(pk INTEGER PRIMARY KEY, j INTEGER); 195INSERT INTO source VALUES (1, 1); 196 197CREATE TABLE child(pk INTEGER PRIMARY KEY, fk INTEGER, 198 FOREIGN KEY (fk) REFERENCES parent(j)); 199 200--echo ## An index is created for the FK, but the unique constraint name is NULL. 201SELECT name FROM mysql.indexes 202 WHERE table_id = (SELECT id from mysql.tables WHERE name LIKE 'child'); 203SELECT unique_constraint_name FROM mysql.foreign_keys 204 WHERE referenced_table_name LIKE 'parent'; 205 206SET @@SESSION.binlog_format=STATEMENT; 207CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER, 208 UNIQUE KEY my_key(j)) AS SELECT * FROM source; 209SET SESSION binlog_format= @saved_binlog_format; 210SELECT * FROM child; 211SET @@foreign_key_checks= 1; 212 213--echo ## After creating the parent, the unique constraint name is updated. 214SELECT unique_constraint_name FROM mysql.foreign_keys 215 WHERE referenced_table_name LIKE 'parent'; 216 217DROP TABLES source, child, parent; 218 219--echo # 220--echo # RENAME will update FK information in both children and parents. 221--echo # 222 223CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER, 224 UNIQUE KEY parent_key(j)); 225 226CREATE TABLE child(pk INTEGER PRIMARY KEY, k INTEGER, fk INTEGER, 227 FOREIGN KEY (fk) REFERENCES parent(j), UNIQUE KEY child_key(k)); 228--echo # Constraint is enforced. 229--error ER_NO_REFERENCED_ROW_2 230INSERT INTO child VALUES (1, 2, 3); 231 232CREATE TABLE grandchild(pk INTEGER PRIMARY KEY, fk INTEGER, 233 FOREIGN KEY (fk) REFERENCES child(k)); 234--echo # Constraint is enforced. 235--error ER_NO_REFERENCED_ROW_2 236INSERT INTO grandchild VALUES (1, 2); 237 238SET @@foreign_key_checks= 0; 239CREATE TABLE orphan_grandchild(pk INTEGER PRIMARY KEY, fk INTEGER, 240 FOREIGN KEY (fk) REFERENCES siebling(k)); 241SET @@foreign_key_checks= 1; 242 243--echo # FK definitions before rename: 244 245SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 246 FROM mysql.foreign_keys 247 WHERE referenced_table_schema LIKE 'test'; 248 249RENAME TABLE child TO siebling; 250 251--echo # After the rename, we see that: 252--echo # 1. The name of the constraint is changed to 'siebling_ibfk...'. 253--echo # 2. The referenced table name of the grandchild is changed to 'siebling'. 254--echo # 3. The unique constraint name of the orphan_grandchild is corrected. 255SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 256 FROM mysql.foreign_keys 257 WHERE referenced_table_schema LIKE 'test'; 258 259--echo # Constraint is still enforced. 260--error ER_NO_REFERENCED_ROW_2 261INSERT INTO siebling VALUES (1, 2, 3); 262 263--echo # Constraint is still enforced. 264--error ER_NO_REFERENCED_ROW_2 265INSERT INTO grandchild VALUES (1, 2); 266 267--echo # Constraint is enforced here too. 268--error ER_NO_REFERENCED_ROW_2 269INSERT INTO orphan_grandchild VALUES (1, 2); 270 271DROP TABLE grandchild; 272DROP TABLE orphan_grandchild; 273DROP TABLE siebling; 274DROP TABLE parent; 275 276--echo # When processing LOCK TABLES, we will prelock even 277--echo # when F_K_C = 0. 278--echo # 279 280CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER, 281 UNIQUE KEY parent_key(j)); 282 283CREATE TABLE child(pk INTEGER PRIMARY KEY, fk INTEGER, 284 FOREIGN KEY (fk) REFERENCES parent(j) ON DELETE CASCADE); 285 286SET @@foreign_key_checks= 0; 287LOCK TABLES parent WRITE; 288 289--echo # There are two metadata locks because the child has 290--echo # two different FK roles wrt. the parent. Note that 291--echo # the locks are stronger for LOCK TABLES. 292SELECT OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, COLUMN_NAME, 293 LOCK_TYPE FROM performance_schema.metadata_locks 294 WHERE OBJECT_NAME LIKE 'child' 295 ORDER BY OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, COLUMN_NAME, LOCK_TYPE; 296 297--echo # From another connection, verify that child is locked. 298--connect (con_1, localhost, root) 299SET @@session.lock_wait_timeout= 1; 300--error ER_LOCK_WAIT_TIMEOUT 301INSERT INTO child VALUES (1, 1); 302--disconnect con_1 303 304--connection default 305UNLOCK TABLES; 306SET @@foreign_key_checks= 1; 307 308--echo # Now, the locks are gone. 309SELECT LOCK_TYPE FROM performance_schema.metadata_locks 310 WHERE OBJECT_NAME LIKE 'child'; 311 312DROP TABLE child; 313DROP TABLE parent; 314 315--echo # 316--echo # A prepared statement will become invalid if a child table 317--echo # is modified between executions of the prepared statement. 318--echo # 319 320CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER, 321 UNIQUE KEY parent_key(j)); 322 323CREATE TABLE child(pk INTEGER PRIMARY KEY, fk INTEGER, 324 FOREIGN KEY (fk) REFERENCES parent(j) ON DELETE CASCADE); 325 326PREPARE stmt FROM 'DELETE FROM parent WHERE pk = ?'; 327 328SELECT COUNT_REPREPARE, COUNT_EXECUTE 329 FROM performance_schema.prepared_statements_instances 330 WHERE STATEMENT_NAME LIKE 'stmt'; 331 332SET @a= 1; 333EXECUTE stmt USING @a; 334 335--echo # No reprepare for first execution. 336SELECT COUNT_REPREPARE, COUNT_EXECUTE 337 FROM performance_schema.prepared_statements_instances 338 WHERE STATEMENT_NAME LIKE 'stmt'; 339 340--echo # Altering child will trigger reprepare on next execution. 341ALTER TABLE child ADD COLUMN (j INTEGER); 342 343EXECUTE stmt USING @a; 344 345--echo # Statement has been reprepared for second execution. 346SELECT COUNT_REPREPARE, COUNT_EXECUTE 347 FROM performance_schema.prepared_statements_instances 348 WHERE STATEMENT_NAME LIKE 'stmt'; 349 350EXECUTE stmt USING @a; 351 352--echo # Cache version for the prelock entry is updated, so no 353--echo # reprepare for third execution. 354SELECT COUNT_REPREPARE, COUNT_EXECUTE 355 FROM performance_schema.prepared_statements_instances 356 WHERE STATEMENT_NAME LIKE 'stmt'; 357 358DROP TABLE child; 359DROP TABLE parent; 360 361 362--echo # 363--echo # Check situations where there are multiple foreign keys 364--echo # referring the same table. 365--echo # 366 367CREATE TABLE parent(pk INTEGER PRIMARY KEY, i INTEGER, j INTEGER, 368 UNIQUE KEY parent_i_key(i), UNIQUE KEY parent_j_key(j)); 369 370CREATE TABLE child(pk INTEGER PRIMARY KEY, fk_i INTEGER, fk_j INTEGER, 371 FOREIGN KEY (fk_i) REFERENCES parent(i), 372 FOREIGN KEY (fk_j) REFERENCES parent(j)); 373 374ALTER TABLE child RENAME TO siebling; 375 376DROP TABLES siebling, parent; 377 378--echo # 379--echo # Rename a table multiple times in the same statement. 380--echo # 381 382CREATE TABLE parent(pk INTEGER PRIMARY KEY, i INTEGER, 383 UNIQUE KEY parent_key(i)); 384 385CREATE TABLE child(pk INTEGER PRIMARY KEY, fk_i INTEGER, 386 FOREIGN KEY (fk_i) REFERENCES parent(i)); 387 388RENAME TABLE parent TO mother, mother TO father; 389 390SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 391 FROM mysql.foreign_keys 392 WHERE referenced_table_schema LIKE 'test'; 393 394RENAME TABLE child TO sister, sister TO brother; 395 396SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 397 FROM mysql.foreign_keys 398 WHERE referenced_table_schema LIKE 'test'; 399 400RENAME TABLE father TO mother, brother TO sister, mother TO parent, sister TO child; 401 402SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 403 FROM mysql.foreign_keys 404 WHERE referenced_table_schema LIKE 'test'; 405 406DROP TABLES child, parent; 407 408--echo # 409--echo # Let a RENAME statement introduce a missing parent and rename 410--echo # it further as well. 411--echo # 412 413SET @@foreign_key_checks= 0; 414CREATE TABLE child(pk INTEGER PRIMARY KEY, fk_i INTEGER, 415 FOREIGN KEY (fk_i) REFERENCES mother(i)); 416SET @@foreign_key_checks= 1; 417 418CREATE TABLE parent(pk INTEGER PRIMARY KEY, i INTEGER, 419 UNIQUE KEY parent_key(i)); 420 421SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 422 FROM mysql.foreign_keys 423 WHERE referenced_table_schema LIKE 'test'; 424 425RENAME TABLE parent TO mother, mother TO father; 426 427SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 428 FROM mysql.foreign_keys 429 WHERE referenced_table_schema LIKE 'test'; 430 431DROP TABLES child, father; 432 433--echo # 434--echo # Rename a parent with a child having several FKs to it. 435--echo # 436 437CREATE TABLE parent(pk INTEGER PRIMARY KEY, i INTEGER, j INTEGER, 438 UNIQUE KEY parent_i_key(i), 439 UNIQUE KEY parent_j_key(j)); 440 441CREATE TABLE child(pk INTEGER PRIMARY KEY, fk_i INTEGER, fk_j INTEGER, 442 FOREIGN KEY (fk_i) REFERENCES parent(i), 443 FOREIGN KEY (fk_j) REFERENCES parent(j)); 444 445SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 446 FROM mysql.foreign_keys 447 WHERE referenced_table_schema LIKE 'test'; 448 449RENAME TABLE parent TO mother; 450 451SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 452 FROM mysql.foreign_keys 453 WHERE referenced_table_schema LIKE 'test'; 454 455DROP TABLES child, mother; 456 457 458--echo # 459--echo # ALTER TABLE RENAME and complex ALTER TABLE RENAME involving 460--echo # self-referncing foreign key. 461--echo # 462CREATE TABLE self (pk INT PRIMARY KEY, fk INT, FOREIGN KEY(fk) REFERENCES self(pk)); 463SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 464 FROM mysql.foreign_keys 465 WHERE referenced_table_schema LIKE 'test'; 466ALTER TABLE self RENAME TO self2; 467SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 468 FROM mysql.foreign_keys 469 WHERE referenced_table_schema LIKE 'test'; 470ALTER TABLE self2 RENAME TO self3, ADD COLUMN i INT; 471SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 472 FROM mysql.foreign_keys 473 WHERE referenced_table_schema LIKE 'test'; 474DROP TABLE self3; 475 476--echo # 477--echo # Drop a schema with tables referencing/being referenced by tables 478--echo # in a different schema. 479--echo # 480 481CREATE TABLE parent(pk INTEGER PRIMARY KEY, i INTEGER, 482 UNIQUE KEY parent_i_key(i)); 483 484SET @@foreign_key_checks= 0; 485CREATE TABLE grandchild(pk INTEGER PRIMARY KEY, fk_i INTEGER, 486 FOREIGN KEY (fk_i) REFERENCES s1.child(i)); 487SET @@foreign_key_checks= 1; 488 489SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 490 FROM mysql.foreign_keys 491 WHERE referenced_table_schema LIKE 's1'; 492 493CREATE SCHEMA s1; 494CREATE TABLE s1.child(pk INTEGER PRIMARY KEY, i INTEGER, fk_i INTEGER, 495 UNIQUE KEY child_i_key(i), 496 FOREIGN KEY (fk_i) REFERENCES test.parent(i)); 497 498SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 499 FROM mysql.foreign_keys 500 WHERE referenced_table_schema LIKE 'test'; 501 502SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 503 FROM mysql.foreign_keys 504 WHERE referenced_table_schema LIKE 's1'; 505 506--error ER_FK_CANNOT_DROP_PARENT 507DROP SCHEMA s1; 508 509SET @@foreign_key_checks= 0; 510DROP SCHEMA s1; 511SET @@foreign_key_checks= 1; 512 513SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 514 FROM mysql.foreign_keys 515 WHERE referenced_table_schema LIKE 'test'; 516 517SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 518 FROM mysql.foreign_keys 519 WHERE referenced_table_schema LIKE 's1'; 520 521--echo # Skip FK to parent. 522CREATE SCHEMA s1; 523CREATE TABLE s1.child(pk INTEGER PRIMARY KEY, i INTEGER, 524 UNIQUE KEY child_i_key(i)); 525 526SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 527 FROM mysql.foreign_keys 528 WHERE referenced_table_schema LIKE 's1'; 529 530--error ER_FK_CANNOT_DROP_PARENT 531DROP SCHEMA s1; 532 533SET @@foreign_key_checks= 0; 534DROP SCHEMA s1; 535SET @@foreign_key_checks= 1; 536 537SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 538 FROM mysql.foreign_keys 539 WHERE referenced_table_schema LIKE 's1'; 540 541DROP TABLE grandchild; 542 543--echo # No FK from grandchild. 544CREATE SCHEMA s1; 545CREATE TABLE s1.child(pk INTEGER PRIMARY KEY, fk_i INTEGER); 546 547SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 548 FROM mysql.foreign_keys 549 WHERE referenced_table_schema LIKE 'test'; 550 551--echo # Introduce FK to parent. 552ALTER TABLE s1.child ADD FOREIGN KEY (fk_i) REFERENCES test.parent(i); 553 554SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 555 FROM mysql.foreign_keys 556 WHERE referenced_table_schema LIKE 'test'; 557 558DROP SCHEMA s1; 559 560DROP TABLE parent; 561 562 563--echo # 564--echo # Trigger an error in Foreign_key_parents_invalidator::invalidate(). 565--echo # 566 567CREATE TABLE parent(pk INTEGER PRIMARY KEY, i INTEGER, 568 UNIQUE KEY parent_key(i)); 569 570CREATE TABLE child(pk INTEGER PRIMARY KEY, fk_i INTEGER, 571 FOREIGN KEY (fk_i) REFERENCES parent(i)); 572 573SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 574 FROM mysql.foreign_keys 575 WHERE referenced_table_schema LIKE 'test'; 576 577SET @@session.debug= '+d,fail_while_invalidating_fk_parents'; 578ALTER TABLE child RENAME TO siebling; 579SET @@session.debug= '-d,fail_while_invalidating_fk_parents'; 580 581SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 582 FROM mysql.foreign_keys 583 WHERE referenced_table_schema LIKE 'test'; 584 585DROP TABLE siebling, parent; 586 587 588--echo # 589--echo # Coverage for various corner cases when figuring out unique_constraint_name. 590--echo # 591CREATE TABLE parent (i INT, j INT, PRIMARY KEY (i), UNIQUE u(i,j)); 592CREATE TABLE child (i INT, j INT, FOREIGN KEY (i, j) REFERENCES parent (i, j)); 593SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 594 FROM mysql.foreign_keys 595 WHERE referenced_table_schema LIKE 'test'; 596ALTER TABLE parent RENAME KEY u TO u1; 597SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 598 FROM mysql.foreign_keys 599 WHERE referenced_table_schema LIKE 'test'; 600DROP TABLE child, parent; 601 602CREATE TABLE parent (i INT, j INT, k INT, PRIMARY KEY (i), UNIQUE u(j), UNIQUE u1(i,j), UNIQUE u2(i,j,k)); 603CREATE TABLE child (i INT, j INT, k INT, FOREIGN KEY (i, j, k) REFERENCES parent (i, j, k)); 604SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 605 FROM mysql.foreign_keys 606 WHERE referenced_table_schema LIKE 'test'; 607ALTER TABLE parent RENAME KEY u2 TO u3; 608SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 609 FROM mysql.foreign_keys 610 WHERE referenced_table_schema LIKE 'test'; 611DROP TABLE child, parent; 612 613CREATE TABLE parent (i INT, j INT, 614 d INT GENERATED ALWAYS AS (i) VIRTUAL, 615 e INT GENERATED ALWAYS AS (j) VIRTUAL, 616 PRIMARY KEY (i), UNIQUE u(i,d), UNIQUE u1(i,j,e)); 617CREATE TABLE child (i INT, j INT, FOREIGN KEY (i, j) REFERENCES parent (i, j)); 618SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 619 FROM mysql.foreign_keys 620 WHERE referenced_table_schema LIKE 'test'; 621ALTER TABLE parent RENAME KEY u1 TO u2; 622SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 623 FROM mysql.foreign_keys 624 WHERE referenced_table_schema LIKE 'test'; 625DROP TABLE child, parent; 626 627CREATE TABLE parent (i INT, a VARCHAR(10), b VARCHAR(10), 628 PRIMARY KEY (i), UNIQUE u(i,a(5)), UNIQUE u1(i,a,b(5))); 629CREATE TABLE child (i INT, a VARCHAR(10), FOREIGN KEY (i, a) REFERENCES parent (i, a)); 630SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 631 FROM mysql.foreign_keys 632 WHERE referenced_table_schema LIKE 'test'; 633ALTER TABLE parent RENAME KEY u1 TO u2; 634SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 635 FROM mysql.foreign_keys 636 WHERE referenced_table_schema LIKE 'test'; 637DROP TABLE child, parent; 638 639CREATE TABLE self (i INT, j INT, i2 INT, j2 INT, PRIMARY KEY (i), UNIQUE u(i,j), 640 FOREIGN KEY (i2, j2) REFERENCES self (i, j)); 641SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 642 FROM mysql.foreign_keys 643 WHERE referenced_table_schema LIKE 'test'; 644ALTER TABLE self RENAME KEY u TO u1; 645SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 646 FROM mysql.foreign_keys 647 WHERE referenced_table_schema LIKE 'test'; 648DROP TABLE self; 649 650CREATE TABLE self (i INT, j INT, k INT, i2 INT, j2 INT, k2 INT, 651 PRIMARY KEY (i), UNIQUE u(j), UNIQUE u1(i,j), UNIQUE u2(i,j,k), 652 FOREIGN KEY (i2, j2, k2) REFERENCES self (i, j, k)); 653SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 654 FROM mysql.foreign_keys 655 WHERE referenced_table_schema LIKE 'test'; 656ALTER TABLE self RENAME KEY u2 TO u3; 657SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 658 FROM mysql.foreign_keys 659 WHERE referenced_table_schema LIKE 'test'; 660DROP TABLE self; 661 662CREATE TABLE self (i INT, j INT, i2 INT, j2 INT, 663 d INT GENERATED ALWAYS AS (i) VIRTUAL, 664 e INT GENERATED ALWAYS AS (j) VIRTUAL, 665 PRIMARY KEY (i), UNIQUE u(i,d), UNIQUE u1(i,j,e), 666 FOREIGN KEY (i2, j2) REFERENCES self (i, j)); 667SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 668 FROM mysql.foreign_keys 669 WHERE referenced_table_schema LIKE 'test'; 670ALTER TABLE self RENAME KEY u1 TO u2; 671SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 672 FROM mysql.foreign_keys 673 WHERE referenced_table_schema LIKE 'test'; 674DROP TABLE self; 675 676CREATE TABLE self (i INT, a VARCHAR(10), b VARCHAR(10), i2 INT, a2 VARCHAR(10), 677 PRIMARY KEY (i), UNIQUE u(i,a(5)), UNIQUE u1(i,a,b(5)), 678 FOREIGN KEY (i2, a2) REFERENCES self (i, a)); 679SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 680 FROM mysql.foreign_keys 681 WHERE referenced_table_schema LIKE 'test'; 682ALTER TABLE self RENAME KEY u1 TO u2; 683SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name 684 FROM mysql.foreign_keys 685 WHERE referenced_table_schema LIKE 'test'; 686DROP TABLE self; 687 688 689# Restore defaults. 690SET @@foreign_key_checks= DEFAULT; 691SET SESSION debug= '-d,skip_dd_table_access_check'; 692 693--echo # 694--echo # Part of systemic test coverage for metadata locks related to foreign 695--echo # keys acquired by various DDL statements which requires debug_sync. 696--echo # 697--echo # The main part of this coverage resides in foreign_key.test. 698--echo # 699 700--enable_connect_log 701connect (con1, localhost, root,,); 702connection default; 703 704--echo # 705--echo # 7) ALTER TABLE ... INPLACE 706--echo # 707 708--echo # 7.1) ALTER TABLE ... ADD FOREIGN KEY ... INPLACE must start by 709--echo # acquiring SU lock on parent table. 710CREATE TABLE parent (pk INT PRIMARY KEY); 711CREATE TABLE child (fk INT); 712 713SET DEBUG_SYNC="alter_table_inplace_after_lock_downgrade SIGNAL reached WAIT_FOR go"; 714SET FOREIGN_KEY_CHECKS=0; 715--send ALTER TABLE child ADD CONSTRAINT fk FOREIGN KEY (fk) REFERENCES parent (pk), ALGORITHM=INPLACE; 716 717connection con1; 718SET DEBUG_SYNC="now WAIT_FOR reached"; 719 720--echo # DML on parent is still possible at this point. 721INSERT INTO parent VALUES (1); 722 723--echo # But not DDL. 724SET @old_lock_wait_timeout= @@lock_wait_timeout; 725SET @@lock_wait_timeout= 1; 726--error ER_LOCK_WAIT_TIMEOUT 727ALTER TABLE parent ADD COLUMN a INT; 728SET @@lock_wait_timeout= @old_lock_wait_timeout; 729 730SET DEBUG_SYNC="now SIGNAL go"; 731 732connection default; 733--echo # Reap ALTER TABLE 734--reap 735SET FOREIGN_KEY_CHECKS=1; 736ALTER TABLE child DROP FOREIGN KEY fk; 737 738--echo # 739--echo # 8) ALTER TABLE ... COPY 740--echo # 741 742--echo # 8.1) ALTER TABLE ... ADD FOREIGN KEY ... COPY must start by 743--echo # acquiring SU lock on parent table. 744 745SET DEBUG_SYNC="alter_table_copy_after_lock_upgrade SIGNAL reached WAIT_FOR go"; 746--send ALTER TABLE child ADD CONSTRAINT fk FOREIGN KEY (fk) REFERENCES parent (pk), ALGORITHM=COPY; 747 748connection con1; 749SET DEBUG_SYNC="now WAIT_FOR reached"; 750 751--echo # DML on parent is still possible at this point. 752INSERT INTO parent VALUES (2); 753 754--echo # But not DDL. 755SET @old_lock_wait_timeout= @@lock_wait_timeout; 756SET @@lock_wait_timeout= 1; 757--error ER_LOCK_WAIT_TIMEOUT 758ALTER TABLE parent ADD COLUMN a INT; 759SET @@lock_wait_timeout= @old_lock_wait_timeout; 760 761SET DEBUG_SYNC="now SIGNAL go"; 762 763connection default; 764--echo # Reap ALTER TABLE 765--reap 766 767SET DEBUG_SYNC="RESET"; 768 769ALTER TABLE child DROP FOREIGN KEY fk; 770 771--echo # 8.1') ALTER TABLE ... ADD FOREIGN KEY ... COPY due to workaround 772--echo # must upgrade SU lock on parent table SRO lock. 773 774SET DEBUG_SYNC="alter_after_copy_table SIGNAL reached WAIT_FOR go"; 775--send ALTER TABLE child ADD CONSTRAINT fk FOREIGN KEY (fk) REFERENCES parent (pk), ALGORITHM=COPY; 776 777connection con1; 778SET DEBUG_SYNC="now WAIT_FOR reached"; 779 780--echo # SELECT on parent is still possible at this point. 781SELECT * FROM parent; 782 783--echo # But not changes. 784SET @old_lock_wait_timeout= @@lock_wait_timeout; 785SET @@lock_wait_timeout= 1; 786--error ER_LOCK_WAIT_TIMEOUT 787DELETE FROM parent; 788SET @@lock_wait_timeout= @old_lock_wait_timeout; 789 790SET DEBUG_SYNC="now SIGNAL go"; 791 792connection default; 793--echo # Reap ALTER TABLE 794--reap 795 796SET DEBUG_SYNC="RESET"; 797 798DROP TABLES child, parent; 799 800connection con1; 801disconnect con1; 802--source include/wait_until_disconnected.inc 803connection default; 804--disable_connect_log 805