github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/optbuilder/testdata/fk-on-update-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 NOT NULL REFERENCES parent(p) ON UPDATE SET DEFAULT)
     7  ----
     8  
     9  build-cascades
    10  UPDATE parent SET p = p * 10 WHERE p > 1
    11  ----
    12  root
    13   ├── update parent
    14   │    ├── columns: <none>
    15   │    ├── fetch columns: p:2
    16   │    ├── update-mapping:
    17   │    │    └── p_new:3 => p:1
    18   │    ├── input binding: &1
    19   │    ├── cascades
    20   │    │    └── fk_p_ref_parent
    21   │    └── project
    22   │         ├── columns: p_new:3!null p:2!null
    23   │         ├── select
    24   │         │    ├── columns: p:2!null
    25   │         │    ├── scan parent
    26   │         │    │    └── columns: p:2!null
    27   │         │    └── filters
    28   │         │         └── p:2 > 1
    29   │         └── projections
    30   │              └── p:2 * 10 [as=p_new:3]
    31   └── cascade
    32        └── update child
    33             ├── columns: <none>
    34             ├── fetch columns: c:6 child.p:7
    35             ├── update-mapping:
    36             │    └── p_new:10 => child.p:5
    37             ├── input binding: &2
    38             ├── project
    39             │    ├── columns: p_new:10!null c:6!null child.p:7!null p:8!null p_new:9!null
    40             │    ├── inner-join (hash)
    41             │    │    ├── columns: c:6!null child.p:7!null p:8!null p_new:9!null
    42             │    │    ├── scan child
    43             │    │    │    └── columns: c:6!null child.p:7!null
    44             │    │    ├── select
    45             │    │    │    ├── columns: p:8!null p_new:9!null
    46             │    │    │    ├── with-scan &1
    47             │    │    │    │    ├── columns: p:8!null p_new:9!null
    48             │    │    │    │    └── mapping:
    49             │    │    │    │         ├──  parent.p:2 => p:8
    50             │    │    │    │         └──  p_new:3 => p_new:9
    51             │    │    │    └── filters
    52             │    │    │         └── p:8 IS DISTINCT FROM p_new:9
    53             │    │    └── filters
    54             │    │         └── child.p:7 = p:8
    55             │    └── projections
    56             │         └── 0 [as=p_new:10]
    57             └── f-k-checks
    58                  └── f-k-checks-item: child(p) -> parent(p)
    59                       └── anti-join (hash)
    60                            ├── columns: p_new:11!null
    61                            ├── with-scan &2
    62                            │    ├── columns: p_new:11!null
    63                            │    └── mapping:
    64                            │         └──  p_new:10 => p_new:11
    65                            ├── scan parent
    66                            │    └── columns: parent.p:12!null
    67                            └── filters
    68                                 └── p_new:11 = parent.p:12
    69  
    70  exec-ddl
    71  CREATE TABLE parent_multi (
    72    pk INT PRIMARY KEY,
    73    p INT, q INT,
    74    UNIQUE (p, q),
    75    FAMILY (pk),
    76    FAMILY (p),
    77    FAMILY (q)
    78  )
    79  ----
    80  
    81  exec-ddl
    82  CREATE TABLE child_multi (
    83    c INT PRIMARY KEY,
    84    p INT DEFAULT 0,
    85    q INT DEFAULT 1,
    86    UNIQUE (c, q),
    87    CONSTRAINT fk FOREIGN KEY (p, q) REFERENCES parent_multi(p, q) ON UPDATE SET DEFAULT 
    88  )
    89  ----
    90  
    91  build-cascades
    92  UPDATE parent_multi SET p = p * 10, q = q + 1 WHERE pk > 1
    93  ----
    94  root
    95   ├── update parent_multi
    96   │    ├── columns: <none>
    97   │    ├── fetch columns: pk:4 p:5 q:6
    98   │    ├── update-mapping:
    99   │    │    ├── p_new:7 => p:2
   100   │    │    └── q_new:8 => q:3
   101   │    ├── input binding: &1
   102   │    ├── cascades
   103   │    │    └── fk
   104   │    └── project
   105   │         ├── columns: p_new:7 q_new:8 pk:4!null p:5 q:6
   106   │         ├── select
   107   │         │    ├── columns: pk:4!null p:5 q:6
   108   │         │    ├── scan parent_multi
   109   │         │    │    └── columns: pk:4!null p:5 q:6
   110   │         │    └── filters
   111   │         │         └── pk:4 > 1
   112   │         └── projections
   113   │              ├── p:5 * 10 [as=p_new:7]
   114   │              └── q:6 + 1 [as=q_new:8]
   115   └── cascade
   116        └── update child_multi
   117             ├── columns: <none>
   118             ├── fetch columns: c:12 child_multi.p:13 child_multi.q:14
   119             ├── update-mapping:
   120             │    ├── p_new:19 => child_multi.p:10
   121             │    └── q_new:20 => child_multi.q:11
   122             ├── input binding: &2
   123             ├── project
   124             │    ├── columns: p_new:19!null q_new:20!null c:12!null child_multi.p:13!null child_multi.q:14!null p:15!null q:16!null p_new:17 q_new:18
   125             │    ├── inner-join (hash)
   126             │    │    ├── columns: c:12!null child_multi.p:13!null child_multi.q:14!null p:15!null q:16!null p_new:17 q_new:18
   127             │    │    ├── scan child_multi
   128             │    │    │    └── columns: c:12!null child_multi.p:13 child_multi.q:14
   129             │    │    ├── select
   130             │    │    │    ├── columns: p:15 q:16 p_new:17 q_new:18
   131             │    │    │    ├── with-scan &1
   132             │    │    │    │    ├── columns: p:15 q:16 p_new:17 q_new:18
   133             │    │    │    │    └── mapping:
   134             │    │    │    │         ├──  parent_multi.p:5 => p:15
   135             │    │    │    │         ├──  parent_multi.q:6 => q:16
   136             │    │    │    │         ├──  p_new:7 => p_new:17
   137             │    │    │    │         └──  q_new:8 => q_new:18
   138             │    │    │    └── filters
   139             │    │    │         └── (p:15 IS DISTINCT FROM p_new:17) OR (q:16 IS DISTINCT FROM q_new:18)
   140             │    │    └── filters
   141             │    │         ├── child_multi.p:13 = p:15
   142             │    │         └── child_multi.q:14 = q:16
   143             │    └── projections
   144             │         ├── 0 [as=p_new:19]
   145             │         └── 1 [as=q_new:20]
   146             └── f-k-checks
   147                  └── f-k-checks-item: child_multi(p,q) -> parent_multi(p,q)
   148                       └── anti-join (hash)
   149                            ├── columns: p_new:21!null q_new:22!null
   150                            ├── with-scan &2
   151                            │    ├── columns: p_new:21!null q_new:22!null
   152                            │    └── mapping:
   153                            │         ├──  p_new:19 => p_new:21
   154                            │         └──  q_new:20 => q_new:22
   155                            ├── scan parent_multi
   156                            │    └── columns: parent_multi.p:24 parent_multi.q:25
   157                            └── filters
   158                                 ├── p_new:21 = parent_multi.p:24
   159                                 └── q_new:22 = parent_multi.q:25
   160  
   161  # Update only one of the two FK columns. The "before" and "after" values of q
   162  # come from the same column in the mutation input.
   163  build-cascades
   164  UPDATE parent_multi SET p = p * 10 WHERE p > 1
   165  ----
   166  root
   167   ├── update parent_multi
   168   │    ├── columns: <none>
   169   │    ├── fetch columns: pk:4 p:5 q:6
   170   │    ├── update-mapping:
   171   │    │    └── p_new:7 => p:2
   172   │    ├── input binding: &1
   173   │    ├── cascades
   174   │    │    └── fk
   175   │    └── project
   176   │         ├── columns: p_new:7!null pk:4!null p:5!null q:6
   177   │         ├── select
   178   │         │    ├── columns: pk:4!null p:5!null q:6
   179   │         │    ├── scan parent_multi
   180   │         │    │    └── columns: pk:4!null p:5 q:6
   181   │         │    └── filters
   182   │         │         └── p:5 > 1
   183   │         └── projections
   184   │              └── p:5 * 10 [as=p_new:7]
   185   └── cascade
   186        └── update child_multi
   187             ├── columns: <none>
   188             ├── fetch columns: c:11 child_multi.p:12 child_multi.q:13
   189             ├── update-mapping:
   190             │    ├── p_new:18 => child_multi.p:9
   191             │    └── q_new:19 => child_multi.q:10
   192             ├── input binding: &2
   193             ├── project
   194             │    ├── columns: p_new:18!null q_new:19!null c:11!null child_multi.p:12!null child_multi.q:13!null p:14!null q:15!null p_new:16!null q:17
   195             │    ├── inner-join (hash)
   196             │    │    ├── columns: c:11!null child_multi.p:12!null child_multi.q:13!null p:14!null q:15!null p_new:16!null q:17
   197             │    │    ├── scan child_multi
   198             │    │    │    └── columns: c:11!null child_multi.p:12 child_multi.q:13
   199             │    │    ├── select
   200             │    │    │    ├── columns: p:14!null q:15 p_new:16!null q:17
   201             │    │    │    ├── with-scan &1
   202             │    │    │    │    ├── columns: p:14!null q:15 p_new:16!null q:17
   203             │    │    │    │    └── mapping:
   204             │    │    │    │         ├──  parent_multi.p:5 => p:14
   205             │    │    │    │         ├──  parent_multi.q:6 => q:15
   206             │    │    │    │         ├──  p_new:7 => p_new:16
   207             │    │    │    │         └──  parent_multi.q:6 => q:17
   208             │    │    │    └── filters
   209             │    │    │         └── (p:14 IS DISTINCT FROM p_new:16) OR (q:15 IS DISTINCT FROM q:17)
   210             │    │    └── filters
   211             │    │         ├── child_multi.p:12 = p:14
   212             │    │         └── child_multi.q:13 = q:15
   213             │    └── projections
   214             │         ├── 0 [as=p_new:18]
   215             │         └── 1 [as=q_new:19]
   216             └── f-k-checks
   217                  └── f-k-checks-item: child_multi(p,q) -> parent_multi(p,q)
   218                       └── anti-join (hash)
   219                            ├── columns: p_new:20!null q_new:21!null
   220                            ├── with-scan &2
   221                            │    ├── columns: p_new:20!null q_new:21!null
   222                            │    └── mapping:
   223                            │         ├──  p_new:18 => p_new:20
   224                            │         └──  q_new:19 => q_new:21
   225                            ├── scan parent_multi
   226                            │    └── columns: parent_multi.p:23 parent_multi.q:24
   227                            └── filters
   228                                 ├── p_new:20 = parent_multi.p:23
   229                                 └── q_new:21 = parent_multi.q:24
   230  
   231  # Test a two-level cascade.
   232  exec-ddl
   233  CREATE TABLE grandchild (
   234    g INT PRIMARY KEY,
   235    c INT DEFAULT 10, q INT DEFAULT 11,
   236    CONSTRAINT fk2 FOREIGN KEY (c, q) REFERENCES child_multi(c, q) ON UPDATE SET DEFAULT
   237  )
   238  ----
   239  
   240  build-cascades
   241  UPDATE parent_multi SET q = q * 10 WHERE p > 1
   242  ----
   243  root
   244   ├── update parent_multi
   245   │    ├── columns: <none>
   246   │    ├── fetch columns: pk:4 p:5 q:6
   247   │    ├── update-mapping:
   248   │    │    └── q_new:7 => q:3
   249   │    ├── input binding: &1
   250   │    ├── cascades
   251   │    │    └── fk
   252   │    └── project
   253   │         ├── columns: q_new:7 pk:4!null p:5!null q:6
   254   │         ├── select
   255   │         │    ├── columns: pk:4!null p:5!null q:6
   256   │         │    ├── scan parent_multi
   257   │         │    │    └── columns: pk:4!null p:5 q:6
   258   │         │    └── filters
   259   │         │         └── p:5 > 1
   260   │         └── projections
   261   │              └── q:6 * 10 [as=q_new:7]
   262   └── cascade
   263        ├── update child_multi
   264        │    ├── columns: <none>
   265        │    ├── fetch columns: c:11 child_multi.p:12 child_multi.q:13
   266        │    ├── update-mapping:
   267        │    │    ├── p_new:18 => child_multi.p:9
   268        │    │    └── q_new:19 => child_multi.q:10
   269        │    ├── input binding: &2
   270        │    ├── cascades
   271        │    │    └── fk2
   272        │    ├── project
   273        │    │    ├── columns: p_new:18!null q_new:19!null c:11!null child_multi.p:12!null child_multi.q:13!null p:14!null q:15!null p:16!null q_new:17
   274        │    │    ├── inner-join (hash)
   275        │    │    │    ├── columns: c:11!null child_multi.p:12!null child_multi.q:13!null p:14!null q:15!null p:16!null q_new:17
   276        │    │    │    ├── scan child_multi
   277        │    │    │    │    └── columns: c:11!null child_multi.p:12 child_multi.q:13
   278        │    │    │    ├── select
   279        │    │    │    │    ├── columns: p:14!null q:15 p:16!null q_new:17
   280        │    │    │    │    ├── with-scan &1
   281        │    │    │    │    │    ├── columns: p:14!null q:15 p:16!null q_new:17
   282        │    │    │    │    │    └── mapping:
   283        │    │    │    │    │         ├──  parent_multi.p:5 => p:14
   284        │    │    │    │    │         ├──  parent_multi.q:6 => q:15
   285        │    │    │    │    │         ├──  parent_multi.p:5 => p:16
   286        │    │    │    │    │         └──  q_new:7 => q_new:17
   287        │    │    │    │    └── filters
   288        │    │    │    │         └── (p:14 IS DISTINCT FROM p:16) OR (q:15 IS DISTINCT FROM q_new:17)
   289        │    │    │    └── filters
   290        │    │    │         ├── child_multi.p:12 = p:14
   291        │    │    │         └── child_multi.q:13 = q:15
   292        │    │    └── projections
   293        │    │         ├── 0 [as=p_new:18]
   294        │    │         └── 1 [as=q_new:19]
   295        │    └── f-k-checks
   296        │         └── f-k-checks-item: child_multi(p,q) -> parent_multi(p,q)
   297        │              └── anti-join (hash)
   298        │                   ├── columns: p_new:20!null q_new:21!null
   299        │                   ├── with-scan &2
   300        │                   │    ├── columns: p_new:20!null q_new:21!null
   301        │                   │    └── mapping:
   302        │                   │         ├──  p_new:18 => p_new:20
   303        │                   │         └──  q_new:19 => q_new:21
   304        │                   ├── scan parent_multi
   305        │                   │    └── columns: parent_multi.p:23 parent_multi.q:24
   306        │                   └── filters
   307        │                        ├── p_new:20 = parent_multi.p:23
   308        │                        └── q_new:21 = parent_multi.q:24
   309        └── cascade
   310             └── update grandchild
   311                  ├── columns: <none>
   312                  ├── fetch columns: g:28 grandchild.c:29 grandchild.q:30
   313                  ├── update-mapping:
   314                  │    ├── c_new:35 => grandchild.c:26
   315                  │    └── q_new:36 => grandchild.q:27
   316                  ├── input binding: &3
   317                  ├── project
   318                  │    ├── columns: c_new:35!null q_new:36!null g:28!null grandchild.c:29!null grandchild.q:30!null c:31!null q:32!null c:33!null q_new:34!null
   319                  │    ├── inner-join (hash)
   320                  │    │    ├── columns: g:28!null grandchild.c:29!null grandchild.q:30!null c:31!null q:32!null c:33!null q_new:34!null
   321                  │    │    ├── scan grandchild
   322                  │    │    │    └── columns: g:28!null grandchild.c:29 grandchild.q:30
   323                  │    │    ├── select
   324                  │    │    │    ├── columns: c:31!null q:32!null c:33!null q_new:34!null
   325                  │    │    │    ├── with-scan &2
   326                  │    │    │    │    ├── columns: c:31!null q:32!null c:33!null q_new:34!null
   327                  │    │    │    │    └── mapping:
   328                  │    │    │    │         ├──  child_multi.c:11 => c:31
   329                  │    │    │    │         ├──  child_multi.q:13 => q:32
   330                  │    │    │    │         ├──  child_multi.c:11 => c:33
   331                  │    │    │    │         └──  q_new:19 => q_new:34
   332                  │    │    │    └── filters
   333                  │    │    │         └── (c:31 IS DISTINCT FROM c:33) OR (q:32 IS DISTINCT FROM q_new:34)
   334                  │    │    └── filters
   335                  │    │         ├── grandchild.c:29 = c:31
   336                  │    │         └── grandchild.q:30 = q:32
   337                  │    └── projections
   338                  │         ├── 10 [as=c_new:35]
   339                  │         └── 11 [as=q_new:36]
   340                  └── f-k-checks
   341                       └── f-k-checks-item: grandchild(c,q) -> child_multi(c,q)
   342                            └── anti-join (hash)
   343                                 ├── columns: c_new:37!null q_new:38!null
   344                                 ├── with-scan &3
   345                                 │    ├── columns: c_new:37!null q_new:38!null
   346                                 │    └── mapping:
   347                                 │         ├──  c_new:35 => c_new:37
   348                                 │         └──  q_new:36 => q_new:38
   349                                 ├── scan child_multi
   350                                 │    └── columns: child_multi.c:39!null child_multi.q:41
   351                                 └── filters
   352                                      ├── c_new:37 = child_multi.c:39
   353                                      └── q_new:38 = child_multi.q:41