github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/xform/testdata/rules/join_order (about) 1 exec-ddl 2 CREATE TABLE bx ( 3 b INT PRIMARY KEY, 4 x INT 5 ) 6 ---- 7 8 exec-ddl 9 CREATE TABLE cy ( 10 c INT PRIMARY KEY, 11 y INT 12 ) 13 ---- 14 15 exec-ddl 16 CREATE TABLE dz ( 17 d INT PRIMARY KEY, 18 z INT 19 ) 20 ---- 21 22 exec-ddl 23 CREATE TABLE abc ( 24 a INT PRIMARY KEY, 25 b INT, 26 c INT, 27 d INT 28 ) 29 ---- 30 31 opt join-limit=3 32 SELECT * FROM abc, bx, cy WHERE a = 1 AND abc.b = bx.b AND abc.c = cy.c 33 ---- 34 inner-join (lookup bx) 35 ├── columns: a:1!null b:2!null c:3!null d:4 b:5!null x:6 c:7!null y:8 36 ├── key columns: [2] = [5] 37 ├── lookup columns are key 38 ├── cardinality: [0 - 1] 39 ├── key: () 40 ├── fd: ()-->(1-8) 41 ├── inner-join (lookup cy) 42 │ ├── columns: a:1!null abc.b:2 abc.c:3!null d:4 cy.c:7!null y:8 43 │ ├── key columns: [3] = [7] 44 │ ├── lookup columns are key 45 │ ├── cardinality: [0 - 1] 46 │ ├── key: () 47 │ ├── fd: ()-->(1-4,7,8) 48 │ ├── scan abc 49 │ │ ├── columns: a:1!null abc.b:2 abc.c:3 d:4 50 │ │ ├── constraint: /1: [/1 - /1] 51 │ │ ├── cardinality: [0 - 1] 52 │ │ ├── key: () 53 │ │ └── fd: ()-->(1-4) 54 │ └── filters (true) 55 └── filters (true) 56 57 opt join-limit=3 58 SELECT * FROM bx, abc, cy WHERE a = 1 AND abc.b = bx.b AND abc.c = cy.c 59 ---- 60 inner-join (lookup bx) 61 ├── columns: b:1!null x:2 a:3!null b:4!null c:5!null d:6 c:7!null y:8 62 ├── key columns: [4] = [1] 63 ├── lookup columns are key 64 ├── cardinality: [0 - 1] 65 ├── key: () 66 ├── fd: ()-->(1-8) 67 ├── inner-join (lookup cy) 68 │ ├── columns: a:3!null abc.b:4 abc.c:5!null d:6 cy.c:7!null y:8 69 │ ├── key columns: [5] = [7] 70 │ ├── lookup columns are key 71 │ ├── cardinality: [0 - 1] 72 │ ├── key: () 73 │ ├── fd: ()-->(3-8) 74 │ ├── scan abc 75 │ │ ├── columns: a:3!null abc.b:4 abc.c:5 d:6 76 │ │ ├── constraint: /3: [/1 - /1] 77 │ │ ├── cardinality: [0 - 1] 78 │ │ ├── key: () 79 │ │ └── fd: ()-->(3-6) 80 │ └── filters (true) 81 └── filters (true) 82 83 opt join-limit=3 84 SELECT * FROM bx, cy, abc WHERE a = 1 AND abc.b = bx.b AND abc.c = cy.c 85 ---- 86 inner-join (lookup bx) 87 ├── columns: b:1!null x:2 c:3!null y:4 a:5!null b:6!null c:7!null d:8 88 ├── key columns: [6] = [1] 89 ├── lookup columns are key 90 ├── cardinality: [0 - 1] 91 ├── key: () 92 ├── fd: ()-->(1-8) 93 ├── inner-join (lookup cy) 94 │ ├── columns: cy.c:3!null y:4 a:5!null abc.b:6 abc.c:7!null d:8 95 │ ├── key columns: [7] = [3] 96 │ ├── lookup columns are key 97 │ ├── cardinality: [0 - 1] 98 │ ├── key: () 99 │ ├── fd: ()-->(3-8) 100 │ ├── scan abc 101 │ │ ├── columns: a:5!null abc.b:6 abc.c:7 d:8 102 │ │ ├── constraint: /5: [/1 - /1] 103 │ │ ├── cardinality: [0 - 1] 104 │ │ ├── key: () 105 │ │ └── fd: ()-->(5-8) 106 │ └── filters (true) 107 └── filters (true) 108 109 opt join-limit=2 expect-not=AssociateJoin 110 SELECT * FROM bx, cy, abc WHERE a = 1 AND abc.b = bx.b AND abc.c = cy.c 111 ---- 112 inner-join (lookup bx) 113 ├── columns: b:1!null x:2 c:3!null y:4 a:5!null b:6!null c:7!null d:8 114 ├── key columns: [6] = [1] 115 ├── lookup columns are key 116 ├── cardinality: [0 - 1] 117 ├── key: () 118 ├── fd: ()-->(1-8) 119 ├── inner-join (lookup cy) 120 │ ├── columns: cy.c:3!null y:4 a:5!null abc.b:6 abc.c:7!null d:8 121 │ ├── key columns: [7] = [3] 122 │ ├── lookup columns are key 123 │ ├── cardinality: [0 - 1] 124 │ ├── key: () 125 │ ├── fd: ()-->(3-8) 126 │ ├── scan abc 127 │ │ ├── columns: a:5!null abc.b:6 abc.c:7 d:8 128 │ │ ├── constraint: /5: [/1 - /1] 129 │ │ ├── cardinality: [0 - 1] 130 │ │ ├── key: () 131 │ │ └── fd: ()-->(5-8) 132 │ └── filters (true) 133 └── filters (true) 134 135 memo join-limit=3 136 SELECT * FROM bx, cy, abc WHERE a = 1 AND abc.b = bx.b AND abc.c = cy.c 137 ---- 138 memo (optimized, ~33KB, required=[presentation: b:1,x:2,c:3,y:4,a:5,b:6,c:7,d:8]) 139 ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+1,+6) (lookup-join G3 G5 bx,keyCols=[6],outCols=(1-8)) (inner-join G6 G7 G8) (inner-join G9 G10 G11) (inner-join G7 G6 G8) (merge-join G6 G7 G5 inner-join,+3,+7) (inner-join G10 G9 G11) (lookup-join G7 G5 cy,keyCols=[7],outCols=(1-8)) (lookup-join G12 G11 abc,keyCols=[11],outCols=(1-8)) 140 │ └── [presentation: b:1,x:2,c:3,y:4,a:5,b:6,c:7,d:8] 141 │ ├── best: (lookup-join G3 G5 bx,keyCols=[6],outCols=(1-8)) 142 │ └── cost: 13.11 143 ├── G2: (scan bx) 144 │ ├── [ordering: +1] 145 │ │ ├── best: (scan bx) 146 │ │ └── cost: 1040.02 147 │ └── [] 148 │ ├── best: (scan bx) 149 │ └── cost: 1040.02 150 ├── G3: (inner-join G6 G9 G8) (inner-join G9 G6 G8) (merge-join G6 G9 G5 inner-join,+3,+7) (lookup-join G13 G8 abc,keyCols=[9],outCols=(3-8)) (lookup-join G9 G5 cy,keyCols=[7],outCols=(3-8)) 151 │ └── [] 152 │ ├── best: (lookup-join G9 G5 cy,keyCols=[7],outCols=(3-8)) 153 │ └── cost: 7.12 154 ├── G4: (filters G14) 155 ├── G5: (filters) 156 ├── G6: (scan cy) 157 │ ├── [ordering: +3] 158 │ │ ├── best: (scan cy) 159 │ │ └── cost: 1040.02 160 │ └── [] 161 │ ├── best: (scan cy) 162 │ └── cost: 1040.02 163 ├── G7: (inner-join G9 G2 G4) (inner-join G2 G9 G4) (lookup-join G9 G5 bx,keyCols=[6],outCols=(1,2,5-8)) (merge-join G2 G9 G5 inner-join,+1,+6) (lookup-join G15 G4 abc,keyCols=[10],outCols=(1,2,5-8)) 164 │ └── [] 165 │ ├── best: (lookup-join G9 G5 bx,keyCols=[6],outCols=(1,2,5-8)) 166 │ └── cost: 7.12 167 ├── G8: (filters G16) 168 ├── G9: (select G17 G18) (scan abc,constrained) 169 │ └── [] 170 │ ├── best: (scan abc,constrained) 171 │ └── cost: 1.09 172 ├── G10: (inner-join G6 G2 G5) (inner-join G2 G6 G5) 173 │ └── [] 174 │ ├── best: (inner-join G6 G2 G5) 175 │ └── cost: 12110.05 176 ├── G11: (filters G14 G16) 177 ├── G12: (project G10 G19 b x c y) 178 │ └── [] 179 │ ├── best: (project G10 G19 b x c y) 180 │ └── cost: 32110.06 181 ├── G13: (project G6 G19 c y) 182 │ └── [] 183 │ ├── best: (project G6 G19 c y) 184 │ └── cost: 1060.03 185 ├── G14: (eq G20 G21) 186 ├── G15: (project G2 G19 b x) 187 │ └── [] 188 │ ├── best: (project G2 G19 b x) 189 │ └── cost: 1060.03 190 ├── G16: (eq G22 G23) 191 ├── G17: (scan abc) 192 │ └── [] 193 │ ├── best: (scan abc) 194 │ └── cost: 1080.02 195 ├── G18: (filters G24) 196 ├── G19: (projections G25) 197 ├── G20: (variable abc.b) 198 ├── G21: (variable bx.b) 199 ├── G22: (variable abc.c) 200 ├── G23: (variable cy.c) 201 ├── G24: (eq G26 G25) 202 ├── G25: (const 1) 203 └── G26: (variable a) 204 205 opt join-limit=4 206 SELECT * FROM bx, cy, dz, abc WHERE a = 1 207 ---- 208 inner-join (cross) 209 ├── columns: b:1!null x:2 c:3!null y:4 d:5!null z:6 a:7!null b:8 c:9 d:10 210 ├── key: (1,3,5) 211 ├── fd: ()-->(7-10), (1)-->(2), (3)-->(4), (5)-->(6) 212 ├── inner-join (cross) 213 │ ├── columns: cy.c:3!null y:4 dz.d:5!null z:6 a:7!null abc.b:8 abc.c:9 abc.d:10 214 │ ├── key: (3,5) 215 │ ├── fd: ()-->(7-10), (3)-->(4), (5)-->(6) 216 │ ├── scan cy 217 │ │ ├── columns: cy.c:3!null y:4 218 │ │ ├── key: (3) 219 │ │ └── fd: (3)-->(4) 220 │ ├── inner-join (cross) 221 │ │ ├── columns: dz.d:5!null z:6 a:7!null abc.b:8 abc.c:9 abc.d:10 222 │ │ ├── key: (5) 223 │ │ ├── fd: ()-->(7-10), (5)-->(6) 224 │ │ ├── scan dz 225 │ │ │ ├── columns: dz.d:5!null z:6 226 │ │ │ ├── key: (5) 227 │ │ │ └── fd: (5)-->(6) 228 │ │ ├── scan abc 229 │ │ │ ├── columns: a:7!null abc.b:8 abc.c:9 abc.d:10 230 │ │ │ ├── constraint: /7: [/1 - /1] 231 │ │ │ ├── cardinality: [0 - 1] 232 │ │ │ ├── key: () 233 │ │ │ └── fd: ()-->(7-10) 234 │ │ └── filters (true) 235 │ └── filters (true) 236 ├── scan bx 237 │ ├── columns: bx.b:1!null x:2 238 │ ├── key: (1) 239 │ └── fd: (1)-->(2) 240 └── filters (true) 241 242 opt join-limit=3 format=show-all 243 SELECT * FROM abc, bx, cy, dz WHERE a = 1 244 ---- 245 inner-join (cross) 246 ├── columns: a:1(int!null) b:2(int) c:3(int) d:4(int) b:5(int!null) x:6(int) c:7(int!null) y:8(int) d:9(int!null) z:10(int) 247 ├── stats: [rows=1e+09] 248 ├── cost: 32525668.7 249 ├── key: (5,7,9) 250 ├── fd: ()-->(1-4), (5)-->(6), (7)-->(8), (9)-->(10) 251 ├── prune: (2-10) 252 ├── interesting orderings: (+7) (+9) (+5) (+1) 253 ├── multiplicity: left-rows(one-or-zero), right-rows(zero-or-more) 254 ├── inner-join (cross) 255 │ ├── columns: t.public.bx.b:5(int!null) t.public.bx.x:6(int) t.public.cy.c:7(int!null) t.public.cy.y:8(int) t.public.dz.d:9(int!null) t.public.dz.z:10(int) 256 │ ├── stats: [rows=1e+09] 257 │ ├── cost: 10025667.6 258 │ ├── key: (5,7,9) 259 │ ├── fd: (5)-->(6), (7)-->(8), (9)-->(10) 260 │ ├── prune: (5-10) 261 │ ├── interesting orderings: (+7) (+9) (+5) 262 │ ├── join-size: 3 263 │ ├── inner-join (cross) 264 │ │ ├── columns: t.public.cy.c:7(int!null) t.public.cy.y:8(int) t.public.dz.d:9(int!null) t.public.dz.z:10(int) 265 │ │ ├── stats: [rows=1000000] 266 │ │ ├── cost: 12110.05 267 │ │ ├── key: (7,9) 268 │ │ ├── fd: (7)-->(8), (9)-->(10) 269 │ │ ├── prune: (7-10) 270 │ │ ├── interesting orderings: (+7) (+9) 271 │ │ ├── join-size: 2 272 │ │ ├── scan t.public.cy 273 │ │ │ ├── columns: t.public.cy.c:7(int!null) t.public.cy.y:8(int) 274 │ │ │ ├── stats: [rows=1000] 275 │ │ │ ├── cost: 1040.02 276 │ │ │ ├── key: (7) 277 │ │ │ ├── fd: (7)-->(8) 278 │ │ │ ├── prune: (7,8) 279 │ │ │ └── interesting orderings: (+7) 280 │ │ ├── scan t.public.dz 281 │ │ │ ├── columns: t.public.dz.d:9(int!null) t.public.dz.z:10(int) 282 │ │ │ ├── stats: [rows=1000] 283 │ │ │ ├── cost: 1040.02 284 │ │ │ ├── key: (9) 285 │ │ │ ├── fd: (9)-->(10) 286 │ │ │ ├── prune: (9,10) 287 │ │ │ └── interesting orderings: (+9) 288 │ │ └── filters (true) 289 │ ├── scan t.public.bx 290 │ │ ├── columns: t.public.bx.b:5(int!null) t.public.bx.x:6(int) 291 │ │ ├── stats: [rows=1000] 292 │ │ ├── cost: 1040.02 293 │ │ ├── key: (5) 294 │ │ ├── fd: (5)-->(6) 295 │ │ ├── prune: (5,6) 296 │ │ └── interesting orderings: (+5) 297 │ └── filters (true) 298 ├── scan t.public.abc 299 │ ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int) t.public.abc.c:3(int) t.public.abc.d:4(int) 300 │ ├── constraint: /1: [/1 - /1] 301 │ ├── cardinality: [0 - 1] 302 │ ├── stats: [rows=1, distinct(1)=1, null(1)=0] 303 │ ├── cost: 1.09 304 │ ├── key: () 305 │ ├── fd: ()-->(1-4) 306 │ ├── prune: (2-4) 307 │ └── interesting orderings: (+1) 308 └── filters (true) 309 310 # Note the difference in memo size for with and without reorder-joins, for only four tables. 311 # TODO(justin): Find a way to reduce this. 312 313 memo join-limit=1 314 SELECT * FROM bx, cy, dz, abc WHERE a = 1 315 ---- 316 memo (optimized, ~13KB, required=[presentation: b:1,x:2,c:3,y:4,d:5,z:6,a:7,b:8,c:9,d:10]) 317 ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) 318 │ └── [presentation: b:1,x:2,c:3,y:4,d:5,z:6,a:7,b:8,c:9,d:10] 319 │ ├── best: (inner-join G3 G2 G4) 320 │ └── cost: 10025691.20 321 ├── G2: (scan bx) 322 │ └── [] 323 │ ├── best: (scan bx) 324 │ └── cost: 1040.02 325 ├── G3: (inner-join G5 G6 G4) (inner-join G6 G5 G4) 326 │ └── [] 327 │ ├── best: (inner-join G5 G6 G4) 328 │ └── cost: 12133.67 329 ├── G4: (filters) 330 ├── G5: (scan cy) 331 │ └── [] 332 │ ├── best: (scan cy) 333 │ └── cost: 1040.02 334 ├── G6: (inner-join G7 G8 G4) (inner-join G8 G7 G4) 335 │ └── [] 336 │ ├── best: (inner-join G7 G8 G4) 337 │ └── cost: 1063.64 338 ├── G7: (scan dz) 339 │ └── [] 340 │ ├── best: (scan dz) 341 │ └── cost: 1040.02 342 ├── G8: (select G9 G10) (scan abc,constrained) 343 │ └── [] 344 │ ├── best: (scan abc,constrained) 345 │ └── cost: 1.09 346 ├── G9: (scan abc) 347 │ └── [] 348 │ ├── best: (scan abc) 349 │ └── cost: 1080.02 350 ├── G10: (filters G11) 351 ├── G11: (eq G12 G13) 352 ├── G12: (variable a) 353 └── G13: (const 1) 354 355 memo join-limit=4 356 SELECT * FROM bx, cy, dz, abc WHERE a = 1 357 ---- 358 memo (optimized, ~28KB, required=[presentation: b:1,x:2,c:3,y:4,d:5,z:6,a:7,b:8,c:9,d:10]) 359 ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) (inner-join G5 G6 G4) (inner-join G7 G8 G4) (inner-join G9 G10 G4) (inner-join G11 G12 G4) (inner-join G13 G14 G4) (inner-join G15 G16 G4) (inner-join G6 G5 G4) (inner-join G8 G7 G4) (inner-join G10 G9 G4) (inner-join G12 G11 G4) (inner-join G14 G13 G4) (inner-join G16 G15 G4) 360 │ └── [presentation: b:1,x:2,c:3,y:4,d:5,z:6,a:7,b:8,c:9,d:10] 361 │ ├── best: (inner-join G3 G2 G4) 362 │ └── cost: 10025691.20 363 ├── G2: (scan bx) 364 │ └── [] 365 │ ├── best: (scan bx) 366 │ └── cost: 1040.02 367 ├── G3: (inner-join G5 G7 G4) (inner-join G7 G5 G4) (inner-join G9 G13 G4) (inner-join G11 G15 G4) (inner-join G13 G9 G4) (inner-join G15 G11 G4) 368 │ └── [] 369 │ ├── best: (inner-join G5 G7 G4) 370 │ └── cost: 12133.67 371 ├── G4: (filters) 372 ├── G5: (scan cy) 373 │ └── [] 374 │ ├── best: (scan cy) 375 │ └── cost: 1040.02 376 ├── G6: (inner-join G7 G2 G4) (inner-join G2 G7 G4) (inner-join G9 G16 G4) (inner-join G11 G14 G4) (inner-join G16 G9 G4) (inner-join G14 G11 G4) 377 │ └── [] 378 │ ├── best: (inner-join G7 G2 G4) 379 │ └── cost: 12133.67 380 ├── G7: (inner-join G9 G11 G4) (inner-join G11 G9 G4) 381 │ └── [] 382 │ ├── best: (inner-join G9 G11 G4) 383 │ └── cost: 1063.64 384 ├── G8: (inner-join G5 G2 G4) (inner-join G2 G5 G4) 385 │ └── [] 386 │ ├── best: (inner-join G5 G2 G4) 387 │ └── cost: 12110.05 388 ├── G9: (scan dz) 389 │ └── [] 390 │ ├── best: (scan dz) 391 │ └── cost: 1040.02 392 ├── G10: (inner-join G13 G2 G4) (inner-join G2 G13 G4) (inner-join G11 G8 G4) (inner-join G5 G16 G4) (inner-join G8 G11 G4) (inner-join G16 G5 G4) 393 │ └── [] 394 │ ├── best: (inner-join G13 G2 G4) 395 │ └── cost: 12133.67 396 ├── G11: (select G17 G18) (scan abc,constrained) 397 │ └── [] 398 │ ├── best: (scan abc,constrained) 399 │ └── cost: 1.09 400 ├── G12: (inner-join G15 G2 G4) (inner-join G2 G15 G4) (inner-join G9 G8 G4) (inner-join G5 G14 G4) (inner-join G8 G9 G4) (inner-join G14 G5 G4) 401 │ └── [] 402 │ ├── best: (inner-join G15 G2 G4) 403 │ └── cost: 10025667.58 404 ├── G13: (inner-join G11 G5 G4) (inner-join G5 G11 G4) 405 │ └── [] 406 │ ├── best: (inner-join G5 G11 G4) 407 │ └── cost: 1063.64 408 ├── G14: (inner-join G9 G2 G4) (inner-join G2 G9 G4) 409 │ └── [] 410 │ ├── best: (inner-join G9 G2 G4) 411 │ └── cost: 12110.05 412 ├── G15: (inner-join G9 G5 G4) (inner-join G5 G9 G4) 413 │ └── [] 414 │ ├── best: (inner-join G9 G5 G4) 415 │ └── cost: 12110.05 416 ├── G16: (inner-join G11 G2 G4) (inner-join G2 G11 G4) 417 │ └── [] 418 │ ├── best: (inner-join G2 G11 G4) 419 │ └── cost: 1063.64 420 ├── G17: (scan abc) 421 │ └── [] 422 │ ├── best: (scan abc) 423 │ └── cost: 1080.02 424 ├── G18: (filters G19) 425 ├── G19: (eq G20 G21) 426 ├── G20: (variable a) 427 └── G21: (const 1) 428 429 # Regression test for #34795. 430 exec-ddl 431 CREATE TABLE a (id INT8 PRIMARY KEY) 432 ---- 433 434 opt join-limit=4 435 SELECT 436 1 437 FROM 438 a as a1 439 INNER JOIN a as a2 ON 1 = a2.id 440 INNER JOIN a AS a3 ON a1.id = a3.id 441 CROSS JOIN a as a4 442 WHERE 443 a4.id = 1 AND (SELECT true FROM a WHERE a1.id = 1) 444 ---- 445 project 446 ├── columns: "?column?":7!null 447 ├── fd: ()-->(7) 448 ├── inner-join (cross) 449 │ ├── columns: a1.id:1!null a2.id:2!null a3.id:3!null a4.id:4!null bool:6!null 450 │ ├── key: (3) 451 │ ├── fd: ()-->(2,4,6), (1)==(3), (3)==(1) 452 │ ├── inner-join (lookup a) 453 │ │ ├── columns: a1.id:1!null a2.id:2!null a3.id:3!null bool:6!null 454 │ │ ├── key columns: [1] = [3] 455 │ │ ├── lookup columns are key 456 │ │ ├── key: (3) 457 │ │ ├── fd: ()-->(2,6), (1)==(3), (3)==(1) 458 │ │ ├── inner-join (cross) 459 │ │ │ ├── columns: a1.id:1!null a2.id:2!null bool:6!null 460 │ │ │ ├── key: (1) 461 │ │ │ ├── fd: ()-->(2,6) 462 │ │ │ ├── select 463 │ │ │ │ ├── columns: a1.id:1!null bool:6!null 464 │ │ │ │ ├── key: (1) 465 │ │ │ │ ├── fd: ()-->(6) 466 │ │ │ │ ├── ensure-distinct-on 467 │ │ │ │ │ ├── columns: a1.id:1!null bool:6 468 │ │ │ │ │ ├── grouping columns: a1.id:1!null 469 │ │ │ │ │ ├── error: "more than one row returned by a subquery used as an expression" 470 │ │ │ │ │ ├── key: (1) 471 │ │ │ │ │ ├── fd: (1)-->(6) 472 │ │ │ │ │ ├── left-join (cross) 473 │ │ │ │ │ │ ├── columns: a1.id:1!null bool:6 474 │ │ │ │ │ │ ├── scan a1 475 │ │ │ │ │ │ │ ├── columns: a1.id:1!null 476 │ │ │ │ │ │ │ └── key: (1) 477 │ │ │ │ │ │ ├── project 478 │ │ │ │ │ │ │ ├── columns: bool:6!null 479 │ │ │ │ │ │ │ ├── fd: ()-->(6) 480 │ │ │ │ │ │ │ ├── scan a 481 │ │ │ │ │ │ │ └── projections 482 │ │ │ │ │ │ │ └── true [as=bool:6] 483 │ │ │ │ │ │ └── filters 484 │ │ │ │ │ │ └── a1.id:1 = 1 [outer=(1), constraints=(/1: [/1 - /1]; tight), fd=()-->(1)] 485 │ │ │ │ │ └── aggregations 486 │ │ │ │ │ └── const-agg [as=bool:6, outer=(6)] 487 │ │ │ │ │ └── bool:6 488 │ │ │ │ └── filters 489 │ │ │ │ └── bool:6 [outer=(6), constraints=(/6: [/true - /true]; tight), fd=()-->(6)] 490 │ │ │ ├── scan a2 491 │ │ │ │ ├── columns: a2.id:2!null 492 │ │ │ │ ├── constraint: /2: [/1 - /1] 493 │ │ │ │ ├── cardinality: [0 - 1] 494 │ │ │ │ ├── key: () 495 │ │ │ │ └── fd: ()-->(2) 496 │ │ │ └── filters (true) 497 │ │ └── filters (true) 498 │ ├── scan a4 499 │ │ ├── columns: a4.id:4!null 500 │ │ ├── constraint: /4: [/1 - /1] 501 │ │ ├── cardinality: [0 - 1] 502 │ │ ├── key: () 503 │ │ └── fd: ()-->(4) 504 │ └── filters (true) 505 └── projections 506 └── 1 [as="?column?":7]