github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/optbuilder/testdata/fk-on-delete-set-null (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 REFERENCES parent(p) ON DELETE SET NULL) 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 └── project 32 ├── columns: p_new:8 c:5!null child.p:6 33 ├── semi-join (hash) 34 │ ├── columns: c:5!null child.p:6 35 │ ├── scan child 36 │ │ └── columns: c:5!null child.p:6 37 │ ├── with-scan &1 38 │ │ ├── columns: p:7!null 39 │ │ └── mapping: 40 │ │ └── parent.p:2 => p:7 41 │ └── filters 42 │ └── child.p:6 = p:7 43 └── projections 44 └── NULL::INT8 [as=p_new:8] 45 46 exec-ddl 47 CREATE TABLE parent_multicol (p INT, q INT, r INT, PRIMARY KEY (p, q, r)) 48 ---- 49 50 exec-ddl 51 CREATE TABLE child_multicol ( 52 c INT PRIMARY KEY, 53 p INT, q INT, r INT, 54 x INT AS (p+q+r) STORED, 55 CONSTRAINT fk FOREIGN KEY (p,q,r) REFERENCES parent_multicol(p,q,r) ON DELETE SET NULL, 56 CONSTRAINT ch CHECK (c > 100 OR p IS NOT NULL) 57 ) 58 ---- 59 60 # Verify that: 61 # - multiple FK columns are handled correctly; 62 # - we recalculate the stored column; 63 # - we verify the CHECK expression. 64 build-cascades 65 DELETE FROM parent_multicol WHERE p > 1 66 ---- 67 root 68 ├── delete parent_multicol 69 │ ├── columns: <none> 70 │ ├── fetch columns: p:4 q:5 r:6 71 │ ├── input binding: &1 72 │ ├── cascades 73 │ │ └── fk 74 │ └── select 75 │ ├── columns: p:4!null q:5!null r:6!null 76 │ ├── scan parent_multicol 77 │ │ └── columns: p:4!null q:5!null r:6!null 78 │ └── filters 79 │ └── p:4 > 1 80 └── cascade 81 └── update child_multicol 82 ├── columns: <none> 83 ├── fetch columns: c:12 child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16 84 ├── update-mapping: 85 │ ├── p_new:20 => child_multicol.p:8 86 │ ├── p_new:20 => child_multicol.q:9 87 │ ├── p_new:20 => child_multicol.r:10 88 │ └── column21:21 => x:11 89 ├── check columns: check1:22 90 └── project 91 ├── columns: check1:22!null c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16 p_new:20 column21:21 92 ├── project 93 │ ├── columns: column21:21 c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16 p_new:20 94 │ ├── project 95 │ │ ├── columns: p_new:20 c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16 96 │ │ ├── semi-join (hash) 97 │ │ │ ├── columns: c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16 98 │ │ │ ├── scan child_multicol 99 │ │ │ │ ├── columns: c:12!null child_multicol.p:13 child_multicol.q:14 child_multicol.r:15 x:16 100 │ │ │ │ ├── check constraint expressions 101 │ │ │ │ │ └── (c:12 > 100) OR (child_multicol.p:13 IS NOT NULL) 102 │ │ │ │ └── computed column expressions 103 │ │ │ │ └── x:16 104 │ │ │ │ └── (child_multicol.p:13 + child_multicol.q:14) + child_multicol.r:15 105 │ │ │ ├── with-scan &1 106 │ │ │ │ ├── columns: p:17!null q:18!null r:19!null 107 │ │ │ │ └── mapping: 108 │ │ │ │ ├── parent_multicol.p:4 => p:17 109 │ │ │ │ ├── parent_multicol.q:5 => q:18 110 │ │ │ │ └── parent_multicol.r:6 => r:19 111 │ │ │ └── filters 112 │ │ │ ├── child_multicol.p:13 = p:17 113 │ │ │ ├── child_multicol.q:14 = q:18 114 │ │ │ └── child_multicol.r:15 = r:19 115 │ │ └── projections 116 │ │ └── NULL::INT8 [as=p_new:20] 117 │ └── projections 118 │ └── (p_new:20 + p_new:20) + p_new:20 [as=column21:21] 119 └── projections 120 └── (c:12 > 100) OR (p_new:20 IS NOT NULL) [as=check1:22]