@@ -1013,11 +1013,72 @@ root
1013
1013
│ └── fd: ()-->(36,37)
1014
1014
└── filters (true)
1015
1015
1016
- # TODO(146705) the delete cascade fast-path prevents the cascade from being
1017
- # limited to the parent row's region .
1016
+ # Avoid using the delete cascade fast-path because it would be unable to
1017
+ # constrain the region column to a single value .
1018
1018
opt-post-queries locality=(region=east)
1019
1019
DELETE FROM parent WHERE k = 1
1020
1020
----
1021
+ root
1022
+ ├── delete parent
1023
+ │ ├── columns: <none>
1024
+ │ ├── fetch columns: k:6 crdb_region:8
1025
+ │ ├── input binding: &1
1026
+ │ ├── cascades
1027
+ │ │ └── child_crdb_region_b_fkey
1028
+ │ ├── cardinality: [0 - 0]
1029
+ │ ├── volatile, mutations
1030
+ │ └── locality-optimized-search
1031
+ │ ├── columns: k:6!null crdb_region:8!null
1032
+ │ ├── left columns: k:11 crdb_region:13
1033
+ │ ├── right columns: k:16 crdb_region:18
1034
+ │ ├── cardinality: [0 - 1]
1035
+ │ ├── key: ()
1036
+ │ ├── fd: ()-->(6,8)
1037
+ │ ├── scan parent
1038
+ │ │ ├── columns: k:11!null crdb_region:13!null
1039
+ │ │ ├── constraint: /13/11: [/'east'/1 - /'east'/1]
1040
+ │ │ ├── flags: avoid-full-scan
1041
+ │ │ ├── cardinality: [0 - 1]
1042
+ │ │ ├── key: ()
1043
+ │ │ └── fd: ()-->(11,13)
1044
+ │ └── scan parent
1045
+ │ ├── columns: k:16!null crdb_region:18!null
1046
+ │ ├── constraint: /18/16
1047
+ │ │ ├── [/'central'/1 - /'central'/1]
1048
+ │ │ └── [/'west'/1 - /'west'/1]
1049
+ │ ├── flags: avoid-full-scan
1050
+ │ ├── cardinality: [0 - 1]
1051
+ │ ├── key: ()
1052
+ │ └── fd: ()-->(16,18)
1053
+ └── cascade
1054
+ └── delete child
1055
+ ├── columns: <none>
1056
+ ├── fetch columns: a:16 b:17 child.crdb_region:18
1057
+ ├── cardinality: [0 - 0]
1058
+ ├── volatile, mutations
1059
+ └── project
1060
+ ├── columns: a:16!null b:17!null child.crdb_region:18!null
1061
+ ├── key: (16)
1062
+ ├── fd: (16)-->(17,18)
1063
+ └── inner-join (lookup child@child_crdb_region_b_idx)
1064
+ ├── columns: a:16!null b:17!null child.crdb_region:18!null crdb_region:21!null k:22!null
1065
+ ├── key columns: [21 22] = [18 17]
1066
+ ├── key: (16)
1067
+ ├── fd: ()-->(17,18,21,22), (18)==(21), (21)==(18), (17)==(22), (22)==(17)
1068
+ ├── with-scan &1
1069
+ │ ├── columns: crdb_region:21!null k:22!null
1070
+ │ ├── mapping:
1071
+ │ │ ├── parent.crdb_region:8 => crdb_region:21
1072
+ │ │ └── parent.k:6 => k:22
1073
+ │ ├── cardinality: [0 - 1]
1074
+ │ ├── key: ()
1075
+ │ └── fd: ()-->(21,22)
1076
+ └── filters (true)
1077
+
1078
+ # Disabling the setting causes the delete cascade fast-path to be used.
1079
+ opt-post-queries locality=(region=east) set=optimizer_disable_cross_region_cascade_fast_path_for_rbr_tables=false
1080
+ DELETE FROM parent WHERE k = 1
1081
+ ----
1021
1082
root
1022
1083
├── delete parent
1023
1084
│ ├── columns: <none>
@@ -1065,6 +1126,39 @@ root
1065
1126
├── key: (16)
1066
1127
└── fd: ()-->(17), (16)-->(18)
1067
1128
1129
+ # Use the delete cascade fast-path here because the region column is
1130
+ # constrained to a single value.
1131
+ opt-post-queries locality=(region=east)
1132
+ DELETE FROM parent WHERE k = 1 AND crdb_region = 'east'
1133
+ ----
1134
+ root
1135
+ ├── delete parent
1136
+ │ ├── columns: <none>
1137
+ │ ├── fetch columns: k:6 crdb_region:8
1138
+ │ ├── cascades
1139
+ │ │ └── child_crdb_region_b_fkey
1140
+ │ ├── cardinality: [0 - 0]
1141
+ │ ├── volatile, mutations
1142
+ │ └── scan parent
1143
+ │ ├── columns: k:6!null crdb_region:8!null
1144
+ │ ├── constraint: /8/6: [/'east'/1 - /'east'/1]
1145
+ │ ├── flags: avoid-full-scan
1146
+ │ ├── cardinality: [0 - 1]
1147
+ │ ├── key: ()
1148
+ │ └── fd: ()-->(6,8)
1149
+ └── cascade
1150
+ └── delete child
1151
+ ├── columns: <none>
1152
+ ├── fetch columns: a:16 b:17 child.crdb_region:18
1153
+ ├── cardinality: [0 - 0]
1154
+ ├── volatile, mutations
1155
+ └── scan child@child_crdb_region_b_idx
1156
+ ├── columns: a:16!null b:17!null child.crdb_region:18!null
1157
+ ├── constraint: /18/17/16: [/'east'/1 - /'east'/1]
1158
+ ├── flags: avoid-full-scan
1159
+ ├── key: (16)
1160
+ └── fd: ()-->(17,18)
1161
+
1068
1162
opt-post-queries locality=(region=east)
1069
1163
DELETE FROM parent WHERE v = 1
1070
1164
----
@@ -1121,3 +1215,139 @@ DROP TABLE child
1121
1215
exec-ddl
1122
1216
DROP TABLE parent
1123
1217
----
1218
+
1219
+ # --------------------------------------------------
1220
+ # Test a computed region column.
1221
+ # --------------------------------------------------
1222
+
1223
+ exec-ddl
1224
+ CREATE TABLE parent (k INT PRIMARY KEY, v INT) LOCALITY REGIONAL BY ROW
1225
+ ----
1226
+
1227
+ exec-ddl
1228
+ CREATE TABLE child (
1229
+ a INT PRIMARY KEY,
1230
+ b INT NOT NULL,
1231
+ crdb_region STRING NOT NULL AS (CASE WHEN b = 1 THEN 'east' ELSE 'west' END) STORED,
1232
+ FOREIGN KEY (crdb_region, b) REFERENCES parent(crdb_region, k) ON UPDATE CASCADE ON DELETE CASCADE,
1233
+ INDEX (b)
1234
+ ) LOCALITY REGIONAL BY ROW
1235
+ ----
1236
+
1237
+ # TODO(#146705): disallowing the fast path for RBR tables regresses in this
1238
+ # case because the computed column expression can be used to infer a filter
1239
+ # that constrains the region column to a constant value.
1240
+ opt-post-queries locality=(region=east)
1241
+ DELETE FROM parent WHERE k = 1
1242
+ ----
1243
+ root
1244
+ ├── delete parent
1245
+ │ ├── columns: <none>
1246
+ │ ├── fetch columns: k:6 crdb_region:8
1247
+ │ ├── input binding: &1
1248
+ │ ├── cascades
1249
+ │ │ └── child_crdb_region_b_fkey
1250
+ │ ├── cardinality: [0 - 0]
1251
+ │ ├── volatile, mutations
1252
+ │ └── locality-optimized-search
1253
+ │ ├── columns: k:6!null crdb_region:8!null
1254
+ │ ├── left columns: k:11 crdb_region:13
1255
+ │ ├── right columns: k:16 crdb_region:18
1256
+ │ ├── cardinality: [0 - 1]
1257
+ │ ├── key: ()
1258
+ │ ├── fd: ()-->(6,8)
1259
+ │ ├── scan parent
1260
+ │ │ ├── columns: k:11!null crdb_region:13!null
1261
+ │ │ ├── constraint: /13/11: [/'east'/1 - /'east'/1]
1262
+ │ │ ├── flags: avoid-full-scan
1263
+ │ │ ├── cardinality: [0 - 1]
1264
+ │ │ ├── key: ()
1265
+ │ │ └── fd: ()-->(11,13)
1266
+ │ └── scan parent
1267
+ │ ├── columns: k:16!null crdb_region:18!null
1268
+ │ ├── constraint: /18/16
1269
+ │ │ ├── [/'central'/1 - /'central'/1]
1270
+ │ │ └── [/'west'/1 - /'west'/1]
1271
+ │ ├── flags: avoid-full-scan
1272
+ │ ├── cardinality: [0 - 1]
1273
+ │ ├── key: ()
1274
+ │ └── fd: ()-->(16,18)
1275
+ └── cascade
1276
+ └── delete child
1277
+ ├── columns: <none>
1278
+ ├── fetch columns: a:16 b:17 child.crdb_region:18
1279
+ ├── cardinality: [0 - 0]
1280
+ ├── volatile, mutations
1281
+ └── project
1282
+ ├── columns: a:16!null b:17!null child.crdb_region:18!null
1283
+ ├── key: (16)
1284
+ ├── fd: (16)-->(17,18), (17)-->(18)
1285
+ └── inner-join (lookup child@child_crdb_region_b_idx)
1286
+ ├── columns: a:16!null b:17!null child.crdb_region:18!null crdb_region:21!null k:22!null
1287
+ ├── key columns: [21 22] = [18 17]
1288
+ ├── key: (16)
1289
+ ├── fd: ()-->(17,18,21,22), (18)==(21), (21)==(18), (17)==(22), (22)==(17)
1290
+ ├── with-scan &1
1291
+ │ ├── columns: crdb_region:21!null k:22!null
1292
+ │ ├── mapping:
1293
+ │ │ ├── parent.crdb_region:8 => crdb_region:21
1294
+ │ │ └── parent.k:6 => k:22
1295
+ │ ├── cardinality: [0 - 1]
1296
+ │ ├── key: ()
1297
+ │ └── fd: ()-->(21,22)
1298
+ └── filters (true)
1299
+
1300
+ opt-post-queries locality=(region=east) set=optimizer_disable_cross_region_cascade_fast_path_for_rbr_tables=false
1301
+ DELETE FROM parent WHERE k = 1
1302
+ ----
1303
+ root
1304
+ ├── delete parent
1305
+ │ ├── columns: <none>
1306
+ │ ├── fetch columns: k:6 crdb_region:8
1307
+ │ ├── cascades
1308
+ │ │ └── child_crdb_region_b_fkey
1309
+ │ ├── cardinality: [0 - 0]
1310
+ │ ├── volatile, mutations
1311
+ │ └── locality-optimized-search
1312
+ │ ├── columns: k:6!null crdb_region:8!null
1313
+ │ ├── left columns: k:11 crdb_region:13
1314
+ │ ├── right columns: k:16 crdb_region:18
1315
+ │ ├── cardinality: [0 - 1]
1316
+ │ ├── key: ()
1317
+ │ ├── fd: ()-->(6,8)
1318
+ │ ├── scan parent
1319
+ │ │ ├── columns: k:11!null crdb_region:13!null
1320
+ │ │ ├── constraint: /13/11: [/'east'/1 - /'east'/1]
1321
+ │ │ ├── flags: avoid-full-scan
1322
+ │ │ ├── cardinality: [0 - 1]
1323
+ │ │ ├── key: ()
1324
+ │ │ └── fd: ()-->(11,13)
1325
+ │ └── scan parent
1326
+ │ ├── columns: k:16!null crdb_region:18!null
1327
+ │ ├── constraint: /18/16
1328
+ │ │ ├── [/'central'/1 - /'central'/1]
1329
+ │ │ └── [/'west'/1 - /'west'/1]
1330
+ │ ├── flags: avoid-full-scan
1331
+ │ ├── cardinality: [0 - 1]
1332
+ │ ├── key: ()
1333
+ │ └── fd: ()-->(16,18)
1334
+ └── cascade
1335
+ └── delete child
1336
+ ├── columns: <none>
1337
+ ├── fetch columns: a:16 b:17 child.crdb_region:18
1338
+ ├── cardinality: [0 - 0]
1339
+ ├── volatile, mutations
1340
+ └── scan child@child_crdb_region_b_idx
1341
+ ├── columns: a:16!null b:17!null child.crdb_region:18!null
1342
+ ├── constraint: /18/17/16: [/'east'/1 - /'east'/1]
1343
+ ├── flags: avoid-full-scan
1344
+ ├── key: (16)
1345
+ └── fd: ()-->(17,18)
1346
+
1347
+ exec-ddl
1348
+ DROP TABLE child
1349
+ ----
1350
+
1351
+ exec-ddl
1352
+ DROP TABLE parent
1353
+ ----
0 commit comments