github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/optbuilder/testdata/fk-on-delete-cascade (about)

     1  exec-ddl
     2  CREATE TABLE parent (p INT PRIMARY KEY)
     3  ----
     4  
     5  exec-ddl
     6  CREATE TABLE child (c INT PRIMARY KEY, p INT NOT NULL REFERENCES parent(p) ON DELETE CASCADE)
     7  ----
     8  
     9  # Simple cascade.
    10  build-cascades
    11  DELETE FROM parent WHERE p > 1
    12  ----
    13  root
    14   ├── delete parent
    15   │    ├── columns: <none>
    16   │    ├── fetch columns: p:2
    17   │    ├── input binding: &1
    18   │    ├── cascades
    19   │    │    └── fk_p_ref_parent
    20   │    └── select
    21   │         ├── columns: p:2!null
    22   │         ├── scan parent
    23   │         │    └── columns: p:2!null
    24   │         └── filters
    25   │              └── p:2 > 1
    26   └── cascade
    27        └── delete child
    28             ├── columns: <none>
    29             ├── fetch columns: c:5 child.p:6
    30             └── semi-join (hash)
    31                  ├── columns: c:5!null child.p:6!null
    32                  ├── scan child
    33                  │    └── columns: c:5!null child.p:6!null
    34                  ├── with-scan &1
    35                  │    ├── columns: p:7!null
    36                  │    └── mapping:
    37                  │         └──  parent.p:2 => p:7
    38                  └── filters
    39                       └── child.p:6 = p:7
    40  
    41  exec-ddl
    42  CREATE TABLE grandchild (g INT PRIMARY KEY, c INT REFERENCES child(c) ON DELETE CASCADE)
    43  ----
    44  
    45  # Two-level cascade.
    46  build-cascades
    47  DELETE FROM parent WHERE p > 1
    48  ----
    49  root
    50   ├── delete parent
    51   │    ├── columns: <none>
    52   │    ├── fetch columns: p:2
    53   │    ├── input binding: &1
    54   │    ├── cascades
    55   │    │    └── fk_p_ref_parent
    56   │    └── select
    57   │         ├── columns: p:2!null
    58   │         ├── scan parent
    59   │         │    └── columns: p:2!null
    60   │         └── filters
    61   │              └── p:2 > 1
    62   └── cascade
    63        ├── delete child
    64        │    ├── columns: <none>
    65        │    ├── fetch columns: c:5 child.p:6
    66        │    ├── input binding: &2
    67        │    ├── cascades
    68        │    │    └── fk_c_ref_child
    69        │    └── semi-join (hash)
    70        │         ├── columns: c:5!null child.p:6!null
    71        │         ├── scan child
    72        │         │    └── columns: c:5!null child.p:6!null
    73        │         ├── with-scan &1
    74        │         │    ├── columns: p:7!null
    75        │         │    └── mapping:
    76        │         │         └──  parent.p:2 => p:7
    77        │         └── filters
    78        │              └── child.p:6 = p:7
    79        └── cascade
    80             └── delete grandchild
    81                  ├── columns: <none>
    82                  ├── fetch columns: g:10 grandchild.c:11
    83                  └── semi-join (hash)
    84                       ├── columns: g:10!null grandchild.c:11
    85                       ├── scan grandchild
    86                       │    └── columns: g:10!null grandchild.c:11
    87                       ├── with-scan &2
    88                       │    ├── columns: c:12!null
    89                       │    └── mapping:
    90                       │         └──  child.c:5 => c:12
    91                       └── filters
    92                            └── grandchild.c:11 = c:12
    93  
    94  # Cascade with check query.
    95  exec-ddl
    96  DROP TABLE grandchild
    97  ----
    98  
    99  exec-ddl
   100  CREATE TABLE grandchild (g INT PRIMARY KEY, c INT REFERENCES child(c))
   101  ----
   102  
   103  build-cascades
   104  DELETE FROM parent WHERE p > 1
   105  ----
   106  root
   107   ├── delete parent
   108   │    ├── columns: <none>
   109   │    ├── fetch columns: p:2
   110   │    ├── input binding: &1
   111   │    ├── cascades
   112   │    │    └── fk_p_ref_parent
   113   │    └── select
   114   │         ├── columns: p:2!null
   115   │         ├── scan parent
   116   │         │    └── columns: p:2!null
   117   │         └── filters
   118   │              └── p:2 > 1
   119   └── cascade
   120        └── delete child
   121             ├── columns: <none>
   122             ├── fetch columns: child.c:5 child.p:6
   123             ├── input binding: &2
   124             ├── semi-join (hash)
   125             │    ├── columns: child.c:5!null child.p:6!null
   126             │    ├── scan child
   127             │    │    └── columns: child.c:5!null child.p:6!null
   128             │    ├── with-scan &1
   129             │    │    ├── columns: p:7!null
   130             │    │    └── mapping:
   131             │    │         └──  parent.p:2 => p:7
   132             │    └── filters
   133             │         └── child.p:6 = p:7
   134             └── f-k-checks
   135                  └── f-k-checks-item: grandchild(c) -> child(c)
   136                       └── semi-join (hash)
   137                            ├── columns: c:8!null
   138                            ├── with-scan &2
   139                            │    ├── columns: c:8!null
   140                            │    └── mapping:
   141                            │         └──  child.c:5 => c:8
   142                            ├── scan grandchild
   143                            │    └── columns: grandchild.c:10
   144                            └── filters
   145                                 └── c:8 = grandchild.c:10
   146  
   147  # Self-reference with cascade.
   148  exec-ddl
   149  CREATE TABLE self (a INT PRIMARY KEY, b INT REFERENCES self(a) ON DELETE CASCADE)
   150  ----
   151  
   152  build-cascades cascade-levels=3
   153  DELETE FROM self WHERE a=1
   154  ----
   155  root
   156   ├── delete self
   157   │    ├── columns: <none>
   158   │    ├── fetch columns: a:3 b:4
   159   │    ├── input binding: &1
   160   │    ├── cascades
   161   │    │    └── fk_b_ref_self
   162   │    └── select
   163   │         ├── columns: a:3!null b:4
   164   │         ├── scan self
   165   │         │    └── columns: a:3!null b:4
   166   │         └── filters
   167   │              └── a:3 = 1
   168   └── cascade
   169        ├── delete self
   170        │    ├── columns: <none>
   171        │    ├── fetch columns: self.a:7 b:8
   172        │    ├── input binding: &2
   173        │    ├── cascades
   174        │    │    └── fk_b_ref_self
   175        │    └── semi-join (hash)
   176        │         ├── columns: self.a:7!null b:8
   177        │         ├── scan self
   178        │         │    └── columns: self.a:7!null b:8
   179        │         ├── with-scan &1
   180        │         │    ├── columns: a:9!null
   181        │         │    └── mapping:
   182        │         │         └──  self.a:3 => a:9
   183        │         └── filters
   184        │              └── b:8 = a:9
   185        └── cascade
   186             ├── delete self
   187             │    ├── columns: <none>
   188             │    ├── fetch columns: self.a:12 b:13
   189             │    ├── input binding: &3
   190             │    ├── cascades
   191             │    │    └── fk_b_ref_self
   192             │    └── semi-join (hash)
   193             │         ├── columns: self.a:12!null b:13
   194             │         ├── scan self
   195             │         │    └── columns: self.a:12!null b:13
   196             │         ├── with-scan &2
   197             │         │    ├── columns: a:14!null
   198             │         │    └── mapping:
   199             │         │         └──  self.a:7 => a:14
   200             │         └── filters
   201             │              └── b:13 = a:14
   202             └── cascade
   203                  └── delete self
   204                       ├── columns: <none>
   205                       ├── fetch columns: self.a:17 b:18
   206                       ├── input binding: &4
   207                       ├── cascades
   208                       │    └── fk_b_ref_self
   209                       └── semi-join (hash)
   210                            ├── columns: self.a:17!null b:18
   211                            ├── scan self
   212                            │    └── columns: self.a:17!null b:18
   213                            ├── with-scan &3
   214                            │    ├── columns: a:19!null
   215                            │    └── mapping:
   216                            │         └──  self.a:12 => a:19
   217                            └── filters
   218                                 └── b:18 = a:19
   219  
   220  # Cascade cycle.
   221  exec-ddl
   222  CREATE TABLE ab (a INT PRIMARY KEY, b INT)
   223  ----
   224  
   225  exec-ddl
   226  CREATE TABLE cd (c INT PRIMARY KEY, d INT)
   227  ----
   228  
   229  exec-ddl
   230  CREATE TABLE ef (e INT PRIMARY KEY, f INT)
   231  ----
   232  
   233  exec-ddl
   234  ALTER TABLE ab ADD CONSTRAINT ab_cd FOREIGN KEY (b) REFERENCES cd(c) ON DELETE CASCADE
   235  ----
   236  
   237  exec-ddl
   238  ALTER TABLE cd ADD CONSTRAINT cd_ef FOREIGN KEY (d) REFERENCES ef(e) ON DELETE CASCADE
   239  ----
   240  
   241  exec-ddl
   242  ALTER TABLE ef ADD CONSTRAINT ef_ab FOREIGN KEY (f) REFERENCES ab(a) ON DELETE CASCADE
   243  ----
   244  
   245  build-cascades cascade-levels=3
   246  DELETE FROM ab WHERE a = 1
   247  ----
   248  root
   249   ├── delete ab
   250   │    ├── columns: <none>
   251   │    ├── fetch columns: a:3 b:4
   252   │    ├── input binding: &1
   253   │    ├── cascades
   254   │    │    └── ef_ab
   255   │    └── select
   256   │         ├── columns: a:3!null b:4
   257   │         ├── scan ab
   258   │         │    └── columns: a:3!null b:4
   259   │         └── filters
   260   │              └── a:3 = 1
   261   └── cascade
   262        ├── delete ef
   263        │    ├── columns: <none>
   264        │    ├── fetch columns: e:7 f:8
   265        │    ├── input binding: &2
   266        │    ├── cascades
   267        │    │    └── cd_ef
   268        │    └── semi-join (hash)
   269        │         ├── columns: e:7!null f:8
   270        │         ├── scan ef
   271        │         │    └── columns: e:7!null f:8
   272        │         ├── with-scan &1
   273        │         │    ├── columns: a:9!null
   274        │         │    └── mapping:
   275        │         │         └──  ab.a:3 => a:9
   276        │         └── filters
   277        │              └── f:8 = a:9
   278        └── cascade
   279             ├── delete cd
   280             │    ├── columns: <none>
   281             │    ├── fetch columns: c:12 d:13
   282             │    ├── input binding: &3
   283             │    ├── cascades
   284             │    │    └── ab_cd
   285             │    └── semi-join (hash)
   286             │         ├── columns: c:12!null d:13
   287             │         ├── scan cd
   288             │         │    └── columns: c:12!null d:13
   289             │         ├── with-scan &2
   290             │         │    ├── columns: e:14!null
   291             │         │    └── mapping:
   292             │         │         └──  ef.e:7 => e:14
   293             │         └── filters
   294             │              └── d:13 = e:14
   295             └── cascade
   296                  └── delete ab
   297                       ├── columns: <none>
   298                       ├── fetch columns: ab.a:17 b:18
   299                       ├── input binding: &4
   300                       ├── cascades
   301                       │    └── ef_ab
   302                       └── semi-join (hash)
   303                            ├── columns: ab.a:17!null b:18
   304                            ├── scan ab
   305                            │    └── columns: ab.a:17!null b:18
   306                            ├── with-scan &3
   307                            │    ├── columns: c:19!null
   308                            │    └── mapping:
   309                            │         └──  cd.c:12 => c:19
   310                            └── filters
   311                                 └── b:18 = c:19