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