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