github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/optbuilder/testdata/fk-on-delete-set-default (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 DEFAULT 0 REFERENCES parent(p) ON DELETE SET DEFAULT)
     7  ----
     8  
     9  build-cascades
    10  DELETE FROM parent WHERE p > 1
    11  ----
    12  root
    13   ├── delete parent
    14   │    ├── columns: <none>
    15   │    ├── fetch columns: p:2
    16   │    ├── input binding: &1
    17   │    ├── cascades
    18   │    │    └── fk_p_ref_parent
    19   │    └── select
    20   │         ├── columns: p:2!null
    21   │         ├── scan parent
    22   │         │    └── columns: p:2!null
    23   │         └── filters
    24   │              └── p:2 > 1
    25   └── cascade
    26        └── update child
    27             ├── columns: <none>
    28             ├── fetch columns: c:5 child.p:6
    29             ├── update-mapping:
    30             │    └── p_new:8 => child.p:4
    31             ├── input binding: &2
    32             ├── project
    33             │    ├── columns: p_new:8!null c:5!null child.p:6
    34             │    ├── semi-join (hash)
    35             │    │    ├── columns: c:5!null child.p:6
    36             │    │    ├── scan child
    37             │    │    │    └── columns: c:5!null child.p:6
    38             │    │    ├── with-scan &1
    39             │    │    │    ├── columns: p:7!null
    40             │    │    │    └── mapping:
    41             │    │    │         └──  parent.p:2 => p:7
    42             │    │    └── filters
    43             │    │         └── child.p:6 = p:7
    44             │    └── projections
    45             │         └── 0 [as=p_new:8]
    46             └── f-k-checks
    47                  └── f-k-checks-item: child(p) -> parent(p)
    48                       └── anti-join (hash)
    49                            ├── columns: p_new:9!null
    50                            ├── with-scan &2
    51                            │    ├── columns: p_new:9!null
    52                            │    └── mapping:
    53                            │         └──  p_new:8 => p_new:9
    54                            ├── scan parent
    55                            │    └── columns: parent.p:10!null
    56                            └── filters
    57                                 └── p_new:9 = parent.p:10
    58  
    59  exec-ddl
    60  DROP TABLE child
    61  ----
    62  
    63  exec-ddl
    64  CREATE TABLE child_null (c INT PRIMARY KEY, p INT REFERENCES parent(p) ON DELETE SET DEFAULT)
    65  ----
    66  
    67  # Verify that no FK check is issued when updating the child, just like ON
    68  # DELETE SET NULL.
    69  build-cascades
    70  DELETE FROM parent WHERE p > 1
    71  ----
    72  root
    73   ├── delete parent
    74   │    ├── columns: <none>
    75   │    ├── fetch columns: p:2
    76   │    ├── input binding: &1
    77   │    ├── cascades
    78   │    │    └── fk_p_ref_parent
    79   │    └── select
    80   │         ├── columns: p:2!null
    81   │         ├── scan parent
    82   │         │    └── columns: p:2!null
    83   │         └── filters
    84   │              └── p:2 > 1
    85   └── cascade
    86        └── update child_null
    87             ├── columns: <none>
    88             ├── fetch columns: c:5 child_null.p:6
    89             ├── update-mapping:
    90             │    └── p_new:8 => child_null.p:4
    91             └── project
    92                  ├── columns: p_new:8 c:5!null child_null.p:6
    93                  ├── semi-join (hash)
    94                  │    ├── columns: c:5!null child_null.p:6
    95                  │    ├── scan child_null
    96                  │    │    └── columns: c:5!null child_null.p:6
    97                  │    ├── with-scan &1
    98                  │    │    ├── columns: p:7!null
    99                  │    │    └── mapping:
   100                  │    │         └──  parent.p:2 => p:7
   101                  │    └── filters
   102                  │         └── child_null.p:6 = p:7
   103                  └── projections
   104                       └── NULL::INT8 [as=p_new:8]
   105  
   106  exec-ddl
   107  CREATE TABLE parent_multicol (p INT, q INT, r INT, PRIMARY KEY (p, q, r))
   108  ----
   109  
   110  exec-ddl
   111  CREATE TABLE child_multicol (
   112    c INT PRIMARY KEY,
   113    p INT DEFAULT (c), q INT DEFAULT (p + 1), r INT DEFAULT (p + q),
   114    x INT AS (p + q + r) STORED,
   115    CONSTRAINT fk FOREIGN KEY (p,q,r) REFERENCES parent_multicol(p,q,r) ON DELETE SET DEFAULT,
   116    CONSTRAINT ch CHECK (c > 100 OR p > c)
   117  )
   118  ----
   119  
   120  # Verify that:
   121  #  - multiple FK columns are handled correctly;
   122  #  - non-trivial default expressions are projected correctly;
   123  #  - we recalculate the stored column;
   124  #  - we verify the CHECK expression.
   125  build-cascades
   126  DELETE FROM parent_multicol WHERE p > 1
   127  ----
   128  root
   129   ├── delete parent_multicol
   130   │    ├── columns: <none>
   131   │    ├── fetch columns: p:4 q:5 r:6
   132   │    ├── input binding: &1
   133   │    ├── cascades
   134   │    │    └── fk
   135   │    └── select
   136   │         ├── columns: p:4!null q:5!null r:6!null
   137   │         ├── scan parent_multicol
   138   │         │    └── columns: p:4!null q:5!null r:6!null
   139   │         └── filters
   140   │              └── p:4 > 1
   141   └── cascade
   142        └── update child_multicol
   143             ├── columns: <none>
   144             ├── fetch columns: child_multicol.c:12 child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16
   145             ├── update-mapping:
   146             │    ├── child_multicol.c:12 => child_multicol.p:8
   147             │    ├── q_new:20 => child_multicol.q:9
   148             │    ├── r_new:21 => child_multicol.r:10
   149             │    └── column22:22 => x:11
   150             ├── check columns: check1:23
   151             ├── input binding: &2
   152             ├── project
   153             │    ├── columns: check1:23!null child_multicol.c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16 q_new:20 r_new:21 column22:22
   154             │    ├── project
   155             │    │    ├── columns: column22:22 child_multicol.c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16 q_new:20 r_new:21
   156             │    │    ├── project
   157             │    │    │    ├── columns: q_new:20 r_new:21 child_multicol.c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16
   158             │    │    │    ├── semi-join (hash)
   159             │    │    │    │    ├── columns: child_multicol.c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16
   160             │    │    │    │    ├── scan child_multicol
   161             │    │    │    │    │    ├── columns: child_multicol.c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16
   162             │    │    │    │    │    └── computed column expressions
   163             │    │    │    │    │         └── x:16
   164             │    │    │    │    │              └── (child_multicol.p:13 + child_multicol.q:14) + child_multicol.r:15
   165             │    │    │    │    ├── with-scan &1
   166             │    │    │    │    │    ├── columns: p:17!null q:18!null r:19!null
   167             │    │    │    │    │    └── mapping:
   168             │    │    │    │    │         ├──  parent_multicol.p:4 => p:17
   169             │    │    │    │    │         ├──  parent_multicol.q:5 => q:18
   170             │    │    │    │    │         └──  parent_multicol.r:6 => r:19
   171             │    │    │    │    └── filters
   172             │    │    │    │         ├── child_multicol.p:13 = p:17
   173             │    │    │    │         ├── child_multicol.q:14 = q:18
   174             │    │    │    │         └── child_multicol.r:15 = r:19
   175             │    │    │    └── projections
   176             │    │    │         ├── child_multicol.p:13 + 1 [as=q_new:20]
   177             │    │    │         └── child_multicol.p:13 + child_multicol.q:14 [as=r_new:21]
   178             │    │    └── projections
   179             │    │         └── (child_multicol.c:12 + q_new:20) + r_new:21 [as=column22:22]
   180             │    └── projections
   181             │         └── (child_multicol.c:12 > 100) OR (child_multicol.c:12 > child_multicol.c:12) [as=check1:23]
   182             └── f-k-checks
   183                  └── f-k-checks-item: child_multicol(p,q,r) -> parent_multicol(p,q,r)
   184                       └── anti-join (hash)
   185                            ├── columns: c:24!null q_new:25!null r_new:26!null
   186                            ├── select
   187                            │    ├── columns: c:24!null q_new:25!null r_new:26!null
   188                            │    ├── with-scan &2
   189                            │    │    ├── columns: c:24!null q_new:25 r_new:26
   190                            │    │    └── mapping:
   191                            │    │         ├──  child_multicol.c:12 => c:24
   192                            │    │         ├──  q_new:20 => q_new:25
   193                            │    │         └──  r_new:21 => r_new:26
   194                            │    └── filters
   195                            │         ├── q_new:25 IS NOT NULL
   196                            │         └── r_new:26 IS NOT NULL
   197                            ├── scan parent_multicol
   198                            │    └── columns: parent_multicol.p:27!null parent_multicol.q:28!null parent_multicol.r:29!null
   199                            └── filters
   200                                 ├── c:24 = parent_multicol.p:27
   201                                 ├── q_new:25 = parent_multicol.q:28
   202                                 └── r_new:26 = parent_multicol.r:29