github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/logictest/testdata/logic_test/cascade (about) 1 # This test times out when run with 3node-tenant. 2 # LogicTest: !3node-tenant 3 4 # The tests in this file target the legacy FK paths. 5 statement ok 6 SET optimizer_foreign_keys = false 7 8 subtest AllCascadingActions 9 ### A test of all cascading actions in their most basic form. 10 # A 11 # | 12 # B 13 14 statement ok 15 CREATE TABLE a ( 16 id INT PRIMARY KEY 17 ); 18 19 statement ok 20 CREATE TABLE b ( 21 delete_no_action INT NOT NULL REFERENCES a ON DELETE NO ACTION 22 ,update_no_action INT NOT NULL REFERENCES a ON UPDATE NO ACTION 23 ,delete_restrict INT NOT NULL REFERENCES a ON DELETE RESTRICT 24 ,update_restrict INT NOT NULL REFERENCES a ON UPDATE RESTRICT 25 ,delete_cascade INT NOT NULL REFERENCES a ON DELETE CASCADE 26 ,update_cascade INT NOT NULL REFERENCES a ON UPDATE CASCADE 27 ,delete_null INT REFERENCES a ON DELETE SET NULL 28 ,update_null INT REFERENCES a ON UPDATE SET NULL 29 ,delete_default INT DEFAULT 109 REFERENCES a ON DELETE SET DEFAULT 30 ,update_default INT DEFAULT 110 REFERENCES a ON UPDATE SET DEFAULT 31 ); 32 33 statement ok 34 INSERT INTO a (id) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (109), (110); 35 INSERT INTO b VALUES (1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 36 37 query IIIIIIIIII 38 SELECT * FROM b; 39 ---- 40 1 2 3 4 5 6 7 8 9 10 41 42 # 1. ON DELETE NO ACTION 43 statement error pq: foreign key violation: values \[1\] in columns \[id\] referenced in table "b" 44 DELETE FROM a WHERE id = 1; 45 46 # 2. ON UPDATE NO ACTION 47 statement error pq: foreign key violation: values \[2\] in columns \[id\] referenced in table "b" 48 UPDATE a SET id = 1000 WHERE id = 2; 49 50 # 3. ON DELETE RESTRICT 51 statement error pq: foreign key violation: values \[3\] in columns \[id\] referenced in table "b" 52 DELETE FROM a WHERE id = 3; 53 54 # 4. ON UPDATE RESTRICT 55 statement error pq: foreign key violation: values \[4\] in columns \[id\] referenced in table "b" 56 UPDATE a SET id = 1000 WHERE id = 4; 57 58 # 5. ON DELETE CASCADE 59 statement ok 60 DELETE FROM a WHERE id = 5; 61 62 query I 63 SELECT count(*) FROM b; 64 ---- 65 0 66 67 statement ok 68 INSERT INTO a VALUES (5); 69 INSERT INTO b VALUES (1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 70 71 # 6. ON UPDATE CASCADE 72 statement ok 73 UPDATE a SET id = 1006 WHERE id = 6; 74 75 query IIIIIIIIII 76 SELECT * FROM b; 77 ---- 78 1 2 3 4 5 1006 7 8 9 10 79 80 # Also ensure that normal errors are still correctly wrapped even if cascading. 81 statement error pq: duplicate key value \(id\)=\(1\) violates unique constraint "primary" 82 UPDATE a SET id = 1 WHERE id = 1006; 83 84 # 7. ON DELETE SET NULL 85 statement ok 86 DELETE FROM a WHERE id = 7; 87 88 query IIIIIIIIII 89 SELECT * FROM b; 90 ---- 91 1 2 3 4 5 1006 NULL 8 9 10 92 93 # 8. ON UPDATE SET NULL 94 statement ok 95 UPDATE a SET id = 1008 WHERE id = 8; 96 97 query IIIIIIIIII 98 SELECT * FROM b; 99 ---- 100 1 2 3 4 5 1006 NULL NULL 9 10 101 102 # 9. ON DELETE SET DEFAULT 103 statement ok 104 DELETE FROM a WHERE id = 9 105 106 query IIIIIIIIII 107 SELECT * FROM b; 108 ---- 109 1 2 3 4 5 1006 NULL NULL 109 10 110 111 # 10. ON UPDATE SET DEFAULT 112 statement ok 113 UPDATE a SET id = 1010 WHERE id = 10; 114 115 query IIIIIIIIII 116 SELECT * FROM b; 117 ---- 118 1 2 3 4 5 1006 NULL NULL 109 110 119 120 # Post Test Clean up 121 statement ok 122 DROP TABLE b, a; 123 124 subtest DeleteCascade_Basic 125 ### Basic Delete Cascade 126 # a 127 # / \ 128 # b1 b2 129 # / \ \ 130 # c1 c2 c3 131 132 statement ok 133 CREATE TABLE a ( 134 id STRING PRIMARY KEY 135 ); 136 137 statement ok 138 CREATE TABLE b1 ( 139 id STRING PRIMARY KEY 140 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 141 ); 142 143 statement ok 144 CREATE TABLE b2 ( 145 id STRING PRIMARY KEY 146 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 147 ); 148 149 statement ok 150 CREATE TABLE c1 ( 151 id STRING PRIMARY KEY 152 ,delete_cascade STRING NOT NULL REFERENCES b1 ON DELETE CASCADE 153 ); 154 155 statement ok 156 CREATE TABLE c2 ( 157 id STRING PRIMARY KEY 158 ,delete_cascade STRING NOT NULL REFERENCES b1 ON DELETE CASCADE 159 ); 160 161 statement ok 162 CREATE TABLE c3 ( 163 id STRING PRIMARY KEY REFERENCES b2 ON DELETE CASCADE 164 ); 165 166 statement ok 167 INSERT INTO a VALUES ('a-pk1'); 168 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1'), ('b1-pk2', 'a-pk1'); 169 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1'), ('b2-pk2', 'a-pk1'); 170 INSERT INTO c1 VALUES 171 ('c1-pk1-b1-pk1', 'b1-pk1') 172 ,('c1-pk2-b1-pk1', 'b1-pk1') 173 ,('c1-pk3-b1-pk2', 'b1-pk2') 174 ,('c1-pk4-b1-pk2', 'b1-pk2') 175 ; 176 INSERT INTO c2 VALUES 177 ('c2-pk1-b1-pk1', 'b1-pk1') 178 ,('c2-pk2-b1-pk1', 'b1-pk1') 179 ,('c2-pk3-b1-pk2', 'b1-pk2') 180 ,('c2-pk4-b1-pk2', 'b1-pk2') 181 ; 182 INSERT INTO c3 VALUES ('b2-pk1'), ('b2-pk2'); 183 184 # ON DELETE CASCADE 185 statement ok 186 DELETE FROM a WHERE id = 'a-pk1'; 187 188 query IIIIII 189 SELECT 190 (SELECT count(*) FROM a) 191 ,(SELECT count(*) FROM b1) 192 ,(SELECT count(*) FROM b2) 193 ,(SELECT count(*) FROM c1) 194 ,(SELECT count(*) FROM c2) 195 ,(SELECT count(*) FROM c3) 196 ; 197 ---- 198 0 0 0 0 0 0 199 200 # Clean up after the test. 201 statement ok 202 DROP TABLE c3, c2, c1, b2, b1, a; 203 204 subtest DeleteCascade_PrimaryKeys 205 ### Basic Delete Cascade using primary keys 206 # a 207 # / \ 208 # b1 b2 209 # / \ 210 # c1 c2 211 212 statement ok 213 CREATE TABLE a ( 214 id STRING PRIMARY KEY 215 ); 216 217 statement ok 218 CREATE TABLE b1 ( 219 id STRING PRIMARY KEY REFERENCES a ON DELETE CASCADE 220 ); 221 222 statement ok 223 CREATE TABLE b2 ( 224 id STRING PRIMARY KEY REFERENCES a ON DELETE CASCADE 225 ); 226 227 statement ok 228 CREATE TABLE c1 ( 229 id STRING PRIMARY KEY REFERENCES b1 ON DELETE CASCADE 230 ); 231 232 statement ok 233 CREATE TABLE c2 ( 234 id STRING PRIMARY KEY REFERENCES b1 ON DELETE CASCADE 235 ); 236 237 statement ok 238 INSERT INTO a VALUES ('pk1'); 239 INSERT INTO b1 VALUES ('pk1'); 240 INSERT INTO b2 VALUES ('pk1'); 241 INSERT INTO c1 VALUES ('pk1'); 242 INSERT INTO c2 VALUES ('pk1'); 243 244 # ON DELETE CASCADE 245 statement ok 246 DELETE FROM a WHERE id = 'pk1'; 247 248 query IIIII 249 SELECT 250 (SELECT count(*) FROM a) 251 ,(SELECT count(*) FROM b1) 252 ,(SELECT count(*) FROM b2) 253 ,(SELECT count(*) FROM c1) 254 ,(SELECT count(*) FROM c2) 255 ; 256 ---- 257 0 0 0 0 0 258 259 # Clean up after the test. 260 statement ok 261 DROP TABLE c2, c1, b2, b1, a; 262 263 subtest DeleteCascade_CompositeFKs_MatchSimple 264 ### Basic Delete Cascade with composite FKs 265 # a 266 # / \ 267 # b1 b2 268 # / \ 269 # c1 c2 270 271 statement ok 272 CREATE TABLE a ( 273 id STRING PRIMARY KEY 274 ,x INT 275 ,UNIQUE (id, x) 276 ); 277 278 statement ok 279 CREATE TABLE b1 ( 280 id STRING PRIMARY KEY 281 ,a_id STRING 282 ,x INT 283 ,y INT 284 ,INDEX (a_id, x, y) 285 ,FOREIGN KEY (a_id, x) REFERENCES a (id, x) ON DELETE CASCADE 286 ,UNIQUE (id, x) 287 ); 288 289 statement ok 290 CREATE TABLE b2 ( 291 id STRING PRIMARY KEY 292 ,a_id STRING 293 ,x INT 294 ,y INT 295 ,INDEX (a_id, x, y) 296 ,FOREIGN KEY (a_id, x) REFERENCES a (id, x) ON DELETE CASCADE 297 ,UNIQUE (id, x) 298 ); 299 300 statement ok 301 CREATE TABLE c1 ( 302 id STRING PRIMARY KEY 303 ,b_id STRING 304 ,x INT 305 ,FOREIGN KEY (b_id, x) REFERENCES b1 (id, x) ON DELETE CASCADE 306 ); 307 308 statement ok 309 CREATE TABLE c2 ( 310 id STRING PRIMARY KEY 311 ,b_id STRING 312 ,x INT 313 ,FOREIGN KEY (b_id, x) REFERENCES b1 (id, x) ON DELETE CASCADE 314 ); 315 316 statement ok 317 INSERT INTO a VALUES ('a-pk1', 1); 318 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1', 1, 1), ('b1-pk2', 'a-pk1', 1, 2); 319 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1', 1, 1), ('b2-pk2', 'a-pk1', 1, 2); 320 INSERT INTO c1 VALUES 321 ('c1-pk1-b1-pk1', 'b1-pk1', 1) 322 ,('c1-pk2-b1-pk1', 'b1-pk1', 1) 323 ,('c1-pk3-b1-pk2', 'b1-pk2', 1) 324 ,('c1-pk4-b1-pk2', 'b1-pk2', 1) 325 ; 326 INSERT INTO c2 VALUES 327 ('c2-pk1-b1-pk1', 'b1-pk1', 1) 328 ,('c2-pk2-b1-pk1', 'b1-pk1', 1) 329 ,('c2-pk3-b1-pk2', 'b1-pk2', 1) 330 ,('c2-pk4-b1-pk2', 'b1-pk2', 1) 331 ; 332 333 # ON DELETE CASCADE 334 statement ok 335 DELETE FROM a WHERE id = 'a-pk1'; 336 337 query IIIII 338 SELECT 339 (SELECT count(*) FROM a) 340 ,(SELECT count(*) FROM b1) 341 ,(SELECT count(*) FROM b2) 342 ,(SELECT count(*) FROM c1) 343 ,(SELECT count(*) FROM c2) 344 ; 345 ---- 346 0 0 0 0 0 347 348 # Clean up after the test. 349 statement ok 350 DROP TABLE c2, c1, b2, b1, a; 351 352 subtest DeleteCascade_CompositeFKs_MatchFull 353 ### Basic Delete Cascade with composite FKs 354 # a 355 # / \ 356 # b1 b2 357 # / \ 358 # c1 c2 359 360 statement ok 361 CREATE TABLE a ( 362 id STRING PRIMARY KEY 363 ,x INT 364 ,UNIQUE (id, x) 365 ); 366 367 statement ok 368 CREATE TABLE b1 ( 369 id STRING PRIMARY KEY 370 ,a_id STRING 371 ,x INT 372 ,y INT 373 ,INDEX (a_id, x, y) 374 ,FOREIGN KEY (a_id, x) REFERENCES a (id, x) MATCH FULL ON DELETE CASCADE 375 ,UNIQUE (id, x) 376 ); 377 378 statement ok 379 CREATE TABLE b2 ( 380 id STRING PRIMARY KEY 381 ,a_id STRING 382 ,x INT 383 ,y INT 384 ,INDEX (a_id, x, y) 385 ,FOREIGN KEY (a_id, x) REFERENCES a (id, x) MATCH FULL ON DELETE CASCADE 386 ,UNIQUE (id, x) 387 ); 388 389 statement ok 390 CREATE TABLE c1 ( 391 id STRING PRIMARY KEY 392 ,b_id STRING 393 ,x INT 394 ,FOREIGN KEY (b_id, x) REFERENCES b1 (id, x) MATCH FULL ON DELETE CASCADE 395 ); 396 397 statement ok 398 CREATE TABLE c2 ( 399 id STRING PRIMARY KEY 400 ,b_id STRING 401 ,x INT 402 ,FOREIGN KEY (b_id, x) REFERENCES b1 (id, x) MATCH FULL ON DELETE CASCADE 403 ); 404 405 statement ok 406 INSERT INTO a VALUES ('a-pk1', 1); 407 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1', 1, 1), ('b1-pk2', 'a-pk1', 1, 2); 408 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1', 1, 1), ('b2-pk2', 'a-pk1', 1, 2); 409 INSERT INTO c1 VALUES 410 ('c1-pk1-b1-pk1', 'b1-pk1', 1) 411 ,('c1-pk2-b1-pk1', 'b1-pk1', 1) 412 ,('c1-pk3-b1-pk2', 'b1-pk2', 1) 413 ,('c1-pk4-b1-pk2', 'b1-pk2', 1) 414 ; 415 INSERT INTO c2 VALUES 416 ('c2-pk1-b1-pk1', 'b1-pk1', 1) 417 ,('c2-pk2-b1-pk1', 'b1-pk1', 1) 418 ,('c2-pk3-b1-pk2', 'b1-pk2', 1) 419 ,('c2-pk4-b1-pk2', 'b1-pk2', 1) 420 ; 421 422 # ON DELETE CASCADE 423 statement ok 424 DELETE FROM a WHERE id = 'a-pk1'; 425 426 query IIIII 427 SELECT 428 (SELECT count(*) FROM a) 429 ,(SELECT count(*) FROM b1) 430 ,(SELECT count(*) FROM b2) 431 ,(SELECT count(*) FROM c1) 432 ,(SELECT count(*) FROM c2) 433 ; 434 ---- 435 0 0 0 0 0 436 437 # Clean up after the test. 438 statement ok 439 DROP TABLE c2, c1, b2, b1, a; 440 441 subtest DeleteCascade_Restrict 442 ### Basic Delete Cascade with Restrict 443 # a 444 # / \ 445 # b1 b2 446 # / \ 447 # c1 c2 448 # | 449 # d 450 451 statement ok 452 CREATE TABLE a ( 453 id STRING PRIMARY KEY 454 ); 455 456 statement ok 457 CREATE TABLE b1 ( 458 id STRING PRIMARY KEY 459 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 460 ); 461 462 statement ok 463 CREATE TABLE b2 ( 464 id STRING PRIMARY KEY 465 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 466 ); 467 468 statement ok 469 CREATE TABLE c1 ( 470 id STRING PRIMARY KEY 471 ,delete_cascade STRING NOT NULL REFERENCES b1 ON DELETE CASCADE 472 ); 473 474 statement ok 475 CREATE TABLE c2 ( 476 id STRING PRIMARY KEY 477 ,delete_cascade STRING NOT NULL REFERENCES b1 ON DELETE CASCADE 478 ); 479 480 statement ok 481 CREATE TABLE d ( 482 id STRING PRIMARY KEY 483 ,delete_restrict STRING NOT NULL REFERENCES c2 ON DELETE RESTRICT 484 ); 485 486 statement ok 487 INSERT INTO a VALUES ('a-pk1'); 488 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1'), ('b1-pk2', 'a-pk1'); 489 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1'), ('b2-pk2', 'a-pk1'); 490 INSERT INTO c1 VALUES 491 ('c1-pk1-b1-pk1', 'b1-pk1') 492 ,('c1-pk2-b1-pk1', 'b1-pk1') 493 ,('c1-pk3-b1-pk2', 'b1-pk2') 494 ,('c1-pk4-b1-pk2', 'b1-pk2') 495 ; 496 INSERT INTO c2 VALUES 497 ('c2-pk1-b1-pk1', 'b1-pk1') 498 ,('c2-pk2-b1-pk1', 'b1-pk1') 499 ,('c2-pk3-b1-pk2', 'b1-pk2') 500 ,('c2-pk4-b1-pk2', 'b1-pk2') 501 ; 502 INSERT INTO d VALUES ('d-pk1-c2-pk4-b1-pk2', 'c2-pk4-b1-pk2'); 503 504 # ON DELETE CASCADE 505 statement error pq: foreign key violation: values \['c2-pk4-b1-pk2'\] in columns \[id\] referenced in table "d" 506 DELETE FROM a WHERE id = 'a-pk1'; 507 508 # Clean up after the test. 509 statement ok 510 DROP TABLE d, c2, c1, b2, b1, a; 511 512 subtest DeleteCascade_Interleaved 513 ### Basic Delete Cascade with Interleaved Tables 514 # a 515 # / \ 516 # b1 b2 517 # / \ \ 518 # c1 c2 c3 519 520 statement ok 521 CREATE TABLE a ( 522 id STRING PRIMARY KEY 523 ); 524 525 statement ok 526 CREATE TABLE b1 ( 527 id STRING PRIMARY KEY REFERENCES a ON DELETE CASCADE 528 ) INTERLEAVE IN PARENT a (id); 529 530 statement ok 531 CREATE TABLE b2 ( 532 id STRING PRIMARY KEY REFERENCES a ON DELETE CASCADE 533 ) INTERLEAVE IN PARENT a (id); 534 535 statement ok 536 CREATE TABLE c1 ( 537 id STRING PRIMARY KEY REFERENCES b1 ON DELETE CASCADE 538 ) INTERLEAVE IN PARENT b1 (id); 539 540 statement ok 541 CREATE TABLE c2 ( 542 id STRING PRIMARY KEY REFERENCES b1 ON DELETE CASCADE 543 ) INTERLEAVE IN PARENT b1 (id); 544 545 statement ok 546 CREATE TABLE c3 ( 547 id STRING PRIMARY KEY REFERENCES b2 ON DELETE CASCADE 548 ) INTERLEAVE IN PARENT b2 (id); 549 550 # Check that telemetry is being collected on creation of interleaved tables. 551 query B 552 SELECT usage_count >= 5 FROM crdb_internal.feature_usage WHERE feature_name = 'sql.schema.create_interleaved_table' 553 ---- 554 true 555 556 statement ok 557 INSERT INTO a VALUES ('pk1'), ('pk2'); 558 INSERT INTO b1 VALUES ('pk1'), ('pk2'); 559 INSERT INTO b2 VALUES ('pk1'), ('pk2'); 560 INSERT INTO c1 VALUES ('pk1'), ('pk2'); 561 INSERT INTO c2 VALUES ('pk1'), ('pk2'); 562 INSERT INTO c3 VALUES ('pk1'), ('pk2'); 563 564 # ON DELETE CASCADE from b1 downward 565 statement ok 566 DELETE FROM b1 WHERE id = 'pk2'; 567 568 query IIIIII 569 SELECT 570 (SELECT count(*) FROM a) 571 ,(SELECT count(*) FROM b1) 572 ,(SELECT count(*) FROM b2) 573 ,(SELECT count(*) FROM c1) 574 ,(SELECT count(*) FROM c2) 575 ,(SELECT count(*) FROM c3) 576 ; 577 ---- 578 2 1 2 1 1 2 579 580 # ON DELETE CASCADE 581 statement ok 582 DELETE FROM a WHERE id = 'pk1'; 583 584 query IIIIII 585 SELECT 586 (SELECT count(*) FROM a) 587 ,(SELECT count(*) FROM b1) 588 ,(SELECT count(*) FROM b2) 589 ,(SELECT count(*) FROM c1) 590 ,(SELECT count(*) FROM c2) 591 ,(SELECT count(*) FROM c3) 592 ; 593 ---- 594 1 0 1 0 0 1 595 596 # ON DELETE CASCADE for the rest 597 statement ok 598 DELETE FROM a WHERE id = 'pk2'; 599 600 query IIIIII 601 SELECT 602 (SELECT count(*) FROM a) 603 ,(SELECT count(*) FROM b1) 604 ,(SELECT count(*) FROM b2) 605 ,(SELECT count(*) FROM c1) 606 ,(SELECT count(*) FROM c2) 607 ,(SELECT count(*) FROM c3) 608 ; 609 ---- 610 0 0 0 0 0 0 611 612 # Clean up after the test. 613 statement ok 614 DROP TABLE c3, c2, c1, b2, b1, a; 615 616 subtest DeleteCascade_InterleavedRestrict 617 ### Basic Delete Cascade with Interleaved Tables To Restrict 618 # a 619 # / \ 620 # b1 b2 621 # / \ \ 622 # c1 c2 c3 623 # 624 # In this test, c3 is restricted, so deleting from a should fail, but from b1 625 # should be ok. 626 627 statement ok 628 CREATE TABLE a ( 629 id STRING PRIMARY KEY 630 ); 631 632 statement ok 633 CREATE TABLE b1 ( 634 id STRING PRIMARY KEY REFERENCES a ON DELETE CASCADE 635 ) INTERLEAVE IN PARENT a (id); 636 637 statement ok 638 CREATE TABLE b2 ( 639 id STRING PRIMARY KEY REFERENCES a ON DELETE CASCADE 640 ) INTERLEAVE IN PARENT a (id); 641 642 statement ok 643 CREATE TABLE c1 ( 644 id STRING PRIMARY KEY REFERENCES b1 ON DELETE CASCADE 645 ) INTERLEAVE IN PARENT b1 (id); 646 647 statement ok 648 CREATE TABLE c2 ( 649 id STRING PRIMARY KEY REFERENCES b1 ON DELETE CASCADE 650 ) INTERLEAVE IN PARENT b1 (id); 651 652 statement ok 653 CREATE TABLE c3 ( 654 id STRING PRIMARY KEY REFERENCES b2 ON DELETE RESTRICT 655 ) INTERLEAVE IN PARENT b2 (id); 656 657 statement ok 658 INSERT INTO a VALUES ('pk1'), ('pk2'); 659 INSERT INTO b1 VALUES ('pk1'), ('pk2'); 660 INSERT INTO b2 VALUES ('pk1'), ('pk2'); 661 INSERT INTO c1 VALUES ('pk1'), ('pk2'); 662 INSERT INTO c2 VALUES ('pk1'), ('pk2'); 663 INSERT INTO c3 VALUES ('pk1'), ('pk2'); 664 665 # ON DELETE CASCADE from b1 downward 666 statement ok 667 DELETE FROM b1 WHERE id = 'pk2'; 668 669 query IIIIII 670 SELECT 671 (SELECT count(*) FROM a) 672 ,(SELECT count(*) FROM b1) 673 ,(SELECT count(*) FROM b2) 674 ,(SELECT count(*) FROM c1) 675 ,(SELECT count(*) FROM c2) 676 ,(SELECT count(*) FROM c3) 677 ; 678 ---- 679 2 1 2 1 1 2 680 681 # ON DELETE CASCADE 682 statement error pq: foreign key violation: values \['pk1'\] in columns \[id\] referenced in table "c3" 683 DELETE FROM a WHERE id = 'pk1'; 684 685 # Clean up after the test. 686 statement ok 687 DROP TABLE c3, c2, c1, b2, b1, a; 688 689 subtest DeleteCascade_SelfReference 690 ### Self Reference Delete Cascade 691 # self <- self 692 693 statement ok 694 CREATE TABLE self ( 695 id INT PRIMARY KEY 696 ,other_id INT REFERENCES self ON DELETE CASCADE 697 ); 698 699 statement ok 700 INSERT INTO self VALUES (1, NULL); 701 INSERT INTO self VALUES (2, 1); 702 INSERT INTO self VALUES (3, 2); 703 INSERT INTO self VALUES (4, 3); 704 705 statement ok 706 DELETE FROM self WHERE id = 1; 707 708 query I 709 SELECT count(*) FROM self 710 ---- 711 0 712 713 # Clean up after the test. 714 statement ok 715 DROP TABLE self; 716 717 subtest DeleteCascade_SelfReferenceCycle 718 ### Self Reference Delete Cascade Cycle 719 # self <- self 720 721 statement ok 722 CREATE TABLE self ( 723 id INT PRIMARY KEY 724 ,other_id INT REFERENCES self ON DELETE CASCADE 725 ); 726 727 statement ok 728 INSERT INTO self VALUES (1, NULL); 729 INSERT INTO self VALUES (2, 1); 730 INSERT INTO self VALUES (3, 2); 731 INSERT INTO self VALUES (4, 3); 732 733 statement ok 734 UPDATE self SET other_id = 4 WHERE id = 1; 735 736 statement ok 737 DELETE FROM self WHERE id = 1; 738 739 query I 740 SELECT count(*) FROM self 741 ---- 742 0 743 744 # Clean up after the test. 745 statement ok 746 DROP TABLE self; 747 748 subtest DeleteCascade_TwoTableLoop 749 ### Delete cascade loop between two tables 750 # loop_a <- loop_b 751 # loop_b <- loop_a 752 753 statement ok 754 CREATE TABLE loop_a ( 755 id STRING PRIMARY KEY 756 ,cascade_delete STRING 757 ,INDEX(cascade_delete) 758 ); 759 760 statement ok 761 CREATE TABLE loop_b ( 762 id STRING PRIMARY KEY 763 ,cascade_delete STRING REFERENCES loop_a ON DELETE CASCADE 764 ); 765 766 statement ok 767 ALTER TABLE loop_a ADD CONSTRAINT cascade_delete_constraint 768 FOREIGN KEY (cascade_delete) REFERENCES loop_b (id) 769 ON DELETE CASCADE; 770 771 statement ok 772 INSERT INTO loop_a (id, cascade_delete) VALUES ('loop_a-pk1', NULL); 773 INSERT INTO loop_b (id, cascade_delete) VALUES ('loop_b-pk1', 'loop_a-pk1'); 774 INSERT INTO loop_a (id, cascade_delete) VALUES ('loop_a-pk2', 'loop_b-pk1'); 775 INSERT INTO loop_b (id, cascade_delete) VALUES ('loop_b-pk2', 'loop_a-pk2'); 776 INSERT INTO loop_a (id, cascade_delete) VALUES ('loop_a-pk3', 'loop_b-pk2'); 777 INSERT INTO loop_b (id, cascade_delete) VALUES ('loop_b-pk3', 'loop_a-pk3'); 778 779 statement ok 780 UPDATE loop_a SET cascade_delete = 'loop_b-pk3' WHERE id = 'loop_a-pk1'; 781 782 statement ok 783 DELETE FROM loop_a WHERE id = 'loop_a-pk1'; 784 785 query II 786 SELECT 787 (SELECT count(*) FROM loop_a) 788 ,(SELECT count(*) FROM loop_b) 789 ; 790 ---- 791 0 0 792 793 # Clean up after the test. 794 statement ok 795 DROP TABLE loop_a, loop_b; 796 797 subtest DeleteCascade_TwoTableLoopCycle 798 ### Delete cascade loop between two tables with cycle 799 # loop_a <- loop_b 800 # loop_b <- loop_a 801 802 statement ok 803 CREATE TABLE loop_a ( 804 id STRING PRIMARY KEY 805 ,cascade_delete STRING 806 ,INDEX(cascade_delete) 807 ); 808 809 statement ok 810 CREATE TABLE loop_b ( 811 id STRING PRIMARY KEY 812 ,cascade_delete STRING REFERENCES loop_a ON DELETE CASCADE 813 ); 814 815 statement ok 816 ALTER TABLE loop_a ADD CONSTRAINT cascade_delete_constraint 817 FOREIGN KEY (cascade_delete) REFERENCES loop_b (id) 818 ON DELETE CASCADE; 819 820 statement ok 821 INSERT INTO loop_a (id, cascade_delete) VALUES ('loop_a-pk1', NULL); 822 INSERT INTO loop_b (id, cascade_delete) VALUES ('loop_b-pk1', 'loop_a-pk1'); 823 INSERT INTO loop_a (id, cascade_delete) VALUES ('loop_a-pk2', 'loop_b-pk1'); 824 INSERT INTO loop_b (id, cascade_delete) VALUES ('loop_b-pk2', 'loop_a-pk2'); 825 INSERT INTO loop_a (id, cascade_delete) VALUES ('loop_a-pk3', 'loop_b-pk2'); 826 INSERT INTO loop_b (id, cascade_delete) VALUES ('loop_b-pk3', 'loop_a-pk3'); 827 828 statement ok 829 DELETE FROM loop_a WHERE id = 'loop_a-pk1'; 830 831 query II 832 SELECT 833 (SELECT count(*) FROM loop_a) 834 ,(SELECT count(*) FROM loop_b) 835 ; 836 ---- 837 0 0 838 839 # Clean up after the test. 840 statement ok 841 DROP TABLE loop_a, loop_b; 842 843 subtest DeleteCascade_DoubleSelfReference 844 ### Delete cascade double self reference 845 # self_x2 (x) <- (y) 846 # self_x2 (y) <- (z) 847 848 statement ok 849 CREATE TABLE self_x2 ( 850 x STRING PRIMARY KEY 851 ,y STRING UNIQUE REFERENCES self_x2(x) ON DELETE CASCADE 852 ,z STRING REFERENCES self_x2(y) ON DELETE CASCADE 853 ); 854 855 statement ok 856 INSERT INTO self_x2 (x, y, z) VALUES ('pk1', NULL, NULL); 857 INSERT INTO self_x2 (x, y, z) VALUES ('pk2', 'pk1', NULL); 858 INSERT INTO self_x2 (x, y, z) VALUES ('pk3', 'pk2', 'pk1'); 859 860 statement ok 861 DELETE FROM self_x2 WHERE x = 'pk1'; 862 863 query I 864 SELECT count(*) FROM self_x2 865 ---- 866 0 867 868 # Clean up after the test. 869 statement ok 870 DROP TABLE self_x2; 871 872 subtest DeleteCascade_Race 873 ### Delete cascade race 874 # a 875 # / \ 876 # b c 877 # | | 878 # | d 879 # \ / 880 # e 881 statement ok 882 CREATE TABLE a ( 883 id STRING PRIMARY KEY 884 ); 885 886 statement ok 887 CREATE TABLE b ( 888 id STRING PRIMARY KEY 889 ,a_id STRING REFERENCES a ON DELETE CASCADE 890 ); 891 892 statement ok 893 CREATE TABLE c ( 894 id STRING PRIMARY KEY 895 ,a_id STRING REFERENCES a ON DELETE CASCADE 896 ); 897 898 statement ok 899 CREATE TABLE d ( 900 id STRING PRIMARY KEY 901 ,c_id STRING REFERENCES c ON DELETE CASCADE 902 ); 903 904 statement ok 905 CREATE TABLE e ( 906 id STRING PRIMARY KEY 907 ,b_id STRING REFERENCES b ON DELETE CASCADE 908 ,d_id STRING REFERENCES d ON DELETE CASCADE 909 ); 910 911 statement ok 912 INSERT INTO a (id) VALUES ('a1'); 913 INSERT INTO b (id, a_id) VALUES ('b1', 'a1'); 914 INSERT INTO c (id, a_id) VALUES ('c1', 'a1'); 915 INSERT INTO d (id, c_id) VALUES ('d1', 'c1'); 916 INSERT INTO e (id, b_id, d_id) VALUES ('e1', 'b1', 'd1'); 917 918 statement ok 919 DELETE FROM a WHERE id = 'a1'; 920 921 query IIIII 922 SELECT 923 (SELECT count(*) FROM a) 924 ,(SELECT count(*) FROM b) 925 ,(SELECT count(*) FROM c) 926 ,(SELECT count(*) FROM d) 927 ,(SELECT count(*) FROM e) 928 ; 929 ---- 930 0 0 0 0 0 931 932 # Clean up after the test. 933 statement ok 934 DROP TABLE e, d, c, b, a; 935 936 subtest DeleteCascade_Multi 937 # Ensures that the cascader can be reused. See #21563. 938 939 statement ok 940 CREATE TABLE a ( 941 id INT PRIMARY KEY 942 ); 943 CREATE TABLE b ( 944 id INT PRIMARY KEY 945 ,a_id INT REFERENCES a ON DELETE CASCADE 946 ) 947 948 statement ok 949 INSERT INTO a VALUES (1), (2), (3); 950 INSERT INTO b VALUES (1, 1), (2, NULL), (3, 2), (4, 1), (5, NULL); 951 952 statement ok 953 DELETE FROM a; 954 955 query II rowsort 956 SELECT id, a_id FROM b; 957 ---- 958 2 NULL 959 5 NULL 960 961 # Clean up. 962 statement ok 963 DROP TABLE b, a; 964 965 subtest UpdateCascade_Basic 966 ### Basic Update Cascade 967 # a 968 # / \ 969 # b1 b2 970 # / \ \ 971 # c1 c2 c3 972 973 statement ok 974 CREATE TABLE a ( 975 id STRING PRIMARY KEY 976 ); 977 978 statement ok 979 CREATE TABLE b1 ( 980 id STRING PRIMARY KEY 981 ,update_cascade STRING NOT NULL UNIQUE REFERENCES a ON UPDATE CASCADE 982 ); 983 984 statement ok 985 CREATE TABLE b2 ( 986 id STRING PRIMARY KEY 987 ,update_cascade STRING NOT NULL UNIQUE REFERENCES a ON UPDATE CASCADE 988 ); 989 990 statement ok 991 CREATE TABLE c1 ( 992 id STRING PRIMARY KEY 993 ,update_cascade STRING NOT NULL REFERENCES b1 (update_cascade) ON UPDATE CASCADE 994 ); 995 996 statement ok 997 CREATE TABLE c2 ( 998 id STRING PRIMARY KEY 999 ,update_cascade STRING NOT NULL REFERENCES b1 (update_cascade) ON UPDATE CASCADE 1000 ); 1001 1002 statement ok 1003 CREATE TABLE c3 ( 1004 id STRING PRIMARY KEY REFERENCES b2(update_cascade) ON UPDATE CASCADE 1005 ); 1006 1007 statement ok 1008 INSERT INTO a VALUES ('original'); 1009 INSERT INTO b1 VALUES ('b1-pk1', 'original'); 1010 INSERT INTO b2 VALUES ('b2-pk1', 'original'); 1011 INSERT INTO c1 VALUES 1012 ('c1-pk1', 'original') 1013 ,('c1-pk2', 'original') 1014 ,('c1-pk3', 'original') 1015 ,('c1-pk4', 'original') 1016 ; 1017 INSERT INTO c2 VALUES 1018 ('c2-pk1', 'original') 1019 ,('c2-pk2', 'original') 1020 ,('c2-pk3', 'original') 1021 ,('c2-pk4', 'original') 1022 ; 1023 INSERT INTO c3 VALUES ('original'); 1024 1025 # ON UPDATE CASCADE 1026 statement ok 1027 UPDATE a SET id = 'updated' WHERE id = 'original'; 1028 1029 query T 1030 SELECT * FROM a; 1031 ---- 1032 updated 1033 1034 query TT 1035 SELECT * FROM b1; 1036 ---- 1037 b1-pk1 updated 1038 1039 query TT 1040 SELECT * FROM b2; 1041 ---- 1042 b2-pk1 updated 1043 1044 query TT rowsort 1045 SELECT * FROM c1; 1046 ---- 1047 c1-pk1 updated 1048 c1-pk2 updated 1049 c1-pk3 updated 1050 c1-pk4 updated 1051 1052 query TT rowsort 1053 SELECT * FROM c2; 1054 ---- 1055 c2-pk1 updated 1056 c2-pk2 updated 1057 c2-pk3 updated 1058 c2-pk4 updated 1059 1060 # Clean up after the test. 1061 statement ok 1062 DROP TABLE c3, c2, c1, b2, b1, a; 1063 1064 subtest UpdateCascade_PrimaryKeys 1065 ### Basic Update Cascade using only primary keys 1066 # a 1067 # / \ 1068 # b1 b2 1069 # / \ 1070 # c1 c2 1071 1072 statement ok 1073 CREATE TABLE a ( 1074 id STRING PRIMARY KEY 1075 ); 1076 1077 statement ok 1078 CREATE TABLE b1 ( 1079 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1080 ); 1081 1082 statement ok 1083 CREATE TABLE b2 ( 1084 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1085 ); 1086 1087 statement ok 1088 CREATE TABLE c1 ( 1089 id STRING PRIMARY KEY REFERENCES b1 ON UPDATE CASCADE 1090 ); 1091 1092 statement ok 1093 CREATE TABLE c2 ( 1094 id STRING PRIMARY KEY REFERENCES b1 ON UPDATE CASCADE 1095 ); 1096 1097 statement ok 1098 INSERT INTO a VALUES ('original'); 1099 INSERT INTO b1 VALUES ('original'); 1100 INSERT INTO b2 VALUES ('original'); 1101 INSERT INTO c1 VALUES ('original'); 1102 INSERT INTO c2 VALUES ('original'); 1103 1104 # ON UPDATE CASCADE 1105 statement ok 1106 UPDATE a SET id = 'updated' WHERE id = 'original'; 1107 1108 query TTTTT 1109 SELECT 1110 (SELECT id FROM a) 1111 ,(SELECT id FROM b1) 1112 ,(SELECT id FROM b2) 1113 ,(SELECT id FROM c1) 1114 ,(SELECT id FROM c2) 1115 ; 1116 ---- 1117 updated updated updated updated updated 1118 1119 # Clean up after the test. 1120 statement ok 1121 DROP TABLE c2, c1, b2, b1, a; 1122 1123 subtest UpdateCascade_CompositeFKs_MatchSimple 1124 ### Basic Update Cascade with composite FKs 1125 # a 1126 # / \ 1127 # b1 b2 1128 # / \ 1129 # c1 c2 1130 1131 statement ok 1132 CREATE TABLE a ( 1133 id STRING PRIMARY KEY 1134 ,x INT 1135 ,UNIQUE (id, x) 1136 ); 1137 1138 statement ok 1139 CREATE TABLE b1 ( 1140 id STRING PRIMARY KEY 1141 ,a_id STRING 1142 ,x INT 1143 ,y INT 1144 ,INDEX (a_id, x, y) 1145 ,FOREIGN KEY (a_id, x) REFERENCES a (id, x) ON UPDATE CASCADE 1146 ,UNIQUE (id, x) 1147 ); 1148 1149 statement ok 1150 CREATE TABLE b2 ( 1151 id STRING PRIMARY KEY 1152 ,a_id STRING 1153 ,x INT 1154 ,y INT 1155 ,INDEX (a_id, x, y) 1156 ,FOREIGN KEY (a_id, x) REFERENCES a (id, x) ON UPDATE CASCADE 1157 ,UNIQUE (id, x) 1158 ); 1159 1160 statement ok 1161 CREATE TABLE c1 ( 1162 id STRING PRIMARY KEY 1163 ,b_id STRING 1164 ,x INT 1165 ,FOREIGN KEY (b_id, x) REFERENCES b1 (id, x) ON UPDATE CASCADE 1166 ); 1167 1168 statement ok 1169 CREATE TABLE c2 ( 1170 id STRING PRIMARY KEY 1171 ,b_id STRING 1172 ,x INT 1173 ,FOREIGN KEY (b_id, x) REFERENCES b1 (id, x) ON UPDATE CASCADE 1174 ); 1175 1176 statement ok 1177 INSERT INTO a VALUES ('a-pk1', 1); 1178 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1', 1, 1), ('b1-pk2', 'a-pk1', 1, 2); 1179 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1', 1, 1), ('b2-pk2', 'a-pk1', 1, 2); 1180 INSERT INTO c1 VALUES 1181 ('c1-pk1-b1-pk1', 'b1-pk1', 1) 1182 ,('c1-pk2-b1-pk1', 'b1-pk1', 1) 1183 ,('c1-pk3-b1-pk2', 'b1-pk2', 1) 1184 ,('c1-pk4-b1-pk2', 'b1-pk2', 1) 1185 ; 1186 INSERT INTO c2 VALUES 1187 ('c2-pk1-b1-pk1', 'b1-pk1', 1) 1188 ,('c2-pk2-b1-pk1', 'b1-pk1', 1) 1189 ,('c2-pk3-b1-pk2', 'b1-pk2', 1) 1190 ,('c2-pk4-b1-pk2', 'b1-pk2', 1) 1191 ; 1192 1193 # ON UPDATE CASCADE 1194 statement ok 1195 UPDATE a SET x = 2 WHERE x = 1; 1196 1197 query TI 1198 SELECT * FROM a; 1199 ---- 1200 a-pk1 2 1201 1202 query TTII rowsort 1203 SELECT * FROM b1; 1204 ---- 1205 b1-pk1 a-pk1 2 1 1206 b1-pk2 a-pk1 2 2 1207 1208 query TTII rowsort 1209 SELECT * FROM b2; 1210 ---- 1211 b2-pk1 a-pk1 2 1 1212 b2-pk2 a-pk1 2 2 1213 1214 query TTI rowsort 1215 SELECT * FROM c1; 1216 ---- 1217 c1-pk1-b1-pk1 b1-pk1 2 1218 c1-pk2-b1-pk1 b1-pk1 2 1219 c1-pk3-b1-pk2 b1-pk2 2 1220 c1-pk4-b1-pk2 b1-pk2 2 1221 1222 query TTI rowsort 1223 SELECT * FROM c2; 1224 ---- 1225 c2-pk1-b1-pk1 b1-pk1 2 1226 c2-pk2-b1-pk1 b1-pk1 2 1227 c2-pk3-b1-pk2 b1-pk2 2 1228 c2-pk4-b1-pk2 b1-pk2 2 1229 1230 # Clean up after the test. 1231 statement ok 1232 DROP TABLE c2, c1, b2, b1, a; 1233 1234 subtest UpdateCascade_CompositeFKs_MatchFull 1235 ### Basic Update Cascade with composite FKs 1236 # a 1237 # / \ 1238 # b1 b2 1239 # / \ 1240 # c1 c2 1241 1242 statement ok 1243 CREATE TABLE a ( 1244 id STRING PRIMARY KEY 1245 ,x INT 1246 ,UNIQUE (id, x) 1247 ); 1248 1249 statement ok 1250 CREATE TABLE b1 ( 1251 id STRING PRIMARY KEY 1252 ,a_id STRING 1253 ,x INT 1254 ,y INT 1255 ,INDEX (a_id, x, y) 1256 ,FOREIGN KEY (a_id, x) REFERENCES a (id, x) MATCH FULL ON UPDATE CASCADE 1257 ,UNIQUE (id, x) 1258 ); 1259 1260 statement ok 1261 CREATE TABLE b2 ( 1262 id STRING PRIMARY KEY 1263 ,a_id STRING 1264 ,x INT 1265 ,y INT 1266 ,INDEX (a_id, x, y) 1267 ,FOREIGN KEY (a_id, x) REFERENCES a (id, x) MATCH FULL ON UPDATE CASCADE 1268 ,UNIQUE (id, x) 1269 ); 1270 1271 statement ok 1272 CREATE TABLE c1 ( 1273 id STRING PRIMARY KEY 1274 ,b_id STRING 1275 ,x INT 1276 ,FOREIGN KEY (b_id, x) REFERENCES b1 (id, x) MATCH FULL ON UPDATE CASCADE 1277 ); 1278 1279 statement ok 1280 CREATE TABLE c2 ( 1281 id STRING PRIMARY KEY 1282 ,b_id STRING 1283 ,x INT 1284 ,FOREIGN KEY (b_id, x) REFERENCES b1 (id, x) MATCH FULL ON UPDATE CASCADE 1285 ); 1286 1287 statement ok 1288 INSERT INTO a VALUES ('a-pk1', 1); 1289 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1', 1, 1), ('b1-pk2', 'a-pk1', 1, 2); 1290 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1', 1, 1), ('b2-pk2', 'a-pk1', 1, 2); 1291 INSERT INTO c1 VALUES 1292 ('c1-pk1-b1-pk1', 'b1-pk1', 1) 1293 ,('c1-pk2-b1-pk1', 'b1-pk1', 1) 1294 ,('c1-pk3-b1-pk2', 'b1-pk2', 1) 1295 ,('c1-pk4-b1-pk2', 'b1-pk2', 1) 1296 ; 1297 INSERT INTO c2 VALUES 1298 ('c2-pk1-b1-pk1', 'b1-pk1', 1) 1299 ,('c2-pk2-b1-pk1', 'b1-pk1', 1) 1300 ,('c2-pk3-b1-pk2', 'b1-pk2', 1) 1301 ,('c2-pk4-b1-pk2', 'b1-pk2', 1) 1302 ; 1303 1304 # ON UPDATE CASCADE 1305 statement ok 1306 UPDATE a SET x = 2 WHERE x = 1; 1307 1308 query TI 1309 SELECT * FROM a; 1310 ---- 1311 a-pk1 2 1312 1313 query TTII rowsort 1314 SELECT * FROM b1; 1315 ---- 1316 b1-pk1 a-pk1 2 1 1317 b1-pk2 a-pk1 2 2 1318 1319 query TTII rowsort 1320 SELECT * FROM b2; 1321 ---- 1322 b2-pk1 a-pk1 2 1 1323 b2-pk2 a-pk1 2 2 1324 1325 query TTI rowsort 1326 SELECT * FROM c1; 1327 ---- 1328 c1-pk1-b1-pk1 b1-pk1 2 1329 c1-pk2-b1-pk1 b1-pk1 2 1330 c1-pk3-b1-pk2 b1-pk2 2 1331 c1-pk4-b1-pk2 b1-pk2 2 1332 1333 query TTI rowsort 1334 SELECT * FROM c2; 1335 ---- 1336 c2-pk1-b1-pk1 b1-pk1 2 1337 c2-pk2-b1-pk1 b1-pk1 2 1338 c2-pk3-b1-pk2 b1-pk2 2 1339 c2-pk4-b1-pk2 b1-pk2 2 1340 1341 # Clean up after the test. 1342 statement ok 1343 DROP TABLE c2, c1, b2, b1, a; 1344 1345 subtest UpdateCascade_Restrict 1346 ### Basic Update Cascade with Restrict 1347 # This test has a restrict on both d tables and tests both. 1348 # c3 and d2 use primary keys to match while the rest use non-primary keys. 1349 # Both restricts are tested. 1350 # a 1351 # / \ 1352 # b1 b2 1353 # / \ \ 1354 # c1 c2 c3 1355 # | | 1356 # d1 d2 1357 1358 statement ok 1359 CREATE TABLE a ( 1360 id STRING PRIMARY KEY 1361 ); 1362 1363 statement ok 1364 CREATE TABLE b1 ( 1365 id STRING PRIMARY KEY 1366 ,update_cascade STRING NOT NULL UNIQUE REFERENCES a ON UPDATE CASCADE 1367 ); 1368 1369 statement ok 1370 CREATE TABLE b2 ( 1371 id STRING PRIMARY KEY 1372 ,update_cascade STRING NOT NULL UNIQUE REFERENCES a ON UPDATE CASCADE 1373 ); 1374 1375 statement ok 1376 CREATE TABLE c1 ( 1377 id STRING PRIMARY KEY 1378 ,update_cascade STRING NOT NULL REFERENCES b1 (update_cascade) ON UPDATE CASCADE 1379 ); 1380 1381 statement ok 1382 CREATE TABLE c2 ( 1383 id STRING PRIMARY KEY 1384 ,update_cascade STRING NOT NULL UNIQUE REFERENCES b1 (update_cascade) ON UPDATE CASCADE 1385 ); 1386 1387 statement ok 1388 CREATE TABLE c3 ( 1389 id STRING PRIMARY KEY REFERENCES b2(update_cascade) ON UPDATE CASCADE 1390 ); 1391 1392 statement ok 1393 CREATE TABLE d1 ( 1394 id STRING PRIMARY KEY 1395 ,update_restrict STRING NOT NULL REFERENCES c2 (update_cascade) ON UPDATE RESTRICT 1396 ); 1397 1398 statement ok 1399 CREATE TABLE d2 ( 1400 id STRING PRIMARY KEY REFERENCES c3 ON UPDATE RESTRICT 1401 ); 1402 1403 statement ok 1404 INSERT INTO a VALUES ('original'); 1405 INSERT INTO b1 VALUES ('b1-pk1', 'original'); 1406 INSERT INTO b2 VALUES ('b2-pk1', 'original'); 1407 INSERT INTO c1 VALUES 1408 ('c1-pk1', 'original') 1409 ,('c1-pk2', 'original') 1410 ,('c1-pk3', 'original') 1411 ,('c1-pk4', 'original') 1412 ; 1413 INSERT INTO c2 VALUES ('c2-pk1', 'original'); 1414 INSERT INTO c3 VALUES ('original'); 1415 1416 # Test non-primary key restrict. 1417 statement ok 1418 INSERT INTO d1 VALUES ('d1-pk1', 'original'); 1419 1420 # ON UPDATE CASCADE 1421 statement error foreign key violation: values \['original'\] in columns \[update_cascade\] referenced in table "d1" 1422 UPDATE a SET id = 'updated' WHERE id = 'original'; 1423 1424 statement ok 1425 DELETE FROM d1 WHERE id = 'd1-pk1'; 1426 1427 # Test a primary key restrict. 1428 statement ok 1429 INSERT INTO d2 VALUES ('original'); 1430 1431 # ON UPDATE CASCADE 1432 statement error foreign key violation: values \['original'\] in columns \[id\] referenced in table "d2" 1433 UPDATE a SET id = 'updated' WHERE id = 'original'; 1434 1435 # Clean up after the test. 1436 statement ok 1437 DROP TABLE d2, d1, c3, c2, c1, b2, b1, a; 1438 1439 subtest UpdateCascade_Interleaved 1440 ### Basic Update Cascade with Interleaved Tables 1441 # a 1442 # / \ 1443 # b1 b2 1444 # / \ \ 1445 # c1 c2 c3 1446 1447 statement ok 1448 CREATE TABLE a ( 1449 id STRING PRIMARY KEY 1450 ); 1451 1452 statement ok 1453 CREATE TABLE b1 ( 1454 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1455 ) INTERLEAVE IN PARENT a (id); 1456 1457 statement ok 1458 CREATE TABLE b2 ( 1459 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1460 ) INTERLEAVE IN PARENT a (id); 1461 1462 statement ok 1463 CREATE TABLE c1 ( 1464 id STRING PRIMARY KEY REFERENCES b1 ON UPDATE CASCADE 1465 ) INTERLEAVE IN PARENT b1 (id); 1466 1467 statement ok 1468 CREATE TABLE c2 ( 1469 id STRING PRIMARY KEY REFERENCES b1 ON UPDATE CASCADE 1470 ) INTERLEAVE IN PARENT b1 (id); 1471 1472 statement ok 1473 CREATE TABLE c3 ( 1474 id STRING PRIMARY KEY REFERENCES b2 ON UPDATE CASCADE 1475 ) INTERLEAVE IN PARENT b2 (id); 1476 1477 statement ok 1478 INSERT INTO a VALUES ('original'), ('updated'); 1479 INSERT INTO b1 VALUES ('original'); 1480 INSERT INTO b2 VALUES ('original'); 1481 INSERT INTO c1 VALUES ('original'); 1482 INSERT INTO c2 VALUES ('original'); 1483 INSERT INTO c3 VALUES ('original'); 1484 1485 # ON UPDATE CASCADE from b1 downward 1486 statement ok 1487 UPDATE b1 SET id = 'updated' WHERE id = 'original'; 1488 1489 query T rowsort 1490 SELECT * FROM a; 1491 ---- 1492 original 1493 updated 1494 1495 query TTTTT 1496 SELECT 1497 (SELECT id FROM b1) 1498 ,(SELECT id FROM b2) 1499 ,(SELECT id FROM c1) 1500 ,(SELECT id FROM c2) 1501 ,(SELECT id FROM c3) 1502 ; 1503 ---- 1504 updated original updated updated original 1505 1506 # ON UPDATE CASCADE from a downward 1507 statement ok 1508 UPDATE a SET id = 'updated2' WHERE id = 'original'; 1509 1510 query T rowsort 1511 SELECT * FROM a; 1512 ---- 1513 updated 1514 updated2 1515 1516 query TTTTT 1517 SELECT 1518 (SELECT id FROM b1) 1519 ,(SELECT id FROM b2) 1520 ,(SELECT id FROM c1) 1521 ,(SELECT id FROM c2) 1522 ,(SELECT id FROM c3) 1523 ; 1524 ---- 1525 updated updated2 updated updated updated2 1526 1527 # Clean up after the test. 1528 statement ok 1529 DROP TABLE c3, c2, c1, b2, b1, a; 1530 1531 subtest UpdateCascade_InterleavedRestrict 1532 ### Basic Update Cascade with Interleaved Tables To Restrict 1533 # a 1534 # / \ 1535 # b1 b2 1536 # / \ \ 1537 # c1 c2 c3 1538 1539 statement ok 1540 CREATE TABLE a ( 1541 id STRING PRIMARY KEY 1542 ); 1543 1544 statement ok 1545 CREATE TABLE b1 ( 1546 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1547 ) INTERLEAVE IN PARENT a (id); 1548 1549 statement ok 1550 CREATE TABLE b2 ( 1551 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1552 ) INTERLEAVE IN PARENT a (id); 1553 1554 statement ok 1555 CREATE TABLE c1 ( 1556 id STRING PRIMARY KEY REFERENCES b1 ON UPDATE CASCADE 1557 ) INTERLEAVE IN PARENT b1 (id); 1558 1559 statement ok 1560 CREATE TABLE c2 ( 1561 id STRING PRIMARY KEY REFERENCES b1 ON UPDATE CASCADE 1562 ) INTERLEAVE IN PARENT b1 (id); 1563 1564 statement ok 1565 CREATE TABLE c3 ( 1566 id STRING PRIMARY KEY REFERENCES b2 ON UPDATE RESTRICT 1567 ) INTERLEAVE IN PARENT b2 (id); 1568 1569 statement ok 1570 INSERT INTO a VALUES ('original'), ('updated'); 1571 INSERT INTO b1 VALUES ('original'); 1572 INSERT INTO b2 VALUES ('original'); 1573 INSERT INTO c1 VALUES ('original'); 1574 INSERT INTO c2 VALUES ('original'); 1575 INSERT INTO c3 VALUES ('original'); 1576 1577 # ON UPDATE CASCADE from b1 downward 1578 statement ok 1579 UPDATE b1 SET id = 'updated' WHERE id = 'original'; 1580 1581 query T rowsort 1582 SELECT * FROM a; 1583 ---- 1584 original 1585 updated 1586 1587 query TTTTT 1588 SELECT 1589 (SELECT id FROM b1) 1590 ,(SELECT id FROM b2) 1591 ,(SELECT id FROM c1) 1592 ,(SELECT id FROM c2) 1593 ,(SELECT id FROM c3) 1594 ; 1595 ---- 1596 updated original updated updated original 1597 1598 # ON UPDATE CASCADE from a downward 1599 statement error foreign key violation: values \['original'\] in columns \[id\] referenced in table "c3" 1600 UPDATE a SET id = 'updated2' WHERE id = 'original'; 1601 1602 # Clean up after the test. 1603 statement ok 1604 DROP TABLE c3, c2, c1, b2, b1, a; 1605 1606 subtest UpdateCascade_SelfReference 1607 ### Self Reference Update Cascade 1608 # self <- self 1609 1610 statement ok 1611 CREATE TABLE self ( 1612 id INT PRIMARY KEY 1613 ,other_id INT REFERENCES self ON UPDATE CASCADE 1614 ); 1615 1616 statement ok 1617 INSERT INTO self VALUES (1, NULL); 1618 INSERT INTO self VALUES (2, 1); 1619 INSERT INTO self VALUES (3, 2); 1620 1621 query II rowsort 1622 SELECT * FROM self; 1623 ---- 1624 1 NULL 1625 2 1 1626 3 2 1627 1628 statement ok 1629 UPDATE self SET id = 4 WHERE id = 2; 1630 1631 query II rowsort 1632 SELECT * FROM self; 1633 ---- 1634 1 NULL 1635 4 1 1636 3 4 1637 1638 # Clean up after the test. 1639 statement ok 1640 DROP TABLE self; 1641 1642 subtest UpdateCascade_TwoTableLoop 1643 ### Delete cascade loop between two tables 1644 # loop_a <- loop_b 1645 # loop_b <- loop_a 1646 1647 statement ok 1648 CREATE TABLE loop_a ( 1649 id STRING PRIMARY KEY 1650 ); 1651 1652 statement ok 1653 CREATE TABLE loop_b ( 1654 id STRING PRIMARY KEY REFERENCES loop_a ON UPDATE CASCADE 1655 ); 1656 1657 statement ok 1658 INSERT INTO loop_a VALUES ('original'); 1659 INSERT INTO loop_b VALUES ('original'); 1660 1661 statement ok 1662 ALTER TABLE loop_a ADD CONSTRAINT cascade_update_constraint 1663 FOREIGN KEY (id) REFERENCES loop_b 1664 ON UPDATE CASCADE; 1665 1666 query TT 1667 SELECT 1668 (SELECT id FROM loop_a) 1669 ,(SELECT id FROM loop_b) 1670 ; 1671 ---- 1672 original original 1673 1674 statement ok 1675 UPDATE loop_a SET id = 'updated' WHERE id = 'original'; 1676 1677 query TT 1678 SELECT 1679 (SELECT id FROM loop_a) 1680 ,(SELECT id FROM loop_b) 1681 ; 1682 ---- 1683 updated updated 1684 1685 statement ok 1686 UPDATE loop_b SET id = 'updated2' WHERE id = 'updated'; 1687 1688 query TT 1689 SELECT 1690 (SELECT id FROM loop_a) 1691 ,(SELECT id FROM loop_b) 1692 ; 1693 ---- 1694 updated2 updated2 1695 1696 # Clean up after the test. 1697 statement ok 1698 DROP TABLE loop_a, loop_b; 1699 1700 subtest UpdateCascade_DoubleSelfReference 1701 ### Update cascade double self reference 1702 # self_x2 (x) <- (y) 1703 # self_x2 (y) <- (z) 1704 1705 statement ok 1706 CREATE TABLE self_x2 ( 1707 x STRING PRIMARY KEY 1708 ,y STRING UNIQUE REFERENCES self_x2(x) ON UPDATE CASCADE 1709 ,z STRING REFERENCES self_x2(y) ON UPDATE CASCADE 1710 ); 1711 1712 statement ok 1713 INSERT INTO self_x2 (x, y, z) VALUES ('pk1', NULL, NULL); 1714 INSERT INTO self_x2 (x, y, z) VALUES ('pk2', 'pk1', NULL); 1715 INSERT INTO self_x2 (x, y, z) VALUES ('pk3', 'pk2', 'pk1'); 1716 1717 # ON UPDATE CASCADE 1718 statement ok 1719 UPDATE self_x2 SET x = 'pk1-updated' WHERE x = 'pk1'; 1720 1721 statement ok 1722 UPDATE self_x2 SET x = 'pk2-updated' WHERE x = 'pk2'; 1723 1724 statement ok 1725 UPDATE self_x2 SET x = 'pk3-updated' WHERE x = 'pk3'; 1726 1727 query TTT rowsort 1728 SELECT * FROM self_x2 1729 ---- 1730 pk1-updated NULL NULL 1731 pk2-updated pk1-updated NULL 1732 pk3-updated pk2-updated pk1-updated 1733 1734 # Clean up after the test. 1735 statement ok 1736 DROP TABLE self_x2; 1737 1738 subtest UpdateCascade_TwoUpdates 1739 ### Update cascade two updates to the same table, then both of those cascade to 1740 # yet another table 1741 # a 1742 # / \ 1743 # b c 1744 # | | 1745 # | d 1746 # \ / 1747 # e 1748 # | 1749 # f 1750 statement ok 1751 CREATE TABLE a ( 1752 id STRING PRIMARY KEY 1753 ); 1754 1755 statement ok 1756 CREATE TABLE b ( 1757 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1758 ); 1759 1760 statement ok 1761 CREATE TABLE c ( 1762 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1763 ); 1764 1765 statement ok 1766 CREATE TABLE d ( 1767 id STRING PRIMARY KEY REFERENCES c ON UPDATE CASCADE 1768 ); 1769 1770 statement ok 1771 CREATE TABLE e ( 1772 b_id STRING PRIMARY KEY REFERENCES b ON UPDATE CASCADE 1773 ,d_id STRING UNIQUE REFERENCES d ON UPDATE CASCADE 1774 ); 1775 1776 statement ok 1777 CREATE TABLE f ( 1778 e_b_id STRING PRIMARY KEY REFERENCES e (b_id) ON UPDATE CASCADE 1779 ,e_d_id STRING REFERENCES e (d_id) ON UPDATE CASCADE 1780 ); 1781 1782 statement ok 1783 INSERT INTO a (id) VALUES ('original'); 1784 INSERT INTO b (id) VALUES ('original'); 1785 INSERT INTO c (id) VALUES ('original'); 1786 INSERT INTO d (id) VALUES ('original'); 1787 INSERT INTO e (b_id, d_id) VALUES ('original', 'original'); 1788 INSERT INTO f (e_b_id, e_d_id) VALUES ('original', 'original'); 1789 1790 statement ok 1791 UPDATE a SET id = 'updated' WHERE id = 'original'; 1792 1793 query TTTT 1794 SELECT 1795 (SELECT id FROM a) 1796 ,(SELECT id FROM b) 1797 ,(SELECT id FROM c) 1798 ,(SELECT id FROM d) 1799 ; 1800 ---- 1801 updated updated updated updated 1802 1803 query TT 1804 SELECT * FROM e 1805 ---- 1806 updated updated 1807 1808 query TT 1809 SELECT * FROM f 1810 ---- 1811 updated updated 1812 1813 # Clean up after the test. 1814 statement ok 1815 DROP TABLE f, e, d, c, b, a; 1816 1817 subtest UpdateCascade_TwoUpdatesReverse 1818 ### Update cascade two updates to the same table, then both of those cascade to 1819 # yet another table. 1820 # This is a similar test to UpdateCascade_TwoUpdates, but table d is now between 1821 # b and e instead of c and e. 1822 # a 1823 # / \ 1824 # b c 1825 # | | 1826 # d | 1827 # \ / 1828 # e 1829 # | 1830 # f 1831 statement ok 1832 CREATE TABLE a ( 1833 id STRING PRIMARY KEY 1834 ); 1835 1836 statement ok 1837 CREATE TABLE b ( 1838 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1839 ); 1840 1841 statement ok 1842 CREATE TABLE c ( 1843 id STRING PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1844 ); 1845 1846 statement ok 1847 CREATE TABLE d ( 1848 id STRING PRIMARY KEY REFERENCES b ON UPDATE CASCADE 1849 ); 1850 1851 statement ok 1852 CREATE TABLE e ( 1853 d_id STRING PRIMARY KEY REFERENCES d ON UPDATE CASCADE 1854 ,c_id STRING UNIQUE REFERENCES c ON UPDATE CASCADE 1855 ); 1856 1857 statement ok 1858 CREATE TABLE f ( 1859 e_d_id STRING PRIMARY KEY REFERENCES e (d_id) ON UPDATE CASCADE 1860 ,e_c_id STRING REFERENCES e (c_id) ON UPDATE CASCADE 1861 ); 1862 1863 statement ok 1864 INSERT INTO a (id) VALUES ('original'); 1865 INSERT INTO b (id) VALUES ('original'); 1866 INSERT INTO c (id) VALUES ('original'); 1867 INSERT INTO d (id) VALUES ('original'); 1868 INSERT INTO e (d_id, c_id) VALUES ('original', 'original'); 1869 INSERT INTO f (e_d_id, e_c_id) VALUES ('original', 'original'); 1870 1871 statement ok 1872 UPDATE a SET id = 'updated' WHERE id = 'original'; 1873 1874 query TTTT 1875 SELECT 1876 (SELECT id FROM a) 1877 ,(SELECT id FROM b) 1878 ,(SELECT id FROM c) 1879 ,(SELECT id FROM d) 1880 ; 1881 ---- 1882 updated updated updated updated 1883 1884 query TT 1885 SELECT * FROM e 1886 ---- 1887 updated updated 1888 1889 query TT 1890 SELECT * FROM f 1891 ---- 1892 updated updated 1893 1894 # Clean up after the test. 1895 statement ok 1896 DROP TABLE f, e, d, c, b, a; 1897 1898 subtest UpdateCascade_Multi 1899 # Ensures that the cascader can be reused. See #21563. 1900 1901 statement ok 1902 CREATE TABLE a ( 1903 id INT PRIMARY KEY 1904 ); 1905 CREATE TABLE b ( 1906 id INT PRIMARY KEY 1907 ,a_id INT REFERENCES a ON UPDATE CASCADE 1908 ) 1909 1910 statement ok 1911 INSERT INTO a VALUES (1), (2), (3); 1912 INSERT INTO b VALUES (1, 1), (2, NULL), (3, 2), (4, 1), (5, NULL); 1913 1914 statement ok 1915 UPDATE a SET id = id + 10; 1916 1917 query II rowsort 1918 SELECT id, a_id FROM b; 1919 ---- 1920 1 11 1921 2 NULL 1922 3 12 1923 4 11 1924 5 NULL 1925 1926 # Clean up. 1927 statement ok 1928 DROP TABLE b, a; 1929 1930 subtest UpdateCascade_WithChecks 1931 ### Check constraints on 3 levels, with each one being more restrictive. 1932 # A 1933 # | 1934 # B 1935 # | 1936 # C 1937 1938 statement ok 1939 CREATE TABLE a ( 1940 id INT PRIMARY KEY 1941 ); 1942 CREATE TABLE b ( 1943 id INT PRIMARY KEY REFERENCES a ON UPDATE CASCADE 1944 ,CONSTRAINT less_than_1000 CHECK (id < 1000) 1945 ); 1946 CREATE TABLE c ( 1947 id INT PRIMARY KEY REFERENCES b ON UPDATE CASCADE 1948 ,CONSTRAINT less_than_100 CHECK (id < 100) 1949 ,CONSTRAINT no_99 CHECK (id != 99) 1950 ); 1951 1952 statement ok 1953 INSERT INTO a VALUES (1), (2), (3); 1954 INSERT INTO b VALUES (1), (2); 1955 INSERT INTO c VALUES (1); 1956 1957 # Perform a standard cascading update. 1958 statement ok 1959 UPDATE a SET id = id*10; 1960 1961 query TI rowsort 1962 SELECT name, id FROM ( 1963 SELECT 'a' AS name, id FROM a 1964 UNION ALL 1965 SELECT 'b' AS name, id FROM b 1966 UNION ALL 1967 SELECT 'c' AS name, id FROM c 1968 ) 1969 ORDER BY name, id 1970 ; 1971 ---- 1972 a 10 1973 a 20 1974 a 30 1975 b 10 1976 b 20 1977 c 10 1978 1979 # Perform another cascading update that should fail c.less_than_100. 1980 statement error pq: failed to satisfy CHECK constraint \(id < 100\) 1981 UPDATE a SET id = id*10; 1982 1983 # Perform another cascading update that should fail b.less_than_1000 or 1984 # c.less_than_100. The order of which check fails first is not deterministic. 1985 statement error pq: failed to satisfy CHECK constraint \(id < (100|1000)\) 1986 UPDATE a SET id = id*1000; 1987 1988 # Perform another cascading update that should fail b.less_than_1000. 1989 statement error pq: failed to satisfy CHECK constraint \(id < 1000\) 1990 UPDATE a SET id = id*1000 WHERE id > 10; 1991 1992 # And check another direct cascading constraint c.no_99. 1993 statement error pq: failed to satisfy CHECK constraint \(id != 99\) 1994 UPDATE a SET id = 99 WHERE id = 10; 1995 1996 # But it should still be possible to cascade an update that doesn't hit c. 1997 # First check against c.no_99. 1998 statement ok 1999 UPDATE a SET id = 99 WHERE id = 20; 2000 2001 # And for c.less_then_100. 2002 statement ok 2003 UPDATE a SET id = 999 WHERE id = 99; 2004 2005 # And update a value that isn't cascaded at all. 2006 statement ok 2007 UPDATE a SET id = 100000 WHERE id = 30; 2008 2009 query TI rowsort 2010 SELECT name, id FROM ( 2011 SELECT 'a' AS name, id FROM a 2012 UNION ALL 2013 SELECT 'b' AS name, id FROM b 2014 UNION ALL 2015 SELECT 'c' AS name, id FROM c 2016 ) 2017 ORDER BY name, id 2018 ; 2019 ---- 2020 a 10 2021 a 999 2022 a 100000 2023 b 10 2024 b 999 2025 c 10 2026 2027 # Clean up. 2028 statement ok 2029 DROP TABLE c, b, a; 2030 2031 subtest UpdateCascade_WithChecksMultiColumn 2032 ### Check constraints on 3 levels using multi-column constraints. 2033 # A 2034 # | 2035 # B 2036 # | 2037 # C 2038 2039 statement ok 2040 CREATE TABLE a ( 2041 id INT PRIMARY KEY 2042 ); 2043 CREATE TABLE b ( 2044 id1 INT PRIMARY KEY REFERENCES a ON UPDATE CASCADE 2045 ,id2 INT UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE 2046 ,CONSTRAINT less_than_1000 CHECK (id1 + id2 < 1000) 2047 ); 2048 CREATE TABLE c ( 2049 id1 INT PRIMARY KEY REFERENCES b(id1) ON UPDATE CASCADE 2050 ,id2 INT UNIQUE NOT NULL REFERENCES b(id2) ON UPDATE CASCADE 2051 ,CONSTRAINT less_than_100 CHECK (id1 + id2 < 100) 2052 ); 2053 2054 statement ok 2055 INSERT INTO a VALUES (1), (2), (3), (4), (5); 2056 INSERT INTO b VALUES (1, 1), (2, 2), (3, 4); 2057 INSERT INTO c VALUES (2, 1), (1, 2); 2058 2059 # Perform a standard cascading update. 2060 statement ok 2061 UPDATE a SET id = id*10; 2062 2063 query TII rowsort 2064 SELECT name, id1, id2 FROM ( 2065 SELECT 'a' AS name, id AS id1, 0 AS id2 FROM a 2066 UNION ALL 2067 SELECT 'b' AS name, id1, id2 FROM b 2068 UNION ALL 2069 SELECT 'c' AS name, id1, id2 FROM c 2070 ) ORDER BY name, id1, id2 2071 ; 2072 ---- 2073 a 10 0 2074 a 20 0 2075 a 30 0 2076 a 40 0 2077 a 50 0 2078 b 10 10 2079 b 20 20 2080 b 30 40 2081 c 10 20 2082 c 20 10 2083 2084 # Try to update one value to fail c.less_than_100 2085 statement error pq: failed to satisfy CHECK constraint \(\(id1 \+ id2\) < 100\) 2086 UPDATE a SET id = id*10; 2087 2088 # Try to update one value to fail c.less_than_100 or c.less_than_1000 2089 statement error pq: failed to satisfy CHECK constraint \(\(id1 \+ id2\) < 100\) 2090 UPDATE a SET id = id*10; 2091 2092 # Try to update one value to fail c.less_than_100 2093 statement error pq: failed to satisfy CHECK constraint \(\(id1 \+ id2\) < 1000\) 2094 UPDATE a SET id = 1000 WHERE id = 30; 2095 2096 statement error pq: failed to satisfy CHECK constraint \(\(id1 \+ id2\) < 1000\) 2097 UPDATE a SET id = 1000 WHERE id = 40; 2098 2099 # Update a value that would fail the check if it was cascaded, but wasn't. 2100 statement ok 2101 UPDATE a SET id = 100000 WHERE id = 50; 2102 2103 # Clean up. 2104 statement ok 2105 DROP TABLE c, b, a; 2106 2107 subtest DeleteSetNull_Basic1 2108 ### Basic Delete Set Null 2109 # a 2110 # // \\ 2111 # / | | \ 2112 # b1 b2 b3 b4 2113 2114 statement ok 2115 CREATE TABLE a ( 2116 id STRING PRIMARY KEY 2117 ); 2118 CREATE TABLE b1 ( 2119 id STRING PRIMARY KEY 2120 ,delete_set_null STRING REFERENCES a ON DELETE SET NULL 2121 ); 2122 CREATE TABLE b2 ( 2123 id STRING PRIMARY KEY 2124 ,delete_set_null STRING REFERENCES a ON DELETE SET NULL 2125 ); 2126 CREATE TABLE b3 ( 2127 id STRING PRIMARY KEY 2128 ,delete_set_null STRING REFERENCES a ON DELETE SET NULL 2129 ); 2130 CREATE TABLE b4 ( 2131 id STRING PRIMARY KEY 2132 ,delete_set_null STRING REFERENCES a ON DELETE SET NULL 2133 ); 2134 2135 statement ok 2136 INSERT INTO a VALUES ('delete_me'), ('untouched'); 2137 INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched'); 2138 INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'delete_me'); 2139 INSERT INTO b3 VALUES ('b3-pk1', 'delete_me'), ('b3-pk2', 'untouched'); 2140 INSERT INTO b4 VALUES ('b4-pk1', 'delete_me'), ('b4-pk2', 'delete_me'); 2141 2142 # ON DELETE CASCADE 2143 statement ok 2144 DELETE FROM a WHERE id = 'delete_me'; 2145 2146 query TT rowsort 2147 SELECT id, delete_set_null FROM b1 2148 UNION ALL 2149 SELECT id, delete_set_null FROM b2 2150 UNION ALL 2151 SELECT id, delete_set_null FROM b3 2152 UNION ALL 2153 SELECT id, delete_set_null FROM b4 2154 ; 2155 ---- 2156 b1-pk1 untouched 2157 b1-pk2 untouched 2158 b2-pk1 untouched 2159 b2-pk2 NULL 2160 b3-pk1 NULL 2161 b3-pk2 untouched 2162 b4-pk1 NULL 2163 b4-pk2 NULL 2164 2165 # Clean up after the test. 2166 statement ok 2167 DROP TABLE b4, b3, b2, b1, a; 2168 2169 subtest DeleteSetNull_Basic2 2170 ### Basic Delete Set Null 2171 # a 2172 # / \ 2173 # b1 b2 2174 # / \ \ 2175 # c1 c2 c3 2176 2177 statement ok 2178 CREATE TABLE a ( 2179 id STRING PRIMARY KEY 2180 ); 2181 CREATE TABLE b1 ( 2182 id STRING PRIMARY KEY 2183 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 2184 ); 2185 CREATE TABLE b2 ( 2186 id STRING PRIMARY KEY 2187 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 2188 ); 2189 CREATE TABLE c1 ( 2190 id STRING PRIMARY KEY 2191 ,delete_set_null STRING REFERENCES b1 ON DELETE SET NULL 2192 ); 2193 CREATE TABLE c2 ( 2194 id STRING PRIMARY KEY 2195 ,delete_set_null STRING REFERENCES b1 ON DELETE SET NULL 2196 ); 2197 CREATE TABLE c3 ( 2198 id STRING PRIMARY KEY 2199 ,delete_set_null STRING REFERENCES b2 ON DELETE SET NULL 2200 ); 2201 2202 statement ok 2203 INSERT INTO a VALUES ('a-pk1'); 2204 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1'), ('b1-pk2', 'a-pk1'); 2205 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1'), ('b2-pk2', 'a-pk1'); 2206 INSERT INTO c1 VALUES 2207 ('c1-pk1-b1-pk1', 'b1-pk1') 2208 ,('c1-pk2-b1-pk1', 'b1-pk1') 2209 ,('c1-pk3-b1-pk2', 'b1-pk2') 2210 ,('c1-pk4-b1-pk2', 'b1-pk2') 2211 ; 2212 INSERT INTO c2 VALUES 2213 ('c2-pk1-b1-pk1', 'b1-pk1') 2214 ,('c2-pk2-b1-pk1', 'b1-pk1') 2215 ,('c2-pk3-b1-pk2', 'b1-pk2') 2216 ,('c2-pk4-b1-pk2', 'b1-pk2') 2217 ; 2218 INSERT INTO c3 VALUES 2219 ('c3-pk1-b2-pk1', 'b2-pk1') 2220 ,('c3-pk2-b2-pk1', 'b2-pk1') 2221 ,('c3-pk3-b2-pk2', 'b2-pk2') 2222 ,('c3-pk4-b2-pk2', 'b2-pk2') 2223 ; 2224 2225 # This query expects to cascade the deletion in a into b1 and b2, but not into 2226 # the c tables which have ON DELETE SET NULL instead. 2227 statement ok 2228 DELETE FROM a WHERE id = 'a-pk1'; 2229 2230 query TT rowsort 2231 SELECT id, 'empty' FROM a 2232 UNION ALL 2233 SELECT id, delete_cascade FROM b1 2234 UNION ALL 2235 SELECT id, delete_cascade FROM b2 2236 UNION ALL 2237 SELECT id, delete_set_null FROM c1 2238 UNION ALL 2239 SELECT id, delete_set_null FROM c2 2240 UNION ALL 2241 SELECT id, delete_set_null FROM c3 2242 ; 2243 ---- 2244 c1-pk1-b1-pk1 NULL 2245 c1-pk2-b1-pk1 NULL 2246 c1-pk3-b1-pk2 NULL 2247 c1-pk4-b1-pk2 NULL 2248 c2-pk1-b1-pk1 NULL 2249 c2-pk2-b1-pk1 NULL 2250 c2-pk3-b1-pk2 NULL 2251 c2-pk4-b1-pk2 NULL 2252 c3-pk1-b2-pk1 NULL 2253 c3-pk2-b2-pk1 NULL 2254 c3-pk3-b2-pk2 NULL 2255 c3-pk4-b2-pk2 NULL 2256 2257 statement ok 2258 TRUNCATE c3, c2, c1, b2, b1, a; 2259 2260 # Clean up after the test. 2261 statement ok 2262 DROP TABLE c3, c2, c1, b2, b1, a; 2263 2264 subtest DeleteSetNull_ToUpdateCascade 2265 ### Cascade a delete in table a, to set null in table b, to an on update cascade 2266 # of that null into table c 2267 # a 2268 # | 2269 # b 2270 # | 2271 # c 2272 2273 statement ok 2274 CREATE TABLE a ( 2275 id STRING PRIMARY KEY 2276 ); 2277 CREATE TABLE b ( 2278 id STRING PRIMARY KEY 2279 ,a_id STRING UNIQUE REFERENCES a ON DELETE SET NULL 2280 ); 2281 CREATE TABLE c ( 2282 id STRING PRIMARY KEY 2283 ,b_a_id STRING REFERENCES b(a_id) ON UPDATE CASCADE 2284 ); 2285 2286 statement oK 2287 INSERT INTO a VALUES ('delete-me'), ('untouched'); 2288 INSERT INTO b VALUES ('b1', 'delete-me'), ('b2', 'untouched'); 2289 INSERT INTO c VALUES 2290 ('c1-b1', 'delete-me') 2291 ,('c2-b1', 'delete-me') 2292 ,('c3-b2', 'untouched') 2293 ,('c4-b2', 'untouched') 2294 ; 2295 2296 statement ok 2297 DELETE FROM a WHERE id = 'delete-me'; 2298 2299 query I 2300 SELECT count(*) FROM a; 2301 ---- 2302 1 2303 2304 query TT rowsort 2305 SELECT id, a_id FROM b 2306 UNION ALL 2307 SELECT id, b_a_id FROM c 2308 ; 2309 ---- 2310 b1 NULL 2311 b2 untouched 2312 c1-b1 NULL 2313 c2-b1 NULL 2314 c3-b2 untouched 2315 c4-b2 untouched 2316 2317 # Clean up after the test. 2318 statement ok 2319 DROP TABLE c, b, a; 2320 2321 subtest DeleteSetNull_ToUpdateCascadeNotNull 2322 ### Cascade a delete in table a, to set null in table b, to an on update cascade 2323 # of that null into table c, but table c's column is NOT NULL 2324 # a 2325 # | 2326 # b 2327 # | 2328 # c 2329 2330 statement ok 2331 CREATE TABLE a ( 2332 id STRING PRIMARY KEY 2333 ); 2334 CREATE TABLE b ( 2335 id STRING PRIMARY KEY 2336 ,a_id STRING UNIQUE REFERENCES a ON DELETE SET NULL 2337 ); 2338 CREATE TABLE c ( 2339 id STRING PRIMARY KEY 2340 ,b_a_id STRING NOT NULL REFERENCES b(a_id) ON UPDATE CASCADE 2341 ); 2342 2343 statement oK 2344 INSERT INTO a VALUES ('delete-me'), ('untouched'); 2345 INSERT INTO b VALUES ('b1', 'delete-me'), ('b2', 'untouched'); 2346 INSERT INTO c VALUES 2347 ('c1-b1', 'delete-me') 2348 ,('c2-b1', 'delete-me') 2349 ,('c3-b2', 'untouched') 2350 ,('c4-b2', 'untouched') 2351 ; 2352 2353 statement error pq: cannot cascade a null value into "test.public.c.b_a_id" as it violates a NOT NULL constraint 2354 DELETE FROM a WHERE id = 'delete-me'; 2355 2356 # Clean up after the test. 2357 statement ok 2358 DROP TABLE c, b, a; 2359 2360 subtest UpdateSetNull_Basic1 2361 ### Basic Update Set Null 2362 # a 2363 # // \\ 2364 # / | | \ 2365 # b1 b2 b3 b4 2366 2367 statement ok 2368 CREATE TABLE a ( 2369 id STRING PRIMARY KEY 2370 ); 2371 CREATE TABLE b1 ( 2372 id STRING PRIMARY KEY 2373 ,update_set_null STRING REFERENCES a ON UPDATE SET NULL 2374 ); 2375 CREATE TABLE b2 ( 2376 id STRING PRIMARY KEY 2377 ,update_set_null STRING REFERENCES a ON UPDATE SET NULL 2378 ); 2379 CREATE TABLE b3 ( 2380 id STRING PRIMARY KEY 2381 ,update_set_null STRING REFERENCES a ON UPDATE SET NULL 2382 ); 2383 CREATE TABLE b4 ( 2384 id STRING PRIMARY KEY 2385 ,update_set_null STRING REFERENCES a ON UPDATE SET NULL 2386 ); 2387 2388 statement ok 2389 INSERT INTO a VALUES ('original'), ('untouched'); 2390 INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched'); 2391 INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'original'); 2392 INSERT INTO b3 VALUES ('b3-pk1', 'original'), ('b3-pk2', 'untouched'); 2393 INSERT INTO b3 VALUES ('b4-pk1', 'original'), ('b4-pk2', 'original'); 2394 2395 # ON UPDATE CASCADE 2396 statement ok 2397 UPDATE a SET id = 'updated' WHERE id = 'original'; 2398 2399 query TT rowsort 2400 SELECT id, update_set_null FROM b1 2401 UNION ALL 2402 SELECT id, update_set_null FROM b2 2403 UNION ALL 2404 SELECT id, update_set_null FROM b3 2405 UNION ALL 2406 SELECT id, update_set_null FROM b4 2407 ; 2408 ---- 2409 b1-pk1 untouched 2410 b1-pk2 untouched 2411 b2-pk1 untouched 2412 b2-pk2 NULL 2413 b3-pk1 NULL 2414 b3-pk2 untouched 2415 b4-pk1 NULL 2416 b4-pk2 NULL 2417 2418 # Clean up after the test. 2419 statement ok 2420 DROP TABLE b4, b3, b2, b1, a; 2421 2422 subtest UpdateSetNull_Basic2 2423 ### Basic Update Set Null 2424 # a 2425 # / \ 2426 # b1 b2 2427 # / \ \ 2428 # c1 c2 c3 2429 2430 statement ok 2431 CREATE TABLE a ( 2432 id STRING PRIMARY KEY 2433 ); 2434 CREATE TABLE b1 ( 2435 id STRING PRIMARY KEY 2436 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE 2437 ); 2438 CREATE TABLE b2 ( 2439 id STRING PRIMARY KEY 2440 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE 2441 ); 2442 CREATE TABLE c1 ( 2443 id STRING PRIMARY KEY 2444 ,update_set_null STRING REFERENCES b1(update_cascade) ON UPDATE SET NULL 2445 ); 2446 CREATE TABLE c2 ( 2447 id STRING PRIMARY KEY 2448 ,update_set_null STRING REFERENCES b1(update_cascade) ON UPDATE SET NULL 2449 ); 2450 CREATE TABLE c3 ( 2451 id STRING PRIMARY KEY 2452 ,update_set_null STRING REFERENCES b2(update_cascade) ON UPDATE SET NULL 2453 ); 2454 2455 statement ok 2456 INSERT INTO a VALUES ('original'), ('untouched'); 2457 INSERT INTO b1 VALUES ('b1-pk1', 'original'), ('b1-pk2', 'untouched'); 2458 INSERT INTO b2 VALUES ('b2-pk1', 'original'), ('b2-pk2', 'untouched'); 2459 INSERT INTO c1 VALUES 2460 ('c1-pk1-b1-pk1', 'original') 2461 ,('c1-pk2-b1-pk1', 'original') 2462 ,('c1-pk3-b1-pk2', 'untouched') 2463 ,('c1-pk4-b1-pk2', 'untouched') 2464 ; 2465 INSERT INTO c2 VALUES 2466 ('c2-pk1-b1-pk1', 'original') 2467 ,('c2-pk2-b1-pk1', 'original') 2468 ,('c2-pk3-b1-pk2', 'untouched') 2469 ,('c2-pk4-b1-pk2', 'untouched') 2470 ; 2471 INSERT INTO c3 VALUES 2472 ('c3-pk1-b2-pk1', 'original') 2473 ,('c3-pk2-b2-pk1', 'original') 2474 ,('c3-pk3-b2-pk2', 'untouched') 2475 ,('c3-pk4-b2-pk2', 'untouched') 2476 ; 2477 2478 # ON UPDATE CASCADE 2479 statement ok 2480 UPDATE a SET id = 'updated' WHERE id = 'original'; 2481 2482 query TT rowsort 2483 SELECT id, update_cascade FROM b1 2484 UNION ALL 2485 SELECT id, update_cascade FROM b2 2486 UNION ALL 2487 SELECT id, update_set_null FROM c1 2488 UNION ALL 2489 SELECT id, update_set_null FROM c2 2490 UNION ALL 2491 SELECT id, update_set_null FROM c3 2492 ; 2493 ---- 2494 b1-pk1 updated 2495 b1-pk2 untouched 2496 b2-pk1 updated 2497 b2-pk2 untouched 2498 c1-pk1-b1-pk1 NULL 2499 c1-pk2-b1-pk1 NULL 2500 c1-pk3-b1-pk2 untouched 2501 c1-pk4-b1-pk2 untouched 2502 c2-pk1-b1-pk1 NULL 2503 c2-pk2-b1-pk1 NULL 2504 c2-pk3-b1-pk2 untouched 2505 c2-pk4-b1-pk2 untouched 2506 c3-pk1-b2-pk1 NULL 2507 c3-pk2-b2-pk1 NULL 2508 c3-pk3-b2-pk2 untouched 2509 c3-pk4-b2-pk2 untouched 2510 2511 # Clean up after the test. 2512 statement ok 2513 DROP TABLE c3, c2, c1, b2, b1, a; 2514 2515 subtest UpdateSetNull_ToUpdateCascade 2516 ### Cascade an update in table a, to set null in table b, to an on update 2517 # cascade of that null into table c. 2518 # a 2519 # | 2520 # b 2521 # | 2522 # c 2523 2524 statement ok 2525 CREATE TABLE a ( 2526 id STRING PRIMARY KEY 2527 ); 2528 CREATE TABLE b ( 2529 id STRING PRIMARY KEY 2530 ,a_id STRING UNIQUE REFERENCES a ON UPDATE SET NULL 2531 ); 2532 CREATE TABLE c ( 2533 id STRING PRIMARY KEY 2534 ,b_a_id STRING REFERENCES b(a_id) ON UPDATE CASCADE 2535 ); 2536 2537 statement oK 2538 INSERT INTO a VALUES ('original'), ('untouched'); 2539 INSERT INTO b VALUES ('b1', 'original'), ('b2', 'untouched'); 2540 INSERT INTO c VALUES 2541 ('c1-b1', 'original') 2542 ,('c2-b1', 'original') 2543 ,('c3-b2', 'untouched') 2544 ,('c4-b2', 'untouched') 2545 ; 2546 2547 statement ok 2548 UPDATE a SET id = 'updated' WHERE id = 'original'; 2549 2550 query TT rowsort 2551 SELECT id, a_id FROM b 2552 UNION ALL 2553 SELECT id, b_a_id FROM c 2554 ---- 2555 b1 NULL 2556 b2 untouched 2557 c1-b1 NULL 2558 c2-b1 NULL 2559 c3-b2 untouched 2560 c4-b2 untouched 2561 2562 # Clean up after the test. 2563 statement ok 2564 DROP TABLE c, b, a; 2565 2566 subtest UpdateSetNull_ToUpdateCascadeNotNull 2567 ### Cascade a delete in table a, to set null in table b, to an on update cascade 2568 # of that null into table c, but table c's column is NOT NULL. 2569 # a 2570 # | 2571 # b 2572 # | 2573 # c 2574 2575 statement ok 2576 CREATE TABLE a ( 2577 id STRING PRIMARY KEY 2578 ); 2579 CREATE TABLE b ( 2580 id STRING PRIMARY KEY 2581 ,a_id STRING UNIQUE REFERENCES a ON UPDATE SET NULL 2582 ); 2583 CREATE TABLE c ( 2584 id STRING PRIMARY KEY 2585 ,b_a_id STRING NOT NULL REFERENCES b(a_id) ON UPDATE CASCADE 2586 ); 2587 2588 statement oK 2589 INSERT INTO a VALUES ('original'), ('untouched'); 2590 INSERT INTO b VALUES ('b1', 'original'), ('b2', 'untouched'); 2591 INSERT INTO c VALUES 2592 ('c1-b1', 'original') 2593 ,('c2-b1', 'original') 2594 ,('c3-b2', 'untouched') 2595 ,('c4-b2', 'untouched') 2596 ; 2597 2598 statement error pq: cannot cascade a null value into "test.public.c.b_a_id" as it violates a NOT NULL constraint 2599 UPDATE a SET id = 'updated' WHERE id = 'original'; 2600 2601 # Clean up after the test. 2602 statement ok 2603 DROP TABLE c, b, a; 2604 2605 ############## 2606 2607 subtest DeleteSetDefault_Basic1 2608 ### Basic Delete Set Default 2609 # a 2610 # // \\ 2611 # / | | \ 2612 # b1 b2 b3 b4 2613 2614 statement ok 2615 CREATE TABLE a ( 2616 id STRING PRIMARY KEY 2617 ); 2618 CREATE TABLE b1 ( 2619 id STRING PRIMARY KEY 2620 ,delete_set_default STRING DEFAULT 'b1-default' REFERENCES a ON DELETE SET DEFAULT 2621 ); 2622 CREATE TABLE b2 ( 2623 id STRING PRIMARY KEY 2624 ,delete_set_default STRING DEFAULT 'b2-default' REFERENCES a ON DELETE SET DEFAULT 2625 ); 2626 CREATE TABLE b3 ( 2627 id STRING PRIMARY KEY 2628 ,delete_set_default STRING DEFAULT 'b3-default' REFERENCES a ON DELETE SET DEFAULT 2629 ); 2630 CREATE TABLE b4 ( 2631 id STRING PRIMARY KEY 2632 ,delete_set_default STRING DEFAULT 'b4-default' REFERENCES a ON DELETE SET DEFAULT 2633 ); 2634 2635 statement ok 2636 INSERT INTO a VALUES ('delete_me'), ('untouched'), ('b1-default'), ('b2-default'), ('b3-default'), ('b4-default'); 2637 INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched'); 2638 INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'delete_me'); 2639 INSERT INTO b3 VALUES ('b3-pk1', 'delete_me'), ('b3-pk2', 'untouched'); 2640 INSERT INTO b4 VALUES ('b4-pk1', 'delete_me'), ('b4-pk2', 'delete_me'); 2641 2642 # ON DELETE CASCADE 2643 statement ok 2644 DELETE FROM a WHERE id = 'delete_me'; 2645 2646 query TT rowsort 2647 SELECT id, delete_set_default FROM b1 2648 UNION ALL 2649 SELECT id, delete_set_default FROM b2 2650 UNION ALL 2651 SELECT id, delete_set_default FROM b3 2652 UNION ALL 2653 SELECT id, delete_set_default FROM b4 2654 ; 2655 ---- 2656 b1-pk1 untouched 2657 b1-pk2 untouched 2658 b2-pk1 untouched 2659 b2-pk2 b2-default 2660 b3-pk1 b3-default 2661 b3-pk2 untouched 2662 b4-pk1 b4-default 2663 b4-pk2 b4-default 2664 2665 # Clean up after the test. 2666 statement ok 2667 DROP TABLE b4, b3, b2, b1, a; 2668 2669 subtest DeleteSetDefault_Basic1_WrongDefault 2670 ### The same test as DeleteSetDefault_Basic1 but a default is set to a value 2671 # that does not exist in the table above it. 2672 # a 2673 # // \\ 2674 # / | | \ 2675 # b1 b2 b3 b4 2676 2677 statement ok 2678 CREATE TABLE a ( 2679 id STRING PRIMARY KEY 2680 ); 2681 CREATE TABLE b1 ( 2682 id STRING PRIMARY KEY 2683 ,delete_set_default STRING DEFAULT 'b1-def' REFERENCES a ON DELETE SET DEFAULT 2684 ); 2685 CREATE TABLE b2 ( 2686 id STRING PRIMARY KEY 2687 ,delete_set_default STRING DEFAULT 'b2-def' REFERENCES a ON DELETE SET DEFAULT 2688 ); 2689 CREATE TABLE b3 ( 2690 id STRING PRIMARY KEY 2691 ,delete_set_default STRING DEFAULT 'missing' REFERENCES a ON DELETE SET DEFAULT 2692 ); 2693 CREATE TABLE b4 ( 2694 id STRING PRIMARY KEY 2695 ,delete_set_default STRING DEFAULT 'b4-def' REFERENCES a ON DELETE SET DEFAULT 2696 ); 2697 2698 statement ok 2699 INSERT INTO a VALUES ('delete_me'), ('untouched'), ('b1-def'), ('b2-def'), ('b3-def'), ('b4-def'); 2700 INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched'); 2701 INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'delete_me'); 2702 INSERT INTO b3 VALUES ('b3-pk1', 'delete_me'), ('b3-pk2', 'untouched'); 2703 INSERT INTO b4 VALUES ('b4-pk1', 'delete_me'), ('b4-pk2', 'delete_me'); 2704 2705 # ON DELETE CASCADE, which should fail since the value 'missing' is not in a. 2706 statement error pq: foreign key violation: value \['missing'\] not found in a@primary \[id\] 2707 DELETE FROM a WHERE id = 'delete_me'; 2708 2709 # Clean up after the test. 2710 statement ok 2711 DROP TABLE b4, b3, b2, b1, a; 2712 2713 subtest DeleteSetDefault_Basic2 2714 ### Basic Delete Set Null via an ON DELETE CASCADE 2715 # a 2716 # / \ 2717 # b1 b2 2718 # / \ \ 2719 # c1 c2 c3 2720 2721 statement ok 2722 CREATE TABLE a ( 2723 id STRING PRIMARY KEY 2724 ); 2725 CREATE TABLE b1 ( 2726 id STRING PRIMARY KEY 2727 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 2728 ); 2729 CREATE TABLE b2 ( 2730 id STRING PRIMARY KEY 2731 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 2732 ); 2733 CREATE TABLE c1 ( 2734 id STRING PRIMARY KEY 2735 ,delete_set_default STRING DEFAULT 'b1-default' REFERENCES b1 ON DELETE SET DEFAULT 2736 ); 2737 CREATE TABLE c2 ( 2738 id STRING PRIMARY KEY 2739 ,delete_set_default STRING DEFAULT 'b1-default' REFERENCES b1 ON DELETE SET DEFAULT 2740 ); 2741 CREATE TABLE c3 ( 2742 id STRING PRIMARY KEY 2743 ,delete_set_default STRING DEFAULT 'b2-default' REFERENCES b2 ON DELETE SET DEFAULT 2744 ); 2745 2746 statement ok 2747 INSERT INTO a VALUES ('a-pk1'), ('a-default'); 2748 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1'), ('b1-pk2', 'a-pk1'), ('b1-default', 'a-default'); 2749 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1'), ('b2-pk2', 'a-pk1'), ('b2-default', 'a-default'); 2750 INSERT INTO c1 VALUES 2751 ('c1-pk1-b1-pk1', 'b1-pk1') 2752 ,('c1-pk2-b1-pk1', 'b1-pk1') 2753 ,('c1-pk3-b1-pk2', 'b1-pk2') 2754 ,('c1-pk4-b1-pk2', 'b1-pk2') 2755 ; 2756 INSERT INTO c2 VALUES 2757 ('c2-pk1-b1-pk1', 'b1-pk1') 2758 ,('c2-pk2-b1-pk1', 'b1-pk1') 2759 ,('c2-pk3-b1-pk2', 'b1-pk2') 2760 ,('c2-pk4-b1-pk2', 'b1-pk2') 2761 ; 2762 INSERT INTO c3 VALUES 2763 ('c3-pk1-b2-pk1', 'b2-pk1') 2764 ,('c3-pk2-b2-pk1', 'b2-pk1') 2765 ,('c3-pk3-b2-pk2', 'b2-pk2') 2766 ,('c3-pk4-b2-pk2', 'b2-pk2') 2767 ; 2768 2769 # This query expects to cascade the deletion in a into b1 and b2, but not into 2770 # the c tables which have ON DELETE SET DEFAULT instead. 2771 statement ok 2772 DELETE FROM a WHERE id = 'a-pk1'; 2773 2774 query TT rowsort 2775 SELECT id, 'empty' FROM a 2776 UNION ALL 2777 SELECT id, delete_cascade FROM b1 2778 UNION ALL 2779 SELECT id, delete_cascade FROM b2 2780 UNION ALL 2781 SELECT id, delete_set_default FROM c1 2782 UNION ALL 2783 SELECT id, delete_set_default FROM c2 2784 UNION ALL 2785 SELECT id, delete_set_default FROM c3 2786 ; 2787 ---- 2788 a-default empty 2789 b1-default a-default 2790 b2-default a-default 2791 c1-pk1-b1-pk1 b1-default 2792 c1-pk2-b1-pk1 b1-default 2793 c1-pk3-b1-pk2 b1-default 2794 c1-pk4-b1-pk2 b1-default 2795 c2-pk1-b1-pk1 b1-default 2796 c2-pk2-b1-pk1 b1-default 2797 c2-pk3-b1-pk2 b1-default 2798 c2-pk4-b1-pk2 b1-default 2799 c3-pk1-b2-pk1 b2-default 2800 c3-pk2-b2-pk1 b2-default 2801 c3-pk3-b2-pk2 b2-default 2802 c3-pk4-b2-pk2 b2-default 2803 2804 statement ok 2805 TRUNCATE c3, c2, c1, b2, b1, a; 2806 2807 # Clean up after the test. 2808 statement ok 2809 DROP TABLE c3, c2, c1, b2, b1, a; 2810 2811 subtest DeleteSetDefault_Basic2_WrongDefault 2812 ### The same test as DeleteSetDefault_Basic2 but a default is set to a value 2813 # that does not exist in the table above it. 2814 # a 2815 # / \ 2816 # b1 b2 2817 # / \ \ 2818 # c1 c2 c3 2819 2820 statement ok 2821 CREATE TABLE a ( 2822 id STRING PRIMARY KEY 2823 ); 2824 CREATE TABLE b1 ( 2825 id STRING PRIMARY KEY 2826 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 2827 ); 2828 CREATE TABLE b2 ( 2829 id STRING PRIMARY KEY 2830 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE 2831 ); 2832 CREATE TABLE c1 ( 2833 id STRING PRIMARY KEY 2834 ,delete_set_default STRING DEFAULT 'b1-default' REFERENCES b1 ON DELETE SET DEFAULT 2835 ); 2836 CREATE TABLE c2 ( 2837 id STRING PRIMARY KEY 2838 ,delete_set_default STRING DEFAULT 'missing' REFERENCES b1 ON DELETE SET DEFAULT 2839 ); 2840 CREATE TABLE c3 ( 2841 id STRING PRIMARY KEY 2842 ,delete_set_default STRING DEFAULT 'b2-default' REFERENCES b2 ON DELETE SET DEFAULT 2843 ); 2844 2845 statement ok 2846 INSERT INTO a VALUES ('a-pk1'), ('a-default'); 2847 INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1'), ('b1-pk2', 'a-pk1'), ('b1-default', 'a-default'); 2848 INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1'), ('b2-pk2', 'a-pk1'), ('b2-default', 'a-default'); 2849 INSERT INTO c1 VALUES 2850 ('c1-pk1-b1-pk1', 'b1-pk1') 2851 ,('c1-pk2-b1-pk1', 'b1-pk1') 2852 ,('c1-pk3-b1-pk2', 'b1-pk2') 2853 ,('c1-pk4-b1-pk2', 'b1-pk2') 2854 ; 2855 INSERT INTO c2 VALUES 2856 ('c2-pk1-b1-pk1', 'b1-pk1') 2857 ,('c2-pk2-b1-pk1', 'b1-pk1') 2858 ,('c2-pk3-b1-pk2', 'b1-pk2') 2859 ,('c2-pk4-b1-pk2', 'b1-pk2') 2860 ; 2861 INSERT INTO c3 VALUES 2862 ('c3-pk1-b2-pk1', 'b2-pk1') 2863 ,('c3-pk2-b2-pk1', 'b2-pk1') 2864 ,('c3-pk3-b2-pk2', 'b2-pk2') 2865 ,('c3-pk4-b2-pk2', 'b2-pk2') 2866 ; 2867 2868 # This query expects to cascade the deletion in a into b1 and b2, but not into 2869 # the c tables which have ON DELETE SET DEFAULT instead. And ultimately fail 2870 # since the default value 'missing' is not present in b1. 2871 statement error pq: foreign key violation: value \['missing'\] not found in b1@primary \[id\] 2872 DELETE FROM a WHERE id = 'a-pk1'; 2873 2874 # Clean up after the test. 2875 statement ok 2876 DROP TABLE c3, c2, c1, b2, b1, a; 2877 2878 subtest DeleteSetDefault_ToUpdateCascade 2879 ### Cascade a delete in table a, to a SET DEFAULT in table b, to an ON UPDATE 2880 # CASCADE of that default value into table c. 2881 # a 2882 # | 2883 # b 2884 # | 2885 # c 2886 2887 statement ok 2888 CREATE TABLE a ( 2889 id STRING PRIMARY KEY 2890 ); 2891 CREATE TABLE b ( 2892 id STRING PRIMARY KEY 2893 ,a_id STRING DEFAULT 'default' UNIQUE REFERENCES a ON DELETE SET DEFAULT 2894 ); 2895 CREATE TABLE c ( 2896 id STRING PRIMARY KEY 2897 ,b_a_id STRING REFERENCES b(a_id) ON UPDATE CASCADE 2898 ); 2899 2900 statement oK 2901 INSERT INTO a VALUES ('delete-me'), ('untouched'), ('default'); 2902 INSERT INTO b VALUES ('b1', 'delete-me'), ('b2', 'untouched'); 2903 INSERT INTO c VALUES 2904 ('c1-b1', 'delete-me') 2905 ,('c2-b1', 'delete-me') 2906 ,('c3-b2', 'untouched') 2907 ,('c4-b2', 'untouched') 2908 ; 2909 2910 statement ok 2911 DELETE FROM a WHERE id = 'delete-me'; 2912 2913 query T rowsort 2914 SELECT id FROM a; 2915 ---- 2916 default 2917 untouched 2918 2919 query TT rowsort 2920 SELECT id, a_id FROM b 2921 UNION ALL 2922 SELECT id, b_a_id FROM c 2923 ; 2924 ---- 2925 b1 default 2926 b2 untouched 2927 c1-b1 default 2928 c2-b1 default 2929 c3-b2 untouched 2930 c4-b2 untouched 2931 2932 # Clean up after the test. 2933 statement ok 2934 DROP TABLE c, b, a; 2935 2936 subtest DeleteSetDefault_ToUpdateCascade 2937 ### Cascade a delete in table a, to a SET DEFAULT in table b (of a NULL), to an 2938 # ON UPDATE CASCADE of that null into table c. 2939 # a 2940 # | 2941 # b 2942 # | 2943 # c 2944 2945 statement ok 2946 CREATE TABLE a ( 2947 id STRING PRIMARY KEY 2948 ); 2949 CREATE TABLE b ( 2950 id STRING PRIMARY KEY 2951 ,a_id STRING DEFAULT NULL UNIQUE REFERENCES a ON DELETE SET DEFAULT 2952 ); 2953 CREATE TABLE c ( 2954 id STRING PRIMARY KEY 2955 ,b_a_id STRING REFERENCES b(a_id) ON UPDATE CASCADE 2956 ); 2957 2958 statement oK 2959 INSERT INTO a VALUES ('delete-me'), ('untouched'); 2960 INSERT INTO b VALUES ('b1', 'delete-me'), ('b2', 'untouched'); 2961 INSERT INTO c VALUES 2962 ('c1-b1', 'delete-me') 2963 ,('c2-b1', 'delete-me') 2964 ,('c3-b2', 'untouched') 2965 ,('c4-b2', 'untouched') 2966 ; 2967 2968 # Cascade the delete in a to the SET DEFAULT in b to the CASCADE in c 2969 statement ok 2970 DELETE FROM a WHERE id = 'delete-me'; 2971 2972 query TT rowsort 2973 SELECT id, a_id FROM b 2974 UNION ALL 2975 SELECT id, b_a_id FROM c 2976 ; 2977 ---- 2978 b1 NULL 2979 b2 untouched 2980 c1-b1 NULL 2981 c2-b1 NULL 2982 c3-b2 untouched 2983 c4-b2 untouched 2984 2985 # Clean up after the test. 2986 statement ok 2987 DROP TABLE c, b, a; 2988 2989 subtest DeleteSetDefault_ToUpdateCascadeNotNull 2990 ### Cascade a delete in table a, to a SET DEFAULT in table b (of a NULL), to an 2991 # on update cascade of that null into table c, but table c's column is NOT NULL. 2992 # a 2993 # | 2994 # b 2995 # | 2996 # c 2997 2998 statement ok 2999 CREATE TABLE a ( 3000 id STRING PRIMARY KEY 3001 ); 3002 CREATE TABLE b ( 3003 id STRING PRIMARY KEY 3004 ,a_id STRING DEFAULT NULL UNIQUE REFERENCES a ON DELETE SET DEFAULT 3005 ); 3006 CREATE TABLE c ( 3007 id STRING PRIMARY KEY 3008 ,b_a_id STRING NOT NULL REFERENCES b(a_id) ON UPDATE CASCADE 3009 ); 3010 3011 statement oK 3012 INSERT INTO a VALUES ('delete-me'), ('untouched'); 3013 INSERT INTO b VALUES ('b1', 'delete-me'), ('b2', 'untouched'); 3014 INSERT INTO c VALUES 3015 ('c1-b1', 'delete-me') 3016 ,('c2-b1', 'delete-me') 3017 ,('c3-b2', 'untouched') 3018 ,('c4-b2', 'untouched') 3019 ; 3020 3021 # Cascade the delete in a to the SET DEFAULT in b to the CASCADE in c which 3022 # should violate the NOT NULL in c.b_a_id. 3023 statement error pq: cannot cascade a null value into "test.public.c.b_a_id" as it violates a NOT NULL constraint 3024 DELETE FROM a WHERE id = 'delete-me'; 3025 3026 # Clean up after the test. 3027 statement ok 3028 DROP TABLE c, b, a; 3029 3030 subtest DefaultSetDefault_Unique 3031 ### Have a SET DEFAULT break a uniqueness constraint. 3032 # a 3033 # | 3034 # b 3035 3036 statement ok 3037 CREATE TABLE a ( 3038 id STRING PRIMARY KEY 3039 ); 3040 CREATE TABLE b ( 3041 id STRING PRIMARY KEY 3042 ,a_id STRING DEFAULT 'default' UNIQUE REFERENCES a ON DELETE SET DEFAULT 3043 ); 3044 3045 statement oK 3046 INSERT INTO a VALUES ('original'), ('default'); 3047 INSERT INTO b VALUES ('b1', 'original'), ('b2', 'default'); 3048 3049 statement error pq: duplicate key value \(a_id\)=\('default'\) violates unique constraint "b_a_id_key" 3050 DELETE FROM a WHERE id = 'original'; 3051 3052 # Clean up after the test. 3053 statement ok 3054 DROP TABLE b, a; 3055 3056 subtest UpdateSetDefault_Basic1 3057 ### Basic Update Set Default 3058 # a 3059 # // \\ 3060 # / | | \ 3061 # b1 b2 b3 b4 3062 3063 statement ok 3064 CREATE TABLE a ( 3065 id STRING PRIMARY KEY 3066 ); 3067 CREATE TABLE b1 ( 3068 id STRING PRIMARY KEY 3069 ,update_set_null STRING DEFAULT 'b1-default' REFERENCES a ON UPDATE SET DEFAULT 3070 ); 3071 CREATE TABLE b2 ( 3072 id STRING PRIMARY KEY 3073 ,update_set_null STRING DEFAULT 'b2-default' REFERENCES a ON UPDATE SET DEFAULT 3074 ); 3075 CREATE TABLE b3 ( 3076 id STRING PRIMARY KEY 3077 ,update_set_null STRING DEFAULT 'b3-default' REFERENCES a ON UPDATE SET DEFAULT 3078 ); 3079 CREATE TABLE b4 ( 3080 id STRING PRIMARY KEY 3081 ,update_set_null STRING DEFAULT 'b4-default' REFERENCES a ON UPDATE SET DEFAULT 3082 ); 3083 3084 statement ok 3085 INSERT INTO a VALUES ('original'), ('untouched'), ('b1-default'), ('b2-default'), ('b3-default'), ('b4-default'); 3086 INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched'); 3087 INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'original'); 3088 INSERT INTO b3 VALUES ('b3-pk1', 'original'), ('b3-pk2', 'untouched'); 3089 INSERT INTO b3 VALUES ('b4-pk1', 'original'), ('b4-pk2', 'original'); 3090 3091 # ON UPDATE CASCADE 3092 statement ok 3093 UPDATE a SET id = 'updated' WHERE id = 'original'; 3094 3095 query TT rowsort 3096 SELECT id, update_set_null FROM b1 3097 UNION ALL 3098 SELECT id, update_set_null FROM b2 3099 UNION ALL 3100 SELECT id, update_set_null FROM b3 3101 UNION ALL 3102 SELECT id, update_set_null FROM b4 3103 ; 3104 ---- 3105 b1-pk1 untouched 3106 b1-pk2 untouched 3107 b2-pk1 untouched 3108 b2-pk2 b2-default 3109 b3-pk1 b3-default 3110 b3-pk2 untouched 3111 b4-pk1 b3-default 3112 b4-pk2 b3-default 3113 3114 # Clean up after the test. 3115 statement ok 3116 DROP TABLE b4, b3, b2, b1, a; 3117 3118 subtest UpdateSetDefault_Basic1_WrongDefault 3119 ### Basic Update Set Default 3120 # a 3121 # // \\ 3122 # / | | \ 3123 # b1 b2 b3 b4 3124 3125 statement ok 3126 CREATE TABLE a ( 3127 id STRING PRIMARY KEY 3128 ); 3129 CREATE TABLE b1 ( 3130 id STRING PRIMARY KEY 3131 ,update_set_null STRING DEFAULT 'b1-default' REFERENCES a ON UPDATE SET DEFAULT 3132 ); 3133 CREATE TABLE b2 ( 3134 id STRING PRIMARY KEY 3135 ,update_set_null STRING DEFAULT 'b2-default' REFERENCES a ON UPDATE SET DEFAULT 3136 ); 3137 CREATE TABLE b3 ( 3138 id STRING PRIMARY KEY 3139 ,update_set_null STRING DEFAULT 'missing' REFERENCES a ON UPDATE SET DEFAULT 3140 ); 3141 CREATE TABLE b4 ( 3142 id STRING PRIMARY KEY 3143 ,update_set_null STRING DEFAULT 'b4-default' REFERENCES a ON UPDATE SET DEFAULT 3144 ); 3145 3146 statement ok 3147 INSERT INTO a VALUES ('original'), ('untouched'), ('b1-default'), ('b2-default'), ('b3-default'), ('b4-default'); 3148 INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched'); 3149 INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'original'); 3150 INSERT INTO b3 VALUES ('b3-pk1', 'original'), ('b3-pk2', 'untouched'); 3151 INSERT INTO b3 VALUES ('b4-pk1', 'original'), ('b4-pk2', 'original'); 3152 3153 # ON UPDATE CASCADE, which should fail since the value 'missing' is not in a. 3154 statement error pq: foreign key violation: value \['missing'\] not found in a@primary \[id\] 3155 UPDATE a SET id = 'updated' WHERE id = 'original'; 3156 3157 # Clean up after the test. 3158 statement ok 3159 DROP TABLE b4, b3, b2, b1, a; 3160 3161 subtest UpdateSetDefault_Basic2 3162 ### Basic UPDATE SET DEFAULT via an UPDATE CASCADE 3163 # a 3164 # / \ 3165 # b1 b2 3166 # / \ \ 3167 # c1 c2 c3 3168 3169 statement ok 3170 CREATE TABLE a ( 3171 id STRING PRIMARY KEY 3172 ); 3173 CREATE TABLE b1 ( 3174 id STRING PRIMARY KEY 3175 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE 3176 ); 3177 CREATE TABLE b2 ( 3178 id STRING PRIMARY KEY 3179 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE 3180 ); 3181 CREATE TABLE c1 ( 3182 id STRING PRIMARY KEY 3183 ,update_set_null STRING DEFAULT 'b1-default' REFERENCES b1(update_cascade) ON UPDATE SET DEFAULT 3184 ); 3185 CREATE TABLE c2 ( 3186 id STRING PRIMARY KEY 3187 ,update_set_null STRING DEFAULT 'b1-default' REFERENCES b1(update_cascade) ON UPDATE SET DEFAULT 3188 ); 3189 CREATE TABLE c3 ( 3190 id STRING PRIMARY KEY 3191 ,update_set_null STRING DEFAULT 'b2-default' REFERENCES b2(update_cascade) ON UPDATE SET DEFAULT 3192 ); 3193 3194 statement ok 3195 INSERT INTO a VALUES ('original'), ('untouched'), ('b1-default'), ('b2-default'); 3196 INSERT INTO b1 VALUES ('b1-pk1', 'original'), ('b1-pk2', 'untouched'), ('b1-default', 'b1-default'); 3197 INSERT INTO b2 VALUES ('b2-pk1', 'original'), ('b2-pk2', 'untouched'), ('b2-default', 'b2-default'); 3198 INSERT INTO c1 VALUES 3199 ('c1-pk1-b1-pk1', 'original') 3200 ,('c1-pk2-b1-pk1', 'original') 3201 ,('c1-pk3-b1-pk2', 'untouched') 3202 ,('c1-pk4-b1-pk2', 'untouched') 3203 ; 3204 INSERT INTO c2 VALUES 3205 ('c2-pk1-b1-pk1', 'original') 3206 ,('c2-pk2-b1-pk1', 'original') 3207 ,('c2-pk3-b1-pk2', 'untouched') 3208 ,('c2-pk4-b1-pk2', 'untouched') 3209 ; 3210 INSERT INTO c3 VALUES 3211 ('c3-pk1-b2-pk1', 'original') 3212 ,('c3-pk2-b2-pk1', 'original') 3213 ,('c3-pk3-b2-pk2', 'untouched') 3214 ,('c3-pk4-b2-pk2', 'untouched') 3215 ; 3216 3217 # ON UPDATE CASCADE all b1 originals should now be updated, and all c1 3218 # originals should now be set to defaults. 3219 statement ok 3220 UPDATE a SET id = 'updated' WHERE id = 'original'; 3221 3222 query TT rowsort 3223 SELECT id, update_cascade FROM b1 3224 UNION ALL 3225 SELECT id, update_cascade FROM b2 3226 UNION ALL 3227 SELECT id, update_set_null FROM c1 3228 UNION ALL 3229 SELECT id, update_set_null FROM c2 3230 UNION ALL 3231 SELECT id, update_set_null FROM c3 3232 ; 3233 ---- 3234 b1-default b1-default 3235 b1-pk1 updated 3236 b1-pk2 untouched 3237 b2-default b2-default 3238 b2-pk1 updated 3239 b2-pk2 untouched 3240 c1-pk1-b1-pk1 b1-default 3241 c1-pk2-b1-pk1 b1-default 3242 c1-pk3-b1-pk2 untouched 3243 c1-pk4-b1-pk2 untouched 3244 c2-pk1-b1-pk1 b1-default 3245 c2-pk2-b1-pk1 b1-default 3246 c2-pk3-b1-pk2 untouched 3247 c2-pk4-b1-pk2 untouched 3248 c3-pk1-b2-pk1 b2-default 3249 c3-pk2-b2-pk1 b2-default 3250 c3-pk3-b2-pk2 untouched 3251 c3-pk4-b2-pk2 untouched 3252 3253 # Clean up after the test. 3254 statement ok 3255 DROP TABLE c3, c2, c1, b2, b1, a; 3256 3257 subtest UpdateSetDefault_Basic2_WrongDefault 3258 ### Basic UPDATE SET DEFAULT via an UPDATE CASCADE 3259 # a 3260 # / \ 3261 # b1 b2 3262 # / \ \ 3263 # c1 c2 c3 3264 3265 statement ok 3266 CREATE TABLE a ( 3267 id STRING PRIMARY KEY 3268 ); 3269 CREATE TABLE b1 ( 3270 id STRING PRIMARY KEY 3271 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE 3272 ); 3273 CREATE TABLE b2 ( 3274 id STRING PRIMARY KEY 3275 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE 3276 ); 3277 CREATE TABLE c1 ( 3278 id STRING PRIMARY KEY 3279 ,update_set_null STRING DEFAULT 'b1-default' REFERENCES b1(update_cascade) ON UPDATE SET DEFAULT 3280 ); 3281 CREATE TABLE c2 ( 3282 id STRING PRIMARY KEY 3283 ,update_set_null STRING DEFAULT 'missing' REFERENCES b1(update_cascade) ON UPDATE SET DEFAULT 3284 ); 3285 CREATE TABLE c3 ( 3286 id STRING PRIMARY KEY 3287 ,update_set_null STRING DEFAULT 'b2-default' REFERENCES b2(update_cascade) ON UPDATE SET DEFAULT 3288 ); 3289 3290 statement ok 3291 INSERT INTO a VALUES ('original'), ('untouched'), ('b1-default'), ('b2-default'); 3292 INSERT INTO b1 VALUES ('b1-pk1', 'original'), ('b1-pk2', 'untouched'), ('b1-default', 'b1-default'); 3293 INSERT INTO b2 VALUES ('b2-pk1', 'original'), ('b2-pk2', 'untouched'), ('b2-default', 'b2-default'); 3294 INSERT INTO c1 VALUES 3295 ('c1-pk1-b1-pk1', 'original') 3296 ,('c1-pk2-b1-pk1', 'original') 3297 ,('c1-pk3-b1-pk2', 'untouched') 3298 ,('c1-pk4-b1-pk2', 'untouched') 3299 ; 3300 INSERT INTO c2 VALUES 3301 ('c2-pk1-b1-pk1', 'original') 3302 ,('c2-pk2-b1-pk1', 'original') 3303 ,('c2-pk3-b1-pk2', 'untouched') 3304 ,('c2-pk4-b1-pk2', 'untouched') 3305 ; 3306 INSERT INTO c3 VALUES 3307 ('c3-pk1-b2-pk1', 'original') 3308 ,('c3-pk2-b2-pk1', 'original') 3309 ,('c3-pk3-b2-pk2', 'untouched') 3310 ,('c3-pk4-b2-pk2', 'untouched') 3311 ; 3312 3313 # ON UPDATE CASCADE all b tables into the c tables, but fail due to a default 3314 # value that does not exist. 3315 statement error pq: foreign key violation: value \['missing'\] not found in b1@b1_update_cascade_key \[update_cascade\] 3316 UPDATE a SET id = 'updated' WHERE id = 'original'; 3317 3318 # Clean up after the test. 3319 statement ok 3320 DROP TABLE c3, c2, c1, b2, b1, a; 3321 3322 subtest UpdateSetDefault_ToUpdateCascade 3323 ### Cascade an update in table a, to SET DEFAULT in table b, to an UPDATE 3324 # CASCADE of that default into table c. 3325 # a 3326 # | 3327 # b 3328 # | 3329 # c 3330 3331 statement ok 3332 CREATE TABLE a ( 3333 id STRING PRIMARY KEY 3334 ); 3335 CREATE TABLE b ( 3336 id STRING PRIMARY KEY 3337 ,a_id STRING UNIQUE DEFAULT 'default' REFERENCES a ON UPDATE SET DEFAULT 3338 ); 3339 CREATE TABLE c ( 3340 id STRING PRIMARY KEY 3341 ,b_a_id STRING REFERENCES b(a_id) ON UPDATE CASCADE 3342 ); 3343 3344 statement oK 3345 INSERT INTO a VALUES ('original'), ('untouched'), ('default'); 3346 INSERT INTO b VALUES ('b1', 'original'), ('b2', 'untouched'); 3347 INSERT INTO c VALUES 3348 ('c1-b1', 'original') 3349 ,('c2-b1', 'original') 3350 ,('c3-b2', 'untouched') 3351 ,('c4-b2', 'untouched') 3352 ; 3353 3354 statement ok 3355 UPDATE a SET id = 'updated' WHERE id = 'original'; 3356 3357 query TT rowsort 3358 SELECT id, a_id FROM b 3359 UNION ALL 3360 SELECT id, b_a_id FROM c 3361 ---- 3362 b1 default 3363 b2 untouched 3364 c1-b1 default 3365 c2-b1 default 3366 c3-b2 untouched 3367 c4-b2 untouched 3368 3369 # Clean up after the test. 3370 statement ok 3371 DROP TABLE c, b, a; 3372 3373 subtest UpdateSetDefault_ToUpdateCascadeNotNull 3374 ### Cascade a update in table a, to SET DEFAULT in table b, but that default is 3375 # a null. Then to an ON UPDATE CASCADE of that null into table c, but table c's 3376 # column is NOT NULL. 3377 # a 3378 # | 3379 # b 3380 # | 3381 # c 3382 3383 statement ok 3384 CREATE TABLE a ( 3385 id STRING PRIMARY KEY 3386 ); 3387 CREATE TABLE b ( 3388 id STRING PRIMARY KEY 3389 ,a_id STRING DEFAULT NULL UNIQUE REFERENCES a ON UPDATE SET DEFAULT 3390 ); 3391 CREATE TABLE c ( 3392 id STRING PRIMARY KEY 3393 ,b_a_id STRING NOT NULL REFERENCES b(a_id) ON UPDATE CASCADE 3394 ); 3395 3396 statement oK 3397 INSERT INTO a VALUES ('original'), ('untouched'), ('default'); 3398 INSERT INTO b VALUES ('b1', 'original'), ('b2', 'untouched'); 3399 INSERT INTO c VALUES 3400 ('c1-b1', 'original') 3401 ,('c2-b1', 'original') 3402 ,('c3-b2', 'untouched') 3403 ,('c4-b2', 'untouched') 3404 ; 3405 3406 statement error pq: cannot cascade a null value into "test.public.c.b_a_id" as it violates a NOT NULL constraint 3407 UPDATE a SET id = 'updated' WHERE id = 'original'; 3408 3409 # Clean up after the test. 3410 statement ok 3411 DROP TABLE c, b, a; 3412 3413 subtest UpdateSetDefault_Unique 3414 ### Have a SET DEFAULT break a uniqueness constraint. 3415 # a 3416 # | 3417 # b 3418 3419 statement ok 3420 CREATE TABLE a ( 3421 id STRING PRIMARY KEY 3422 ); 3423 CREATE TABLE b ( 3424 id STRING PRIMARY KEY 3425 ,a_id STRING DEFAULT 'default' UNIQUE REFERENCES a ON UPDATE SET DEFAULT 3426 ); 3427 3428 statement oK 3429 INSERT INTO a VALUES ('original'), ('default'); 3430 INSERT INTO b VALUES ('b1', 'original'), ('b2', 'default'); 3431 3432 statement error pq: duplicate key value \(a_id\)=\('default'\) violates unique constraint "b_a_id_key" 3433 UPDATE a SET id = 'updated' WHERE id = 'original'; 3434 3435 # Clean up after the test. 3436 statement ok 3437 DROP TABLE b, a; 3438 3439 subtest NoNullCascades_NonComposite 3440 3441 # First with a non-composite index 3442 statement ok 3443 CREATE TABLE IF NOT EXISTS example ( 3444 a INT UNIQUE, 3445 b INT REFERENCES example (a) ON DELETE CASCADE ON UPDATE CASCADE 3446 ); 3447 3448 statement ok 3449 INSERT INTO example VALUES (20, NULL); 3450 INSERT INTO example VALUES (30, 20); 3451 INSERT INTO example VALUES (NULL, 30); 3452 3453 statement ok 3454 DELETE FROM example where a = 30; 3455 3456 query II colnames 3457 SELECT * FROM example; 3458 ---- 3459 a b 3460 20 NULL 3461 3462 # Clean up after the test. 3463 statement ok 3464 DROP TABLE example; 3465 3466 subtest NoNullCascades_MatchSimple 3467 # Note that these matches use a composite index with MATCH SIMPLE. 3468 3469 statement ok 3470 CREATE TABLE a ( 3471 x INT 3472 ,y INT 3473 ,UNIQUE (x, y) 3474 ); 3475 3476 statement ok 3477 CREATE TABLE b ( 3478 x INT 3479 ,y INT 3480 ,INDEX (x, y) 3481 ,FOREIGN KEY (x, y) REFERENCES a (x, y) ON DELETE CASCADE ON UPDATE CASCADE 3482 ); 3483 3484 statement ok 3485 INSERT INTO a VALUES (NULL, NULL), (NULL, 1), (2, NULL), (3, 3); 3486 INSERT INTO b VALUES (NULL, NULL), (NULL, 1), (2, NULL), (3, 3); 3487 3488 # What we start with. 3489 query II colnames 3490 SELECT * FROM b ORDER BY x, y; 3491 ---- 3492 x y 3493 NULL NULL 3494 NULL 1 3495 2 NULL 3496 3 3 3497 3498 # Remove everything from a. x=3,y=3 should be the only cascading values. 3499 statement ok 3500 DELETE FROM a; 3501 3502 # A match consisting of only NULLs is not cascaded. 3503 query II colnames 3504 SELECT * FROM b ORDER BY x, y; 3505 ---- 3506 x y 3507 NULL NULL 3508 NULL 1 3509 2 NULL 3510 3511 # Make sure that a is now empty. 3512 query II colnames 3513 SELECT * FROM a ORDER BY x; 3514 ---- 3515 x y 3516 3517 # Now try the same with inserts 3518 statement ok 3519 TRUNCATE b, a; 3520 INSERT INTO a VALUES (NULL, NULL), (NULL, 4), (5, NULL), (6, 6); 3521 INSERT INTO b VALUES (NULL, NULL), (NULL, 4), (5, NULL), (6, 6); 3522 3523 # For this, only x=6,y=6 should cascade. 3524 statement ok 3525 UPDATE a SET y = y*10 WHERE y > 0; 3526 UPDATE a SET x = x*10 WHERE x > 0; 3527 3528 query II colnames 3529 SELECT * FROM b ORDER BY x, y; 3530 ---- 3531 x y 3532 NULL NULL 3533 NULL 4 3534 5 NULL 3535 60 60 3536 3537 # Clean up after the test. 3538 statement ok 3539 DROP TABLE b, a; 3540 3541 subtest NoNullCascades_MatchFull 3542 # Note that these matches use a composite index with MATCH FULL. 3543 3544 statement ok 3545 CREATE TABLE a ( 3546 x INT 3547 ,y INT 3548 ,UNIQUE (x, y) 3549 ); 3550 3551 statement ok 3552 CREATE TABLE b ( 3553 x INT 3554 ,y INT 3555 ,INDEX (x, y) 3556 ,FOREIGN KEY (x, y) REFERENCES a (x, y) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE 3557 ); 3558 3559 statement ok 3560 INSERT INTO a VALUES (NULL, NULL), (NULL, 1), (2, NULL), (3, 3); 3561 INSERT INTO b VALUES (NULL, NULL), (3, 3); 3562 3563 # What we start with 3564 query II colnames 3565 SELECT * FROM b ORDER BY x, y; 3566 ---- 3567 x y 3568 NULL NULL 3569 3 3 3570 3571 # Remove everything from a. x=3,y=3 should be the only cascading value. 3572 statement ok 3573 DELETE FROM a; 3574 3575 # A match consisting of only NULLs is not cascaded. 3576 query II colnames 3577 SELECT * FROM b ORDER BY x, y; 3578 ---- 3579 x y 3580 NULL NULL 3581 3582 # Just make sure that a is empty. 3583 query II colnames 3584 SELECT * FROM a ORDER BY x; 3585 ---- 3586 x y 3587 3588 # Now try the same with updates. 3589 statement ok 3590 TRUNCATE b, a; 3591 INSERT INTO a VALUES (NULL, NULL), (NULL, 4), (5, NULL), (6, 6); 3592 INSERT INTO b VALUES (NULL, NULL), (6, 6); 3593 3594 # For this test, only x=6,y=6 should cascade. 3595 statement ok 3596 UPDATE a SET y = y*10 WHERE y > 0; 3597 UPDATE a SET x = x*10 WHERE x > 0; 3598 3599 query II colnames 3600 SELECT * FROM b ORDER BY x, y; 3601 ---- 3602 x y 3603 NULL NULL 3604 60 60 3605 3606 # Clean up after the test. 3607 statement ok 3608 DROP TABLE b, a; 3609 3610 subtest MatchFullViaCascade 3611 # Test to ensure that setting a null value cannot cascade into a MATCH FULL fk 3612 # reference. 3613 3614 statement ok 3615 CREATE TABLE a ( 3616 x INT 3617 ,y INT 3618 ,UNIQUE (x, y) 3619 ); 3620 3621 statement ok 3622 CREATE TABLE b ( 3623 x INT DEFAULT 1 3624 ,y INT DEFAULT NULL 3625 ,UNIQUE (x, y) 3626 ,FOREIGN KEY (x, y) REFERENCES a (x, y) MATCH SIMPLE ON DELETE SET DEFAULT ON UPDATE SET DEFAULT 3627 ); 3628 3629 statement ok 3630 CREATE TABLE c ( 3631 x INT 3632 ,y INT 3633 ,UNIQUE (x, y) 3634 ,FOREIGN KEY (x, y) REFERENCES b (x, y) MATCH FULL ON UPDATE CASCADE 3635 ); 3636 3637 statement ok 3638 INSERT INTO a VALUES (2,2); 3639 INSERT INTO b VALUES (2,2); 3640 INSERT INTO c VALUES (2,2); 3641 3642 # C's MATCH FULL should reject this. 3643 statement error MATCH FULL does not allow mixing of null and nonnull values 3644 DELETE FROM a; 3645 3646 # Again, for the same reason. 3647 statement error MATCH FULL does not allow mixing of null and nonnull values 3648 UPDATE a SET x = 3 WHERE x = 2; 3649 3650 # Ensure nothing has changed. 3651 query II colnames 3652 SELECT * from a; 3653 ---- 3654 x y 3655 2 2 3656 3657 statement ok 3658 DROP TABLE c, b, a; 3659 3660 # Now repeat the same test but make it ON DELETE SET NULL and ON UPDATE CASCADE. 3661 3662 statement ok 3663 CREATE TABLE a ( 3664 x INT 3665 ,y INT 3666 ,UNIQUE (x, y) 3667 ); 3668 3669 statement ok 3670 CREATE TABLE b ( 3671 x INT 3672 ,y INT 3673 ,UNIQUE (x, y) 3674 ,FOREIGN KEY (x, y) REFERENCES a (x, y) MATCH SIMPLE ON DELETE SET NULL ON UPDATE CASCADE 3675 ); 3676 3677 statement ok 3678 CREATE TABLE c ( 3679 x INT 3680 ,y INT 3681 ,UNIQUE (x, y) 3682 ,FOREIGN KEY (x, y) REFERENCES b (x, y) MATCH FULL ON UPDATE CASCADE 3683 ); 3684 3685 statement ok 3686 INSERT INTO a VALUES (2,2), (3,3); 3687 INSERT INTO b VALUES (2,2), (3,3); 3688 INSERT INTO c VALUES (2,2), (3,3); 3689 3690 # This will populate b and c with (null, null) where (2,2) used to be. 3691 statement ok 3692 DELETE FROM a WHERE x = 2; 3693 3694 # We can't cascade the null value though to c, since it would break MATCH FULL. 3695 statement error MATCH FULL does not allow mixing of null and nonnull values 3696 UPDATE a SET x = NULL WHERE x = 3; 3697 3698 statement error MATCH FULL does not allow mixing of null and nonnull values 3699 UPDATE a SET y = NULL WHERE y = 3; 3700 3701 # Now update (3,3) to (null, null) which should cascade. 3702 statement ok 3703 UPDATE a SET x = NULL, y = NULL WHERE x = 3; 3704 3705 query II colnames 3706 SELECT * from c; 3707 ---- 3708 x y 3709 NULL NULL 3710 NULL NULL 3711 3712 statement ok 3713 DROP TABLE c, b, a; 3714 3715 # Make sure the CHECK constraint is checked when a self-referencing cascade 3716 # modifies the original table (#42117). 3717 subtest SelfReferencingCheckFail 3718 3719 statement ok 3720 CREATE TABLE self_ab ( 3721 a INT UNIQUE, 3722 b INT DEFAULT 1 CHECK (b != 1), 3723 INDEX (b) 3724 ) 3725 3726 statement ok 3727 INSERT INTO self_ab VALUES (1, 2), (2, 2) 3728 3729 statement ok 3730 ALTER TABLE self_ab ADD CONSTRAINT fk FOREIGN KEY (b) REFERENCES self_ab (a) ON UPDATE SET DEFAULT 3731 3732 # This update would cause the references to 2 to get reset to the default, 3733 # which violates the check. 3734 statement error failed to satisfy CHECK constraint \(b != 1\) 3735 UPDATE self_ab SET a = 3 WHERE a = 2 3736 3737 # Make sure the check fails when we apply the same update through a cascade. 3738 statement ok 3739 CREATE TABLE self_ab_parent (p INT PRIMARY KEY) 3740 3741 statement ok 3742 INSERT INTO self_ab_parent VALUES (1), (2) 3743 3744 statement ok 3745 ALTER TABLE self_ab ADD CONSTRAINT fk2 FOREIGN KEY (a) REFERENCES self_ab_parent (p) ON UPDATE CASCADE 3746 3747 statement error failed to satisfy CHECK constraint \(b != 1\) 3748 UPDATE self_ab_parent SET p = 3 WHERE p = 2 3749 3750 # Clean up. 3751 statement ok 3752 DROP TABLE self_ab, self_ab_parent 3753 3754 # Extra test for self referencing foreign keys with set default. 3755 subtest SelfReferencingSetDefault 3756 3757 statement ok 3758 CREATE TABLE self_abcd ( 3759 a INT DEFAULT 2, 3760 b INT DEFAULT 2, 3761 c INT DEFAULT 2, 3762 d INT DEFAULT 2, 3763 INDEX (c), 3764 INDEX (d), 3765 PRIMARY KEY (a), FAMILY (a, b, c, d) 3766 ) 3767 3768 statement ok 3769 INSERT INTO self_abcd VALUES (1, 2, 3, 4), (4, 1, 2, 3), (3, 4, 1, 2), (2, 3, 4, 1) 3770 3771 statement ok 3772 ALTER TABLE self_abcd ADD CONSTRAINT fk1 FOREIGN KEY (c) REFERENCES self_abcd(a) ON UPDATE SET DEFAULT; 3773 ALTER TABLE self_abcd ADD CONSTRAINT fk2 FOREIGN KEY (d) REFERENCES self_abcd(a) ON UPDATE SET DEFAULT 3774 3775 statement ok 3776 UPDATE self_abcd SET a = 5 WHERE a = 1 3777 3778 query IIII 3779 SELECT * FROM self_abcd ORDER BY (a, b, c, d) 3780 ---- 3781 2 3 4 2 3782 3 4 2 2 3783 4 1 2 3 3784 5 2 3 4 3785 3786 # Clean up. 3787 statement ok 3788 DROP TABLE self_abcd