1-- 2-- JOIN 3-- Test JOIN clauses 4-- 5CREATE TABLE J1_TBL ( 6 i integer, 7 j integer, 8 t text 9); 10CREATE TABLE J2_TBL ( 11 i integer, 12 k integer 13); 14INSERT INTO J1_TBL VALUES (1, 4, 'one'); 15INSERT INTO J1_TBL VALUES (2, 3, 'two'); 16INSERT INTO J1_TBL VALUES (3, 2, 'three'); 17INSERT INTO J1_TBL VALUES (4, 1, 'four'); 18INSERT INTO J1_TBL VALUES (5, 0, 'five'); 19INSERT INTO J1_TBL VALUES (6, 6, 'six'); 20INSERT INTO J1_TBL VALUES (7, 7, 'seven'); 21INSERT INTO J1_TBL VALUES (8, 8, 'eight'); 22INSERT INTO J1_TBL VALUES (0, NULL, 'zero'); 23INSERT INTO J1_TBL VALUES (NULL, NULL, 'null'); 24INSERT INTO J1_TBL VALUES (NULL, 0, 'zero'); 25INSERT INTO J2_TBL VALUES (1, -1); 26INSERT INTO J2_TBL VALUES (2, 2); 27INSERT INTO J2_TBL VALUES (3, -3); 28INSERT INTO J2_TBL VALUES (2, 4); 29INSERT INTO J2_TBL VALUES (5, -5); 30INSERT INTO J2_TBL VALUES (5, -5); 31INSERT INTO J2_TBL VALUES (0, NULL); 32INSERT INTO J2_TBL VALUES (NULL, NULL); 33INSERT INTO J2_TBL VALUES (NULL, 0); 34-- useful in some tests below 35create temp table onerow(); 36insert into onerow default values; 37analyze onerow; 38-- 39-- CORRELATION NAMES 40-- Make sure that table/column aliases are supported 41-- before diving into more complex join syntax. 42-- 43SELECT * 44 FROM J1_TBL AS tx; 45 i | j | t 46---+---+------- 47 1 | 4 | one 48 2 | 3 | two 49 3 | 2 | three 50 4 | 1 | four 51 5 | 0 | five 52 6 | 6 | six 53 7 | 7 | seven 54 8 | 8 | eight 55 0 | | zero 56 | | null 57 | 0 | zero 58(11 rows) 59 60SELECT * 61 FROM J1_TBL tx; 62 i | j | t 63---+---+------- 64 1 | 4 | one 65 2 | 3 | two 66 3 | 2 | three 67 4 | 1 | four 68 5 | 0 | five 69 6 | 6 | six 70 7 | 7 | seven 71 8 | 8 | eight 72 0 | | zero 73 | | null 74 | 0 | zero 75(11 rows) 76 77SELECT * 78 FROM J1_TBL AS t1 (a, b, c); 79 a | b | c 80---+---+------- 81 1 | 4 | one 82 2 | 3 | two 83 3 | 2 | three 84 4 | 1 | four 85 5 | 0 | five 86 6 | 6 | six 87 7 | 7 | seven 88 8 | 8 | eight 89 0 | | zero 90 | | null 91 | 0 | zero 92(11 rows) 93 94SELECT * 95 FROM J1_TBL t1 (a, b, c); 96 a | b | c 97---+---+------- 98 1 | 4 | one 99 2 | 3 | two 100 3 | 2 | three 101 4 | 1 | four 102 5 | 0 | five 103 6 | 6 | six 104 7 | 7 | seven 105 8 | 8 | eight 106 0 | | zero 107 | | null 108 | 0 | zero 109(11 rows) 110 111SELECT * 112 FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e); 113 a | b | c | d | e 114---+---+-------+---+---- 115 1 | 4 | one | 1 | -1 116 2 | 3 | two | 1 | -1 117 3 | 2 | three | 1 | -1 118 4 | 1 | four | 1 | -1 119 5 | 0 | five | 1 | -1 120 6 | 6 | six | 1 | -1 121 7 | 7 | seven | 1 | -1 122 8 | 8 | eight | 1 | -1 123 0 | | zero | 1 | -1 124 | | null | 1 | -1 125 | 0 | zero | 1 | -1 126 1 | 4 | one | 2 | 2 127 2 | 3 | two | 2 | 2 128 3 | 2 | three | 2 | 2 129 4 | 1 | four | 2 | 2 130 5 | 0 | five | 2 | 2 131 6 | 6 | six | 2 | 2 132 7 | 7 | seven | 2 | 2 133 8 | 8 | eight | 2 | 2 134 0 | | zero | 2 | 2 135 | | null | 2 | 2 136 | 0 | zero | 2 | 2 137 1 | 4 | one | 3 | -3 138 2 | 3 | two | 3 | -3 139 3 | 2 | three | 3 | -3 140 4 | 1 | four | 3 | -3 141 5 | 0 | five | 3 | -3 142 6 | 6 | six | 3 | -3 143 7 | 7 | seven | 3 | -3 144 8 | 8 | eight | 3 | -3 145 0 | | zero | 3 | -3 146 | | null | 3 | -3 147 | 0 | zero | 3 | -3 148 1 | 4 | one | 2 | 4 149 2 | 3 | two | 2 | 4 150 3 | 2 | three | 2 | 4 151 4 | 1 | four | 2 | 4 152 5 | 0 | five | 2 | 4 153 6 | 6 | six | 2 | 4 154 7 | 7 | seven | 2 | 4 155 8 | 8 | eight | 2 | 4 156 0 | | zero | 2 | 4 157 | | null | 2 | 4 158 | 0 | zero | 2 | 4 159 1 | 4 | one | 5 | -5 160 2 | 3 | two | 5 | -5 161 3 | 2 | three | 5 | -5 162 4 | 1 | four | 5 | -5 163 5 | 0 | five | 5 | -5 164 6 | 6 | six | 5 | -5 165 7 | 7 | seven | 5 | -5 166 8 | 8 | eight | 5 | -5 167 0 | | zero | 5 | -5 168 | | null | 5 | -5 169 | 0 | zero | 5 | -5 170 1 | 4 | one | 5 | -5 171 2 | 3 | two | 5 | -5 172 3 | 2 | three | 5 | -5 173 4 | 1 | four | 5 | -5 174 5 | 0 | five | 5 | -5 175 6 | 6 | six | 5 | -5 176 7 | 7 | seven | 5 | -5 177 8 | 8 | eight | 5 | -5 178 0 | | zero | 5 | -5 179 | | null | 5 | -5 180 | 0 | zero | 5 | -5 181 1 | 4 | one | 0 | 182 2 | 3 | two | 0 | 183 3 | 2 | three | 0 | 184 4 | 1 | four | 0 | 185 5 | 0 | five | 0 | 186 6 | 6 | six | 0 | 187 7 | 7 | seven | 0 | 188 8 | 8 | eight | 0 | 189 0 | | zero | 0 | 190 | | null | 0 | 191 | 0 | zero | 0 | 192 1 | 4 | one | | 193 2 | 3 | two | | 194 3 | 2 | three | | 195 4 | 1 | four | | 196 5 | 0 | five | | 197 6 | 6 | six | | 198 7 | 7 | seven | | 199 8 | 8 | eight | | 200 0 | | zero | | 201 | | null | | 202 | 0 | zero | | 203 1 | 4 | one | | 0 204 2 | 3 | two | | 0 205 3 | 2 | three | | 0 206 4 | 1 | four | | 0 207 5 | 0 | five | | 0 208 6 | 6 | six | | 0 209 7 | 7 | seven | | 0 210 8 | 8 | eight | | 0 211 0 | | zero | | 0 212 | | null | | 0 213 | 0 | zero | | 0 214(99 rows) 215 216SELECT t1.a, t2.e 217 FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e) 218 WHERE t1.a = t2.d; 219 a | e 220---+---- 221 0 | 222 1 | -1 223 2 | 2 224 2 | 4 225 3 | -3 226 5 | -5 227 5 | -5 228(7 rows) 229 230-- 231-- CROSS JOIN 232-- Qualifications are not allowed on cross joins, 233-- which degenerate into a standard unqualified inner join. 234-- 235SELECT * 236 FROM J1_TBL CROSS JOIN J2_TBL; 237 i | j | t | i | k 238---+---+-------+---+---- 239 1 | 4 | one | 1 | -1 240 2 | 3 | two | 1 | -1 241 3 | 2 | three | 1 | -1 242 4 | 1 | four | 1 | -1 243 5 | 0 | five | 1 | -1 244 6 | 6 | six | 1 | -1 245 7 | 7 | seven | 1 | -1 246 8 | 8 | eight | 1 | -1 247 0 | | zero | 1 | -1 248 | | null | 1 | -1 249 | 0 | zero | 1 | -1 250 1 | 4 | one | 2 | 2 251 2 | 3 | two | 2 | 2 252 3 | 2 | three | 2 | 2 253 4 | 1 | four | 2 | 2 254 5 | 0 | five | 2 | 2 255 6 | 6 | six | 2 | 2 256 7 | 7 | seven | 2 | 2 257 8 | 8 | eight | 2 | 2 258 0 | | zero | 2 | 2 259 | | null | 2 | 2 260 | 0 | zero | 2 | 2 261 1 | 4 | one | 3 | -3 262 2 | 3 | two | 3 | -3 263 3 | 2 | three | 3 | -3 264 4 | 1 | four | 3 | -3 265 5 | 0 | five | 3 | -3 266 6 | 6 | six | 3 | -3 267 7 | 7 | seven | 3 | -3 268 8 | 8 | eight | 3 | -3 269 0 | | zero | 3 | -3 270 | | null | 3 | -3 271 | 0 | zero | 3 | -3 272 1 | 4 | one | 2 | 4 273 2 | 3 | two | 2 | 4 274 3 | 2 | three | 2 | 4 275 4 | 1 | four | 2 | 4 276 5 | 0 | five | 2 | 4 277 6 | 6 | six | 2 | 4 278 7 | 7 | seven | 2 | 4 279 8 | 8 | eight | 2 | 4 280 0 | | zero | 2 | 4 281 | | null | 2 | 4 282 | 0 | zero | 2 | 4 283 1 | 4 | one | 5 | -5 284 2 | 3 | two | 5 | -5 285 3 | 2 | three | 5 | -5 286 4 | 1 | four | 5 | -5 287 5 | 0 | five | 5 | -5 288 6 | 6 | six | 5 | -5 289 7 | 7 | seven | 5 | -5 290 8 | 8 | eight | 5 | -5 291 0 | | zero | 5 | -5 292 | | null | 5 | -5 293 | 0 | zero | 5 | -5 294 1 | 4 | one | 5 | -5 295 2 | 3 | two | 5 | -5 296 3 | 2 | three | 5 | -5 297 4 | 1 | four | 5 | -5 298 5 | 0 | five | 5 | -5 299 6 | 6 | six | 5 | -5 300 7 | 7 | seven | 5 | -5 301 8 | 8 | eight | 5 | -5 302 0 | | zero | 5 | -5 303 | | null | 5 | -5 304 | 0 | zero | 5 | -5 305 1 | 4 | one | 0 | 306 2 | 3 | two | 0 | 307 3 | 2 | three | 0 | 308 4 | 1 | four | 0 | 309 5 | 0 | five | 0 | 310 6 | 6 | six | 0 | 311 7 | 7 | seven | 0 | 312 8 | 8 | eight | 0 | 313 0 | | zero | 0 | 314 | | null | 0 | 315 | 0 | zero | 0 | 316 1 | 4 | one | | 317 2 | 3 | two | | 318 3 | 2 | three | | 319 4 | 1 | four | | 320 5 | 0 | five | | 321 6 | 6 | six | | 322 7 | 7 | seven | | 323 8 | 8 | eight | | 324 0 | | zero | | 325 | | null | | 326 | 0 | zero | | 327 1 | 4 | one | | 0 328 2 | 3 | two | | 0 329 3 | 2 | three | | 0 330 4 | 1 | four | | 0 331 5 | 0 | five | | 0 332 6 | 6 | six | | 0 333 7 | 7 | seven | | 0 334 8 | 8 | eight | | 0 335 0 | | zero | | 0 336 | | null | | 0 337 | 0 | zero | | 0 338(99 rows) 339 340-- ambiguous column 341SELECT i, k, t 342 FROM J1_TBL CROSS JOIN J2_TBL; 343ERROR: column reference "i" is ambiguous 344LINE 1: SELECT i, k, t 345 ^ 346-- resolve previous ambiguity by specifying the table name 347SELECT t1.i, k, t 348 FROM J1_TBL t1 CROSS JOIN J2_TBL t2; 349 i | k | t 350---+----+------- 351 1 | -1 | one 352 2 | -1 | two 353 3 | -1 | three 354 4 | -1 | four 355 5 | -1 | five 356 6 | -1 | six 357 7 | -1 | seven 358 8 | -1 | eight 359 0 | -1 | zero 360 | -1 | null 361 | -1 | zero 362 1 | 2 | one 363 2 | 2 | two 364 3 | 2 | three 365 4 | 2 | four 366 5 | 2 | five 367 6 | 2 | six 368 7 | 2 | seven 369 8 | 2 | eight 370 0 | 2 | zero 371 | 2 | null 372 | 2 | zero 373 1 | -3 | one 374 2 | -3 | two 375 3 | -3 | three 376 4 | -3 | four 377 5 | -3 | five 378 6 | -3 | six 379 7 | -3 | seven 380 8 | -3 | eight 381 0 | -3 | zero 382 | -3 | null 383 | -3 | zero 384 1 | 4 | one 385 2 | 4 | two 386 3 | 4 | three 387 4 | 4 | four 388 5 | 4 | five 389 6 | 4 | six 390 7 | 4 | seven 391 8 | 4 | eight 392 0 | 4 | zero 393 | 4 | null 394 | 4 | zero 395 1 | -5 | one 396 2 | -5 | two 397 3 | -5 | three 398 4 | -5 | four 399 5 | -5 | five 400 6 | -5 | six 401 7 | -5 | seven 402 8 | -5 | eight 403 0 | -5 | zero 404 | -5 | null 405 | -5 | zero 406 1 | -5 | one 407 2 | -5 | two 408 3 | -5 | three 409 4 | -5 | four 410 5 | -5 | five 411 6 | -5 | six 412 7 | -5 | seven 413 8 | -5 | eight 414 0 | -5 | zero 415 | -5 | null 416 | -5 | zero 417 1 | | one 418 2 | | two 419 3 | | three 420 4 | | four 421 5 | | five 422 6 | | six 423 7 | | seven 424 8 | | eight 425 0 | | zero 426 | | null 427 | | zero 428 1 | | one 429 2 | | two 430 3 | | three 431 4 | | four 432 5 | | five 433 6 | | six 434 7 | | seven 435 8 | | eight 436 0 | | zero 437 | | null 438 | | zero 439 1 | 0 | one 440 2 | 0 | two 441 3 | 0 | three 442 4 | 0 | four 443 5 | 0 | five 444 6 | 0 | six 445 7 | 0 | seven 446 8 | 0 | eight 447 0 | 0 | zero 448 | 0 | null 449 | 0 | zero 450(99 rows) 451 452SELECT ii, tt, kk 453 FROM (J1_TBL CROSS JOIN J2_TBL) 454 AS tx (ii, jj, tt, ii2, kk); 455 ii | tt | kk 456----+-------+---- 457 1 | one | -1 458 2 | two | -1 459 3 | three | -1 460 4 | four | -1 461 5 | five | -1 462 6 | six | -1 463 7 | seven | -1 464 8 | eight | -1 465 0 | zero | -1 466 | null | -1 467 | zero | -1 468 1 | one | 2 469 2 | two | 2 470 3 | three | 2 471 4 | four | 2 472 5 | five | 2 473 6 | six | 2 474 7 | seven | 2 475 8 | eight | 2 476 0 | zero | 2 477 | null | 2 478 | zero | 2 479 1 | one | -3 480 2 | two | -3 481 3 | three | -3 482 4 | four | -3 483 5 | five | -3 484 6 | six | -3 485 7 | seven | -3 486 8 | eight | -3 487 0 | zero | -3 488 | null | -3 489 | zero | -3 490 1 | one | 4 491 2 | two | 4 492 3 | three | 4 493 4 | four | 4 494 5 | five | 4 495 6 | six | 4 496 7 | seven | 4 497 8 | eight | 4 498 0 | zero | 4 499 | null | 4 500 | zero | 4 501 1 | one | -5 502 2 | two | -5 503 3 | three | -5 504 4 | four | -5 505 5 | five | -5 506 6 | six | -5 507 7 | seven | -5 508 8 | eight | -5 509 0 | zero | -5 510 | null | -5 511 | zero | -5 512 1 | one | -5 513 2 | two | -5 514 3 | three | -5 515 4 | four | -5 516 5 | five | -5 517 6 | six | -5 518 7 | seven | -5 519 8 | eight | -5 520 0 | zero | -5 521 | null | -5 522 | zero | -5 523 1 | one | 524 2 | two | 525 3 | three | 526 4 | four | 527 5 | five | 528 6 | six | 529 7 | seven | 530 8 | eight | 531 0 | zero | 532 | null | 533 | zero | 534 1 | one | 535 2 | two | 536 3 | three | 537 4 | four | 538 5 | five | 539 6 | six | 540 7 | seven | 541 8 | eight | 542 0 | zero | 543 | null | 544 | zero | 545 1 | one | 0 546 2 | two | 0 547 3 | three | 0 548 4 | four | 0 549 5 | five | 0 550 6 | six | 0 551 7 | seven | 0 552 8 | eight | 0 553 0 | zero | 0 554 | null | 0 555 | zero | 0 556(99 rows) 557 558SELECT tx.ii, tx.jj, tx.kk 559 FROM (J1_TBL t1 (a, b, c) CROSS JOIN J2_TBL t2 (d, e)) 560 AS tx (ii, jj, tt, ii2, kk); 561 ii | jj | kk 562----+----+---- 563 1 | 4 | -1 564 2 | 3 | -1 565 3 | 2 | -1 566 4 | 1 | -1 567 5 | 0 | -1 568 6 | 6 | -1 569 7 | 7 | -1 570 8 | 8 | -1 571 0 | | -1 572 | | -1 573 | 0 | -1 574 1 | 4 | 2 575 2 | 3 | 2 576 3 | 2 | 2 577 4 | 1 | 2 578 5 | 0 | 2 579 6 | 6 | 2 580 7 | 7 | 2 581 8 | 8 | 2 582 0 | | 2 583 | | 2 584 | 0 | 2 585 1 | 4 | -3 586 2 | 3 | -3 587 3 | 2 | -3 588 4 | 1 | -3 589 5 | 0 | -3 590 6 | 6 | -3 591 7 | 7 | -3 592 8 | 8 | -3 593 0 | | -3 594 | | -3 595 | 0 | -3 596 1 | 4 | 4 597 2 | 3 | 4 598 3 | 2 | 4 599 4 | 1 | 4 600 5 | 0 | 4 601 6 | 6 | 4 602 7 | 7 | 4 603 8 | 8 | 4 604 0 | | 4 605 | | 4 606 | 0 | 4 607 1 | 4 | -5 608 2 | 3 | -5 609 3 | 2 | -5 610 4 | 1 | -5 611 5 | 0 | -5 612 6 | 6 | -5 613 7 | 7 | -5 614 8 | 8 | -5 615 0 | | -5 616 | | -5 617 | 0 | -5 618 1 | 4 | -5 619 2 | 3 | -5 620 3 | 2 | -5 621 4 | 1 | -5 622 5 | 0 | -5 623 6 | 6 | -5 624 7 | 7 | -5 625 8 | 8 | -5 626 0 | | -5 627 | | -5 628 | 0 | -5 629 1 | 4 | 630 2 | 3 | 631 3 | 2 | 632 4 | 1 | 633 5 | 0 | 634 6 | 6 | 635 7 | 7 | 636 8 | 8 | 637 0 | | 638 | | 639 | 0 | 640 1 | 4 | 641 2 | 3 | 642 3 | 2 | 643 4 | 1 | 644 5 | 0 | 645 6 | 6 | 646 7 | 7 | 647 8 | 8 | 648 0 | | 649 | | 650 | 0 | 651 1 | 4 | 0 652 2 | 3 | 0 653 3 | 2 | 0 654 4 | 1 | 0 655 5 | 0 | 0 656 6 | 6 | 0 657 7 | 7 | 0 658 8 | 8 | 0 659 0 | | 0 660 | | 0 661 | 0 | 0 662(99 rows) 663 664SELECT * 665 FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; 666 i | j | t | i | k | i | k 667---+---+-------+---+----+---+---- 668 1 | 4 | one | 1 | -1 | 1 | -1 669 1 | 4 | one | 1 | -1 | 2 | 2 670 1 | 4 | one | 1 | -1 | 3 | -3 671 1 | 4 | one | 1 | -1 | 2 | 4 672 1 | 4 | one | 1 | -1 | 5 | -5 673 1 | 4 | one | 1 | -1 | 5 | -5 674 1 | 4 | one | 1 | -1 | 0 | 675 1 | 4 | one | 1 | -1 | | 676 1 | 4 | one | 1 | -1 | | 0 677 2 | 3 | two | 1 | -1 | 1 | -1 678 2 | 3 | two | 1 | -1 | 2 | 2 679 2 | 3 | two | 1 | -1 | 3 | -3 680 2 | 3 | two | 1 | -1 | 2 | 4 681 2 | 3 | two | 1 | -1 | 5 | -5 682 2 | 3 | two | 1 | -1 | 5 | -5 683 2 | 3 | two | 1 | -1 | 0 | 684 2 | 3 | two | 1 | -1 | | 685 2 | 3 | two | 1 | -1 | | 0 686 3 | 2 | three | 1 | -1 | 1 | -1 687 3 | 2 | three | 1 | -1 | 2 | 2 688 3 | 2 | three | 1 | -1 | 3 | -3 689 3 | 2 | three | 1 | -1 | 2 | 4 690 3 | 2 | three | 1 | -1 | 5 | -5 691 3 | 2 | three | 1 | -1 | 5 | -5 692 3 | 2 | three | 1 | -1 | 0 | 693 3 | 2 | three | 1 | -1 | | 694 3 | 2 | three | 1 | -1 | | 0 695 4 | 1 | four | 1 | -1 | 1 | -1 696 4 | 1 | four | 1 | -1 | 2 | 2 697 4 | 1 | four | 1 | -1 | 3 | -3 698 4 | 1 | four | 1 | -1 | 2 | 4 699 4 | 1 | four | 1 | -1 | 5 | -5 700 4 | 1 | four | 1 | -1 | 5 | -5 701 4 | 1 | four | 1 | -1 | 0 | 702 4 | 1 | four | 1 | -1 | | 703 4 | 1 | four | 1 | -1 | | 0 704 5 | 0 | five | 1 | -1 | 1 | -1 705 5 | 0 | five | 1 | -1 | 2 | 2 706 5 | 0 | five | 1 | -1 | 3 | -3 707 5 | 0 | five | 1 | -1 | 2 | 4 708 5 | 0 | five | 1 | -1 | 5 | -5 709 5 | 0 | five | 1 | -1 | 5 | -5 710 5 | 0 | five | 1 | -1 | 0 | 711 5 | 0 | five | 1 | -1 | | 712 5 | 0 | five | 1 | -1 | | 0 713 6 | 6 | six | 1 | -1 | 1 | -1 714 6 | 6 | six | 1 | -1 | 2 | 2 715 6 | 6 | six | 1 | -1 | 3 | -3 716 6 | 6 | six | 1 | -1 | 2 | 4 717 6 | 6 | six | 1 | -1 | 5 | -5 718 6 | 6 | six | 1 | -1 | 5 | -5 719 6 | 6 | six | 1 | -1 | 0 | 720 6 | 6 | six | 1 | -1 | | 721 6 | 6 | six | 1 | -1 | | 0 722 7 | 7 | seven | 1 | -1 | 1 | -1 723 7 | 7 | seven | 1 | -1 | 2 | 2 724 7 | 7 | seven | 1 | -1 | 3 | -3 725 7 | 7 | seven | 1 | -1 | 2 | 4 726 7 | 7 | seven | 1 | -1 | 5 | -5 727 7 | 7 | seven | 1 | -1 | 5 | -5 728 7 | 7 | seven | 1 | -1 | 0 | 729 7 | 7 | seven | 1 | -1 | | 730 7 | 7 | seven | 1 | -1 | | 0 731 8 | 8 | eight | 1 | -1 | 1 | -1 732 8 | 8 | eight | 1 | -1 | 2 | 2 733 8 | 8 | eight | 1 | -1 | 3 | -3 734 8 | 8 | eight | 1 | -1 | 2 | 4 735 8 | 8 | eight | 1 | -1 | 5 | -5 736 8 | 8 | eight | 1 | -1 | 5 | -5 737 8 | 8 | eight | 1 | -1 | 0 | 738 8 | 8 | eight | 1 | -1 | | 739 8 | 8 | eight | 1 | -1 | | 0 740 0 | | zero | 1 | -1 | 1 | -1 741 0 | | zero | 1 | -1 | 2 | 2 742 0 | | zero | 1 | -1 | 3 | -3 743 0 | | zero | 1 | -1 | 2 | 4 744 0 | | zero | 1 | -1 | 5 | -5 745 0 | | zero | 1 | -1 | 5 | -5 746 0 | | zero | 1 | -1 | 0 | 747 0 | | zero | 1 | -1 | | 748 0 | | zero | 1 | -1 | | 0 749 | | null | 1 | -1 | 1 | -1 750 | | null | 1 | -1 | 2 | 2 751 | | null | 1 | -1 | 3 | -3 752 | | null | 1 | -1 | 2 | 4 753 | | null | 1 | -1 | 5 | -5 754 | | null | 1 | -1 | 5 | -5 755 | | null | 1 | -1 | 0 | 756 | | null | 1 | -1 | | 757 | | null | 1 | -1 | | 0 758 | 0 | zero | 1 | -1 | 1 | -1 759 | 0 | zero | 1 | -1 | 2 | 2 760 | 0 | zero | 1 | -1 | 3 | -3 761 | 0 | zero | 1 | -1 | 2 | 4 762 | 0 | zero | 1 | -1 | 5 | -5 763 | 0 | zero | 1 | -1 | 5 | -5 764 | 0 | zero | 1 | -1 | 0 | 765 | 0 | zero | 1 | -1 | | 766 | 0 | zero | 1 | -1 | | 0 767 1 | 4 | one | 2 | 2 | 1 | -1 768 1 | 4 | one | 2 | 2 | 2 | 2 769 1 | 4 | one | 2 | 2 | 3 | -3 770 1 | 4 | one | 2 | 2 | 2 | 4 771 1 | 4 | one | 2 | 2 | 5 | -5 772 1 | 4 | one | 2 | 2 | 5 | -5 773 1 | 4 | one | 2 | 2 | 0 | 774 1 | 4 | one | 2 | 2 | | 775 1 | 4 | one | 2 | 2 | | 0 776 2 | 3 | two | 2 | 2 | 1 | -1 777 2 | 3 | two | 2 | 2 | 2 | 2 778 2 | 3 | two | 2 | 2 | 3 | -3 779 2 | 3 | two | 2 | 2 | 2 | 4 780 2 | 3 | two | 2 | 2 | 5 | -5 781 2 | 3 | two | 2 | 2 | 5 | -5 782 2 | 3 | two | 2 | 2 | 0 | 783 2 | 3 | two | 2 | 2 | | 784 2 | 3 | two | 2 | 2 | | 0 785 3 | 2 | three | 2 | 2 | 1 | -1 786 3 | 2 | three | 2 | 2 | 2 | 2 787 3 | 2 | three | 2 | 2 | 3 | -3 788 3 | 2 | three | 2 | 2 | 2 | 4 789 3 | 2 | three | 2 | 2 | 5 | -5 790 3 | 2 | three | 2 | 2 | 5 | -5 791 3 | 2 | three | 2 | 2 | 0 | 792 3 | 2 | three | 2 | 2 | | 793 3 | 2 | three | 2 | 2 | | 0 794 4 | 1 | four | 2 | 2 | 1 | -1 795 4 | 1 | four | 2 | 2 | 2 | 2 796 4 | 1 | four | 2 | 2 | 3 | -3 797 4 | 1 | four | 2 | 2 | 2 | 4 798 4 | 1 | four | 2 | 2 | 5 | -5 799 4 | 1 | four | 2 | 2 | 5 | -5 800 4 | 1 | four | 2 | 2 | 0 | 801 4 | 1 | four | 2 | 2 | | 802 4 | 1 | four | 2 | 2 | | 0 803 5 | 0 | five | 2 | 2 | 1 | -1 804 5 | 0 | five | 2 | 2 | 2 | 2 805 5 | 0 | five | 2 | 2 | 3 | -3 806 5 | 0 | five | 2 | 2 | 2 | 4 807 5 | 0 | five | 2 | 2 | 5 | -5 808 5 | 0 | five | 2 | 2 | 5 | -5 809 5 | 0 | five | 2 | 2 | 0 | 810 5 | 0 | five | 2 | 2 | | 811 5 | 0 | five | 2 | 2 | | 0 812 6 | 6 | six | 2 | 2 | 1 | -1 813 6 | 6 | six | 2 | 2 | 2 | 2 814 6 | 6 | six | 2 | 2 | 3 | -3 815 6 | 6 | six | 2 | 2 | 2 | 4 816 6 | 6 | six | 2 | 2 | 5 | -5 817 6 | 6 | six | 2 | 2 | 5 | -5 818 6 | 6 | six | 2 | 2 | 0 | 819 6 | 6 | six | 2 | 2 | | 820 6 | 6 | six | 2 | 2 | | 0 821 7 | 7 | seven | 2 | 2 | 1 | -1 822 7 | 7 | seven | 2 | 2 | 2 | 2 823 7 | 7 | seven | 2 | 2 | 3 | -3 824 7 | 7 | seven | 2 | 2 | 2 | 4 825 7 | 7 | seven | 2 | 2 | 5 | -5 826 7 | 7 | seven | 2 | 2 | 5 | -5 827 7 | 7 | seven | 2 | 2 | 0 | 828 7 | 7 | seven | 2 | 2 | | 829 7 | 7 | seven | 2 | 2 | | 0 830 8 | 8 | eight | 2 | 2 | 1 | -1 831 8 | 8 | eight | 2 | 2 | 2 | 2 832 8 | 8 | eight | 2 | 2 | 3 | -3 833 8 | 8 | eight | 2 | 2 | 2 | 4 834 8 | 8 | eight | 2 | 2 | 5 | -5 835 8 | 8 | eight | 2 | 2 | 5 | -5 836 8 | 8 | eight | 2 | 2 | 0 | 837 8 | 8 | eight | 2 | 2 | | 838 8 | 8 | eight | 2 | 2 | | 0 839 0 | | zero | 2 | 2 | 1 | -1 840 0 | | zero | 2 | 2 | 2 | 2 841 0 | | zero | 2 | 2 | 3 | -3 842 0 | | zero | 2 | 2 | 2 | 4 843 0 | | zero | 2 | 2 | 5 | -5 844 0 | | zero | 2 | 2 | 5 | -5 845 0 | | zero | 2 | 2 | 0 | 846 0 | | zero | 2 | 2 | | 847 0 | | zero | 2 | 2 | | 0 848 | | null | 2 | 2 | 1 | -1 849 | | null | 2 | 2 | 2 | 2 850 | | null | 2 | 2 | 3 | -3 851 | | null | 2 | 2 | 2 | 4 852 | | null | 2 | 2 | 5 | -5 853 | | null | 2 | 2 | 5 | -5 854 | | null | 2 | 2 | 0 | 855 | | null | 2 | 2 | | 856 | | null | 2 | 2 | | 0 857 | 0 | zero | 2 | 2 | 1 | -1 858 | 0 | zero | 2 | 2 | 2 | 2 859 | 0 | zero | 2 | 2 | 3 | -3 860 | 0 | zero | 2 | 2 | 2 | 4 861 | 0 | zero | 2 | 2 | 5 | -5 862 | 0 | zero | 2 | 2 | 5 | -5 863 | 0 | zero | 2 | 2 | 0 | 864 | 0 | zero | 2 | 2 | | 865 | 0 | zero | 2 | 2 | | 0 866 1 | 4 | one | 3 | -3 | 1 | -1 867 1 | 4 | one | 3 | -3 | 2 | 2 868 1 | 4 | one | 3 | -3 | 3 | -3 869 1 | 4 | one | 3 | -3 | 2 | 4 870 1 | 4 | one | 3 | -3 | 5 | -5 871 1 | 4 | one | 3 | -3 | 5 | -5 872 1 | 4 | one | 3 | -3 | 0 | 873 1 | 4 | one | 3 | -3 | | 874 1 | 4 | one | 3 | -3 | | 0 875 2 | 3 | two | 3 | -3 | 1 | -1 876 2 | 3 | two | 3 | -3 | 2 | 2 877 2 | 3 | two | 3 | -3 | 3 | -3 878 2 | 3 | two | 3 | -3 | 2 | 4 879 2 | 3 | two | 3 | -3 | 5 | -5 880 2 | 3 | two | 3 | -3 | 5 | -5 881 2 | 3 | two | 3 | -3 | 0 | 882 2 | 3 | two | 3 | -3 | | 883 2 | 3 | two | 3 | -3 | | 0 884 3 | 2 | three | 3 | -3 | 1 | -1 885 3 | 2 | three | 3 | -3 | 2 | 2 886 3 | 2 | three | 3 | -3 | 3 | -3 887 3 | 2 | three | 3 | -3 | 2 | 4 888 3 | 2 | three | 3 | -3 | 5 | -5 889 3 | 2 | three | 3 | -3 | 5 | -5 890 3 | 2 | three | 3 | -3 | 0 | 891 3 | 2 | three | 3 | -3 | | 892 3 | 2 | three | 3 | -3 | | 0 893 4 | 1 | four | 3 | -3 | 1 | -1 894 4 | 1 | four | 3 | -3 | 2 | 2 895 4 | 1 | four | 3 | -3 | 3 | -3 896 4 | 1 | four | 3 | -3 | 2 | 4 897 4 | 1 | four | 3 | -3 | 5 | -5 898 4 | 1 | four | 3 | -3 | 5 | -5 899 4 | 1 | four | 3 | -3 | 0 | 900 4 | 1 | four | 3 | -3 | | 901 4 | 1 | four | 3 | -3 | | 0 902 5 | 0 | five | 3 | -3 | 1 | -1 903 5 | 0 | five | 3 | -3 | 2 | 2 904 5 | 0 | five | 3 | -3 | 3 | -3 905 5 | 0 | five | 3 | -3 | 2 | 4 906 5 | 0 | five | 3 | -3 | 5 | -5 907 5 | 0 | five | 3 | -3 | 5 | -5 908 5 | 0 | five | 3 | -3 | 0 | 909 5 | 0 | five | 3 | -3 | | 910 5 | 0 | five | 3 | -3 | | 0 911 6 | 6 | six | 3 | -3 | 1 | -1 912 6 | 6 | six | 3 | -3 | 2 | 2 913 6 | 6 | six | 3 | -3 | 3 | -3 914 6 | 6 | six | 3 | -3 | 2 | 4 915 6 | 6 | six | 3 | -3 | 5 | -5 916 6 | 6 | six | 3 | -3 | 5 | -5 917 6 | 6 | six | 3 | -3 | 0 | 918 6 | 6 | six | 3 | -3 | | 919 6 | 6 | six | 3 | -3 | | 0 920 7 | 7 | seven | 3 | -3 | 1 | -1 921 7 | 7 | seven | 3 | -3 | 2 | 2 922 7 | 7 | seven | 3 | -3 | 3 | -3 923 7 | 7 | seven | 3 | -3 | 2 | 4 924 7 | 7 | seven | 3 | -3 | 5 | -5 925 7 | 7 | seven | 3 | -3 | 5 | -5 926 7 | 7 | seven | 3 | -3 | 0 | 927 7 | 7 | seven | 3 | -3 | | 928 7 | 7 | seven | 3 | -3 | | 0 929 8 | 8 | eight | 3 | -3 | 1 | -1 930 8 | 8 | eight | 3 | -3 | 2 | 2 931 8 | 8 | eight | 3 | -3 | 3 | -3 932 8 | 8 | eight | 3 | -3 | 2 | 4 933 8 | 8 | eight | 3 | -3 | 5 | -5 934 8 | 8 | eight | 3 | -3 | 5 | -5 935 8 | 8 | eight | 3 | -3 | 0 | 936 8 | 8 | eight | 3 | -3 | | 937 8 | 8 | eight | 3 | -3 | | 0 938 0 | | zero | 3 | -3 | 1 | -1 939 0 | | zero | 3 | -3 | 2 | 2 940 0 | | zero | 3 | -3 | 3 | -3 941 0 | | zero | 3 | -3 | 2 | 4 942 0 | | zero | 3 | -3 | 5 | -5 943 0 | | zero | 3 | -3 | 5 | -5 944 0 | | zero | 3 | -3 | 0 | 945 0 | | zero | 3 | -3 | | 946 0 | | zero | 3 | -3 | | 0 947 | | null | 3 | -3 | 1 | -1 948 | | null | 3 | -3 | 2 | 2 949 | | null | 3 | -3 | 3 | -3 950 | | null | 3 | -3 | 2 | 4 951 | | null | 3 | -3 | 5 | -5 952 | | null | 3 | -3 | 5 | -5 953 | | null | 3 | -3 | 0 | 954 | | null | 3 | -3 | | 955 | | null | 3 | -3 | | 0 956 | 0 | zero | 3 | -3 | 1 | -1 957 | 0 | zero | 3 | -3 | 2 | 2 958 | 0 | zero | 3 | -3 | 3 | -3 959 | 0 | zero | 3 | -3 | 2 | 4 960 | 0 | zero | 3 | -3 | 5 | -5 961 | 0 | zero | 3 | -3 | 5 | -5 962 | 0 | zero | 3 | -3 | 0 | 963 | 0 | zero | 3 | -3 | | 964 | 0 | zero | 3 | -3 | | 0 965 1 | 4 | one | 2 | 4 | 1 | -1 966 1 | 4 | one | 2 | 4 | 2 | 2 967 1 | 4 | one | 2 | 4 | 3 | -3 968 1 | 4 | one | 2 | 4 | 2 | 4 969 1 | 4 | one | 2 | 4 | 5 | -5 970 1 | 4 | one | 2 | 4 | 5 | -5 971 1 | 4 | one | 2 | 4 | 0 | 972 1 | 4 | one | 2 | 4 | | 973 1 | 4 | one | 2 | 4 | | 0 974 2 | 3 | two | 2 | 4 | 1 | -1 975 2 | 3 | two | 2 | 4 | 2 | 2 976 2 | 3 | two | 2 | 4 | 3 | -3 977 2 | 3 | two | 2 | 4 | 2 | 4 978 2 | 3 | two | 2 | 4 | 5 | -5 979 2 | 3 | two | 2 | 4 | 5 | -5 980 2 | 3 | two | 2 | 4 | 0 | 981 2 | 3 | two | 2 | 4 | | 982 2 | 3 | two | 2 | 4 | | 0 983 3 | 2 | three | 2 | 4 | 1 | -1 984 3 | 2 | three | 2 | 4 | 2 | 2 985 3 | 2 | three | 2 | 4 | 3 | -3 986 3 | 2 | three | 2 | 4 | 2 | 4 987 3 | 2 | three | 2 | 4 | 5 | -5 988 3 | 2 | three | 2 | 4 | 5 | -5 989 3 | 2 | three | 2 | 4 | 0 | 990 3 | 2 | three | 2 | 4 | | 991 3 | 2 | three | 2 | 4 | | 0 992 4 | 1 | four | 2 | 4 | 1 | -1 993 4 | 1 | four | 2 | 4 | 2 | 2 994 4 | 1 | four | 2 | 4 | 3 | -3 995 4 | 1 | four | 2 | 4 | 2 | 4 996 4 | 1 | four | 2 | 4 | 5 | -5 997 4 | 1 | four | 2 | 4 | 5 | -5 998 4 | 1 | four | 2 | 4 | 0 | 999 4 | 1 | four | 2 | 4 | | 1000 4 | 1 | four | 2 | 4 | | 0 1001 5 | 0 | five | 2 | 4 | 1 | -1 1002 5 | 0 | five | 2 | 4 | 2 | 2 1003 5 | 0 | five | 2 | 4 | 3 | -3 1004 5 | 0 | five | 2 | 4 | 2 | 4 1005 5 | 0 | five | 2 | 4 | 5 | -5 1006 5 | 0 | five | 2 | 4 | 5 | -5 1007 5 | 0 | five | 2 | 4 | 0 | 1008 5 | 0 | five | 2 | 4 | | 1009 5 | 0 | five | 2 | 4 | | 0 1010 6 | 6 | six | 2 | 4 | 1 | -1 1011 6 | 6 | six | 2 | 4 | 2 | 2 1012 6 | 6 | six | 2 | 4 | 3 | -3 1013 6 | 6 | six | 2 | 4 | 2 | 4 1014 6 | 6 | six | 2 | 4 | 5 | -5 1015 6 | 6 | six | 2 | 4 | 5 | -5 1016 6 | 6 | six | 2 | 4 | 0 | 1017 6 | 6 | six | 2 | 4 | | 1018 6 | 6 | six | 2 | 4 | | 0 1019 7 | 7 | seven | 2 | 4 | 1 | -1 1020 7 | 7 | seven | 2 | 4 | 2 | 2 1021 7 | 7 | seven | 2 | 4 | 3 | -3 1022 7 | 7 | seven | 2 | 4 | 2 | 4 1023 7 | 7 | seven | 2 | 4 | 5 | -5 1024 7 | 7 | seven | 2 | 4 | 5 | -5 1025 7 | 7 | seven | 2 | 4 | 0 | 1026 7 | 7 | seven | 2 | 4 | | 1027 7 | 7 | seven | 2 | 4 | | 0 1028 8 | 8 | eight | 2 | 4 | 1 | -1 1029 8 | 8 | eight | 2 | 4 | 2 | 2 1030 8 | 8 | eight | 2 | 4 | 3 | -3 1031 8 | 8 | eight | 2 | 4 | 2 | 4 1032 8 | 8 | eight | 2 | 4 | 5 | -5 1033 8 | 8 | eight | 2 | 4 | 5 | -5 1034 8 | 8 | eight | 2 | 4 | 0 | 1035 8 | 8 | eight | 2 | 4 | | 1036 8 | 8 | eight | 2 | 4 | | 0 1037 0 | | zero | 2 | 4 | 1 | -1 1038 0 | | zero | 2 | 4 | 2 | 2 1039 0 | | zero | 2 | 4 | 3 | -3 1040 0 | | zero | 2 | 4 | 2 | 4 1041 0 | | zero | 2 | 4 | 5 | -5 1042 0 | | zero | 2 | 4 | 5 | -5 1043 0 | | zero | 2 | 4 | 0 | 1044 0 | | zero | 2 | 4 | | 1045 0 | | zero | 2 | 4 | | 0 1046 | | null | 2 | 4 | 1 | -1 1047 | | null | 2 | 4 | 2 | 2 1048 | | null | 2 | 4 | 3 | -3 1049 | | null | 2 | 4 | 2 | 4 1050 | | null | 2 | 4 | 5 | -5 1051 | | null | 2 | 4 | 5 | -5 1052 | | null | 2 | 4 | 0 | 1053 | | null | 2 | 4 | | 1054 | | null | 2 | 4 | | 0 1055 | 0 | zero | 2 | 4 | 1 | -1 1056 | 0 | zero | 2 | 4 | 2 | 2 1057 | 0 | zero | 2 | 4 | 3 | -3 1058 | 0 | zero | 2 | 4 | 2 | 4 1059 | 0 | zero | 2 | 4 | 5 | -5 1060 | 0 | zero | 2 | 4 | 5 | -5 1061 | 0 | zero | 2 | 4 | 0 | 1062 | 0 | zero | 2 | 4 | | 1063 | 0 | zero | 2 | 4 | | 0 1064 1 | 4 | one | 5 | -5 | 1 | -1 1065 1 | 4 | one | 5 | -5 | 2 | 2 1066 1 | 4 | one | 5 | -5 | 3 | -3 1067 1 | 4 | one | 5 | -5 | 2 | 4 1068 1 | 4 | one | 5 | -5 | 5 | -5 1069 1 | 4 | one | 5 | -5 | 5 | -5 1070 1 | 4 | one | 5 | -5 | 0 | 1071 1 | 4 | one | 5 | -5 | | 1072 1 | 4 | one | 5 | -5 | | 0 1073 2 | 3 | two | 5 | -5 | 1 | -1 1074 2 | 3 | two | 5 | -5 | 2 | 2 1075 2 | 3 | two | 5 | -5 | 3 | -3 1076 2 | 3 | two | 5 | -5 | 2 | 4 1077 2 | 3 | two | 5 | -5 | 5 | -5 1078 2 | 3 | two | 5 | -5 | 5 | -5 1079 2 | 3 | two | 5 | -5 | 0 | 1080 2 | 3 | two | 5 | -5 | | 1081 2 | 3 | two | 5 | -5 | | 0 1082 3 | 2 | three | 5 | -5 | 1 | -1 1083 3 | 2 | three | 5 | -5 | 2 | 2 1084 3 | 2 | three | 5 | -5 | 3 | -3 1085 3 | 2 | three | 5 | -5 | 2 | 4 1086 3 | 2 | three | 5 | -5 | 5 | -5 1087 3 | 2 | three | 5 | -5 | 5 | -5 1088 3 | 2 | three | 5 | -5 | 0 | 1089 3 | 2 | three | 5 | -5 | | 1090 3 | 2 | three | 5 | -5 | | 0 1091 4 | 1 | four | 5 | -5 | 1 | -1 1092 4 | 1 | four | 5 | -5 | 2 | 2 1093 4 | 1 | four | 5 | -5 | 3 | -3 1094 4 | 1 | four | 5 | -5 | 2 | 4 1095 4 | 1 | four | 5 | -5 | 5 | -5 1096 4 | 1 | four | 5 | -5 | 5 | -5 1097 4 | 1 | four | 5 | -5 | 0 | 1098 4 | 1 | four | 5 | -5 | | 1099 4 | 1 | four | 5 | -5 | | 0 1100 5 | 0 | five | 5 | -5 | 1 | -1 1101 5 | 0 | five | 5 | -5 | 2 | 2 1102 5 | 0 | five | 5 | -5 | 3 | -3 1103 5 | 0 | five | 5 | -5 | 2 | 4 1104 5 | 0 | five | 5 | -5 | 5 | -5 1105 5 | 0 | five | 5 | -5 | 5 | -5 1106 5 | 0 | five | 5 | -5 | 0 | 1107 5 | 0 | five | 5 | -5 | | 1108 5 | 0 | five | 5 | -5 | | 0 1109 6 | 6 | six | 5 | -5 | 1 | -1 1110 6 | 6 | six | 5 | -5 | 2 | 2 1111 6 | 6 | six | 5 | -5 | 3 | -3 1112 6 | 6 | six | 5 | -5 | 2 | 4 1113 6 | 6 | six | 5 | -5 | 5 | -5 1114 6 | 6 | six | 5 | -5 | 5 | -5 1115 6 | 6 | six | 5 | -5 | 0 | 1116 6 | 6 | six | 5 | -5 | | 1117 6 | 6 | six | 5 | -5 | | 0 1118 7 | 7 | seven | 5 | -5 | 1 | -1 1119 7 | 7 | seven | 5 | -5 | 2 | 2 1120 7 | 7 | seven | 5 | -5 | 3 | -3 1121 7 | 7 | seven | 5 | -5 | 2 | 4 1122 7 | 7 | seven | 5 | -5 | 5 | -5 1123 7 | 7 | seven | 5 | -5 | 5 | -5 1124 7 | 7 | seven | 5 | -5 | 0 | 1125 7 | 7 | seven | 5 | -5 | | 1126 7 | 7 | seven | 5 | -5 | | 0 1127 8 | 8 | eight | 5 | -5 | 1 | -1 1128 8 | 8 | eight | 5 | -5 | 2 | 2 1129 8 | 8 | eight | 5 | -5 | 3 | -3 1130 8 | 8 | eight | 5 | -5 | 2 | 4 1131 8 | 8 | eight | 5 | -5 | 5 | -5 1132 8 | 8 | eight | 5 | -5 | 5 | -5 1133 8 | 8 | eight | 5 | -5 | 0 | 1134 8 | 8 | eight | 5 | -5 | | 1135 8 | 8 | eight | 5 | -5 | | 0 1136 0 | | zero | 5 | -5 | 1 | -1 1137 0 | | zero | 5 | -5 | 2 | 2 1138 0 | | zero | 5 | -5 | 3 | -3 1139 0 | | zero | 5 | -5 | 2 | 4 1140 0 | | zero | 5 | -5 | 5 | -5 1141 0 | | zero | 5 | -5 | 5 | -5 1142 0 | | zero | 5 | -5 | 0 | 1143 0 | | zero | 5 | -5 | | 1144 0 | | zero | 5 | -5 | | 0 1145 | | null | 5 | -5 | 1 | -1 1146 | | null | 5 | -5 | 2 | 2 1147 | | null | 5 | -5 | 3 | -3 1148 | | null | 5 | -5 | 2 | 4 1149 | | null | 5 | -5 | 5 | -5 1150 | | null | 5 | -5 | 5 | -5 1151 | | null | 5 | -5 | 0 | 1152 | | null | 5 | -5 | | 1153 | | null | 5 | -5 | | 0 1154 | 0 | zero | 5 | -5 | 1 | -1 1155 | 0 | zero | 5 | -5 | 2 | 2 1156 | 0 | zero | 5 | -5 | 3 | -3 1157 | 0 | zero | 5 | -5 | 2 | 4 1158 | 0 | zero | 5 | -5 | 5 | -5 1159 | 0 | zero | 5 | -5 | 5 | -5 1160 | 0 | zero | 5 | -5 | 0 | 1161 | 0 | zero | 5 | -5 | | 1162 | 0 | zero | 5 | -5 | | 0 1163 1 | 4 | one | 5 | -5 | 1 | -1 1164 1 | 4 | one | 5 | -5 | 2 | 2 1165 1 | 4 | one | 5 | -5 | 3 | -3 1166 1 | 4 | one | 5 | -5 | 2 | 4 1167 1 | 4 | one | 5 | -5 | 5 | -5 1168 1 | 4 | one | 5 | -5 | 5 | -5 1169 1 | 4 | one | 5 | -5 | 0 | 1170 1 | 4 | one | 5 | -5 | | 1171 1 | 4 | one | 5 | -5 | | 0 1172 2 | 3 | two | 5 | -5 | 1 | -1 1173 2 | 3 | two | 5 | -5 | 2 | 2 1174 2 | 3 | two | 5 | -5 | 3 | -3 1175 2 | 3 | two | 5 | -5 | 2 | 4 1176 2 | 3 | two | 5 | -5 | 5 | -5 1177 2 | 3 | two | 5 | -5 | 5 | -5 1178 2 | 3 | two | 5 | -5 | 0 | 1179 2 | 3 | two | 5 | -5 | | 1180 2 | 3 | two | 5 | -5 | | 0 1181 3 | 2 | three | 5 | -5 | 1 | -1 1182 3 | 2 | three | 5 | -5 | 2 | 2 1183 3 | 2 | three | 5 | -5 | 3 | -3 1184 3 | 2 | three | 5 | -5 | 2 | 4 1185 3 | 2 | three | 5 | -5 | 5 | -5 1186 3 | 2 | three | 5 | -5 | 5 | -5 1187 3 | 2 | three | 5 | -5 | 0 | 1188 3 | 2 | three | 5 | -5 | | 1189 3 | 2 | three | 5 | -5 | | 0 1190 4 | 1 | four | 5 | -5 | 1 | -1 1191 4 | 1 | four | 5 | -5 | 2 | 2 1192 4 | 1 | four | 5 | -5 | 3 | -3 1193 4 | 1 | four | 5 | -5 | 2 | 4 1194 4 | 1 | four | 5 | -5 | 5 | -5 1195 4 | 1 | four | 5 | -5 | 5 | -5 1196 4 | 1 | four | 5 | -5 | 0 | 1197 4 | 1 | four | 5 | -5 | | 1198 4 | 1 | four | 5 | -5 | | 0 1199 5 | 0 | five | 5 | -5 | 1 | -1 1200 5 | 0 | five | 5 | -5 | 2 | 2 1201 5 | 0 | five | 5 | -5 | 3 | -3 1202 5 | 0 | five | 5 | -5 | 2 | 4 1203 5 | 0 | five | 5 | -5 | 5 | -5 1204 5 | 0 | five | 5 | -5 | 5 | -5 1205 5 | 0 | five | 5 | -5 | 0 | 1206 5 | 0 | five | 5 | -5 | | 1207 5 | 0 | five | 5 | -5 | | 0 1208 6 | 6 | six | 5 | -5 | 1 | -1 1209 6 | 6 | six | 5 | -5 | 2 | 2 1210 6 | 6 | six | 5 | -5 | 3 | -3 1211 6 | 6 | six | 5 | -5 | 2 | 4 1212 6 | 6 | six | 5 | -5 | 5 | -5 1213 6 | 6 | six | 5 | -5 | 5 | -5 1214 6 | 6 | six | 5 | -5 | 0 | 1215 6 | 6 | six | 5 | -5 | | 1216 6 | 6 | six | 5 | -5 | | 0 1217 7 | 7 | seven | 5 | -5 | 1 | -1 1218 7 | 7 | seven | 5 | -5 | 2 | 2 1219 7 | 7 | seven | 5 | -5 | 3 | -3 1220 7 | 7 | seven | 5 | -5 | 2 | 4 1221 7 | 7 | seven | 5 | -5 | 5 | -5 1222 7 | 7 | seven | 5 | -5 | 5 | -5 1223 7 | 7 | seven | 5 | -5 | 0 | 1224 7 | 7 | seven | 5 | -5 | | 1225 7 | 7 | seven | 5 | -5 | | 0 1226 8 | 8 | eight | 5 | -5 | 1 | -1 1227 8 | 8 | eight | 5 | -5 | 2 | 2 1228 8 | 8 | eight | 5 | -5 | 3 | -3 1229 8 | 8 | eight | 5 | -5 | 2 | 4 1230 8 | 8 | eight | 5 | -5 | 5 | -5 1231 8 | 8 | eight | 5 | -5 | 5 | -5 1232 8 | 8 | eight | 5 | -5 | 0 | 1233 8 | 8 | eight | 5 | -5 | | 1234 8 | 8 | eight | 5 | -5 | | 0 1235 0 | | zero | 5 | -5 | 1 | -1 1236 0 | | zero | 5 | -5 | 2 | 2 1237 0 | | zero | 5 | -5 | 3 | -3 1238 0 | | zero | 5 | -5 | 2 | 4 1239 0 | | zero | 5 | -5 | 5 | -5 1240 0 | | zero | 5 | -5 | 5 | -5 1241 0 | | zero | 5 | -5 | 0 | 1242 0 | | zero | 5 | -5 | | 1243 0 | | zero | 5 | -5 | | 0 1244 | | null | 5 | -5 | 1 | -1 1245 | | null | 5 | -5 | 2 | 2 1246 | | null | 5 | -5 | 3 | -3 1247 | | null | 5 | -5 | 2 | 4 1248 | | null | 5 | -5 | 5 | -5 1249 | | null | 5 | -5 | 5 | -5 1250 | | null | 5 | -5 | 0 | 1251 | | null | 5 | -5 | | 1252 | | null | 5 | -5 | | 0 1253 | 0 | zero | 5 | -5 | 1 | -1 1254 | 0 | zero | 5 | -5 | 2 | 2 1255 | 0 | zero | 5 | -5 | 3 | -3 1256 | 0 | zero | 5 | -5 | 2 | 4 1257 | 0 | zero | 5 | -5 | 5 | -5 1258 | 0 | zero | 5 | -5 | 5 | -5 1259 | 0 | zero | 5 | -5 | 0 | 1260 | 0 | zero | 5 | -5 | | 1261 | 0 | zero | 5 | -5 | | 0 1262 1 | 4 | one | 0 | | 1 | -1 1263 1 | 4 | one | 0 | | 2 | 2 1264 1 | 4 | one | 0 | | 3 | -3 1265 1 | 4 | one | 0 | | 2 | 4 1266 1 | 4 | one | 0 | | 5 | -5 1267 1 | 4 | one | 0 | | 5 | -5 1268 1 | 4 | one | 0 | | 0 | 1269 1 | 4 | one | 0 | | | 1270 1 | 4 | one | 0 | | | 0 1271 2 | 3 | two | 0 | | 1 | -1 1272 2 | 3 | two | 0 | | 2 | 2 1273 2 | 3 | two | 0 | | 3 | -3 1274 2 | 3 | two | 0 | | 2 | 4 1275 2 | 3 | two | 0 | | 5 | -5 1276 2 | 3 | two | 0 | | 5 | -5 1277 2 | 3 | two | 0 | | 0 | 1278 2 | 3 | two | 0 | | | 1279 2 | 3 | two | 0 | | | 0 1280 3 | 2 | three | 0 | | 1 | -1 1281 3 | 2 | three | 0 | | 2 | 2 1282 3 | 2 | three | 0 | | 3 | -3 1283 3 | 2 | three | 0 | | 2 | 4 1284 3 | 2 | three | 0 | | 5 | -5 1285 3 | 2 | three | 0 | | 5 | -5 1286 3 | 2 | three | 0 | | 0 | 1287 3 | 2 | three | 0 | | | 1288 3 | 2 | three | 0 | | | 0 1289 4 | 1 | four | 0 | | 1 | -1 1290 4 | 1 | four | 0 | | 2 | 2 1291 4 | 1 | four | 0 | | 3 | -3 1292 4 | 1 | four | 0 | | 2 | 4 1293 4 | 1 | four | 0 | | 5 | -5 1294 4 | 1 | four | 0 | | 5 | -5 1295 4 | 1 | four | 0 | | 0 | 1296 4 | 1 | four | 0 | | | 1297 4 | 1 | four | 0 | | | 0 1298 5 | 0 | five | 0 | | 1 | -1 1299 5 | 0 | five | 0 | | 2 | 2 1300 5 | 0 | five | 0 | | 3 | -3 1301 5 | 0 | five | 0 | | 2 | 4 1302 5 | 0 | five | 0 | | 5 | -5 1303 5 | 0 | five | 0 | | 5 | -5 1304 5 | 0 | five | 0 | | 0 | 1305 5 | 0 | five | 0 | | | 1306 5 | 0 | five | 0 | | | 0 1307 6 | 6 | six | 0 | | 1 | -1 1308 6 | 6 | six | 0 | | 2 | 2 1309 6 | 6 | six | 0 | | 3 | -3 1310 6 | 6 | six | 0 | | 2 | 4 1311 6 | 6 | six | 0 | | 5 | -5 1312 6 | 6 | six | 0 | | 5 | -5 1313 6 | 6 | six | 0 | | 0 | 1314 6 | 6 | six | 0 | | | 1315 6 | 6 | six | 0 | | | 0 1316 7 | 7 | seven | 0 | | 1 | -1 1317 7 | 7 | seven | 0 | | 2 | 2 1318 7 | 7 | seven | 0 | | 3 | -3 1319 7 | 7 | seven | 0 | | 2 | 4 1320 7 | 7 | seven | 0 | | 5 | -5 1321 7 | 7 | seven | 0 | | 5 | -5 1322 7 | 7 | seven | 0 | | 0 | 1323 7 | 7 | seven | 0 | | | 1324 7 | 7 | seven | 0 | | | 0 1325 8 | 8 | eight | 0 | | 1 | -1 1326 8 | 8 | eight | 0 | | 2 | 2 1327 8 | 8 | eight | 0 | | 3 | -3 1328 8 | 8 | eight | 0 | | 2 | 4 1329 8 | 8 | eight | 0 | | 5 | -5 1330 8 | 8 | eight | 0 | | 5 | -5 1331 8 | 8 | eight | 0 | | 0 | 1332 8 | 8 | eight | 0 | | | 1333 8 | 8 | eight | 0 | | | 0 1334 0 | | zero | 0 | | 1 | -1 1335 0 | | zero | 0 | | 2 | 2 1336 0 | | zero | 0 | | 3 | -3 1337 0 | | zero | 0 | | 2 | 4 1338 0 | | zero | 0 | | 5 | -5 1339 0 | | zero | 0 | | 5 | -5 1340 0 | | zero | 0 | | 0 | 1341 0 | | zero | 0 | | | 1342 0 | | zero | 0 | | | 0 1343 | | null | 0 | | 1 | -1 1344 | | null | 0 | | 2 | 2 1345 | | null | 0 | | 3 | -3 1346 | | null | 0 | | 2 | 4 1347 | | null | 0 | | 5 | -5 1348 | | null | 0 | | 5 | -5 1349 | | null | 0 | | 0 | 1350 | | null | 0 | | | 1351 | | null | 0 | | | 0 1352 | 0 | zero | 0 | | 1 | -1 1353 | 0 | zero | 0 | | 2 | 2 1354 | 0 | zero | 0 | | 3 | -3 1355 | 0 | zero | 0 | | 2 | 4 1356 | 0 | zero | 0 | | 5 | -5 1357 | 0 | zero | 0 | | 5 | -5 1358 | 0 | zero | 0 | | 0 | 1359 | 0 | zero | 0 | | | 1360 | 0 | zero | 0 | | | 0 1361 1 | 4 | one | | | 1 | -1 1362 1 | 4 | one | | | 2 | 2 1363 1 | 4 | one | | | 3 | -3 1364 1 | 4 | one | | | 2 | 4 1365 1 | 4 | one | | | 5 | -5 1366 1 | 4 | one | | | 5 | -5 1367 1 | 4 | one | | | 0 | 1368 1 | 4 | one | | | | 1369 1 | 4 | one | | | | 0 1370 2 | 3 | two | | | 1 | -1 1371 2 | 3 | two | | | 2 | 2 1372 2 | 3 | two | | | 3 | -3 1373 2 | 3 | two | | | 2 | 4 1374 2 | 3 | two | | | 5 | -5 1375 2 | 3 | two | | | 5 | -5 1376 2 | 3 | two | | | 0 | 1377 2 | 3 | two | | | | 1378 2 | 3 | two | | | | 0 1379 3 | 2 | three | | | 1 | -1 1380 3 | 2 | three | | | 2 | 2 1381 3 | 2 | three | | | 3 | -3 1382 3 | 2 | three | | | 2 | 4 1383 3 | 2 | three | | | 5 | -5 1384 3 | 2 | three | | | 5 | -5 1385 3 | 2 | three | | | 0 | 1386 3 | 2 | three | | | | 1387 3 | 2 | three | | | | 0 1388 4 | 1 | four | | | 1 | -1 1389 4 | 1 | four | | | 2 | 2 1390 4 | 1 | four | | | 3 | -3 1391 4 | 1 | four | | | 2 | 4 1392 4 | 1 | four | | | 5 | -5 1393 4 | 1 | four | | | 5 | -5 1394 4 | 1 | four | | | 0 | 1395 4 | 1 | four | | | | 1396 4 | 1 | four | | | | 0 1397 5 | 0 | five | | | 1 | -1 1398 5 | 0 | five | | | 2 | 2 1399 5 | 0 | five | | | 3 | -3 1400 5 | 0 | five | | | 2 | 4 1401 5 | 0 | five | | | 5 | -5 1402 5 | 0 | five | | | 5 | -5 1403 5 | 0 | five | | | 0 | 1404 5 | 0 | five | | | | 1405 5 | 0 | five | | | | 0 1406 6 | 6 | six | | | 1 | -1 1407 6 | 6 | six | | | 2 | 2 1408 6 | 6 | six | | | 3 | -3 1409 6 | 6 | six | | | 2 | 4 1410 6 | 6 | six | | | 5 | -5 1411 6 | 6 | six | | | 5 | -5 1412 6 | 6 | six | | | 0 | 1413 6 | 6 | six | | | | 1414 6 | 6 | six | | | | 0 1415 7 | 7 | seven | | | 1 | -1 1416 7 | 7 | seven | | | 2 | 2 1417 7 | 7 | seven | | | 3 | -3 1418 7 | 7 | seven | | | 2 | 4 1419 7 | 7 | seven | | | 5 | -5 1420 7 | 7 | seven | | | 5 | -5 1421 7 | 7 | seven | | | 0 | 1422 7 | 7 | seven | | | | 1423 7 | 7 | seven | | | | 0 1424 8 | 8 | eight | | | 1 | -1 1425 8 | 8 | eight | | | 2 | 2 1426 8 | 8 | eight | | | 3 | -3 1427 8 | 8 | eight | | | 2 | 4 1428 8 | 8 | eight | | | 5 | -5 1429 8 | 8 | eight | | | 5 | -5 1430 8 | 8 | eight | | | 0 | 1431 8 | 8 | eight | | | | 1432 8 | 8 | eight | | | | 0 1433 0 | | zero | | | 1 | -1 1434 0 | | zero | | | 2 | 2 1435 0 | | zero | | | 3 | -3 1436 0 | | zero | | | 2 | 4 1437 0 | | zero | | | 5 | -5 1438 0 | | zero | | | 5 | -5 1439 0 | | zero | | | 0 | 1440 0 | | zero | | | | 1441 0 | | zero | | | | 0 1442 | | null | | | 1 | -1 1443 | | null | | | 2 | 2 1444 | | null | | | 3 | -3 1445 | | null | | | 2 | 4 1446 | | null | | | 5 | -5 1447 | | null | | | 5 | -5 1448 | | null | | | 0 | 1449 | | null | | | | 1450 | | null | | | | 0 1451 | 0 | zero | | | 1 | -1 1452 | 0 | zero | | | 2 | 2 1453 | 0 | zero | | | 3 | -3 1454 | 0 | zero | | | 2 | 4 1455 | 0 | zero | | | 5 | -5 1456 | 0 | zero | | | 5 | -5 1457 | 0 | zero | | | 0 | 1458 | 0 | zero | | | | 1459 | 0 | zero | | | | 0 1460 1 | 4 | one | | 0 | 1 | -1 1461 1 | 4 | one | | 0 | 2 | 2 1462 1 | 4 | one | | 0 | 3 | -3 1463 1 | 4 | one | | 0 | 2 | 4 1464 1 | 4 | one | | 0 | 5 | -5 1465 1 | 4 | one | | 0 | 5 | -5 1466 1 | 4 | one | | 0 | 0 | 1467 1 | 4 | one | | 0 | | 1468 1 | 4 | one | | 0 | | 0 1469 2 | 3 | two | | 0 | 1 | -1 1470 2 | 3 | two | | 0 | 2 | 2 1471 2 | 3 | two | | 0 | 3 | -3 1472 2 | 3 | two | | 0 | 2 | 4 1473 2 | 3 | two | | 0 | 5 | -5 1474 2 | 3 | two | | 0 | 5 | -5 1475 2 | 3 | two | | 0 | 0 | 1476 2 | 3 | two | | 0 | | 1477 2 | 3 | two | | 0 | | 0 1478 3 | 2 | three | | 0 | 1 | -1 1479 3 | 2 | three | | 0 | 2 | 2 1480 3 | 2 | three | | 0 | 3 | -3 1481 3 | 2 | three | | 0 | 2 | 4 1482 3 | 2 | three | | 0 | 5 | -5 1483 3 | 2 | three | | 0 | 5 | -5 1484 3 | 2 | three | | 0 | 0 | 1485 3 | 2 | three | | 0 | | 1486 3 | 2 | three | | 0 | | 0 1487 4 | 1 | four | | 0 | 1 | -1 1488 4 | 1 | four | | 0 | 2 | 2 1489 4 | 1 | four | | 0 | 3 | -3 1490 4 | 1 | four | | 0 | 2 | 4 1491 4 | 1 | four | | 0 | 5 | -5 1492 4 | 1 | four | | 0 | 5 | -5 1493 4 | 1 | four | | 0 | 0 | 1494 4 | 1 | four | | 0 | | 1495 4 | 1 | four | | 0 | | 0 1496 5 | 0 | five | | 0 | 1 | -1 1497 5 | 0 | five | | 0 | 2 | 2 1498 5 | 0 | five | | 0 | 3 | -3 1499 5 | 0 | five | | 0 | 2 | 4 1500 5 | 0 | five | | 0 | 5 | -5 1501 5 | 0 | five | | 0 | 5 | -5 1502 5 | 0 | five | | 0 | 0 | 1503 5 | 0 | five | | 0 | | 1504 5 | 0 | five | | 0 | | 0 1505 6 | 6 | six | | 0 | 1 | -1 1506 6 | 6 | six | | 0 | 2 | 2 1507 6 | 6 | six | | 0 | 3 | -3 1508 6 | 6 | six | | 0 | 2 | 4 1509 6 | 6 | six | | 0 | 5 | -5 1510 6 | 6 | six | | 0 | 5 | -5 1511 6 | 6 | six | | 0 | 0 | 1512 6 | 6 | six | | 0 | | 1513 6 | 6 | six | | 0 | | 0 1514 7 | 7 | seven | | 0 | 1 | -1 1515 7 | 7 | seven | | 0 | 2 | 2 1516 7 | 7 | seven | | 0 | 3 | -3 1517 7 | 7 | seven | | 0 | 2 | 4 1518 7 | 7 | seven | | 0 | 5 | -5 1519 7 | 7 | seven | | 0 | 5 | -5 1520 7 | 7 | seven | | 0 | 0 | 1521 7 | 7 | seven | | 0 | | 1522 7 | 7 | seven | | 0 | | 0 1523 8 | 8 | eight | | 0 | 1 | -1 1524 8 | 8 | eight | | 0 | 2 | 2 1525 8 | 8 | eight | | 0 | 3 | -3 1526 8 | 8 | eight | | 0 | 2 | 4 1527 8 | 8 | eight | | 0 | 5 | -5 1528 8 | 8 | eight | | 0 | 5 | -5 1529 8 | 8 | eight | | 0 | 0 | 1530 8 | 8 | eight | | 0 | | 1531 8 | 8 | eight | | 0 | | 0 1532 0 | | zero | | 0 | 1 | -1 1533 0 | | zero | | 0 | 2 | 2 1534 0 | | zero | | 0 | 3 | -3 1535 0 | | zero | | 0 | 2 | 4 1536 0 | | zero | | 0 | 5 | -5 1537 0 | | zero | | 0 | 5 | -5 1538 0 | | zero | | 0 | 0 | 1539 0 | | zero | | 0 | | 1540 0 | | zero | | 0 | | 0 1541 | | null | | 0 | 1 | -1 1542 | | null | | 0 | 2 | 2 1543 | | null | | 0 | 3 | -3 1544 | | null | | 0 | 2 | 4 1545 | | null | | 0 | 5 | -5 1546 | | null | | 0 | 5 | -5 1547 | | null | | 0 | 0 | 1548 | | null | | 0 | | 1549 | | null | | 0 | | 0 1550 | 0 | zero | | 0 | 1 | -1 1551 | 0 | zero | | 0 | 2 | 2 1552 | 0 | zero | | 0 | 3 | -3 1553 | 0 | zero | | 0 | 2 | 4 1554 | 0 | zero | | 0 | 5 | -5 1555 | 0 | zero | | 0 | 5 | -5 1556 | 0 | zero | | 0 | 0 | 1557 | 0 | zero | | 0 | | 1558 | 0 | zero | | 0 | | 0 1559(891 rows) 1560 1561-- 1562-- 1563-- Inner joins (equi-joins) 1564-- 1565-- 1566-- 1567-- Inner joins (equi-joins) with USING clause 1568-- The USING syntax changes the shape of the resulting table 1569-- by including a column in the USING clause only once in the result. 1570-- 1571-- Inner equi-join on specified column 1572SELECT * 1573 FROM J1_TBL INNER JOIN J2_TBL USING (i); 1574 i | j | t | k 1575---+---+-------+---- 1576 0 | | zero | 1577 1 | 4 | one | -1 1578 2 | 3 | two | 2 1579 2 | 3 | two | 4 1580 3 | 2 | three | -3 1581 5 | 0 | five | -5 1582 5 | 0 | five | -5 1583(7 rows) 1584 1585-- Same as above, slightly different syntax 1586SELECT * 1587 FROM J1_TBL JOIN J2_TBL USING (i); 1588 i | j | t | k 1589---+---+-------+---- 1590 0 | | zero | 1591 1 | 4 | one | -1 1592 2 | 3 | two | 2 1593 2 | 3 | two | 4 1594 3 | 2 | three | -3 1595 5 | 0 | five | -5 1596 5 | 0 | five | -5 1597(7 rows) 1598 1599SELECT * 1600 FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, d) USING (a) 1601 ORDER BY a, d; 1602 a | b | c | d 1603---+---+-------+---- 1604 0 | | zero | 1605 1 | 4 | one | -1 1606 2 | 3 | two | 2 1607 2 | 3 | two | 4 1608 3 | 2 | three | -3 1609 5 | 0 | five | -5 1610 5 | 0 | five | -5 1611(7 rows) 1612 1613SELECT * 1614 FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b) 1615 ORDER BY b, t1.a; 1616 b | a | c | a 1617---+---+-------+--- 1618 0 | 5 | five | 1619 0 | | zero | 1620 2 | 3 | three | 2 1621 4 | 1 | one | 2 1622(4 rows) 1623 1624-- test join using aliases 1625SELECT * FROM J1_TBL JOIN J2_TBL USING (i) WHERE J1_TBL.t = 'one'; -- ok 1626 i | j | t | k 1627---+---+-----+---- 1628 1 | 4 | one | -1 1629(1 row) 1630 1631SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; -- ok 1632 i | j | t | k 1633---+---+-----+---- 1634 1 | 4 | one | -1 1635(1 row) 1636 1637SELECT * FROM (J1_TBL JOIN J2_TBL USING (i)) AS x WHERE J1_TBL.t = 'one'; -- error 1638ERROR: invalid reference to FROM-clause entry for table "j1_tbl" 1639LINE 1: ... * FROM (J1_TBL JOIN J2_TBL USING (i)) AS x WHERE J1_TBL.t =... 1640 ^ 1641HINT: There is an entry for table "j1_tbl", but it cannot be referenced from this part of the query. 1642SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.i = 1; -- ok 1643 i | j | t | k 1644---+---+-----+---- 1645 1 | 4 | one | -1 1646(1 row) 1647 1648SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.t = 'one'; -- error 1649ERROR: column x.t does not exist 1650LINE 1: ...CT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.t = 'one... 1651 ^ 1652SELECT * FROM (J1_TBL JOIN J2_TBL USING (i) AS x) AS xx WHERE x.i = 1; -- error (XXX could use better hint) 1653ERROR: missing FROM-clause entry for table "x" 1654LINE 1: ...ROM (J1_TBL JOIN J2_TBL USING (i) AS x) AS xx WHERE x.i = 1; 1655 ^ 1656SELECT * FROM J1_TBL a1 JOIN J2_TBL a2 USING (i) AS a1; -- error 1657ERROR: table name "a1" specified more than once 1658SELECT x.* FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; 1659 i 1660--- 1661 1 1662(1 row) 1663 1664SELECT ROW(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; 1665 row 1666----- 1667 (1) 1668(1 row) 1669 1670SELECT row_to_json(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; 1671 row_to_json 1672------------- 1673 {"i":1} 1674(1 row) 1675 1676-- 1677-- NATURAL JOIN 1678-- Inner equi-join on all columns with the same name 1679-- 1680SELECT * 1681 FROM J1_TBL NATURAL JOIN J2_TBL; 1682 i | j | t | k 1683---+---+-------+---- 1684 0 | | zero | 1685 1 | 4 | one | -1 1686 2 | 3 | two | 2 1687 2 | 3 | two | 4 1688 3 | 2 | three | -3 1689 5 | 0 | five | -5 1690 5 | 0 | five | -5 1691(7 rows) 1692 1693SELECT * 1694 FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); 1695 a | b | c | d 1696---+---+-------+---- 1697 0 | | zero | 1698 1 | 4 | one | -1 1699 2 | 3 | two | 2 1700 2 | 3 | two | 4 1701 3 | 2 | three | -3 1702 5 | 0 | five | -5 1703 5 | 0 | five | -5 1704(7 rows) 1705 1706SELECT * 1707 FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); 1708 a | b | c | d 1709---+---+------+--- 1710 0 | | zero | 1711 2 | 3 | two | 2 1712 4 | 1 | four | 2 1713(3 rows) 1714 1715-- mismatch number of columns 1716-- currently, Postgres will fill in with underlying names 1717SELECT * 1718 FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); 1719 a | b | t | k 1720---+---+-------+---- 1721 0 | | zero | 1722 1 | 4 | one | -1 1723 2 | 3 | two | 2 1724 2 | 3 | two | 4 1725 3 | 2 | three | -3 1726 5 | 0 | five | -5 1727 5 | 0 | five | -5 1728(7 rows) 1729 1730-- 1731-- Inner joins (equi-joins) 1732-- 1733SELECT * 1734 FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); 1735 i | j | t | i | k 1736---+---+-------+---+---- 1737 0 | | zero | 0 | 1738 1 | 4 | one | 1 | -1 1739 2 | 3 | two | 2 | 2 1740 2 | 3 | two | 2 | 4 1741 3 | 2 | three | 3 | -3 1742 5 | 0 | five | 5 | -5 1743 5 | 0 | five | 5 | -5 1744(7 rows) 1745 1746SELECT * 1747 FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); 1748 i | j | t | i | k 1749---+---+------+---+--- 1750 0 | | zero | | 0 1751 2 | 3 | two | 2 | 2 1752 4 | 1 | four | 2 | 4 1753(3 rows) 1754 1755-- 1756-- Non-equi-joins 1757-- 1758SELECT * 1759 FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); 1760 i | j | t | i | k 1761---+---+-------+---+--- 1762 1 | 4 | one | 2 | 2 1763 2 | 3 | two | 2 | 2 1764 0 | | zero | 2 | 2 1765 1 | 4 | one | 2 | 4 1766 2 | 3 | two | 2 | 4 1767 3 | 2 | three | 2 | 4 1768 4 | 1 | four | 2 | 4 1769 0 | | zero | 2 | 4 1770 0 | | zero | | 0 1771(9 rows) 1772 1773-- 1774-- Outer joins 1775-- Note that OUTER is a noise word 1776-- 1777SELECT * 1778 FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) 1779 ORDER BY i, k, t; 1780 i | j | t | k 1781---+---+-------+---- 1782 0 | | zero | 1783 1 | 4 | one | -1 1784 2 | 3 | two | 2 1785 2 | 3 | two | 4 1786 3 | 2 | three | -3 1787 4 | 1 | four | 1788 5 | 0 | five | -5 1789 5 | 0 | five | -5 1790 6 | 6 | six | 1791 7 | 7 | seven | 1792 8 | 8 | eight | 1793 | | null | 1794 | 0 | zero | 1795(13 rows) 1796 1797SELECT * 1798 FROM J1_TBL LEFT JOIN J2_TBL USING (i) 1799 ORDER BY i, k, t; 1800 i | j | t | k 1801---+---+-------+---- 1802 0 | | zero | 1803 1 | 4 | one | -1 1804 2 | 3 | two | 2 1805 2 | 3 | two | 4 1806 3 | 2 | three | -3 1807 4 | 1 | four | 1808 5 | 0 | five | -5 1809 5 | 0 | five | -5 1810 6 | 6 | six | 1811 7 | 7 | seven | 1812 8 | 8 | eight | 1813 | | null | 1814 | 0 | zero | 1815(13 rows) 1816 1817SELECT * 1818 FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); 1819 i | j | t | k 1820---+---+-------+---- 1821 0 | | zero | 1822 1 | 4 | one | -1 1823 2 | 3 | two | 2 1824 2 | 3 | two | 4 1825 3 | 2 | three | -3 1826 5 | 0 | five | -5 1827 5 | 0 | five | -5 1828 | | | 1829 | | | 0 1830(9 rows) 1831 1832SELECT * 1833 FROM J1_TBL RIGHT JOIN J2_TBL USING (i); 1834 i | j | t | k 1835---+---+-------+---- 1836 0 | | zero | 1837 1 | 4 | one | -1 1838 2 | 3 | two | 2 1839 2 | 3 | two | 4 1840 3 | 2 | three | -3 1841 5 | 0 | five | -5 1842 5 | 0 | five | -5 1843 | | | 1844 | | | 0 1845(9 rows) 1846 1847SELECT * 1848 FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) 1849 ORDER BY i, k, t; 1850 i | j | t | k 1851---+---+-------+---- 1852 0 | | zero | 1853 1 | 4 | one | -1 1854 2 | 3 | two | 2 1855 2 | 3 | two | 4 1856 3 | 2 | three | -3 1857 4 | 1 | four | 1858 5 | 0 | five | -5 1859 5 | 0 | five | -5 1860 6 | 6 | six | 1861 7 | 7 | seven | 1862 8 | 8 | eight | 1863 | | | 0 1864 | | null | 1865 | 0 | zero | 1866 | | | 1867(15 rows) 1868 1869SELECT * 1870 FROM J1_TBL FULL JOIN J2_TBL USING (i) 1871 ORDER BY i, k, t; 1872 i | j | t | k 1873---+---+-------+---- 1874 0 | | zero | 1875 1 | 4 | one | -1 1876 2 | 3 | two | 2 1877 2 | 3 | two | 4 1878 3 | 2 | three | -3 1879 4 | 1 | four | 1880 5 | 0 | five | -5 1881 5 | 0 | five | -5 1882 6 | 6 | six | 1883 7 | 7 | seven | 1884 8 | 8 | eight | 1885 | | | 0 1886 | | null | 1887 | 0 | zero | 1888 | | | 1889(15 rows) 1890 1891SELECT * 1892 FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1); 1893 i | j | t | k 1894---+---+---+--- 1895(0 rows) 1896 1897SELECT * 1898 FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1); 1899 i | j | t | k 1900---+---+-----+---- 1901 1 | 4 | one | -1 1902(1 row) 1903 1904-- 1905-- semijoin selectivity for <> 1906-- 1907explain (costs off) 1908select * from int4_tbl i4, tenk1 a 1909where exists(select * from tenk1 b 1910 where a.twothousand = b.twothousand and a.fivethous <> b.fivethous) 1911 and i4.f1 = a.tenthous; 1912 QUERY PLAN 1913---------------------------------------------- 1914 Hash Semi Join 1915 Hash Cond: (a.twothousand = b.twothousand) 1916 Join Filter: (a.fivethous <> b.fivethous) 1917 -> Hash Join 1918 Hash Cond: (a.tenthous = i4.f1) 1919 -> Seq Scan on tenk1 a 1920 -> Hash 1921 -> Seq Scan on int4_tbl i4 1922 -> Hash 1923 -> Seq Scan on tenk1 b 1924(10 rows) 1925 1926-- 1927-- More complicated constructs 1928-- 1929-- 1930-- Multiway full join 1931-- 1932CREATE TABLE t1 (name TEXT, n INTEGER); 1933CREATE TABLE t2 (name TEXT, n INTEGER); 1934CREATE TABLE t3 (name TEXT, n INTEGER); 1935INSERT INTO t1 VALUES ( 'bb', 11 ); 1936INSERT INTO t2 VALUES ( 'bb', 12 ); 1937INSERT INTO t2 VALUES ( 'cc', 22 ); 1938INSERT INTO t2 VALUES ( 'ee', 42 ); 1939INSERT INTO t3 VALUES ( 'bb', 13 ); 1940INSERT INTO t3 VALUES ( 'cc', 23 ); 1941INSERT INTO t3 VALUES ( 'dd', 33 ); 1942SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); 1943 name | n | n | n 1944------+----+----+---- 1945 bb | 11 | 12 | 13 1946 cc | | 22 | 23 1947 dd | | | 33 1948 ee | | 42 | 1949(4 rows) 1950 1951-- 1952-- Test interactions of join syntax and subqueries 1953-- 1954-- Basic cases (we expect planner to pull up the subquery here) 1955SELECT * FROM 1956(SELECT * FROM t2) as s2 1957INNER JOIN 1958(SELECT * FROM t3) s3 1959USING (name); 1960 name | n | n 1961------+----+---- 1962 bb | 12 | 13 1963 cc | 22 | 23 1964(2 rows) 1965 1966SELECT * FROM 1967(SELECT * FROM t2) as s2 1968LEFT JOIN 1969(SELECT * FROM t3) s3 1970USING (name); 1971 name | n | n 1972------+----+---- 1973 bb | 12 | 13 1974 cc | 22 | 23 1975 ee | 42 | 1976(3 rows) 1977 1978SELECT * FROM 1979(SELECT * FROM t2) as s2 1980FULL JOIN 1981(SELECT * FROM t3) s3 1982USING (name); 1983 name | n | n 1984------+----+---- 1985 bb | 12 | 13 1986 cc | 22 | 23 1987 dd | | 33 1988 ee | 42 | 1989(4 rows) 1990 1991-- Cases with non-nullable expressions in subquery results; 1992-- make sure these go to null as expected 1993SELECT * FROM 1994(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 1995NATURAL INNER JOIN 1996(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; 1997 name | s2_n | s2_2 | s3_n | s3_2 1998------+------+------+------+------ 1999 bb | 12 | 2 | 13 | 3 2000 cc | 22 | 2 | 23 | 3 2001(2 rows) 2002 2003SELECT * FROM 2004(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 2005NATURAL LEFT JOIN 2006(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; 2007 name | s2_n | s2_2 | s3_n | s3_2 2008------+------+------+------+------ 2009 bb | 12 | 2 | 13 | 3 2010 cc | 22 | 2 | 23 | 3 2011 ee | 42 | 2 | | 2012(3 rows) 2013 2014SELECT * FROM 2015(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 2016NATURAL FULL JOIN 2017(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; 2018 name | s2_n | s2_2 | s3_n | s3_2 2019------+------+------+------+------ 2020 bb | 12 | 2 | 13 | 3 2021 cc | 22 | 2 | 23 | 3 2022 dd | | | 33 | 3 2023 ee | 42 | 2 | | 2024(4 rows) 2025 2026SELECT * FROM 2027(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 2028NATURAL INNER JOIN 2029(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 2030NATURAL INNER JOIN 2031(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; 2032 name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 2033------+------+------+------+------+------+------ 2034 bb | 11 | 1 | 12 | 2 | 13 | 3 2035(1 row) 2036 2037SELECT * FROM 2038(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 2039NATURAL FULL JOIN 2040(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 2041NATURAL FULL JOIN 2042(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; 2043 name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 2044------+------+------+------+------+------+------ 2045 bb | 11 | 1 | 12 | 2 | 13 | 3 2046 cc | | | 22 | 2 | 23 | 3 2047 dd | | | | | 33 | 3 2048 ee | | | 42 | 2 | | 2049(4 rows) 2050 2051SELECT * FROM 2052(SELECT name, n as s1_n FROM t1) as s1 2053NATURAL FULL JOIN 2054 (SELECT * FROM 2055 (SELECT name, n as s2_n FROM t2) as s2 2056 NATURAL FULL JOIN 2057 (SELECT name, n as s3_n FROM t3) as s3 2058 ) ss2; 2059 name | s1_n | s2_n | s3_n 2060------+------+------+------ 2061 bb | 11 | 12 | 13 2062 cc | | 22 | 23 2063 dd | | | 33 2064 ee | | 42 | 2065(4 rows) 2066 2067SELECT * FROM 2068(SELECT name, n as s1_n FROM t1) as s1 2069NATURAL FULL JOIN 2070 (SELECT * FROM 2071 (SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 2072 NATURAL FULL JOIN 2073 (SELECT name, n as s3_n FROM t3) as s3 2074 ) ss2; 2075 name | s1_n | s2_n | s2_2 | s3_n 2076------+------+------+------+------ 2077 bb | 11 | 12 | 2 | 13 2078 cc | | 22 | 2 | 23 2079 dd | | | | 33 2080 ee | | 42 | 2 | 2081(4 rows) 2082 2083-- Constants as join keys can also be problematic 2084SELECT * FROM 2085 (SELECT name, n as s1_n FROM t1) as s1 2086FULL JOIN 2087 (SELECT name, 2 as s2_n FROM t2) as s2 2088ON (s1_n = s2_n); 2089 name | s1_n | name | s2_n 2090------+------+------+------ 2091 | | bb | 2 2092 | | cc | 2 2093 | | ee | 2 2094 bb | 11 | | 2095(4 rows) 2096 2097-- Test for propagation of nullability constraints into sub-joins 2098create temp table x (x1 int, x2 int); 2099insert into x values (1,11); 2100insert into x values (2,22); 2101insert into x values (3,null); 2102insert into x values (4,44); 2103insert into x values (5,null); 2104create temp table y (y1 int, y2 int); 2105insert into y values (1,111); 2106insert into y values (2,222); 2107insert into y values (3,333); 2108insert into y values (4,null); 2109select * from x; 2110 x1 | x2 2111----+---- 2112 1 | 11 2113 2 | 22 2114 3 | 2115 4 | 44 2116 5 | 2117(5 rows) 2118 2119select * from y; 2120 y1 | y2 2121----+----- 2122 1 | 111 2123 2 | 222 2124 3 | 333 2125 4 | 2126(4 rows) 2127 2128select * from x left join y on (x1 = y1 and x2 is not null); 2129 x1 | x2 | y1 | y2 2130----+----+----+----- 2131 1 | 11 | 1 | 111 2132 2 | 22 | 2 | 222 2133 3 | | | 2134 4 | 44 | 4 | 2135 5 | | | 2136(5 rows) 2137 2138select * from x left join y on (x1 = y1 and y2 is not null); 2139 x1 | x2 | y1 | y2 2140----+----+----+----- 2141 1 | 11 | 1 | 111 2142 2 | 22 | 2 | 222 2143 3 | | 3 | 333 2144 4 | 44 | | 2145 5 | | | 2146(5 rows) 2147 2148select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) 2149on (x1 = xx1); 2150 x1 | x2 | y1 | y2 | xx1 | xx2 2151----+----+----+-----+-----+----- 2152 1 | 11 | 1 | 111 | 1 | 11 2153 2 | 22 | 2 | 222 | 2 | 22 2154 3 | | 3 | 333 | 3 | 2155 4 | 44 | 4 | | 4 | 44 2156 5 | | | | 5 | 2157(5 rows) 2158 2159select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) 2160on (x1 = xx1 and x2 is not null); 2161 x1 | x2 | y1 | y2 | xx1 | xx2 2162----+----+----+-----+-----+----- 2163 1 | 11 | 1 | 111 | 1 | 11 2164 2 | 22 | 2 | 222 | 2 | 22 2165 3 | | 3 | 333 | | 2166 4 | 44 | 4 | | 4 | 44 2167 5 | | | | | 2168(5 rows) 2169 2170select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) 2171on (x1 = xx1 and y2 is not null); 2172 x1 | x2 | y1 | y2 | xx1 | xx2 2173----+----+----+-----+-----+----- 2174 1 | 11 | 1 | 111 | 1 | 11 2175 2 | 22 | 2 | 222 | 2 | 22 2176 3 | | 3 | 333 | 3 | 2177 4 | 44 | 4 | | | 2178 5 | | | | | 2179(5 rows) 2180 2181select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) 2182on (x1 = xx1 and xx2 is not null); 2183 x1 | x2 | y1 | y2 | xx1 | xx2 2184----+----+----+-----+-----+----- 2185 1 | 11 | 1 | 111 | 1 | 11 2186 2 | 22 | 2 | 222 | 2 | 22 2187 3 | | 3 | 333 | | 2188 4 | 44 | 4 | | 4 | 44 2189 5 | | | | | 2190(5 rows) 2191 2192-- these should NOT give the same answers as above 2193select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) 2194on (x1 = xx1) where (x2 is not null); 2195 x1 | x2 | y1 | y2 | xx1 | xx2 2196----+----+----+-----+-----+----- 2197 1 | 11 | 1 | 111 | 1 | 11 2198 2 | 22 | 2 | 222 | 2 | 22 2199 4 | 44 | 4 | | 4 | 44 2200(3 rows) 2201 2202select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) 2203on (x1 = xx1) where (y2 is not null); 2204 x1 | x2 | y1 | y2 | xx1 | xx2 2205----+----+----+-----+-----+----- 2206 1 | 11 | 1 | 111 | 1 | 11 2207 2 | 22 | 2 | 222 | 2 | 22 2208 3 | | 3 | 333 | 3 | 2209(3 rows) 2210 2211select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) 2212on (x1 = xx1) where (xx2 is not null); 2213 x1 | x2 | y1 | y2 | xx1 | xx2 2214----+----+----+-----+-----+----- 2215 1 | 11 | 1 | 111 | 1 | 11 2216 2 | 22 | 2 | 222 | 2 | 22 2217 4 | 44 | 4 | | 4 | 44 2218(3 rows) 2219 2220-- 2221-- regression test: check for bug with propagation of implied equality 2222-- to outside an IN 2223-- 2224select count(*) from tenk1 a where unique1 in 2225 (select unique1 from tenk1 b join tenk1 c using (unique1) 2226 where b.unique2 = 42); 2227 count 2228------- 2229 1 2230(1 row) 2231 2232-- 2233-- regression test: check for failure to generate a plan with multiple 2234-- degenerate IN clauses 2235-- 2236select count(*) from tenk1 x where 2237 x.unique1 in (select a.f1 from int4_tbl a,float8_tbl b where a.f1=b.f1) and 2238 x.unique1 = 0 and 2239 x.unique1 in (select aa.f1 from int4_tbl aa,float8_tbl bb where aa.f1=bb.f1); 2240 count 2241------- 2242 1 2243(1 row) 2244 2245-- try that with GEQO too 2246begin; 2247set geqo = on; 2248set geqo_threshold = 2; 2249select count(*) from tenk1 x where 2250 x.unique1 in (select a.f1 from int4_tbl a,float8_tbl b where a.f1=b.f1) and 2251 x.unique1 = 0 and 2252 x.unique1 in (select aa.f1 from int4_tbl aa,float8_tbl bb where aa.f1=bb.f1); 2253 count 2254------- 2255 1 2256(1 row) 2257 2258rollback; 2259-- 2260-- regression test: be sure we cope with proven-dummy append rels 2261-- 2262explain (costs off) 2263select aa, bb, unique1, unique1 2264 from tenk1 right join b on aa = unique1 2265 where bb < bb and bb is null; 2266 QUERY PLAN 2267-------------------------- 2268 Result 2269 One-Time Filter: false 2270(2 rows) 2271 2272select aa, bb, unique1, unique1 2273 from tenk1 right join b on aa = unique1 2274 where bb < bb and bb is null; 2275 aa | bb | unique1 | unique1 2276----+----+---------+--------- 2277(0 rows) 2278 2279-- 2280-- regression test: check handling of empty-FROM subquery underneath outer join 2281-- 2282explain (costs off) 2283select * from int8_tbl i1 left join (int8_tbl i2 join 2284 (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 2285order by 1, 2; 2286 QUERY PLAN 2287------------------------------------------- 2288 Sort 2289 Sort Key: i1.q1, i1.q2 2290 -> Hash Left Join 2291 Hash Cond: (i1.q2 = i2.q2) 2292 -> Seq Scan on int8_tbl i1 2293 -> Hash 2294 -> Seq Scan on int8_tbl i2 2295 Filter: (q1 = 123) 2296(8 rows) 2297 2298select * from int8_tbl i1 left join (int8_tbl i2 join 2299 (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 2300order by 1, 2; 2301 q1 | q2 | q1 | q2 | x 2302------------------+-------------------+-----+------------------+----- 2303 123 | 456 | 123 | 456 | 123 2304 123 | 4567890123456789 | 123 | 4567890123456789 | 123 2305 4567890123456789 | -4567890123456789 | | | 2306 4567890123456789 | 123 | | | 2307 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 123 2308(5 rows) 2309 2310-- 2311-- regression test: check a case where join_clause_is_movable_into() gives 2312-- an imprecise result, causing an assertion failure 2313-- 2314select count(*) 2315from 2316 (select t3.tenthous as x1, coalesce(t1.stringu1, t2.stringu1) as x2 2317 from tenk1 t1 2318 left join tenk1 t2 on t1.unique1 = t2.unique1 2319 join tenk1 t3 on t1.unique2 = t3.unique2) ss, 2320 tenk1 t4, 2321 tenk1 t5 2322where t4.thousand = t5.unique1 and ss.x1 = t4.tenthous and ss.x2 = t5.stringu1; 2323 count 2324------- 2325 1000 2326(1 row) 2327 2328-- 2329-- regression test: check a case where we formerly missed including an EC 2330-- enforcement clause because it was expected to be handled at scan level 2331-- 2332explain (costs off) 2333select a.f1, b.f1, t.thousand, t.tenthous from 2334 tenk1 t, 2335 (select sum(f1)+1 as f1 from int4_tbl i4a) a, 2336 (select sum(f1) as f1 from int4_tbl i4b) b 2337where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; 2338 QUERY PLAN 2339----------------------------------------------------------------------------------------------------------------------- 2340 Nested Loop 2341 -> Aggregate 2342 -> Seq Scan on int4_tbl i4b 2343 -> Nested Loop 2344 Join Filter: ((sum(i4b.f1)) = ((sum(i4a.f1) + 1))) 2345 -> Aggregate 2346 -> Seq Scan on int4_tbl i4a 2347 -> Index Only Scan using tenk1_thous_tenthous on tenk1 t 2348 Index Cond: ((thousand = (sum(i4b.f1))) AND (tenthous = ((((sum(i4a.f1) + 1)) + (sum(i4b.f1))) + 999))) 2349(9 rows) 2350 2351select a.f1, b.f1, t.thousand, t.tenthous from 2352 tenk1 t, 2353 (select sum(f1)+1 as f1 from int4_tbl i4a) a, 2354 (select sum(f1) as f1 from int4_tbl i4b) b 2355where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; 2356 f1 | f1 | thousand | tenthous 2357----+----+----------+---------- 2358(0 rows) 2359 2360-- 2361-- check a case where we formerly got confused by conflicting sort orders 2362-- in redundant merge join path keys 2363-- 2364explain (costs off) 2365select * from 2366 j1_tbl full join 2367 (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl 2368 on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; 2369 QUERY PLAN 2370----------------------------------------------------------------- 2371 Merge Full Join 2372 Merge Cond: ((j2_tbl.i = j1_tbl.i) AND (j2_tbl.k = j1_tbl.i)) 2373 -> Sort 2374 Sort Key: j2_tbl.i DESC, j2_tbl.k 2375 -> Seq Scan on j2_tbl 2376 -> Sort 2377 Sort Key: j1_tbl.i DESC 2378 -> Seq Scan on j1_tbl 2379(8 rows) 2380 2381select * from 2382 j1_tbl full join 2383 (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl 2384 on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; 2385 i | j | t | i | k 2386---+---+-------+---+---- 2387 | | | | 0 2388 | | | | 2389 | 0 | zero | | 2390 | | null | | 2391 8 | 8 | eight | | 2392 7 | 7 | seven | | 2393 6 | 6 | six | | 2394 | | | 5 | -5 2395 | | | 5 | -5 2396 5 | 0 | five | | 2397 4 | 1 | four | | 2398 | | | 3 | -3 2399 3 | 2 | three | | 2400 2 | 3 | two | 2 | 2 2401 | | | 2 | 4 2402 | | | 1 | -1 2403 | | | 0 | 2404 1 | 4 | one | | 2405 0 | | zero | | 2406(19 rows) 2407 2408-- 2409-- a different check for handling of redundant sort keys in merge joins 2410-- 2411explain (costs off) 2412select count(*) from 2413 (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x 2414 left join 2415 (select * from tenk1 y order by y.unique2) y 2416 on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; 2417 QUERY PLAN 2418---------------------------------------------------------------------------------- 2419 Aggregate 2420 -> Merge Left Join 2421 Merge Cond: (x.thousand = y.unique2) 2422 Join Filter: ((x.twothousand = y.hundred) AND (x.fivethous = y.unique2)) 2423 -> Sort 2424 Sort Key: x.thousand, x.twothousand, x.fivethous 2425 -> Seq Scan on tenk1 x 2426 -> Materialize 2427 -> Index Scan using tenk1_unique2 on tenk1 y 2428(9 rows) 2429 2430select count(*) from 2431 (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x 2432 left join 2433 (select * from tenk1 y order by y.unique2) y 2434 on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; 2435 count 2436------- 2437 10000 2438(1 row) 2439 2440-- 2441-- Clean up 2442-- 2443DROP TABLE t1; 2444DROP TABLE t2; 2445DROP TABLE t3; 2446DROP TABLE J1_TBL; 2447DROP TABLE J2_TBL; 2448-- Both DELETE and UPDATE allow the specification of additional tables 2449-- to "join" against to determine which rows should be modified. 2450CREATE TEMP TABLE t1 (a int, b int); 2451CREATE TEMP TABLE t2 (a int, b int); 2452CREATE TEMP TABLE t3 (x int, y int); 2453INSERT INTO t1 VALUES (5, 10); 2454INSERT INTO t1 VALUES (15, 20); 2455INSERT INTO t1 VALUES (100, 100); 2456INSERT INTO t1 VALUES (200, 1000); 2457INSERT INTO t2 VALUES (200, 2000); 2458INSERT INTO t3 VALUES (5, 20); 2459INSERT INTO t3 VALUES (6, 7); 2460INSERT INTO t3 VALUES (7, 8); 2461INSERT INTO t3 VALUES (500, 100); 2462DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a; 2463SELECT * FROM t3; 2464 x | y 2465-----+----- 2466 6 | 7 2467 7 | 8 2468 500 | 100 2469(3 rows) 2470 2471DELETE FROM t3 USING t1 JOIN t2 USING (a) WHERE t3.x > t1.a; 2472SELECT * FROM t3; 2473 x | y 2474---+--- 2475 6 | 7 2476 7 | 8 2477(2 rows) 2478 2479DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y; 2480SELECT * FROM t3; 2481 x | y 2482---+--- 2483(0 rows) 2484 2485-- Test join against inheritance tree 2486create temp table t2a () inherits (t2); 2487insert into t2a values (200, 2001); 2488select * from t1 left join t2 on (t1.a = t2.a); 2489 a | b | a | b 2490-----+------+-----+------ 2491 5 | 10 | | 2492 15 | 20 | | 2493 100 | 100 | | 2494 200 | 1000 | 200 | 2000 2495 200 | 1000 | 200 | 2001 2496(5 rows) 2497 2498-- Test matching of column name with wrong alias 2499select t1.x from t1 join t3 on (t1.a = t3.x); 2500ERROR: column t1.x does not exist 2501LINE 1: select t1.x from t1 join t3 on (t1.a = t3.x); 2502 ^ 2503HINT: Perhaps you meant to reference the column "t3.x". 2504-- 2505-- regression test for 8.1 merge right join bug 2506-- 2507CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ); 2508INSERT INTO tt1 VALUES (1, 11); 2509INSERT INTO tt1 VALUES (2, NULL); 2510CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ); 2511INSERT INTO tt2 VALUES (21, 11); 2512INSERT INTO tt2 VALUES (22, 11); 2513set enable_hashjoin to off; 2514set enable_nestloop to off; 2515-- these should give the same results 2516select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; 2517 tt1_id | joincol | tt2_id | joincol 2518--------+---------+--------+--------- 2519 1 | 11 | 21 | 11 2520 1 | 11 | 22 | 11 2521 2 | | | 2522(3 rows) 2523 2524select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; 2525 tt1_id | joincol | tt2_id | joincol 2526--------+---------+--------+--------- 2527 1 | 11 | 21 | 11 2528 1 | 11 | 22 | 11 2529 2 | | | 2530(3 rows) 2531 2532reset enable_hashjoin; 2533reset enable_nestloop; 2534-- 2535-- regression test for bug #13908 (hash join with skew tuples & nbatch increase) 2536-- 2537set work_mem to '64kB'; 2538set enable_mergejoin to off; 2539set enable_memoize to off; 2540explain (costs off) 2541select count(*) from tenk1 a, tenk1 b 2542 where a.hundred = b.thousand and (b.fivethous % 10) < 10; 2543 QUERY PLAN 2544------------------------------------------------------------ 2545 Aggregate 2546 -> Hash Join 2547 Hash Cond: (a.hundred = b.thousand) 2548 -> Index Only Scan using tenk1_hundred on tenk1 a 2549 -> Hash 2550 -> Seq Scan on tenk1 b 2551 Filter: ((fivethous % 10) < 10) 2552(7 rows) 2553 2554select count(*) from tenk1 a, tenk1 b 2555 where a.hundred = b.thousand and (b.fivethous % 10) < 10; 2556 count 2557-------- 2558 100000 2559(1 row) 2560 2561reset work_mem; 2562reset enable_mergejoin; 2563reset enable_memoize; 2564-- 2565-- regression test for 8.2 bug with improper re-ordering of left joins 2566-- 2567create temp table tt3(f1 int, f2 text); 2568insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; 2569create index tt3i on tt3(f1); 2570analyze tt3; 2571create temp table tt4(f1 int); 2572insert into tt4 values (0),(1),(9999); 2573analyze tt4; 2574SELECT a.f1 2575FROM tt4 a 2576LEFT JOIN ( 2577 SELECT b.f1 2578 FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) 2579 WHERE c.f1 IS NULL 2580) AS d ON (a.f1 = d.f1) 2581WHERE d.f1 IS NULL; 2582 f1 2583------ 2584 0 2585 1 2586 9999 2587(3 rows) 2588 2589-- 2590-- regression test for proper handling of outer joins within antijoins 2591-- 2592create temp table tt4x(c1 int, c2 int, c3 int); 2593explain (costs off) 2594select * from tt4x t1 2595where not exists ( 2596 select 1 from tt4x t2 2597 left join tt4x t3 on t2.c3 = t3.c1 2598 left join ( select t5.c1 as c1 2599 from tt4x t4 left join tt4x t5 on t4.c2 = t5.c1 2600 ) a1 on t3.c2 = a1.c1 2601 where t1.c1 = t2.c2 2602); 2603 QUERY PLAN 2604--------------------------------------------------------- 2605 Hash Anti Join 2606 Hash Cond: (t1.c1 = t2.c2) 2607 -> Seq Scan on tt4x t1 2608 -> Hash 2609 -> Merge Right Join 2610 Merge Cond: (t5.c1 = t3.c2) 2611 -> Merge Join 2612 Merge Cond: (t4.c2 = t5.c1) 2613 -> Sort 2614 Sort Key: t4.c2 2615 -> Seq Scan on tt4x t4 2616 -> Sort 2617 Sort Key: t5.c1 2618 -> Seq Scan on tt4x t5 2619 -> Sort 2620 Sort Key: t3.c2 2621 -> Merge Left Join 2622 Merge Cond: (t2.c3 = t3.c1) 2623 -> Sort 2624 Sort Key: t2.c3 2625 -> Seq Scan on tt4x t2 2626 -> Sort 2627 Sort Key: t3.c1 2628 -> Seq Scan on tt4x t3 2629(24 rows) 2630 2631-- 2632-- regression test for problems of the sort depicted in bug #3494 2633-- 2634create temp table tt5(f1 int, f2 int); 2635create temp table tt6(f1 int, f2 int); 2636insert into tt5 values(1, 10); 2637insert into tt5 values(1, 11); 2638insert into tt6 values(1, 9); 2639insert into tt6 values(1, 2); 2640insert into tt6 values(2, 9); 2641select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; 2642 f1 | f2 | f1 | f2 2643----+----+----+---- 2644 1 | 10 | 1 | 9 2645(1 row) 2646 2647-- 2648-- regression test for problems of the sort depicted in bug #3588 2649-- 2650create temp table xx (pkxx int); 2651create temp table yy (pkyy int, pkxx int); 2652insert into xx values (1); 2653insert into xx values (2); 2654insert into xx values (3); 2655insert into yy values (101, 1); 2656insert into yy values (201, 2); 2657insert into yy values (301, NULL); 2658select yy.pkyy as yy_pkyy, yy.pkxx as yy_pkxx, yya.pkyy as yya_pkyy, 2659 xxa.pkxx as xxa_pkxx, xxb.pkxx as xxb_pkxx 2660from yy 2661 left join (SELECT * FROM yy where pkyy = 101) as yya ON yy.pkyy = yya.pkyy 2662 left join xx xxa on yya.pkxx = xxa.pkxx 2663 left join xx xxb on coalesce (xxa.pkxx, 1) = xxb.pkxx; 2664 yy_pkyy | yy_pkxx | yya_pkyy | xxa_pkxx | xxb_pkxx 2665---------+---------+----------+----------+---------- 2666 101 | 1 | 101 | 1 | 1 2667 201 | 2 | | | 1 2668 301 | | | | 1 2669(3 rows) 2670 2671-- 2672-- regression test for improper pushing of constants across outer-join clauses 2673-- (as seen in early 8.2.x releases) 2674-- 2675create temp table zt1 (f1 int primary key); 2676create temp table zt2 (f2 int primary key); 2677create temp table zt3 (f3 int primary key); 2678insert into zt1 values(53); 2679insert into zt2 values(53); 2680select * from 2681 zt2 left join zt3 on (f2 = f3) 2682 left join zt1 on (f3 = f1) 2683where f2 = 53; 2684 f2 | f3 | f1 2685----+----+---- 2686 53 | | 2687(1 row) 2688 2689create temp view zv1 as select *,'dummy'::text AS junk from zt1; 2690select * from 2691 zt2 left join zt3 on (f2 = f3) 2692 left join zv1 on (f3 = f1) 2693where f2 = 53; 2694 f2 | f3 | f1 | junk 2695----+----+----+------ 2696 53 | | | 2697(1 row) 2698 2699-- 2700-- regression test for improper extraction of OR indexqual conditions 2701-- (as seen in early 8.3.x releases) 2702-- 2703select a.unique2, a.ten, b.tenthous, b.unique2, b.hundred 2704from tenk1 a left join tenk1 b on a.unique2 = b.tenthous 2705where a.unique1 = 42 and 2706 ((b.unique2 is null and a.ten = 2) or b.hundred = 3); 2707 unique2 | ten | tenthous | unique2 | hundred 2708---------+-----+----------+---------+--------- 2709(0 rows) 2710 2711-- 2712-- test proper positioning of one-time quals in EXISTS (8.4devel bug) 2713-- 2714prepare foo(bool) as 2715 select count(*) from tenk1 a left join tenk1 b 2716 on (a.unique2 = b.unique1 and exists 2717 (select 1 from tenk1 c where c.thousand = b.unique2 and $1)); 2718execute foo(true); 2719 count 2720------- 2721 10000 2722(1 row) 2723 2724execute foo(false); 2725 count 2726------- 2727 10000 2728(1 row) 2729 2730-- 2731-- test for sane behavior with noncanonical merge clauses, per bug #4926 2732-- 2733begin; 2734set enable_mergejoin = 1; 2735set enable_hashjoin = 0; 2736set enable_nestloop = 0; 2737create temp table a (i integer); 2738create temp table b (x integer, y integer); 2739select * from a left join b on i = x and i = y and x = i; 2740 i | x | y 2741---+---+--- 2742(0 rows) 2743 2744rollback; 2745-- 2746-- test handling of merge clauses using record_ops 2747-- 2748begin; 2749create type mycomptype as (id int, v bigint); 2750create temp table tidv (idv mycomptype); 2751create index on tidv (idv); 2752explain (costs off) 2753select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; 2754 QUERY PLAN 2755---------------------------------------------------------- 2756 Merge Join 2757 Merge Cond: (a.idv = b.idv) 2758 -> Index Only Scan using tidv_idv_idx on tidv a 2759 -> Materialize 2760 -> Index Only Scan using tidv_idv_idx on tidv b 2761(5 rows) 2762 2763set enable_mergejoin = 0; 2764set enable_hashjoin = 0; 2765explain (costs off) 2766select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; 2767 QUERY PLAN 2768---------------------------------------------------- 2769 Nested Loop 2770 -> Seq Scan on tidv a 2771 -> Index Only Scan using tidv_idv_idx on tidv b 2772 Index Cond: (idv = a.idv) 2773(4 rows) 2774 2775rollback; 2776-- 2777-- test NULL behavior of whole-row Vars, per bug #5025 2778-- 2779select t1.q2, count(t2.*) 2780from int8_tbl t1 left join int8_tbl t2 on (t1.q2 = t2.q1) 2781group by t1.q2 order by 1; 2782 q2 | count 2783-------------------+------- 2784 -4567890123456789 | 0 2785 123 | 2 2786 456 | 0 2787 4567890123456789 | 6 2788(4 rows) 2789 2790select t1.q2, count(t2.*) 2791from int8_tbl t1 left join (select * from int8_tbl) t2 on (t1.q2 = t2.q1) 2792group by t1.q2 order by 1; 2793 q2 | count 2794-------------------+------- 2795 -4567890123456789 | 0 2796 123 | 2 2797 456 | 0 2798 4567890123456789 | 6 2799(4 rows) 2800 2801select t1.q2, count(t2.*) 2802from int8_tbl t1 left join (select * from int8_tbl offset 0) t2 on (t1.q2 = t2.q1) 2803group by t1.q2 order by 1; 2804 q2 | count 2805-------------------+------- 2806 -4567890123456789 | 0 2807 123 | 2 2808 456 | 0 2809 4567890123456789 | 6 2810(4 rows) 2811 2812select t1.q2, count(t2.*) 2813from int8_tbl t1 left join 2814 (select q1, case when q2=1 then 1 else q2 end as q2 from int8_tbl) t2 2815 on (t1.q2 = t2.q1) 2816group by t1.q2 order by 1; 2817 q2 | count 2818-------------------+------- 2819 -4567890123456789 | 0 2820 123 | 2 2821 456 | 0 2822 4567890123456789 | 6 2823(4 rows) 2824 2825-- 2826-- test incorrect failure to NULL pulled-up subexpressions 2827-- 2828begin; 2829create temp table a ( 2830 code char not null, 2831 constraint a_pk primary key (code) 2832); 2833create temp table b ( 2834 a char not null, 2835 num integer not null, 2836 constraint b_pk primary key (a, num) 2837); 2838create temp table c ( 2839 name char not null, 2840 a char, 2841 constraint c_pk primary key (name) 2842); 2843insert into a (code) values ('p'); 2844insert into a (code) values ('q'); 2845insert into b (a, num) values ('p', 1); 2846insert into b (a, num) values ('p', 2); 2847insert into c (name, a) values ('A', 'p'); 2848insert into c (name, a) values ('B', 'q'); 2849insert into c (name, a) values ('C', null); 2850select c.name, ss.code, ss.b_cnt, ss.const 2851from c left join 2852 (select a.code, coalesce(b_grp.cnt, 0) as b_cnt, -1 as const 2853 from a left join 2854 (select count(1) as cnt, b.a from b group by b.a) as b_grp 2855 on a.code = b_grp.a 2856 ) as ss 2857 on (c.a = ss.code) 2858order by c.name; 2859 name | code | b_cnt | const 2860------+------+-------+------- 2861 A | p | 2 | -1 2862 B | q | 0 | -1 2863 C | | | 2864(3 rows) 2865 2866rollback; 2867-- 2868-- test incorrect handling of placeholders that only appear in targetlists, 2869-- per bug #6154 2870-- 2871SELECT * FROM 2872( SELECT 1 as key1 ) sub1 2873LEFT JOIN 2874( SELECT sub3.key3, sub4.value2, COALESCE(sub4.value2, 66) as value3 FROM 2875 ( SELECT 1 as key3 ) sub3 2876 LEFT JOIN 2877 ( SELECT sub5.key5, COALESCE(sub6.value1, 1) as value2 FROM 2878 ( SELECT 1 as key5 ) sub5 2879 LEFT JOIN 2880 ( SELECT 2 as key6, 42 as value1 ) sub6 2881 ON sub5.key5 = sub6.key6 2882 ) sub4 2883 ON sub4.key5 = sub3.key3 2884) sub2 2885ON sub1.key1 = sub2.key3; 2886 key1 | key3 | value2 | value3 2887------+------+--------+-------- 2888 1 | 1 | 1 | 1 2889(1 row) 2890 2891-- test the path using join aliases, too 2892SELECT * FROM 2893( SELECT 1 as key1 ) sub1 2894LEFT JOIN 2895( SELECT sub3.key3, value2, COALESCE(value2, 66) as value3 FROM 2896 ( SELECT 1 as key3 ) sub3 2897 LEFT JOIN 2898 ( SELECT sub5.key5, COALESCE(sub6.value1, 1) as value2 FROM 2899 ( SELECT 1 as key5 ) sub5 2900 LEFT JOIN 2901 ( SELECT 2 as key6, 42 as value1 ) sub6 2902 ON sub5.key5 = sub6.key6 2903 ) sub4 2904 ON sub4.key5 = sub3.key3 2905) sub2 2906ON sub1.key1 = sub2.key3; 2907 key1 | key3 | value2 | value3 2908------+------+--------+-------- 2909 1 | 1 | 1 | 1 2910(1 row) 2911 2912-- 2913-- test case where a PlaceHolderVar is used as a nestloop parameter 2914-- 2915EXPLAIN (COSTS OFF) 2916SELECT qq, unique1 2917 FROM 2918 ( SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a ) AS ss1 2919 FULL OUTER JOIN 2920 ( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2 2921 USING (qq) 2922 INNER JOIN tenk1 c ON qq = unique2; 2923 QUERY PLAN 2924--------------------------------------------------------------------------------------------------------- 2925 Nested Loop 2926 -> Hash Full Join 2927 Hash Cond: ((COALESCE(a.q1, '0'::bigint)) = (COALESCE(b.q2, '-1'::bigint))) 2928 -> Seq Scan on int8_tbl a 2929 -> Hash 2930 -> Seq Scan on int8_tbl b 2931 -> Index Scan using tenk1_unique2 on tenk1 c 2932 Index Cond: (unique2 = COALESCE((COALESCE(a.q1, '0'::bigint)), (COALESCE(b.q2, '-1'::bigint)))) 2933(8 rows) 2934 2935SELECT qq, unique1 2936 FROM 2937 ( SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a ) AS ss1 2938 FULL OUTER JOIN 2939 ( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2 2940 USING (qq) 2941 INNER JOIN tenk1 c ON qq = unique2; 2942 qq | unique1 2943-----+--------- 2944 123 | 4596 2945 123 | 4596 2946 456 | 7318 2947(3 rows) 2948 2949-- 2950-- nested nestloops can require nested PlaceHolderVars 2951-- 2952create temp table nt1 ( 2953 id int primary key, 2954 a1 boolean, 2955 a2 boolean 2956); 2957create temp table nt2 ( 2958 id int primary key, 2959 nt1_id int, 2960 b1 boolean, 2961 b2 boolean, 2962 foreign key (nt1_id) references nt1(id) 2963); 2964create temp table nt3 ( 2965 id int primary key, 2966 nt2_id int, 2967 c1 boolean, 2968 foreign key (nt2_id) references nt2(id) 2969); 2970insert into nt1 values (1,true,true); 2971insert into nt1 values (2,true,false); 2972insert into nt1 values (3,false,false); 2973insert into nt2 values (1,1,true,true); 2974insert into nt2 values (2,2,true,false); 2975insert into nt2 values (3,3,false,false); 2976insert into nt3 values (1,1,true); 2977insert into nt3 values (2,2,false); 2978insert into nt3 values (3,3,true); 2979explain (costs off) 2980select nt3.id 2981from nt3 as nt3 2982 left join 2983 (select nt2.*, (nt2.b1 and ss1.a3) AS b3 2984 from nt2 as nt2 2985 left join 2986 (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 2987 on ss1.id = nt2.nt1_id 2988 ) as ss2 2989 on ss2.id = nt3.nt2_id 2990where nt3.id = 1 and ss2.b3; 2991 QUERY PLAN 2992----------------------------------------------- 2993 Nested Loop 2994 -> Nested Loop 2995 -> Index Scan using nt3_pkey on nt3 2996 Index Cond: (id = 1) 2997 -> Index Scan using nt2_pkey on nt2 2998 Index Cond: (id = nt3.nt2_id) 2999 -> Index Only Scan using nt1_pkey on nt1 3000 Index Cond: (id = nt2.nt1_id) 3001 Filter: (nt2.b1 AND (id IS NOT NULL)) 3002(9 rows) 3003 3004select nt3.id 3005from nt3 as nt3 3006 left join 3007 (select nt2.*, (nt2.b1 and ss1.a3) AS b3 3008 from nt2 as nt2 3009 left join 3010 (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 3011 on ss1.id = nt2.nt1_id 3012 ) as ss2 3013 on ss2.id = nt3.nt2_id 3014where nt3.id = 1 and ss2.b3; 3015 id 3016---- 3017 1 3018(1 row) 3019 3020-- 3021-- test case where a PlaceHolderVar is propagated into a subquery 3022-- 3023explain (costs off) 3024select * from 3025 int8_tbl t1 left join 3026 (select q1 as x, 42 as y from int8_tbl t2) ss 3027 on t1.q2 = ss.x 3028where 3029 1 = (select 1 from int8_tbl t3 where ss.y is not null limit 1) 3030order by 1,2; 3031 QUERY PLAN 3032----------------------------------------------------------- 3033 Sort 3034 Sort Key: t1.q1, t1.q2 3035 -> Hash Left Join 3036 Hash Cond: (t1.q2 = t2.q1) 3037 Filter: (1 = (SubPlan 1)) 3038 -> Seq Scan on int8_tbl t1 3039 -> Hash 3040 -> Seq Scan on int8_tbl t2 3041 SubPlan 1 3042 -> Limit 3043 -> Result 3044 One-Time Filter: ((42) IS NOT NULL) 3045 -> Seq Scan on int8_tbl t3 3046(13 rows) 3047 3048select * from 3049 int8_tbl t1 left join 3050 (select q1 as x, 42 as y from int8_tbl t2) ss 3051 on t1.q2 = ss.x 3052where 3053 1 = (select 1 from int8_tbl t3 where ss.y is not null limit 1) 3054order by 1,2; 3055 q1 | q2 | x | y 3056------------------+------------------+------------------+---- 3057 123 | 4567890123456789 | 4567890123456789 | 42 3058 123 | 4567890123456789 | 4567890123456789 | 42 3059 123 | 4567890123456789 | 4567890123456789 | 42 3060 4567890123456789 | 123 | 123 | 42 3061 4567890123456789 | 123 | 123 | 42 3062 4567890123456789 | 4567890123456789 | 4567890123456789 | 42 3063 4567890123456789 | 4567890123456789 | 4567890123456789 | 42 3064 4567890123456789 | 4567890123456789 | 4567890123456789 | 42 3065(8 rows) 3066 3067-- 3068-- variant where a PlaceHolderVar is needed at a join, but not above the join 3069-- 3070explain (costs off) 3071select * from 3072 int4_tbl as i41, 3073 lateral 3074 (select 1 as x from 3075 (select i41.f1 as lat, 3076 i42.f1 as loc from 3077 int8_tbl as i81, int4_tbl as i42) as ss1 3078 right join int4_tbl as i43 on (i43.f1 > 1) 3079 where ss1.loc = ss1.lat) as ss2 3080where i41.f1 > 0; 3081 QUERY PLAN 3082-------------------------------------------------- 3083 Nested Loop 3084 -> Nested Loop 3085 -> Seq Scan on int4_tbl i41 3086 Filter: (f1 > 0) 3087 -> Nested Loop 3088 Join Filter: (i41.f1 = i42.f1) 3089 -> Seq Scan on int8_tbl i81 3090 -> Materialize 3091 -> Seq Scan on int4_tbl i42 3092 -> Materialize 3093 -> Seq Scan on int4_tbl i43 3094 Filter: (f1 > 1) 3095(12 rows) 3096 3097select * from 3098 int4_tbl as i41, 3099 lateral 3100 (select 1 as x from 3101 (select i41.f1 as lat, 3102 i42.f1 as loc from 3103 int8_tbl as i81, int4_tbl as i42) as ss1 3104 right join int4_tbl as i43 on (i43.f1 > 1) 3105 where ss1.loc = ss1.lat) as ss2 3106where i41.f1 > 0; 3107 f1 | x 3108------------+--- 3109 123456 | 1 3110 123456 | 1 3111 123456 | 1 3112 123456 | 1 3113 123456 | 1 3114 123456 | 1 3115 123456 | 1 3116 123456 | 1 3117 123456 | 1 3118 123456 | 1 3119 2147483647 | 1 3120 2147483647 | 1 3121 2147483647 | 1 3122 2147483647 | 1 3123 2147483647 | 1 3124 2147483647 | 1 3125 2147483647 | 1 3126 2147483647 | 1 3127 2147483647 | 1 3128 2147483647 | 1 3129(20 rows) 3130 3131-- 3132-- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE 3133-- 3134select * from int4_tbl a full join int4_tbl b on true; 3135 f1 | f1 3136-------------+------------- 3137 0 | 0 3138 0 | 123456 3139 0 | -123456 3140 0 | 2147483647 3141 0 | -2147483647 3142 123456 | 0 3143 123456 | 123456 3144 123456 | -123456 3145 123456 | 2147483647 3146 123456 | -2147483647 3147 -123456 | 0 3148 -123456 | 123456 3149 -123456 | -123456 3150 -123456 | 2147483647 3151 -123456 | -2147483647 3152 2147483647 | 0 3153 2147483647 | 123456 3154 2147483647 | -123456 3155 2147483647 | 2147483647 3156 2147483647 | -2147483647 3157 -2147483647 | 0 3158 -2147483647 | 123456 3159 -2147483647 | -123456 3160 -2147483647 | 2147483647 3161 -2147483647 | -2147483647 3162(25 rows) 3163 3164select * from int4_tbl a full join int4_tbl b on false; 3165 f1 | f1 3166-------------+------------- 3167 | 0 3168 | 123456 3169 | -123456 3170 | 2147483647 3171 | -2147483647 3172 0 | 3173 123456 | 3174 -123456 | 3175 2147483647 | 3176 -2147483647 | 3177(10 rows) 3178 3179-- 3180-- test for ability to use a cartesian join when necessary 3181-- 3182create temp table q1 as select 1 as q1; 3183create temp table q2 as select 0 as q2; 3184analyze q1; 3185analyze q2; 3186explain (costs off) 3187select * from 3188 tenk1 join int4_tbl on f1 = twothousand, 3189 q1, q2 3190where q1 = thousand or q2 = thousand; 3191 QUERY PLAN 3192------------------------------------------------------------------------ 3193 Hash Join 3194 Hash Cond: (tenk1.twothousand = int4_tbl.f1) 3195 -> Nested Loop 3196 -> Nested Loop 3197 -> Seq Scan on q1 3198 -> Seq Scan on q2 3199 -> Bitmap Heap Scan on tenk1 3200 Recheck Cond: ((q1.q1 = thousand) OR (q2.q2 = thousand)) 3201 -> BitmapOr 3202 -> Bitmap Index Scan on tenk1_thous_tenthous 3203 Index Cond: (thousand = q1.q1) 3204 -> Bitmap Index Scan on tenk1_thous_tenthous 3205 Index Cond: (thousand = q2.q2) 3206 -> Hash 3207 -> Seq Scan on int4_tbl 3208(15 rows) 3209 3210explain (costs off) 3211select * from 3212 tenk1 join int4_tbl on f1 = twothousand, 3213 q1, q2 3214where thousand = (q1 + q2); 3215 QUERY PLAN 3216-------------------------------------------------------------- 3217 Hash Join 3218 Hash Cond: (tenk1.twothousand = int4_tbl.f1) 3219 -> Nested Loop 3220 -> Nested Loop 3221 -> Seq Scan on q1 3222 -> Seq Scan on q2 3223 -> Bitmap Heap Scan on tenk1 3224 Recheck Cond: (thousand = (q1.q1 + q2.q2)) 3225 -> Bitmap Index Scan on tenk1_thous_tenthous 3226 Index Cond: (thousand = (q1.q1 + q2.q2)) 3227 -> Hash 3228 -> Seq Scan on int4_tbl 3229(12 rows) 3230 3231-- 3232-- test ability to generate a suitable plan for a star-schema query 3233-- 3234explain (costs off) 3235select * from 3236 tenk1, int8_tbl a, int8_tbl b 3237where thousand = a.q1 and tenthous = b.q1 and a.q2 = 1 and b.q2 = 2; 3238 QUERY PLAN 3239--------------------------------------------------------------------- 3240 Nested Loop 3241 -> Seq Scan on int8_tbl b 3242 Filter: (q2 = 2) 3243 -> Nested Loop 3244 -> Seq Scan on int8_tbl a 3245 Filter: (q2 = 1) 3246 -> Index Scan using tenk1_thous_tenthous on tenk1 3247 Index Cond: ((thousand = a.q1) AND (tenthous = b.q1)) 3248(8 rows) 3249 3250-- 3251-- test a corner case in which we shouldn't apply the star-schema optimization 3252-- 3253explain (costs off) 3254select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from 3255 tenk1 t1 3256 inner join int4_tbl i1 3257 left join (select v1.x2, v2.y1, 11 AS d1 3258 from (select 1,0 from onerow) v1(x1,x2) 3259 left join (select 3,1 from onerow) v2(y1,y2) 3260 on v1.x1 = v2.y2) subq1 3261 on (i1.f1 = subq1.x2) 3262 on (t1.unique2 = subq1.d1) 3263 left join tenk1 t2 3264 on (subq1.y1 = t2.unique1) 3265where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; 3266 QUERY PLAN 3267----------------------------------------------------------------------- 3268 Nested Loop 3269 -> Nested Loop 3270 Join Filter: (t1.stringu1 > t2.stringu2) 3271 -> Nested Loop 3272 -> Nested Loop 3273 -> Seq Scan on onerow 3274 -> Seq Scan on onerow onerow_1 3275 -> Index Scan using tenk1_unique2 on tenk1 t1 3276 Index Cond: ((unique2 = (11)) AND (unique2 < 42)) 3277 -> Index Scan using tenk1_unique1 on tenk1 t2 3278 Index Cond: (unique1 = (3)) 3279 -> Seq Scan on int4_tbl i1 3280 Filter: (f1 = 0) 3281(13 rows) 3282 3283select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from 3284 tenk1 t1 3285 inner join int4_tbl i1 3286 left join (select v1.x2, v2.y1, 11 AS d1 3287 from (select 1,0 from onerow) v1(x1,x2) 3288 left join (select 3,1 from onerow) v2(y1,y2) 3289 on v1.x1 = v2.y2) subq1 3290 on (i1.f1 = subq1.x2) 3291 on (t1.unique2 = subq1.d1) 3292 left join tenk1 t2 3293 on (subq1.y1 = t2.unique1) 3294where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; 3295 unique2 | stringu1 | unique1 | stringu2 3296---------+----------+---------+---------- 3297 11 | WFAAAA | 3 | LKIAAA 3298(1 row) 3299 3300-- variant that isn't quite a star-schema case 3301select ss1.d1 from 3302 tenk1 as t1 3303 inner join tenk1 as t2 3304 on t1.tenthous = t2.ten 3305 inner join 3306 int8_tbl as i8 3307 left join int4_tbl as i4 3308 inner join (select 64::information_schema.cardinal_number as d1 3309 from tenk1 t3, 3310 lateral (select abs(t3.unique1) + random()) ss0(x) 3311 where t3.fivethous < 0) as ss1 3312 on i4.f1 = ss1.d1 3313 on i8.q1 = i4.f1 3314 on t1.tenthous = ss1.d1 3315where t1.unique1 < i4.f1; 3316 d1 3317---- 3318(0 rows) 3319 3320-- this variant is foldable by the remove-useless-RESULT-RTEs code 3321explain (costs off) 3322select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from 3323 tenk1 t1 3324 inner join int4_tbl i1 3325 left join (select v1.x2, v2.y1, 11 AS d1 3326 from (values(1,0)) v1(x1,x2) 3327 left join (values(3,1)) v2(y1,y2) 3328 on v1.x1 = v2.y2) subq1 3329 on (i1.f1 = subq1.x2) 3330 on (t1.unique2 = subq1.d1) 3331 left join tenk1 t2 3332 on (subq1.y1 = t2.unique1) 3333where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; 3334 QUERY PLAN 3335----------------------------------------------------------------- 3336 Nested Loop 3337 Join Filter: (t1.stringu1 > t2.stringu2) 3338 -> Nested Loop 3339 -> Seq Scan on int4_tbl i1 3340 Filter: (f1 = 0) 3341 -> Index Scan using tenk1_unique2 on tenk1 t1 3342 Index Cond: ((unique2 = (11)) AND (unique2 < 42)) 3343 -> Index Scan using tenk1_unique1 on tenk1 t2 3344 Index Cond: (unique1 = (3)) 3345(9 rows) 3346 3347select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from 3348 tenk1 t1 3349 inner join int4_tbl i1 3350 left join (select v1.x2, v2.y1, 11 AS d1 3351 from (values(1,0)) v1(x1,x2) 3352 left join (values(3,1)) v2(y1,y2) 3353 on v1.x1 = v2.y2) subq1 3354 on (i1.f1 = subq1.x2) 3355 on (t1.unique2 = subq1.d1) 3356 left join tenk1 t2 3357 on (subq1.y1 = t2.unique1) 3358where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; 3359 unique2 | stringu1 | unique1 | stringu2 3360---------+----------+---------+---------- 3361 11 | WFAAAA | 3 | LKIAAA 3362(1 row) 3363 3364-- Here's a variant that we can't fold too aggressively, though, 3365-- or we end up with noplace to evaluate the lateral PHV 3366explain (verbose, costs off) 3367select * from 3368 (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), 3369 lateral (select ss2.y as z limit 1) ss3; 3370 QUERY PLAN 3371--------------------------- 3372 Nested Loop 3373 Output: 1, (2), ((2)) 3374 -> Result 3375 Output: 2 3376 -> Limit 3377 Output: ((2)) 3378 -> Result 3379 Output: (2) 3380(8 rows) 3381 3382select * from 3383 (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), 3384 lateral (select ss2.y as z limit 1) ss3; 3385 x | y | z 3386---+---+--- 3387 1 | 2 | 2 3388(1 row) 3389 3390-- Test proper handling of appendrel PHVs during useless-RTE removal 3391explain (costs off) 3392select * from 3393 (select 0 as z) as t1 3394 left join 3395 (select true as a) as t2 3396 on true, 3397 lateral (select true as b 3398 union all 3399 select a as b) as t3 3400where b; 3401 QUERY PLAN 3402--------------------------------------- 3403 Nested Loop 3404 -> Result 3405 -> Append 3406 -> Result 3407 -> Result 3408 One-Time Filter: (true) 3409(6 rows) 3410 3411select * from 3412 (select 0 as z) as t1 3413 left join 3414 (select true as a) as t2 3415 on true, 3416 lateral (select true as b 3417 union all 3418 select a as b) as t3 3419where b; 3420 z | a | b 3421---+---+--- 3422 0 | t | t 3423 0 | t | t 3424(2 rows) 3425 3426-- 3427-- test inlining of immutable functions 3428-- 3429create function f_immutable_int4(i integer) returns integer as 3430$$ begin return i; end; $$ language plpgsql immutable; 3431-- check optimization of function scan with join 3432explain (costs off) 3433select unique1 from tenk1, (select * from f_immutable_int4(1) x) x 3434where x = unique1; 3435 QUERY PLAN 3436---------------------------------------------- 3437 Index Only Scan using tenk1_unique1 on tenk1 3438 Index Cond: (unique1 = 1) 3439(2 rows) 3440 3441explain (verbose, costs off) 3442select unique1, x.* 3443from tenk1, (select *, random() from f_immutable_int4(1) x) x 3444where x = unique1; 3445 QUERY PLAN 3446----------------------------------------------------------- 3447 Nested Loop 3448 Output: tenk1.unique1, (1), (random()) 3449 -> Result 3450 Output: 1, random() 3451 -> Index Only Scan using tenk1_unique1 on public.tenk1 3452 Output: tenk1.unique1 3453 Index Cond: (tenk1.unique1 = (1)) 3454(7 rows) 3455 3456explain (costs off) 3457select unique1 from tenk1, f_immutable_int4(1) x where x = unique1; 3458 QUERY PLAN 3459---------------------------------------------- 3460 Index Only Scan using tenk1_unique1 on tenk1 3461 Index Cond: (unique1 = 1) 3462(2 rows) 3463 3464explain (costs off) 3465select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; 3466 QUERY PLAN 3467---------------------------------------------- 3468 Index Only Scan using tenk1_unique1 on tenk1 3469 Index Cond: (unique1 = 1) 3470(2 rows) 3471 3472explain (costs off) 3473select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); 3474 QUERY PLAN 3475-------------------------- 3476 Result 3477 One-Time Filter: false 3478(2 rows) 3479 3480explain (costs off) 3481select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x; 3482 QUERY PLAN 3483---------------------------------------------- 3484 Index Only Scan using tenk1_unique1 on tenk1 3485 Index Cond: (unique1 = 1) 3486(2 rows) 3487 3488explain (costs off) 3489select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x; 3490 QUERY PLAN 3491---------------------------------------------------- 3492 Nested Loop Left Join 3493 Join Filter: (tenk1.unique1 = 1) 3494 -> Index Only Scan using tenk1_unique1 on tenk1 3495 -> Materialize 3496 -> Result 3497(5 rows) 3498 3499explain (costs off) 3500select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x; 3501 QUERY PLAN 3502---------------------------------------------------- 3503 Nested Loop Left Join 3504 -> Result 3505 -> Index Only Scan using tenk1_unique1 on tenk1 3506 Index Cond: (unique1 = 1) 3507(4 rows) 3508 3509explain (costs off) 3510select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; 3511 QUERY PLAN 3512---------------------------------------------------- 3513 Merge Full Join 3514 Merge Cond: (tenk1.unique1 = (1)) 3515 -> Index Only Scan using tenk1_unique1 on tenk1 3516 -> Sort 3517 Sort Key: (1) 3518 -> Result 3519(6 rows) 3520 3521-- check that pullup of a const function allows further const-folding 3522explain (costs off) 3523select unique1 from tenk1, f_immutable_int4(1) x where x = 42; 3524 QUERY PLAN 3525-------------------------- 3526 Result 3527 One-Time Filter: false 3528(2 rows) 3529 3530-- test inlining of immutable functions with PlaceHolderVars 3531explain (costs off) 3532select nt3.id 3533from nt3 as nt3 3534 left join 3535 (select nt2.*, (nt2.b1 or i4 = 42) AS b3 3536 from nt2 as nt2 3537 left join 3538 f_immutable_int4(0) i4 3539 on i4 = nt2.nt1_id 3540 ) as ss2 3541 on ss2.id = nt3.nt2_id 3542where nt3.id = 1 and ss2.b3; 3543 QUERY PLAN 3544---------------------------------------------- 3545 Nested Loop Left Join 3546 Filter: ((nt2.b1 OR ((0) = 42))) 3547 -> Index Scan using nt3_pkey on nt3 3548 Index Cond: (id = 1) 3549 -> Nested Loop Left Join 3550 Join Filter: (0 = nt2.nt1_id) 3551 -> Index Scan using nt2_pkey on nt2 3552 Index Cond: (id = nt3.nt2_id) 3553 -> Result 3554(9 rows) 3555 3556drop function f_immutable_int4(int); 3557-- test inlining when function returns composite 3558create function mki8(bigint, bigint) returns int8_tbl as 3559$$select row($1,$2)::int8_tbl$$ language sql; 3560create function mki4(int) returns int4_tbl as 3561$$select row($1)::int4_tbl$$ language sql; 3562explain (verbose, costs off) 3563select * from mki8(1,2); 3564 QUERY PLAN 3565------------------------------------ 3566 Function Scan on mki8 3567 Output: q1, q2 3568 Function Call: '(1,2)'::int8_tbl 3569(3 rows) 3570 3571select * from mki8(1,2); 3572 q1 | q2 3573----+---- 3574 1 | 2 3575(1 row) 3576 3577explain (verbose, costs off) 3578select * from mki4(42); 3579 QUERY PLAN 3580----------------------------------- 3581 Function Scan on mki4 3582 Output: f1 3583 Function Call: '(42)'::int4_tbl 3584(3 rows) 3585 3586select * from mki4(42); 3587 f1 3588---- 3589 42 3590(1 row) 3591 3592drop function mki8(bigint, bigint); 3593drop function mki4(int); 3594-- 3595-- test extraction of restriction OR clauses from join OR clause 3596-- (we used to only do this for indexable clauses) 3597-- 3598explain (costs off) 3599select * from tenk1 a join tenk1 b on 3600 (a.unique1 = 1 and b.unique1 = 2) or (a.unique2 = 3 and b.hundred = 4); 3601 QUERY PLAN 3602------------------------------------------------------------------------------------------------- 3603 Nested Loop 3604 Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = 3) AND (b.hundred = 4))) 3605 -> Bitmap Heap Scan on tenk1 b 3606 Recheck Cond: ((unique1 = 2) OR (hundred = 4)) 3607 -> BitmapOr 3608 -> Bitmap Index Scan on tenk1_unique1 3609 Index Cond: (unique1 = 2) 3610 -> Bitmap Index Scan on tenk1_hundred 3611 Index Cond: (hundred = 4) 3612 -> Materialize 3613 -> Bitmap Heap Scan on tenk1 a 3614 Recheck Cond: ((unique1 = 1) OR (unique2 = 3)) 3615 -> BitmapOr 3616 -> Bitmap Index Scan on tenk1_unique1 3617 Index Cond: (unique1 = 1) 3618 -> Bitmap Index Scan on tenk1_unique2 3619 Index Cond: (unique2 = 3) 3620(17 rows) 3621 3622explain (costs off) 3623select * from tenk1 a join tenk1 b on 3624 (a.unique1 = 1 and b.unique1 = 2) or (a.unique2 = 3 and b.ten = 4); 3625 QUERY PLAN 3626--------------------------------------------------------------------------------------------- 3627 Nested Loop 3628 Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = 3) AND (b.ten = 4))) 3629 -> Seq Scan on tenk1 b 3630 Filter: ((unique1 = 2) OR (ten = 4)) 3631 -> Materialize 3632 -> Bitmap Heap Scan on tenk1 a 3633 Recheck Cond: ((unique1 = 1) OR (unique2 = 3)) 3634 -> BitmapOr 3635 -> Bitmap Index Scan on tenk1_unique1 3636 Index Cond: (unique1 = 1) 3637 -> Bitmap Index Scan on tenk1_unique2 3638 Index Cond: (unique2 = 3) 3639(12 rows) 3640 3641explain (costs off) 3642select * from tenk1 a join tenk1 b on 3643 (a.unique1 = 1 and b.unique1 = 2) or 3644 ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4); 3645 QUERY PLAN 3646---------------------------------------------------------------------------------------------------------------------- 3647 Nested Loop 3648 Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR (((a.unique2 = 3) OR (a.unique2 = 7)) AND (b.hundred = 4))) 3649 -> Bitmap Heap Scan on tenk1 b 3650 Recheck Cond: ((unique1 = 2) OR (hundred = 4)) 3651 -> BitmapOr 3652 -> Bitmap Index Scan on tenk1_unique1 3653 Index Cond: (unique1 = 2) 3654 -> Bitmap Index Scan on tenk1_hundred 3655 Index Cond: (hundred = 4) 3656 -> Materialize 3657 -> Bitmap Heap Scan on tenk1 a 3658 Recheck Cond: ((unique1 = 1) OR (unique2 = 3) OR (unique2 = 7)) 3659 -> BitmapOr 3660 -> Bitmap Index Scan on tenk1_unique1 3661 Index Cond: (unique1 = 1) 3662 -> Bitmap Index Scan on tenk1_unique2 3663 Index Cond: (unique2 = 3) 3664 -> Bitmap Index Scan on tenk1_unique2 3665 Index Cond: (unique2 = 7) 3666(19 rows) 3667 3668-- 3669-- test placement of movable quals in a parameterized join tree 3670-- 3671explain (costs off) 3672select * from tenk1 t1 left join 3673 (tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2) 3674 on t1.hundred = t2.hundred and t1.ten = t3.ten 3675where t1.unique1 = 1; 3676 QUERY PLAN 3677-------------------------------------------------------------- 3678 Nested Loop Left Join 3679 -> Index Scan using tenk1_unique1 on tenk1 t1 3680 Index Cond: (unique1 = 1) 3681 -> Nested Loop 3682 Join Filter: (t1.ten = t3.ten) 3683 -> Bitmap Heap Scan on tenk1 t2 3684 Recheck Cond: (t1.hundred = hundred) 3685 -> Bitmap Index Scan on tenk1_hundred 3686 Index Cond: (hundred = t1.hundred) 3687 -> Memoize 3688 Cache Key: t2.thousand 3689 -> Index Scan using tenk1_unique2 on tenk1 t3 3690 Index Cond: (unique2 = t2.thousand) 3691(13 rows) 3692 3693explain (costs off) 3694select * from tenk1 t1 left join 3695 (tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2) 3696 on t1.hundred = t2.hundred and t1.ten + t2.ten = t3.ten 3697where t1.unique1 = 1; 3698 QUERY PLAN 3699-------------------------------------------------------------- 3700 Nested Loop Left Join 3701 -> Index Scan using tenk1_unique1 on tenk1 t1 3702 Index Cond: (unique1 = 1) 3703 -> Nested Loop 3704 Join Filter: ((t1.ten + t2.ten) = t3.ten) 3705 -> Bitmap Heap Scan on tenk1 t2 3706 Recheck Cond: (t1.hundred = hundred) 3707 -> Bitmap Index Scan on tenk1_hundred 3708 Index Cond: (hundred = t1.hundred) 3709 -> Memoize 3710 Cache Key: t2.thousand 3711 -> Index Scan using tenk1_unique2 on tenk1 t3 3712 Index Cond: (unique2 = t2.thousand) 3713(13 rows) 3714 3715explain (costs off) 3716select count(*) from 3717 tenk1 a join tenk1 b on a.unique1 = b.unique2 3718 left join tenk1 c on a.unique2 = b.unique1 and c.thousand = a.thousand 3719 join int4_tbl on b.thousand = f1; 3720 QUERY PLAN 3721------------------------------------------------------------------------- 3722 Aggregate 3723 -> Nested Loop Left Join 3724 Join Filter: (a.unique2 = b.unique1) 3725 -> Nested Loop 3726 -> Nested Loop 3727 -> Seq Scan on int4_tbl 3728 -> Bitmap Heap Scan on tenk1 b 3729 Recheck Cond: (thousand = int4_tbl.f1) 3730 -> Bitmap Index Scan on tenk1_thous_tenthous 3731 Index Cond: (thousand = int4_tbl.f1) 3732 -> Index Scan using tenk1_unique1 on tenk1 a 3733 Index Cond: (unique1 = b.unique2) 3734 -> Index Only Scan using tenk1_thous_tenthous on tenk1 c 3735 Index Cond: (thousand = a.thousand) 3736(14 rows) 3737 3738select count(*) from 3739 tenk1 a join tenk1 b on a.unique1 = b.unique2 3740 left join tenk1 c on a.unique2 = b.unique1 and c.thousand = a.thousand 3741 join int4_tbl on b.thousand = f1; 3742 count 3743------- 3744 10 3745(1 row) 3746 3747explain (costs off) 3748select b.unique1 from 3749 tenk1 a join tenk1 b on a.unique1 = b.unique2 3750 left join tenk1 c on b.unique1 = 42 and c.thousand = a.thousand 3751 join int4_tbl i1 on b.thousand = f1 3752 right join int4_tbl i2 on i2.f1 = b.tenthous 3753 order by 1; 3754 QUERY PLAN 3755----------------------------------------------------------------------------------------- 3756 Sort 3757 Sort Key: b.unique1 3758 -> Nested Loop Left Join 3759 -> Seq Scan on int4_tbl i2 3760 -> Nested Loop Left Join 3761 Join Filter: (b.unique1 = 42) 3762 -> Nested Loop 3763 -> Nested Loop 3764 -> Seq Scan on int4_tbl i1 3765 -> Index Scan using tenk1_thous_tenthous on tenk1 b 3766 Index Cond: ((thousand = i1.f1) AND (tenthous = i2.f1)) 3767 -> Index Scan using tenk1_unique1 on tenk1 a 3768 Index Cond: (unique1 = b.unique2) 3769 -> Index Only Scan using tenk1_thous_tenthous on tenk1 c 3770 Index Cond: (thousand = a.thousand) 3771(15 rows) 3772 3773select b.unique1 from 3774 tenk1 a join tenk1 b on a.unique1 = b.unique2 3775 left join tenk1 c on b.unique1 = 42 and c.thousand = a.thousand 3776 join int4_tbl i1 on b.thousand = f1 3777 right join int4_tbl i2 on i2.f1 = b.tenthous 3778 order by 1; 3779 unique1 3780--------- 3781 0 3782 3783 3784 3785 3786(5 rows) 3787 3788explain (costs off) 3789select * from 3790( 3791 select unique1, q1, coalesce(unique1, -1) + q1 as fault 3792 from int8_tbl left join tenk1 on (q2 = unique2) 3793) ss 3794where fault = 122 3795order by fault; 3796 QUERY PLAN 3797-------------------------------------------------------------------------- 3798 Nested Loop Left Join 3799 Filter: ((COALESCE(tenk1.unique1, '-1'::integer) + int8_tbl.q1) = 122) 3800 -> Seq Scan on int8_tbl 3801 -> Index Scan using tenk1_unique2 on tenk1 3802 Index Cond: (unique2 = int8_tbl.q2) 3803(5 rows) 3804 3805select * from 3806( 3807 select unique1, q1, coalesce(unique1, -1) + q1 as fault 3808 from int8_tbl left join tenk1 on (q2 = unique2) 3809) ss 3810where fault = 122 3811order by fault; 3812 unique1 | q1 | fault 3813---------+-----+------- 3814 | 123 | 122 3815(1 row) 3816 3817explain (costs off) 3818select * from 3819(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) 3820left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x 3821left join unnest(v1ys) as u1(u1y) on u1y = v2y; 3822 QUERY PLAN 3823------------------------------------------------------------- 3824 Nested Loop Left Join 3825 -> Values Scan on "*VALUES*" 3826 -> Hash Right Join 3827 Hash Cond: (u1.u1y = "*VALUES*_1".column2) 3828 Filter: ("*VALUES*_1".column1 = "*VALUES*".column1) 3829 -> Function Scan on unnest u1 3830 -> Hash 3831 -> Values Scan on "*VALUES*_1" 3832(8 rows) 3833 3834select * from 3835(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) 3836left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x 3837left join unnest(v1ys) as u1(u1y) on u1y = v2y; 3838 v1x | v1ys | v2x | v2y | u1y 3839-----+---------+-----+-----+----- 3840 1 | {10,20} | 1 | 10 | 10 3841 2 | {20,30} | 2 | 20 | 20 3842(2 rows) 3843 3844-- 3845-- test handling of potential equivalence clauses above outer joins 3846-- 3847explain (costs off) 3848select q1, unique2, thousand, hundred 3849 from int8_tbl a left join tenk1 b on q1 = unique2 3850 where coalesce(thousand,123) = q1 and q1 = coalesce(hundred,123); 3851 QUERY PLAN 3852-------------------------------------------------------------------------------------- 3853 Nested Loop Left Join 3854 Filter: ((COALESCE(b.thousand, 123) = a.q1) AND (a.q1 = COALESCE(b.hundred, 123))) 3855 -> Seq Scan on int8_tbl a 3856 -> Index Scan using tenk1_unique2 on tenk1 b 3857 Index Cond: (unique2 = a.q1) 3858(5 rows) 3859 3860select q1, unique2, thousand, hundred 3861 from int8_tbl a left join tenk1 b on q1 = unique2 3862 where coalesce(thousand,123) = q1 and q1 = coalesce(hundred,123); 3863 q1 | unique2 | thousand | hundred 3864----+---------+----------+--------- 3865(0 rows) 3866 3867explain (costs off) 3868select f1, unique2, case when unique2 is null then f1 else 0 end 3869 from int4_tbl a left join tenk1 b on f1 = unique2 3870 where (case when unique2 is null then f1 else 0 end) = 0; 3871 QUERY PLAN 3872-------------------------------------------------------------------- 3873 Nested Loop Left Join 3874 Filter: (CASE WHEN (b.unique2 IS NULL) THEN a.f1 ELSE 0 END = 0) 3875 -> Seq Scan on int4_tbl a 3876 -> Index Only Scan using tenk1_unique2 on tenk1 b 3877 Index Cond: (unique2 = a.f1) 3878(5 rows) 3879 3880select f1, unique2, case when unique2 is null then f1 else 0 end 3881 from int4_tbl a left join tenk1 b on f1 = unique2 3882 where (case when unique2 is null then f1 else 0 end) = 0; 3883 f1 | unique2 | case 3884----+---------+------ 3885 0 | 0 | 0 3886(1 row) 3887 3888-- 3889-- another case with equivalence clauses above outer joins (bug #8591) 3890-- 3891explain (costs off) 3892select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) 3893 from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand) 3894 where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44; 3895 QUERY PLAN 3896--------------------------------------------------------------------------------------------- 3897 Nested Loop Left Join 3898 -> Nested Loop Left Join 3899 Filter: (COALESCE(b.twothousand, a.twothousand) = 44) 3900 -> Index Scan using tenk1_unique2 on tenk1 a 3901 Index Cond: (unique2 < 10) 3902 -> Bitmap Heap Scan on tenk1 b 3903 Recheck Cond: (thousand = a.unique1) 3904 -> Bitmap Index Scan on tenk1_thous_tenthous 3905 Index Cond: (thousand = a.unique1) 3906 -> Index Scan using tenk1_unique2 on tenk1 c 3907 Index Cond: ((unique2 = COALESCE(b.twothousand, a.twothousand)) AND (unique2 = 44)) 3908(11 rows) 3909 3910select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) 3911 from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand) 3912 where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44; 3913 unique1 | unique1 | unique1 | coalesce 3914---------+---------+---------+---------- 3915(0 rows) 3916 3917-- 3918-- check handling of join aliases when flattening multiple levels of subquery 3919-- 3920explain (verbose, costs off) 3921select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from 3922 (values (0),(1)) foo1(join_key) 3923left join 3924 (select join_key, bug_field from 3925 (select ss1.join_key, ss1.bug_field from 3926 (select f1 as join_key, 666 as bug_field from int4_tbl i1) ss1 3927 ) foo2 3928 left join 3929 (select unique2 as join_key from tenk1 i2) ss2 3930 using (join_key) 3931 ) foo3 3932using (join_key); 3933 QUERY PLAN 3934-------------------------------------------------------------------------- 3935 Nested Loop Left Join 3936 Output: "*VALUES*".column1, i1.f1, (666) 3937 Join Filter: ("*VALUES*".column1 = i1.f1) 3938 -> Values Scan on "*VALUES*" 3939 Output: "*VALUES*".column1 3940 -> Materialize 3941 Output: i1.f1, (666) 3942 -> Nested Loop Left Join 3943 Output: i1.f1, 666 3944 -> Seq Scan on public.int4_tbl i1 3945 Output: i1.f1 3946 -> Index Only Scan using tenk1_unique2 on public.tenk1 i2 3947 Output: i2.unique2 3948 Index Cond: (i2.unique2 = i1.f1) 3949(14 rows) 3950 3951select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from 3952 (values (0),(1)) foo1(join_key) 3953left join 3954 (select join_key, bug_field from 3955 (select ss1.join_key, ss1.bug_field from 3956 (select f1 as join_key, 666 as bug_field from int4_tbl i1) ss1 3957 ) foo2 3958 left join 3959 (select unique2 as join_key from tenk1 i2) ss2 3960 using (join_key) 3961 ) foo3 3962using (join_key); 3963 foo1_id | foo3_id | bug_field 3964---------+---------+----------- 3965 0 | 0 | 666 3966 1 | | 3967(2 rows) 3968 3969-- 3970-- test successful handling of nested outer joins with degenerate join quals 3971-- 3972explain (verbose, costs off) 3973select t1.* from 3974 text_tbl t1 3975 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 3976 left join int8_tbl i8 3977 left join (select *, null::int as d2 from int8_tbl i8b2) b2 3978 on (i8.q1 = b2.q1) 3979 on (b2.d2 = b1.q2) 3980 on (t1.f1 = b1.d1) 3981 left join int4_tbl i4 3982 on (i8.q2 = i4.f1); 3983 QUERY PLAN 3984---------------------------------------------------------------------- 3985 Hash Left Join 3986 Output: t1.f1 3987 Hash Cond: (i8.q2 = i4.f1) 3988 -> Nested Loop Left Join 3989 Output: t1.f1, i8.q2 3990 Join Filter: (t1.f1 = '***'::text) 3991 -> Seq Scan on public.text_tbl t1 3992 Output: t1.f1 3993 -> Materialize 3994 Output: i8.q2 3995 -> Hash Right Join 3996 Output: i8.q2 3997 Hash Cond: ((NULL::integer) = i8b1.q2) 3998 -> Hash Join 3999 Output: i8.q2, (NULL::integer) 4000 Hash Cond: (i8.q1 = i8b2.q1) 4001 -> Seq Scan on public.int8_tbl i8 4002 Output: i8.q1, i8.q2 4003 -> Hash 4004 Output: i8b2.q1, (NULL::integer) 4005 -> Seq Scan on public.int8_tbl i8b2 4006 Output: i8b2.q1, NULL::integer 4007 -> Hash 4008 Output: i8b1.q2 4009 -> Seq Scan on public.int8_tbl i8b1 4010 Output: i8b1.q2 4011 -> Hash 4012 Output: i4.f1 4013 -> Seq Scan on public.int4_tbl i4 4014 Output: i4.f1 4015(30 rows) 4016 4017select t1.* from 4018 text_tbl t1 4019 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 4020 left join int8_tbl i8 4021 left join (select *, null::int as d2 from int8_tbl i8b2) b2 4022 on (i8.q1 = b2.q1) 4023 on (b2.d2 = b1.q2) 4024 on (t1.f1 = b1.d1) 4025 left join int4_tbl i4 4026 on (i8.q2 = i4.f1); 4027 f1 4028------------------- 4029 doh! 4030 hi de ho neighbor 4031(2 rows) 4032 4033explain (verbose, costs off) 4034select t1.* from 4035 text_tbl t1 4036 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 4037 left join int8_tbl i8 4038 left join (select *, null::int as d2 from int8_tbl i8b2, int4_tbl i4b2) b2 4039 on (i8.q1 = b2.q1) 4040 on (b2.d2 = b1.q2) 4041 on (t1.f1 = b1.d1) 4042 left join int4_tbl i4 4043 on (i8.q2 = i4.f1); 4044 QUERY PLAN 4045---------------------------------------------------------------------------- 4046 Hash Left Join 4047 Output: t1.f1 4048 Hash Cond: (i8.q2 = i4.f1) 4049 -> Nested Loop Left Join 4050 Output: t1.f1, i8.q2 4051 Join Filter: (t1.f1 = '***'::text) 4052 -> Seq Scan on public.text_tbl t1 4053 Output: t1.f1 4054 -> Materialize 4055 Output: i8.q2 4056 -> Hash Right Join 4057 Output: i8.q2 4058 Hash Cond: ((NULL::integer) = i8b1.q2) 4059 -> Hash Right Join 4060 Output: i8.q2, (NULL::integer) 4061 Hash Cond: (i8b2.q1 = i8.q1) 4062 -> Nested Loop 4063 Output: i8b2.q1, NULL::integer 4064 -> Seq Scan on public.int8_tbl i8b2 4065 Output: i8b2.q1, i8b2.q2 4066 -> Materialize 4067 -> Seq Scan on public.int4_tbl i4b2 4068 -> Hash 4069 Output: i8.q1, i8.q2 4070 -> Seq Scan on public.int8_tbl i8 4071 Output: i8.q1, i8.q2 4072 -> Hash 4073 Output: i8b1.q2 4074 -> Seq Scan on public.int8_tbl i8b1 4075 Output: i8b1.q2 4076 -> Hash 4077 Output: i4.f1 4078 -> Seq Scan on public.int4_tbl i4 4079 Output: i4.f1 4080(34 rows) 4081 4082select t1.* from 4083 text_tbl t1 4084 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 4085 left join int8_tbl i8 4086 left join (select *, null::int as d2 from int8_tbl i8b2, int4_tbl i4b2) b2 4087 on (i8.q1 = b2.q1) 4088 on (b2.d2 = b1.q2) 4089 on (t1.f1 = b1.d1) 4090 left join int4_tbl i4 4091 on (i8.q2 = i4.f1); 4092 f1 4093------------------- 4094 doh! 4095 hi de ho neighbor 4096(2 rows) 4097 4098explain (verbose, costs off) 4099select t1.* from 4100 text_tbl t1 4101 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 4102 left join int8_tbl i8 4103 left join (select *, null::int as d2 from int8_tbl i8b2, int4_tbl i4b2 4104 where q1 = f1) b2 4105 on (i8.q1 = b2.q1) 4106 on (b2.d2 = b1.q2) 4107 on (t1.f1 = b1.d1) 4108 left join int4_tbl i4 4109 on (i8.q2 = i4.f1); 4110 QUERY PLAN 4111---------------------------------------------------------------------------- 4112 Hash Left Join 4113 Output: t1.f1 4114 Hash Cond: (i8.q2 = i4.f1) 4115 -> Nested Loop Left Join 4116 Output: t1.f1, i8.q2 4117 Join Filter: (t1.f1 = '***'::text) 4118 -> Seq Scan on public.text_tbl t1 4119 Output: t1.f1 4120 -> Materialize 4121 Output: i8.q2 4122 -> Hash Right Join 4123 Output: i8.q2 4124 Hash Cond: ((NULL::integer) = i8b1.q2) 4125 -> Hash Right Join 4126 Output: i8.q2, (NULL::integer) 4127 Hash Cond: (i8b2.q1 = i8.q1) 4128 -> Hash Join 4129 Output: i8b2.q1, NULL::integer 4130 Hash Cond: (i8b2.q1 = i4b2.f1) 4131 -> Seq Scan on public.int8_tbl i8b2 4132 Output: i8b2.q1, i8b2.q2 4133 -> Hash 4134 Output: i4b2.f1 4135 -> Seq Scan on public.int4_tbl i4b2 4136 Output: i4b2.f1 4137 -> Hash 4138 Output: i8.q1, i8.q2 4139 -> Seq Scan on public.int8_tbl i8 4140 Output: i8.q1, i8.q2 4141 -> Hash 4142 Output: i8b1.q2 4143 -> Seq Scan on public.int8_tbl i8b1 4144 Output: i8b1.q2 4145 -> Hash 4146 Output: i4.f1 4147 -> Seq Scan on public.int4_tbl i4 4148 Output: i4.f1 4149(37 rows) 4150 4151select t1.* from 4152 text_tbl t1 4153 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 4154 left join int8_tbl i8 4155 left join (select *, null::int as d2 from int8_tbl i8b2, int4_tbl i4b2 4156 where q1 = f1) b2 4157 on (i8.q1 = b2.q1) 4158 on (b2.d2 = b1.q2) 4159 on (t1.f1 = b1.d1) 4160 left join int4_tbl i4 4161 on (i8.q2 = i4.f1); 4162 f1 4163------------------- 4164 doh! 4165 hi de ho neighbor 4166(2 rows) 4167 4168explain (verbose, costs off) 4169select * from 4170 text_tbl t1 4171 inner join int8_tbl i8 4172 on i8.q2 = 456 4173 right join text_tbl t2 4174 on t1.f1 = 'doh!' 4175 left join int4_tbl i4 4176 on i8.q1 = i4.f1; 4177 QUERY PLAN 4178-------------------------------------------------------- 4179 Nested Loop Left Join 4180 Output: t1.f1, i8.q1, i8.q2, t2.f1, i4.f1 4181 -> Seq Scan on public.text_tbl t2 4182 Output: t2.f1 4183 -> Materialize 4184 Output: i8.q1, i8.q2, i4.f1, t1.f1 4185 -> Nested Loop 4186 Output: i8.q1, i8.q2, i4.f1, t1.f1 4187 -> Nested Loop Left Join 4188 Output: i8.q1, i8.q2, i4.f1 4189 Join Filter: (i8.q1 = i4.f1) 4190 -> Seq Scan on public.int8_tbl i8 4191 Output: i8.q1, i8.q2 4192 Filter: (i8.q2 = 456) 4193 -> Seq Scan on public.int4_tbl i4 4194 Output: i4.f1 4195 -> Seq Scan on public.text_tbl t1 4196 Output: t1.f1 4197 Filter: (t1.f1 = 'doh!'::text) 4198(19 rows) 4199 4200select * from 4201 text_tbl t1 4202 inner join int8_tbl i8 4203 on i8.q2 = 456 4204 right join text_tbl t2 4205 on t1.f1 = 'doh!' 4206 left join int4_tbl i4 4207 on i8.q1 = i4.f1; 4208 f1 | q1 | q2 | f1 | f1 4209------+-----+-----+-------------------+---- 4210 doh! | 123 | 456 | doh! | 4211 doh! | 123 | 456 | hi de ho neighbor | 4212(2 rows) 4213 4214-- 4215-- test for appropriate join order in the presence of lateral references 4216-- 4217explain (verbose, costs off) 4218select * from 4219 text_tbl t1 4220 left join int8_tbl i8 4221 on i8.q2 = 123, 4222 lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss 4223where t1.f1 = ss.f1; 4224 QUERY PLAN 4225-------------------------------------------------- 4226 Nested Loop 4227 Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1 4228 Join Filter: (t1.f1 = t2.f1) 4229 -> Nested Loop Left Join 4230 Output: t1.f1, i8.q1, i8.q2 4231 -> Seq Scan on public.text_tbl t1 4232 Output: t1.f1 4233 -> Materialize 4234 Output: i8.q1, i8.q2 4235 -> Seq Scan on public.int8_tbl i8 4236 Output: i8.q1, i8.q2 4237 Filter: (i8.q2 = 123) 4238 -> Memoize 4239 Output: (i8.q1), t2.f1 4240 Cache Key: i8.q1 4241 -> Limit 4242 Output: (i8.q1), t2.f1 4243 -> Seq Scan on public.text_tbl t2 4244 Output: i8.q1, t2.f1 4245(19 rows) 4246 4247select * from 4248 text_tbl t1 4249 left join int8_tbl i8 4250 on i8.q2 = 123, 4251 lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss 4252where t1.f1 = ss.f1; 4253 f1 | q1 | q2 | q1 | f1 4254------+------------------+-----+------------------+------ 4255 doh! | 4567890123456789 | 123 | 4567890123456789 | doh! 4256(1 row) 4257 4258explain (verbose, costs off) 4259select * from 4260 text_tbl t1 4261 left join int8_tbl i8 4262 on i8.q2 = 123, 4263 lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss1, 4264 lateral (select ss1.* from text_tbl t3 limit 1) as ss2 4265where t1.f1 = ss2.f1; 4266 QUERY PLAN 4267------------------------------------------------------------------- 4268 Nested Loop 4269 Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1, ((i8.q1)), (t2.f1) 4270 Join Filter: (t1.f1 = (t2.f1)) 4271 -> Nested Loop 4272 Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1 4273 -> Nested Loop Left Join 4274 Output: t1.f1, i8.q1, i8.q2 4275 -> Seq Scan on public.text_tbl t1 4276 Output: t1.f1 4277 -> Materialize 4278 Output: i8.q1, i8.q2 4279 -> Seq Scan on public.int8_tbl i8 4280 Output: i8.q1, i8.q2 4281 Filter: (i8.q2 = 123) 4282 -> Memoize 4283 Output: (i8.q1), t2.f1 4284 Cache Key: i8.q1 4285 -> Limit 4286 Output: (i8.q1), t2.f1 4287 -> Seq Scan on public.text_tbl t2 4288 Output: i8.q1, t2.f1 4289 -> Memoize 4290 Output: ((i8.q1)), (t2.f1) 4291 Cache Key: (i8.q1), t2.f1 4292 -> Limit 4293 Output: ((i8.q1)), (t2.f1) 4294 -> Seq Scan on public.text_tbl t3 4295 Output: (i8.q1), t2.f1 4296(28 rows) 4297 4298select * from 4299 text_tbl t1 4300 left join int8_tbl i8 4301 on i8.q2 = 123, 4302 lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss1, 4303 lateral (select ss1.* from text_tbl t3 limit 1) as ss2 4304where t1.f1 = ss2.f1; 4305 f1 | q1 | q2 | q1 | f1 | q1 | f1 4306------+------------------+-----+------------------+------+------------------+------ 4307 doh! | 4567890123456789 | 123 | 4567890123456789 | doh! | 4567890123456789 | doh! 4308(1 row) 4309 4310explain (verbose, costs off) 4311select 1 from 4312 text_tbl as tt1 4313 inner join text_tbl as tt2 on (tt1.f1 = 'foo') 4314 left join text_tbl as tt3 on (tt3.f1 = 'foo') 4315 left join text_tbl as tt4 on (tt3.f1 = tt4.f1), 4316 lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1 4317where tt1.f1 = ss1.c0; 4318 QUERY PLAN 4319---------------------------------------------------------- 4320 Nested Loop 4321 Output: 1 4322 -> Nested Loop Left Join 4323 Output: tt1.f1, tt4.f1 4324 -> Nested Loop 4325 Output: tt1.f1 4326 -> Seq Scan on public.text_tbl tt1 4327 Output: tt1.f1 4328 Filter: (tt1.f1 = 'foo'::text) 4329 -> Seq Scan on public.text_tbl tt2 4330 Output: tt2.f1 4331 -> Materialize 4332 Output: tt4.f1 4333 -> Nested Loop Left Join 4334 Output: tt4.f1 4335 Join Filter: (tt3.f1 = tt4.f1) 4336 -> Seq Scan on public.text_tbl tt3 4337 Output: tt3.f1 4338 Filter: (tt3.f1 = 'foo'::text) 4339 -> Seq Scan on public.text_tbl tt4 4340 Output: tt4.f1 4341 Filter: (tt4.f1 = 'foo'::text) 4342 -> Memoize 4343 Output: ss1.c0 4344 Cache Key: tt4.f1 4345 -> Subquery Scan on ss1 4346 Output: ss1.c0 4347 Filter: (ss1.c0 = 'foo'::text) 4348 -> Limit 4349 Output: (tt4.f1) 4350 -> Seq Scan on public.text_tbl tt5 4351 Output: tt4.f1 4352(32 rows) 4353 4354select 1 from 4355 text_tbl as tt1 4356 inner join text_tbl as tt2 on (tt1.f1 = 'foo') 4357 left join text_tbl as tt3 on (tt3.f1 = 'foo') 4358 left join text_tbl as tt4 on (tt3.f1 = tt4.f1), 4359 lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1 4360where tt1.f1 = ss1.c0; 4361 ?column? 4362---------- 4363(0 rows) 4364 4365-- 4366-- check a case in which a PlaceHolderVar forces join order 4367-- 4368explain (verbose, costs off) 4369select ss2.* from 4370 int4_tbl i41 4371 left join int8_tbl i8 4372 join (select i42.f1 as c1, i43.f1 as c2, 42 as c3 4373 from int4_tbl i42, int4_tbl i43) ss1 4374 on i8.q1 = ss1.c2 4375 on i41.f1 = ss1.c1, 4376 lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 4377where ss1.c2 = 0; 4378 QUERY PLAN 4379------------------------------------------------------------------------ 4380 Nested Loop 4381 Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) 4382 -> Hash Join 4383 Output: i41.f1, i42.f1, i8.q1, i8.q2, i43.f1, 42 4384 Hash Cond: (i41.f1 = i42.f1) 4385 -> Nested Loop 4386 Output: i8.q1, i8.q2, i43.f1, i41.f1 4387 -> Nested Loop 4388 Output: i8.q1, i8.q2, i43.f1 4389 -> Seq Scan on public.int8_tbl i8 4390 Output: i8.q1, i8.q2 4391 Filter: (i8.q1 = 0) 4392 -> Seq Scan on public.int4_tbl i43 4393 Output: i43.f1 4394 Filter: (i43.f1 = 0) 4395 -> Seq Scan on public.int4_tbl i41 4396 Output: i41.f1 4397 -> Hash 4398 Output: i42.f1 4399 -> Seq Scan on public.int4_tbl i42 4400 Output: i42.f1 4401 -> Limit 4402 Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) 4403 -> Seq Scan on public.text_tbl 4404 Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (42) 4405(25 rows) 4406 4407select ss2.* from 4408 int4_tbl i41 4409 left join int8_tbl i8 4410 join (select i42.f1 as c1, i43.f1 as c2, 42 as c3 4411 from int4_tbl i42, int4_tbl i43) ss1 4412 on i8.q1 = ss1.c2 4413 on i41.f1 = ss1.c1, 4414 lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 4415where ss1.c2 = 0; 4416 f1 | q1 | q2 | c1 | c2 | c3 4417----+----+----+----+----+---- 4418(0 rows) 4419 4420-- 4421-- test successful handling of full join underneath left join (bug #14105) 4422-- 4423explain (costs off) 4424select * from 4425 (select 1 as id) as xx 4426 left join 4427 (tenk1 as a1 full join (select 1 as id) as yy on (a1.unique1 = yy.id)) 4428 on (xx.id = coalesce(yy.id)); 4429 QUERY PLAN 4430--------------------------------------- 4431 Nested Loop Left Join 4432 -> Result 4433 -> Hash Full Join 4434 Hash Cond: (a1.unique1 = (1)) 4435 Filter: (1 = COALESCE((1))) 4436 -> Seq Scan on tenk1 a1 4437 -> Hash 4438 -> Result 4439(8 rows) 4440 4441select * from 4442 (select 1 as id) as xx 4443 left join 4444 (tenk1 as a1 full join (select 1 as id) as yy on (a1.unique1 = yy.id)) 4445 on (xx.id = coalesce(yy.id)); 4446 id | unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 | id 4447----+---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------+---- 4448 1 | 1 | 2838 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 3 | BAAAAA | EFEAAA | OOOOxx | 1 4449(1 row) 4450 4451-- 4452-- test ability to push constants through outer join clauses 4453-- 4454explain (costs off) 4455 select * from int4_tbl a left join tenk1 b on f1 = unique2 where f1 = 0; 4456 QUERY PLAN 4457------------------------------------------------- 4458 Nested Loop Left Join 4459 Join Filter: (a.f1 = b.unique2) 4460 -> Seq Scan on int4_tbl a 4461 Filter: (f1 = 0) 4462 -> Index Scan using tenk1_unique2 on tenk1 b 4463 Index Cond: (unique2 = 0) 4464(6 rows) 4465 4466explain (costs off) 4467 select * from tenk1 a full join tenk1 b using(unique2) where unique2 = 42; 4468 QUERY PLAN 4469------------------------------------------------- 4470 Merge Full Join 4471 Merge Cond: (a.unique2 = b.unique2) 4472 -> Index Scan using tenk1_unique2 on tenk1 a 4473 Index Cond: (unique2 = 42) 4474 -> Index Scan using tenk1_unique2 on tenk1 b 4475 Index Cond: (unique2 = 42) 4476(6 rows) 4477 4478-- 4479-- test that quals attached to an outer join have correct semantics, 4480-- specifically that they don't re-use expressions computed below the join; 4481-- we force a mergejoin so that coalesce(b.q1, 1) appears as a join input 4482-- 4483set enable_hashjoin to off; 4484set enable_nestloop to off; 4485explain (verbose, costs off) 4486 select a.q2, b.q1 4487 from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) 4488 where coalesce(b.q1, 1) > 0; 4489 QUERY PLAN 4490--------------------------------------------------------- 4491 Merge Left Join 4492 Output: a.q2, b.q1 4493 Merge Cond: (a.q2 = (COALESCE(b.q1, '1'::bigint))) 4494 Filter: (COALESCE(b.q1, '1'::bigint) > 0) 4495 -> Sort 4496 Output: a.q2 4497 Sort Key: a.q2 4498 -> Seq Scan on public.int8_tbl a 4499 Output: a.q2 4500 -> Sort 4501 Output: b.q1, (COALESCE(b.q1, '1'::bigint)) 4502 Sort Key: (COALESCE(b.q1, '1'::bigint)) 4503 -> Seq Scan on public.int8_tbl b 4504 Output: b.q1, COALESCE(b.q1, '1'::bigint) 4505(14 rows) 4506 4507select a.q2, b.q1 4508 from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) 4509 where coalesce(b.q1, 1) > 0; 4510 q2 | q1 4511-------------------+------------------ 4512 -4567890123456789 | 4513 123 | 123 4514 123 | 123 4515 456 | 4516 4567890123456789 | 4567890123456789 4517 4567890123456789 | 4567890123456789 4518 4567890123456789 | 4567890123456789 4519 4567890123456789 | 4567890123456789 4520 4567890123456789 | 4567890123456789 4521 4567890123456789 | 4567890123456789 4522(10 rows) 4523 4524reset enable_hashjoin; 4525reset enable_nestloop; 4526-- 4527-- test join removal 4528-- 4529begin; 4530CREATE TEMP TABLE a (id int PRIMARY KEY, b_id int); 4531CREATE TEMP TABLE b (id int PRIMARY KEY, c_id int); 4532CREATE TEMP TABLE c (id int PRIMARY KEY); 4533CREATE TEMP TABLE d (a int, b int); 4534INSERT INTO a VALUES (0, 0), (1, NULL); 4535INSERT INTO b VALUES (0, 0), (1, NULL); 4536INSERT INTO c VALUES (0), (1); 4537INSERT INTO d VALUES (1,3), (2,2), (3,1); 4538-- all three cases should be optimizable into a simple seqscan 4539explain (costs off) SELECT a.* FROM a LEFT JOIN b ON a.b_id = b.id; 4540 QUERY PLAN 4541--------------- 4542 Seq Scan on a 4543(1 row) 4544 4545explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; 4546 QUERY PLAN 4547--------------- 4548 Seq Scan on b 4549(1 row) 4550 4551explain (costs off) 4552 SELECT a.* FROM a LEFT JOIN (b left join c on b.c_id = c.id) 4553 ON (a.b_id = b.id); 4554 QUERY PLAN 4555--------------- 4556 Seq Scan on a 4557(1 row) 4558 4559-- check optimization of outer join within another special join 4560explain (costs off) 4561select id from a where id in ( 4562 select b.id from b left join c on b.id = c.id 4563); 4564 QUERY PLAN 4565---------------------------- 4566 Hash Join 4567 Hash Cond: (a.id = b.id) 4568 -> Seq Scan on a 4569 -> Hash 4570 -> Seq Scan on b 4571(5 rows) 4572 4573-- check that join removal works for a left join when joining a subquery 4574-- that is guaranteed to be unique by its GROUP BY clause 4575explain (costs off) 4576select d.* from d left join (select * from b group by b.id, b.c_id) s 4577 on d.a = s.id and d.b = s.c_id; 4578 QUERY PLAN 4579--------------- 4580 Seq Scan on d 4581(1 row) 4582 4583-- similarly, but keying off a DISTINCT clause 4584explain (costs off) 4585select d.* from d left join (select distinct * from b) s 4586 on d.a = s.id and d.b = s.c_id; 4587 QUERY PLAN 4588--------------- 4589 Seq Scan on d 4590(1 row) 4591 4592-- join removal is not possible when the GROUP BY contains a column that is 4593-- not in the join condition. (Note: as of 9.6, we notice that b.id is a 4594-- primary key and so drop b.c_id from the GROUP BY of the resulting plan; 4595-- but this happens too late for join removal in the outer plan level.) 4596explain (costs off) 4597select d.* from d left join (select * from b group by b.id, b.c_id) s 4598 on d.a = s.id; 4599 QUERY PLAN 4600------------------------------------------ 4601 Merge Right Join 4602 Merge Cond: (b.id = d.a) 4603 -> Group 4604 Group Key: b.id 4605 -> Index Scan using b_pkey on b 4606 -> Sort 4607 Sort Key: d.a 4608 -> Seq Scan on d 4609(8 rows) 4610 4611-- similarly, but keying off a DISTINCT clause 4612explain (costs off) 4613select d.* from d left join (select distinct * from b) s 4614 on d.a = s.id; 4615 QUERY PLAN 4616-------------------------------------- 4617 Merge Right Join 4618 Merge Cond: (b.id = d.a) 4619 -> Unique 4620 -> Sort 4621 Sort Key: b.id, b.c_id 4622 -> Seq Scan on b 4623 -> Sort 4624 Sort Key: d.a 4625 -> Seq Scan on d 4626(9 rows) 4627 4628-- check join removal works when uniqueness of the join condition is enforced 4629-- by a UNION 4630explain (costs off) 4631select d.* from d left join (select id from a union select id from b) s 4632 on d.a = s.id; 4633 QUERY PLAN 4634--------------- 4635 Seq Scan on d 4636(1 row) 4637 4638-- check join removal with a cross-type comparison operator 4639explain (costs off) 4640select i8.* from int8_tbl i8 left join (select f1 from int4_tbl group by f1) i4 4641 on i8.q1 = i4.f1; 4642 QUERY PLAN 4643------------------------- 4644 Seq Scan on int8_tbl i8 4645(1 row) 4646 4647-- check join removal with lateral references 4648explain (costs off) 4649select 1 from (select a.id FROM a left join b on a.b_id = b.id) q, 4650 lateral generate_series(1, q.id) gs(i) where q.id = gs.i; 4651 QUERY PLAN 4652------------------------------------------- 4653 Nested Loop 4654 -> Seq Scan on a 4655 -> Function Scan on generate_series gs 4656 Filter: (a.id = i) 4657(4 rows) 4658 4659rollback; 4660create temp table parent (k int primary key, pd int); 4661create temp table child (k int unique, cd int); 4662insert into parent values (1, 10), (2, 20), (3, 30); 4663insert into child values (1, 100), (4, 400); 4664-- this case is optimizable 4665select p.* from parent p left join child c on (p.k = c.k); 4666 k | pd 4667---+---- 4668 1 | 10 4669 2 | 20 4670 3 | 30 4671(3 rows) 4672 4673explain (costs off) 4674 select p.* from parent p left join child c on (p.k = c.k); 4675 QUERY PLAN 4676---------------------- 4677 Seq Scan on parent p 4678(1 row) 4679 4680-- this case is not 4681select p.*, linked from parent p 4682 left join (select c.*, true as linked from child c) as ss 4683 on (p.k = ss.k); 4684 k | pd | linked 4685---+----+-------- 4686 1 | 10 | t 4687 2 | 20 | 4688 3 | 30 | 4689(3 rows) 4690 4691explain (costs off) 4692 select p.*, linked from parent p 4693 left join (select c.*, true as linked from child c) as ss 4694 on (p.k = ss.k); 4695 QUERY PLAN 4696--------------------------------- 4697 Hash Left Join 4698 Hash Cond: (p.k = c.k) 4699 -> Seq Scan on parent p 4700 -> Hash 4701 -> Seq Scan on child c 4702(5 rows) 4703 4704-- check for a 9.0rc1 bug: join removal breaks pseudoconstant qual handling 4705select p.* from 4706 parent p left join child c on (p.k = c.k) 4707 where p.k = 1 and p.k = 2; 4708 k | pd 4709---+---- 4710(0 rows) 4711 4712explain (costs off) 4713select p.* from 4714 parent p left join child c on (p.k = c.k) 4715 where p.k = 1 and p.k = 2; 4716 QUERY PLAN 4717------------------------------------------------ 4718 Result 4719 One-Time Filter: false 4720 -> Index Scan using parent_pkey on parent p 4721 Index Cond: (k = 1) 4722(4 rows) 4723 4724select p.* from 4725 (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k 4726 where p.k = 1 and p.k = 2; 4727 k | pd 4728---+---- 4729(0 rows) 4730 4731explain (costs off) 4732select p.* from 4733 (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k 4734 where p.k = 1 and p.k = 2; 4735 QUERY PLAN 4736-------------------------- 4737 Result 4738 One-Time Filter: false 4739(2 rows) 4740 4741-- bug 5255: this is not optimizable by join removal 4742begin; 4743CREATE TEMP TABLE a (id int PRIMARY KEY); 4744CREATE TEMP TABLE b (id int PRIMARY KEY, a_id int); 4745INSERT INTO a VALUES (0), (1); 4746INSERT INTO b VALUES (0, 0), (1, NULL); 4747SELECT * FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0); 4748 id | a_id | id 4749----+------+---- 4750 1 | | 4751(1 row) 4752 4753SELECT b.* FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0); 4754 id | a_id 4755----+------ 4756 1 | 4757(1 row) 4758 4759rollback; 4760-- another join removal bug: this is not optimizable, either 4761begin; 4762create temp table innertab (id int8 primary key, dat1 int8); 4763insert into innertab values(123, 42); 4764SELECT * FROM 4765 (SELECT 1 AS x) ss1 4766 LEFT JOIN 4767 (SELECT q1, q2, COALESCE(dat1, q1) AS y 4768 FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss2 4769 ON true; 4770 x | q1 | q2 | y 4771---+------------------+-------------------+------------------ 4772 1 | 123 | 456 | 123 4773 1 | 123 | 4567890123456789 | 123 4774 1 | 4567890123456789 | 123 | 42 4775 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 4776 1 | 4567890123456789 | -4567890123456789 | 4567890123456789 4777(5 rows) 4778 4779rollback; 4780-- another join removal bug: we must clean up correctly when removing a PHV 4781begin; 4782create temp table uniquetbl (f1 text unique); 4783explain (costs off) 4784select t1.* from 4785 uniquetbl as t1 4786 left join (select *, '***'::text as d1 from uniquetbl) t2 4787 on t1.f1 = t2.f1 4788 left join uniquetbl t3 4789 on t2.d1 = t3.f1; 4790 QUERY PLAN 4791-------------------------- 4792 Seq Scan on uniquetbl t1 4793(1 row) 4794 4795explain (costs off) 4796select t0.* 4797from 4798 text_tbl t0 4799 left join 4800 (select case t1.ten when 0 then 'doh!'::text else null::text end as case1, 4801 t1.stringu2 4802 from tenk1 t1 4803 join int4_tbl i4 ON i4.f1 = t1.unique2 4804 left join uniquetbl u1 ON u1.f1 = t1.string4) ss 4805 on t0.f1 = ss.case1 4806where ss.stringu2 !~* ss.case1; 4807 QUERY PLAN 4808-------------------------------------------------------------------------------------------- 4809 Nested Loop 4810 Join Filter: (CASE t1.ten WHEN 0 THEN 'doh!'::text ELSE NULL::text END = t0.f1) 4811 -> Nested Loop 4812 -> Seq Scan on int4_tbl i4 4813 -> Index Scan using tenk1_unique2 on tenk1 t1 4814 Index Cond: (unique2 = i4.f1) 4815 Filter: (stringu2 !~* CASE ten WHEN 0 THEN 'doh!'::text ELSE NULL::text END) 4816 -> Materialize 4817 -> Seq Scan on text_tbl t0 4818(9 rows) 4819 4820select t0.* 4821from 4822 text_tbl t0 4823 left join 4824 (select case t1.ten when 0 then 'doh!'::text else null::text end as case1, 4825 t1.stringu2 4826 from tenk1 t1 4827 join int4_tbl i4 ON i4.f1 = t1.unique2 4828 left join uniquetbl u1 ON u1.f1 = t1.string4) ss 4829 on t0.f1 = ss.case1 4830where ss.stringu2 !~* ss.case1; 4831 f1 4832------ 4833 doh! 4834(1 row) 4835 4836rollback; 4837-- test case to expose miscomputation of required relid set for a PHV 4838explain (verbose, costs off) 4839select i8.*, ss.v, t.unique2 4840 from int8_tbl i8 4841 left join int4_tbl i4 on i4.f1 = 1 4842 left join lateral (select i4.f1 + 1 as v) as ss on true 4843 left join tenk1 t on t.unique2 = ss.v 4844where q2 = 456; 4845 QUERY PLAN 4846------------------------------------------------------------- 4847 Nested Loop Left Join 4848 Output: i8.q1, i8.q2, ((i4.f1 + 1)), t.unique2 4849 -> Nested Loop Left Join 4850 Output: i8.q1, i8.q2, (i4.f1 + 1) 4851 -> Seq Scan on public.int8_tbl i8 4852 Output: i8.q1, i8.q2 4853 Filter: (i8.q2 = 456) 4854 -> Seq Scan on public.int4_tbl i4 4855 Output: i4.f1 4856 Filter: (i4.f1 = 1) 4857 -> Index Only Scan using tenk1_unique2 on public.tenk1 t 4858 Output: t.unique2 4859 Index Cond: (t.unique2 = ((i4.f1 + 1))) 4860(13 rows) 4861 4862select i8.*, ss.v, t.unique2 4863 from int8_tbl i8 4864 left join int4_tbl i4 on i4.f1 = 1 4865 left join lateral (select i4.f1 + 1 as v) as ss on true 4866 left join tenk1 t on t.unique2 = ss.v 4867where q2 = 456; 4868 q1 | q2 | v | unique2 4869-----+-----+---+--------- 4870 123 | 456 | | 4871(1 row) 4872 4873-- and check a related issue where we miscompute required relids for 4874-- a PHV that's been translated to a child rel 4875create temp table parttbl (a integer primary key) partition by range (a); 4876create temp table parttbl1 partition of parttbl for values from (1) to (100); 4877insert into parttbl values (11), (12); 4878explain (costs off) 4879select * from 4880 (select *, 12 as phv from parttbl) as ss 4881 right join int4_tbl on true 4882where ss.a = ss.phv and f1 = 0; 4883 QUERY PLAN 4884------------------------------------ 4885 Nested Loop 4886 -> Seq Scan on int4_tbl 4887 Filter: (f1 = 0) 4888 -> Seq Scan on parttbl1 parttbl 4889 Filter: (a = 12) 4890(5 rows) 4891 4892select * from 4893 (select *, 12 as phv from parttbl) as ss 4894 right join int4_tbl on true 4895where ss.a = ss.phv and f1 = 0; 4896 a | phv | f1 4897----+-----+---- 4898 12 | 12 | 0 4899(1 row) 4900 4901-- bug #8444: we've historically allowed duplicate aliases within aliased JOINs 4902select * from 4903 int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = f1; -- error 4904ERROR: column reference "f1" is ambiguous 4905LINE 2: ..._tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = f1; 4906 ^ 4907select * from 4908 int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1; -- error 4909ERROR: invalid reference to FROM-clause entry for table "y" 4910LINE 2: ...bl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1; 4911 ^ 4912HINT: There is an entry for table "y", but it cannot be referenced from this part of the query. 4913select * from 4914 int8_tbl x join (int4_tbl x cross join int4_tbl y(ff)) j on q1 = f1; -- ok 4915 q1 | q2 | f1 | ff 4916----+----+----+---- 4917(0 rows) 4918 4919-- 4920-- Test hints given on incorrect column references are useful 4921-- 4922select t1.uunique1 from 4923 tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, prefer "t1" suggestion 4924ERROR: column t1.uunique1 does not exist 4925LINE 1: select t1.uunique1 from 4926 ^ 4927HINT: Perhaps you meant to reference the column "t1.unique1". 4928select t2.uunique1 from 4929 tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, prefer "t2" suggestion 4930ERROR: column t2.uunique1 does not exist 4931LINE 1: select t2.uunique1 from 4932 ^ 4933HINT: Perhaps you meant to reference the column "t2.unique1". 4934select uunique1 from 4935 tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, suggest both at once 4936ERROR: column "uunique1" does not exist 4937LINE 1: select uunique1 from 4938 ^ 4939HINT: Perhaps you meant to reference the column "t1.unique1" or the column "t2.unique1". 4940-- 4941-- Take care to reference the correct RTE 4942-- 4943select atts.relid::regclass, s.* from pg_stats s join 4944 pg_attribute a on s.attname = a.attname and s.tablename = 4945 a.attrelid::regclass::text join (select unnest(indkey) attnum, 4946 indexrelid from pg_index i) atts on atts.attnum = a.attnum where 4947 schemaname != 'pg_catalog'; 4948ERROR: column atts.relid does not exist 4949LINE 1: select atts.relid::regclass, s.* from pg_stats s join 4950 ^ 4951-- 4952-- Test LATERAL 4953-- 4954select unique2, x.* 4955from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; 4956 unique2 | f1 4957---------+---- 4958 9998 | 0 4959(1 row) 4960 4961explain (costs off) 4962 select unique2, x.* 4963 from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; 4964 QUERY PLAN 4965------------------------------------------------- 4966 Nested Loop 4967 -> Seq Scan on int4_tbl b 4968 -> Index Scan using tenk1_unique1 on tenk1 a 4969 Index Cond: (unique1 = b.f1) 4970(4 rows) 4971 4972select unique2, x.* 4973from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; 4974 unique2 | f1 4975---------+---- 4976 9998 | 0 4977(1 row) 4978 4979explain (costs off) 4980 select unique2, x.* 4981 from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; 4982 QUERY PLAN 4983----------------------------------------------- 4984 Nested Loop 4985 -> Seq Scan on int4_tbl x 4986 -> Index Scan using tenk1_unique1 on tenk1 4987 Index Cond: (unique1 = x.f1) 4988(4 rows) 4989 4990explain (costs off) 4991 select unique2, x.* 4992 from int4_tbl x cross join lateral (select unique2 from tenk1 where f1 = unique1) ss; 4993 QUERY PLAN 4994----------------------------------------------- 4995 Nested Loop 4996 -> Seq Scan on int4_tbl x 4997 -> Index Scan using tenk1_unique1 on tenk1 4998 Index Cond: (unique1 = x.f1) 4999(4 rows) 5000 5001select unique2, x.* 5002from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; 5003 unique2 | f1 5004---------+------------- 5005 9998 | 0 5006 | 123456 5007 | -123456 5008 | 2147483647 5009 | -2147483647 5010(5 rows) 5011 5012explain (costs off) 5013 select unique2, x.* 5014 from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; 5015 QUERY PLAN 5016----------------------------------------------- 5017 Nested Loop Left Join 5018 -> Seq Scan on int4_tbl x 5019 -> Index Scan using tenk1_unique1 on tenk1 5020 Index Cond: (unique1 = x.f1) 5021(4 rows) 5022 5023-- check scoping of lateral versus parent references 5024-- the first of these should return int8_tbl.q2, the second int8_tbl.q1 5025select *, (select r from (select q1 as q2) x, (select q2 as r) y) from int8_tbl; 5026 q1 | q2 | r 5027------------------+-------------------+------------------- 5028 123 | 456 | 456 5029 123 | 4567890123456789 | 4567890123456789 5030 4567890123456789 | 123 | 123 5031 4567890123456789 | 4567890123456789 | 4567890123456789 5032 4567890123456789 | -4567890123456789 | -4567890123456789 5033(5 rows) 5034 5035select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl; 5036 q1 | q2 | r 5037------------------+-------------------+------------------ 5038 123 | 456 | 123 5039 123 | 4567890123456789 | 123 5040 4567890123456789 | 123 | 4567890123456789 5041 4567890123456789 | 4567890123456789 | 4567890123456789 5042 4567890123456789 | -4567890123456789 | 4567890123456789 5043(5 rows) 5044 5045-- lateral with function in FROM 5046select count(*) from tenk1 a, lateral generate_series(1,two) g; 5047 count 5048------- 5049 5000 5050(1 row) 5051 5052explain (costs off) 5053 select count(*) from tenk1 a, lateral generate_series(1,two) g; 5054 QUERY PLAN 5055------------------------------------------------------ 5056 Aggregate 5057 -> Nested Loop 5058 -> Seq Scan on tenk1 a 5059 -> Memoize 5060 Cache Key: a.two 5061 -> Function Scan on generate_series g 5062(6 rows) 5063 5064explain (costs off) 5065 select count(*) from tenk1 a cross join lateral generate_series(1,two) g; 5066 QUERY PLAN 5067------------------------------------------------------ 5068 Aggregate 5069 -> Nested Loop 5070 -> Seq Scan on tenk1 a 5071 -> Memoize 5072 Cache Key: a.two 5073 -> Function Scan on generate_series g 5074(6 rows) 5075 5076-- don't need the explicit LATERAL keyword for functions 5077explain (costs off) 5078 select count(*) from tenk1 a, generate_series(1,two) g; 5079 QUERY PLAN 5080------------------------------------------------------ 5081 Aggregate 5082 -> Nested Loop 5083 -> Seq Scan on tenk1 a 5084 -> Memoize 5085 Cache Key: a.two 5086 -> Function Scan on generate_series g 5087(6 rows) 5088 5089-- lateral with UNION ALL subselect 5090explain (costs off) 5091 select * from generate_series(100,200) g, 5092 lateral (select * from int8_tbl a where g = q1 union all 5093 select * from int8_tbl b where g = q2) ss; 5094 QUERY PLAN 5095------------------------------------------ 5096 Nested Loop 5097 -> Function Scan on generate_series g 5098 -> Append 5099 -> Seq Scan on int8_tbl a 5100 Filter: (g.g = q1) 5101 -> Seq Scan on int8_tbl b 5102 Filter: (g.g = q2) 5103(7 rows) 5104 5105select * from generate_series(100,200) g, 5106 lateral (select * from int8_tbl a where g = q1 union all 5107 select * from int8_tbl b where g = q2) ss; 5108 g | q1 | q2 5109-----+------------------+------------------ 5110 123 | 123 | 456 5111 123 | 123 | 4567890123456789 5112 123 | 4567890123456789 | 123 5113(3 rows) 5114 5115-- lateral with VALUES 5116explain (costs off) 5117 select count(*) from tenk1 a, 5118 tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x; 5119 QUERY PLAN 5120------------------------------------------------------------ 5121 Aggregate 5122 -> Merge Join 5123 Merge Cond: (a.unique1 = b.unique2) 5124 -> Index Only Scan using tenk1_unique1 on tenk1 a 5125 -> Index Only Scan using tenk1_unique2 on tenk1 b 5126(5 rows) 5127 5128select count(*) from tenk1 a, 5129 tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x; 5130 count 5131------- 5132 10000 5133(1 row) 5134 5135-- lateral with VALUES, no flattening possible 5136explain (costs off) 5137 select count(*) from tenk1 a, 5138 tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x; 5139 QUERY PLAN 5140------------------------------------------------------------------ 5141 Aggregate 5142 -> Nested Loop 5143 -> Nested Loop 5144 -> Index Only Scan using tenk1_unique1 on tenk1 a 5145 -> Values Scan on "*VALUES*" 5146 -> Memoize 5147 Cache Key: "*VALUES*".column1 5148 -> Index Only Scan using tenk1_unique2 on tenk1 b 5149 Index Cond: (unique2 = "*VALUES*".column1) 5150(9 rows) 5151 5152select count(*) from tenk1 a, 5153 tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x; 5154 count 5155------- 5156 10000 5157(1 row) 5158 5159-- lateral injecting a strange outer join condition 5160explain (costs off) 5161 select * from int8_tbl a, 5162 int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) 5163 on x.q2 = ss.z 5164 order by a.q1, a.q2, x.q1, x.q2, ss.z; 5165 QUERY PLAN 5166------------------------------------------------ 5167 Sort 5168 Sort Key: a.q1, a.q2, x.q1, x.q2, (a.q1) 5169 -> Nested Loop 5170 -> Seq Scan on int8_tbl a 5171 -> Hash Right Join 5172 Hash Cond: ((a.q1) = x.q2) 5173 -> Seq Scan on int4_tbl y 5174 -> Hash 5175 -> Seq Scan on int8_tbl x 5176(9 rows) 5177 5178select * from int8_tbl a, 5179 int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) 5180 on x.q2 = ss.z 5181 order by a.q1, a.q2, x.q1, x.q2, ss.z; 5182 q1 | q2 | q1 | q2 | z 5183------------------+-------------------+------------------+-------------------+------------------ 5184 123 | 456 | 123 | 456 | 5185 123 | 456 | 123 | 4567890123456789 | 5186 123 | 456 | 4567890123456789 | -4567890123456789 | 5187 123 | 456 | 4567890123456789 | 123 | 123 5188 123 | 456 | 4567890123456789 | 123 | 123 5189 123 | 456 | 4567890123456789 | 123 | 123 5190 123 | 456 | 4567890123456789 | 123 | 123 5191 123 | 456 | 4567890123456789 | 123 | 123 5192 123 | 456 | 4567890123456789 | 4567890123456789 | 5193 123 | 4567890123456789 | 123 | 456 | 5194 123 | 4567890123456789 | 123 | 4567890123456789 | 5195 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 5196 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5197 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5198 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5199 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5200 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5201 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 5202 4567890123456789 | -4567890123456789 | 123 | 456 | 5203 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5204 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5205 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5206 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5207 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5208 4567890123456789 | -4567890123456789 | 4567890123456789 | -4567890123456789 | 5209 4567890123456789 | -4567890123456789 | 4567890123456789 | 123 | 5210 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5211 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5212 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5213 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5214 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5215 4567890123456789 | 123 | 123 | 456 | 5216 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 5217 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 5218 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 5219 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 5220 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 5221 4567890123456789 | 123 | 4567890123456789 | -4567890123456789 | 5222 4567890123456789 | 123 | 4567890123456789 | 123 | 5223 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 5224 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 5225 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 5226 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 5227 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 5228 4567890123456789 | 4567890123456789 | 123 | 456 | 5229 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5230 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5231 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5232 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5233 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5234 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 5235 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 5236 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5237 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5238 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5239 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5240 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5241(57 rows) 5242 5243-- lateral reference to a join alias variable 5244select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, 5245 lateral (select x) ss2(y); 5246 x | f1 | y 5247---+----+--- 5248 0 | 0 | 0 5249(1 row) 5250 5251select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, 5252 lateral (values(x)) ss2(y); 5253 x | f1 | y 5254-------------+-------------+------------- 5255 0 | 0 | 0 5256 123456 | 123456 | 123456 5257 -123456 | -123456 | -123456 5258 2147483647 | 2147483647 | 2147483647 5259 -2147483647 | -2147483647 | -2147483647 5260(5 rows) 5261 5262select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j, 5263 lateral (select x) ss2(y); 5264 x | f1 | y 5265---+----+--- 5266 0 | 0 | 0 5267(1 row) 5268 5269-- lateral references requiring pullup 5270select * from (values(1)) x(lb), 5271 lateral generate_series(lb,4) x4; 5272 lb | x4 5273----+---- 5274 1 | 1 5275 1 | 2 5276 1 | 3 5277 1 | 4 5278(4 rows) 5279 5280select * from (select f1/1000000000 from int4_tbl) x(lb), 5281 lateral generate_series(lb,4) x4; 5282 lb | x4 5283----+---- 5284 0 | 0 5285 0 | 1 5286 0 | 2 5287 0 | 3 5288 0 | 4 5289 0 | 0 5290 0 | 1 5291 0 | 2 5292 0 | 3 5293 0 | 4 5294 0 | 0 5295 0 | 1 5296 0 | 2 5297 0 | 3 5298 0 | 4 5299 2 | 2 5300 2 | 3 5301 2 | 4 5302 -2 | -2 5303 -2 | -1 5304 -2 | 0 5305 -2 | 1 5306 -2 | 2 5307 -2 | 3 5308 -2 | 4 5309(25 rows) 5310 5311select * from (values(1)) x(lb), 5312 lateral (values(lb)) y(lbcopy); 5313 lb | lbcopy 5314----+-------- 5315 1 | 1 5316(1 row) 5317 5318select * from (values(1)) x(lb), 5319 lateral (select lb from int4_tbl) y(lbcopy); 5320 lb | lbcopy 5321----+-------- 5322 1 | 1 5323 1 | 1 5324 1 | 1 5325 1 | 1 5326 1 | 1 5327(5 rows) 5328 5329select * from 5330 int8_tbl x left join (select q1,coalesce(q2,0) q2 from int8_tbl) y on x.q2 = y.q1, 5331 lateral (values(x.q1,y.q1,y.q2)) v(xq1,yq1,yq2); 5332 q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 5333------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- 5334 123 | 456 | | | 123 | | 5335 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 5336 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5337 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5338 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 5339 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 5340 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 5341 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5342 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 5343 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | 5344(10 rows) 5345 5346select * from 5347 int8_tbl x left join (select q1,coalesce(q2,0) q2 from int8_tbl) y on x.q2 = y.q1, 5348 lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); 5349 q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 5350------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- 5351 123 | 456 | | | 123 | | 5352 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 5353 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5354 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5355 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 5356 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 5357 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 5358 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5359 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 5360 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | 5361(10 rows) 5362 5363select x.* from 5364 int8_tbl x left join (select q1,coalesce(q2,0) q2 from int8_tbl) y on x.q2 = y.q1, 5365 lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); 5366 q1 | q2 5367------------------+------------------- 5368 123 | 456 5369 123 | 4567890123456789 5370 123 | 4567890123456789 5371 123 | 4567890123456789 5372 4567890123456789 | 123 5373 4567890123456789 | 123 5374 4567890123456789 | 4567890123456789 5375 4567890123456789 | 4567890123456789 5376 4567890123456789 | 4567890123456789 5377 4567890123456789 | -4567890123456789 5378(10 rows) 5379 5380select v.* from 5381 (int8_tbl x left join (select q1,coalesce(q2,0) q2 from int8_tbl) y on x.q2 = y.q1) 5382 left join int4_tbl z on z.f1 = x.q2, 5383 lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); 5384 vx | vy 5385-------------------+------------------- 5386 123 | 5387 456 | 5388 123 | 4567890123456789 5389 4567890123456789 | -4567890123456789 5390 123 | 4567890123456789 5391 4567890123456789 | 4567890123456789 5392 123 | 4567890123456789 5393 4567890123456789 | 123 5394 4567890123456789 | 123 5395 123 | 4567890123456789 5396 4567890123456789 | 123 5397 123 | 456 5398 4567890123456789 | 4567890123456789 5399 4567890123456789 | -4567890123456789 5400 4567890123456789 | 4567890123456789 5401 4567890123456789 | 4567890123456789 5402 4567890123456789 | 4567890123456789 5403 4567890123456789 | 123 5404 4567890123456789 | 5405 -4567890123456789 | 5406(20 rows) 5407 5408select v.* from 5409 (int8_tbl x left join (select q1,(select coalesce(q2,0)) q2 from int8_tbl) y on x.q2 = y.q1) 5410 left join int4_tbl z on z.f1 = x.q2, 5411 lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); 5412 vx | vy 5413-------------------+------------------- 5414 4567890123456789 | 123 5415 123 | 456 5416 4567890123456789 | 123 5417 123 | 4567890123456789 5418 4567890123456789 | 4567890123456789 5419 4567890123456789 | 123 5420 123 | 4567890123456789 5421 4567890123456789 | 123 5422 4567890123456789 | 4567890123456789 5423 4567890123456789 | 4567890123456789 5424 123 | 4567890123456789 5425 4567890123456789 | 4567890123456789 5426 4567890123456789 | 4567890123456789 5427 4567890123456789 | -4567890123456789 5428 123 | 4567890123456789 5429 4567890123456789 | -4567890123456789 5430 123 | 5431 456 | 5432 4567890123456789 | 5433 -4567890123456789 | 5434(20 rows) 5435 5436select v.* from 5437 (int8_tbl x left join (select q1,(select coalesce(q2,0)) q2 from int8_tbl) y on x.q2 = y.q1) 5438 left join int4_tbl z on z.f1 = x.q2, 5439 lateral (select x.q1,y.q1 from onerow union all select x.q2,y.q2 from onerow) v(vx,vy); 5440 vx | vy 5441-------------------+------------------- 5442 4567890123456789 | 123 5443 123 | 456 5444 4567890123456789 | 123 5445 123 | 4567890123456789 5446 4567890123456789 | 4567890123456789 5447 4567890123456789 | 123 5448 123 | 4567890123456789 5449 4567890123456789 | 123 5450 4567890123456789 | 4567890123456789 5451 4567890123456789 | 4567890123456789 5452 123 | 4567890123456789 5453 4567890123456789 | 4567890123456789 5454 4567890123456789 | 4567890123456789 5455 4567890123456789 | -4567890123456789 5456 123 | 4567890123456789 5457 4567890123456789 | -4567890123456789 5458 123 | 5459 456 | 5460 4567890123456789 | 5461 -4567890123456789 | 5462(20 rows) 5463 5464explain (verbose, costs off) 5465select * from 5466 int8_tbl a left join 5467 lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; 5468 QUERY PLAN 5469------------------------------------------ 5470 Nested Loop Left Join 5471 Output: a.q1, a.q2, b.q1, b.q2, (a.q2) 5472 -> Seq Scan on public.int8_tbl a 5473 Output: a.q1, a.q2 5474 -> Seq Scan on public.int8_tbl b 5475 Output: b.q1, b.q2, a.q2 5476 Filter: (a.q2 = b.q1) 5477(7 rows) 5478 5479select * from 5480 int8_tbl a left join 5481 lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; 5482 q1 | q2 | q1 | q2 | x 5483------------------+-------------------+------------------+-------------------+------------------ 5484 123 | 456 | | | 5485 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 5486 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5487 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 5488 4567890123456789 | 123 | 123 | 456 | 123 5489 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5490 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 5491 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5492 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 5493 4567890123456789 | -4567890123456789 | | | 5494(10 rows) 5495 5496explain (verbose, costs off) 5497select * from 5498 int8_tbl a left join 5499 lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; 5500 QUERY PLAN 5501------------------------------------------------------------------ 5502 Nested Loop Left Join 5503 Output: a.q1, a.q2, b.q1, b.q2, (COALESCE(a.q2, '42'::bigint)) 5504 -> Seq Scan on public.int8_tbl a 5505 Output: a.q1, a.q2 5506 -> Seq Scan on public.int8_tbl b 5507 Output: b.q1, b.q2, COALESCE(a.q2, '42'::bigint) 5508 Filter: (a.q2 = b.q1) 5509(7 rows) 5510 5511select * from 5512 int8_tbl a left join 5513 lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; 5514 q1 | q2 | q1 | q2 | x 5515------------------+-------------------+------------------+-------------------+------------------ 5516 123 | 456 | | | 5517 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 5518 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5519 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 5520 4567890123456789 | 123 | 123 | 456 | 123 5521 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5522 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 5523 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5524 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 5525 4567890123456789 | -4567890123456789 | | | 5526(10 rows) 5527 5528-- lateral can result in join conditions appearing below their 5529-- real semantic level 5530explain (verbose, costs off) 5531select * from int4_tbl i left join 5532 lateral (select * from int2_tbl j where i.f1 = j.f1) k on true; 5533 QUERY PLAN 5534------------------------------------------- 5535 Hash Left Join 5536 Output: i.f1, j.f1 5537 Hash Cond: (i.f1 = j.f1) 5538 -> Seq Scan on public.int4_tbl i 5539 Output: i.f1 5540 -> Hash 5541 Output: j.f1 5542 -> Seq Scan on public.int2_tbl j 5543 Output: j.f1 5544(9 rows) 5545 5546select * from int4_tbl i left join 5547 lateral (select * from int2_tbl j where i.f1 = j.f1) k on true; 5548 f1 | f1 5549-------------+---- 5550 0 | 0 5551 123456 | 5552 -123456 | 5553 2147483647 | 5554 -2147483647 | 5555(5 rows) 5556 5557explain (verbose, costs off) 5558select * from int4_tbl i left join 5559 lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; 5560 QUERY PLAN 5561------------------------------------- 5562 Nested Loop Left Join 5563 Output: i.f1, (COALESCE(i.*)) 5564 -> Seq Scan on public.int4_tbl i 5565 Output: i.f1, i.* 5566 -> Seq Scan on public.int2_tbl j 5567 Output: j.f1, COALESCE(i.*) 5568 Filter: (i.f1 = j.f1) 5569(7 rows) 5570 5571select * from int4_tbl i left join 5572 lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; 5573 f1 | coalesce 5574-------------+---------- 5575 0 | (0) 5576 123456 | 5577 -123456 | 5578 2147483647 | 5579 -2147483647 | 5580(5 rows) 5581 5582explain (verbose, costs off) 5583select * from int4_tbl a, 5584 lateral ( 5585 select * from int4_tbl b left join int8_tbl c on (b.f1 = q1 and a.f1 = q2) 5586 ) ss; 5587 QUERY PLAN 5588------------------------------------------------- 5589 Nested Loop 5590 Output: a.f1, b.f1, c.q1, c.q2 5591 -> Seq Scan on public.int4_tbl a 5592 Output: a.f1 5593 -> Hash Left Join 5594 Output: b.f1, c.q1, c.q2 5595 Hash Cond: (b.f1 = c.q1) 5596 -> Seq Scan on public.int4_tbl b 5597 Output: b.f1 5598 -> Hash 5599 Output: c.q1, c.q2 5600 -> Seq Scan on public.int8_tbl c 5601 Output: c.q1, c.q2 5602 Filter: (a.f1 = c.q2) 5603(14 rows) 5604 5605select * from int4_tbl a, 5606 lateral ( 5607 select * from int4_tbl b left join int8_tbl c on (b.f1 = q1 and a.f1 = q2) 5608 ) ss; 5609 f1 | f1 | q1 | q2 5610-------------+-------------+----+---- 5611 0 | 0 | | 5612 0 | 123456 | | 5613 0 | -123456 | | 5614 0 | 2147483647 | | 5615 0 | -2147483647 | | 5616 123456 | 0 | | 5617 123456 | 123456 | | 5618 123456 | -123456 | | 5619 123456 | 2147483647 | | 5620 123456 | -2147483647 | | 5621 -123456 | 0 | | 5622 -123456 | 123456 | | 5623 -123456 | -123456 | | 5624 -123456 | 2147483647 | | 5625 -123456 | -2147483647 | | 5626 2147483647 | 0 | | 5627 2147483647 | 123456 | | 5628 2147483647 | -123456 | | 5629 2147483647 | 2147483647 | | 5630 2147483647 | -2147483647 | | 5631 -2147483647 | 0 | | 5632 -2147483647 | 123456 | | 5633 -2147483647 | -123456 | | 5634 -2147483647 | 2147483647 | | 5635 -2147483647 | -2147483647 | | 5636(25 rows) 5637 5638-- lateral reference in a PlaceHolderVar evaluated at join level 5639explain (verbose, costs off) 5640select * from 5641 int8_tbl a left join lateral 5642 (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from 5643 int8_tbl b cross join int8_tbl c) ss 5644 on a.q2 = ss.bq1; 5645 QUERY PLAN 5646------------------------------------------------------------- 5647 Nested Loop Left Join 5648 Output: a.q1, a.q2, b.q1, c.q1, (LEAST(a.q1, b.q1, c.q1)) 5649 -> Seq Scan on public.int8_tbl a 5650 Output: a.q1, a.q2 5651 -> Nested Loop 5652 Output: b.q1, c.q1, LEAST(a.q1, b.q1, c.q1) 5653 -> Seq Scan on public.int8_tbl b 5654 Output: b.q1, b.q2 5655 Filter: (a.q2 = b.q1) 5656 -> Seq Scan on public.int8_tbl c 5657 Output: c.q1, c.q2 5658(11 rows) 5659 5660select * from 5661 int8_tbl a left join lateral 5662 (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from 5663 int8_tbl b cross join int8_tbl c) ss 5664 on a.q2 = ss.bq1; 5665 q1 | q2 | bq1 | cq1 | least 5666------------------+-------------------+------------------+------------------+------------------ 5667 123 | 456 | | | 5668 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5669 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5670 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5671 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5672 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5673 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5674 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5675 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5676 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5677 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5678 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5679 123 | 4567890123456789 | 4567890123456789 | 123 | 123 5680 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5681 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5682 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 5683 4567890123456789 | 123 | 123 | 123 | 123 5684 4567890123456789 | 123 | 123 | 123 | 123 5685 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5686 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5687 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5688 4567890123456789 | 123 | 123 | 123 | 123 5689 4567890123456789 | 123 | 123 | 123 | 123 5690 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5691 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5692 4567890123456789 | 123 | 123 | 4567890123456789 | 123 5693 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 5694 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 5695 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5696 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5697 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5698 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 5699 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 5700 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5701 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5702 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5703 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 5704 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 5705 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5706 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5707 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5708 4567890123456789 | -4567890123456789 | | | 5709(42 rows) 5710 5711-- case requiring nested PlaceHolderVars 5712explain (verbose, costs off) 5713select * from 5714 int8_tbl c left join ( 5715 int8_tbl a left join (select q1, coalesce(q2,42) as x from int8_tbl b) ss1 5716 on a.q2 = ss1.q1 5717 cross join 5718 lateral (select q1, coalesce(ss1.x,q2) as y from int8_tbl d) ss2 5719 ) on c.q2 = ss2.q1, 5720 lateral (select ss2.y offset 0) ss3; 5721 QUERY PLAN 5722------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 5723 Nested Loop 5724 Output: c.q1, c.q2, a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)), d.q1, (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)), ((COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))) 5725 -> Hash Right Join 5726 Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) 5727 Hash Cond: (d.q1 = c.q2) 5728 -> Nested Loop 5729 Output: a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) 5730 -> Hash Left Join 5731 Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)) 5732 Hash Cond: (a.q2 = b.q1) 5733 -> Seq Scan on public.int8_tbl a 5734 Output: a.q1, a.q2 5735 -> Hash 5736 Output: b.q1, (COALESCE(b.q2, '42'::bigint)) 5737 -> Seq Scan on public.int8_tbl b 5738 Output: b.q1, COALESCE(b.q2, '42'::bigint) 5739 -> Seq Scan on public.int8_tbl d 5740 Output: d.q1, COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2) 5741 -> Hash 5742 Output: c.q1, c.q2 5743 -> Seq Scan on public.int8_tbl c 5744 Output: c.q1, c.q2 5745 -> Result 5746 Output: (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) 5747(24 rows) 5748 5749-- case that breaks the old ph_may_need optimization 5750explain (verbose, costs off) 5751select c.*,a.*,ss1.q1,ss2.q1,ss3.* from 5752 int8_tbl c left join ( 5753 int8_tbl a left join 5754 (select q1, coalesce(q2,f1) as x from int8_tbl b, int4_tbl b2 5755 where q1 < f1) ss1 5756 on a.q2 = ss1.q1 5757 cross join 5758 lateral (select q1, coalesce(ss1.x,q2) as y from int8_tbl d) ss2 5759 ) on c.q2 = ss2.q1, 5760 lateral (select * from int4_tbl i where ss2.y > f1) ss3; 5761 QUERY PLAN 5762--------------------------------------------------------------------------------------------------------- 5763 Nested Loop 5764 Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, i.f1 5765 Join Filter: ((COALESCE((COALESCE(b.q2, (b2.f1)::bigint)), d.q2)) > i.f1) 5766 -> Hash Right Join 5767 Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, (COALESCE((COALESCE(b.q2, (b2.f1)::bigint)), d.q2)) 5768 Hash Cond: (d.q1 = c.q2) 5769 -> Nested Loop 5770 Output: a.q1, a.q2, b.q1, d.q1, (COALESCE((COALESCE(b.q2, (b2.f1)::bigint)), d.q2)) 5771 -> Hash Right Join 5772 Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, (b2.f1)::bigint)) 5773 Hash Cond: (b.q1 = a.q2) 5774 -> Nested Loop 5775 Output: b.q1, COALESCE(b.q2, (b2.f1)::bigint) 5776 Join Filter: (b.q1 < b2.f1) 5777 -> Seq Scan on public.int8_tbl b 5778 Output: b.q1, b.q2 5779 -> Materialize 5780 Output: b2.f1 5781 -> Seq Scan on public.int4_tbl b2 5782 Output: b2.f1 5783 -> Hash 5784 Output: a.q1, a.q2 5785 -> Seq Scan on public.int8_tbl a 5786 Output: a.q1, a.q2 5787 -> Seq Scan on public.int8_tbl d 5788 Output: d.q1, COALESCE((COALESCE(b.q2, (b2.f1)::bigint)), d.q2) 5789 -> Hash 5790 Output: c.q1, c.q2 5791 -> Seq Scan on public.int8_tbl c 5792 Output: c.q1, c.q2 5793 -> Materialize 5794 Output: i.f1 5795 -> Seq Scan on public.int4_tbl i 5796 Output: i.f1 5797(34 rows) 5798 5799-- check processing of postponed quals (bug #9041) 5800explain (verbose, costs off) 5801select * from 5802 (select 1 as x offset 0) x cross join (select 2 as y offset 0) y 5803 left join lateral ( 5804 select * from (select 3 as z offset 0) z where z.z = x.x 5805 ) zz on zz.z = y.y; 5806 QUERY PLAN 5807---------------------------------------------- 5808 Nested Loop Left Join 5809 Output: (1), (2), (3) 5810 Join Filter: (((3) = (1)) AND ((3) = (2))) 5811 -> Nested Loop 5812 Output: (1), (2) 5813 -> Result 5814 Output: 1 5815 -> Result 5816 Output: 2 5817 -> Result 5818 Output: 3 5819(11 rows) 5820 5821-- check dummy rels with lateral references (bug #15694) 5822explain (verbose, costs off) 5823select * from int8_tbl i8 left join lateral 5824 (select *, i8.q2 from int4_tbl where false) ss on true; 5825 QUERY PLAN 5826-------------------------------------- 5827 Nested Loop Left Join 5828 Output: i8.q1, i8.q2, f1, (i8.q2) 5829 -> Seq Scan on public.int8_tbl i8 5830 Output: i8.q1, i8.q2 5831 -> Result 5832 Output: f1, i8.q2 5833 One-Time Filter: false 5834(7 rows) 5835 5836explain (verbose, costs off) 5837select * from int8_tbl i8 left join lateral 5838 (select *, i8.q2 from int4_tbl i1, int4_tbl i2 where false) ss on true; 5839 QUERY PLAN 5840----------------------------------------- 5841 Nested Loop Left Join 5842 Output: i8.q1, i8.q2, f1, f1, (i8.q2) 5843 -> Seq Scan on public.int8_tbl i8 5844 Output: i8.q1, i8.q2 5845 -> Result 5846 Output: f1, f1, i8.q2 5847 One-Time Filter: false 5848(7 rows) 5849 5850-- check handling of nested appendrels inside LATERAL 5851select * from 5852 ((select 2 as v) union all (select 3 as v)) as q1 5853 cross join lateral 5854 ((select * from 5855 ((select 4 as v) union all (select 5 as v)) as q3) 5856 union all 5857 (select q1.v) 5858 ) as q2; 5859 v | v 5860---+--- 5861 2 | 4 5862 2 | 5 5863 2 | 2 5864 3 | 4 5865 3 | 5 5866 3 | 3 5867(6 rows) 5868 5869-- check we don't try to do a unique-ified semijoin with LATERAL 5870explain (verbose, costs off) 5871select * from 5872 (values (0,9998), (1,1000)) v(id,x), 5873 lateral (select f1 from int4_tbl 5874 where f1 = any (select unique1 from tenk1 5875 where unique2 = v.x offset 0)) ss; 5876 QUERY PLAN 5877---------------------------------------------------------------------- 5878 Nested Loop 5879 Output: "*VALUES*".column1, "*VALUES*".column2, int4_tbl.f1 5880 -> Values Scan on "*VALUES*" 5881 Output: "*VALUES*".column1, "*VALUES*".column2 5882 -> Nested Loop Semi Join 5883 Output: int4_tbl.f1 5884 Join Filter: (int4_tbl.f1 = tenk1.unique1) 5885 -> Seq Scan on public.int4_tbl 5886 Output: int4_tbl.f1 5887 -> Materialize 5888 Output: tenk1.unique1 5889 -> Index Scan using tenk1_unique2 on public.tenk1 5890 Output: tenk1.unique1 5891 Index Cond: (tenk1.unique2 = "*VALUES*".column2) 5892(14 rows) 5893 5894select * from 5895 (values (0,9998), (1,1000)) v(id,x), 5896 lateral (select f1 from int4_tbl 5897 where f1 = any (select unique1 from tenk1 5898 where unique2 = v.x offset 0)) ss; 5899 id | x | f1 5900----+------+---- 5901 0 | 9998 | 0 5902(1 row) 5903 5904-- check proper extParam/allParam handling (this isn't exactly a LATERAL issue, 5905-- but we can make the test case much more compact with LATERAL) 5906explain (verbose, costs off) 5907select * from (values (0), (1)) v(id), 5908lateral (select * from int8_tbl t1, 5909 lateral (select * from 5910 (select * from int8_tbl t2 5911 where q1 = any (select q2 from int8_tbl t3 5912 where q2 = (select greatest(t1.q1,t2.q2)) 5913 and (select v.id=0)) offset 0) ss2) ss 5914 where t1.q1 = ss.q2) ss0; 5915 QUERY PLAN 5916----------------------------------------------------------------- 5917 Nested Loop 5918 Output: "*VALUES*".column1, t1.q1, t1.q2, ss2.q1, ss2.q2 5919 -> Seq Scan on public.int8_tbl t1 5920 Output: t1.q1, t1.q2 5921 -> Nested Loop 5922 Output: "*VALUES*".column1, ss2.q1, ss2.q2 5923 -> Values Scan on "*VALUES*" 5924 Output: "*VALUES*".column1 5925 -> Subquery Scan on ss2 5926 Output: ss2.q1, ss2.q2 5927 Filter: (t1.q1 = ss2.q2) 5928 -> Seq Scan on public.int8_tbl t2 5929 Output: t2.q1, t2.q2 5930 Filter: (SubPlan 3) 5931 SubPlan 3 5932 -> Result 5933 Output: t3.q2 5934 One-Time Filter: $4 5935 InitPlan 1 (returns $2) 5936 -> Result 5937 Output: GREATEST($0, t2.q2) 5938 InitPlan 2 (returns $4) 5939 -> Result 5940 Output: ($3 = 0) 5941 -> Seq Scan on public.int8_tbl t3 5942 Output: t3.q1, t3.q2 5943 Filter: (t3.q2 = $2) 5944(27 rows) 5945 5946select * from (values (0), (1)) v(id), 5947lateral (select * from int8_tbl t1, 5948 lateral (select * from 5949 (select * from int8_tbl t2 5950 where q1 = any (select q2 from int8_tbl t3 5951 where q2 = (select greatest(t1.q1,t2.q2)) 5952 and (select v.id=0)) offset 0) ss2) ss 5953 where t1.q1 = ss.q2) ss0; 5954 id | q1 | q2 | q1 | q2 5955----+------------------+-------------------+------------------+------------------ 5956 0 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 5957 0 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 5958 0 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 5959(3 rows) 5960 5961-- test some error cases where LATERAL should have been used but wasn't 5962select f1,g from int4_tbl a, (select f1 as g) ss; 5963ERROR: column "f1" does not exist 5964LINE 1: select f1,g from int4_tbl a, (select f1 as g) ss; 5965 ^ 5966HINT: There is a column named "f1" in table "a", but it cannot be referenced from this part of the query. 5967select f1,g from int4_tbl a, (select a.f1 as g) ss; 5968ERROR: invalid reference to FROM-clause entry for table "a" 5969LINE 1: select f1,g from int4_tbl a, (select a.f1 as g) ss; 5970 ^ 5971HINT: There is an entry for table "a", but it cannot be referenced from this part of the query. 5972select f1,g from int4_tbl a cross join (select f1 as g) ss; 5973ERROR: column "f1" does not exist 5974LINE 1: select f1,g from int4_tbl a cross join (select f1 as g) ss; 5975 ^ 5976HINT: There is a column named "f1" in table "a", but it cannot be referenced from this part of the query. 5977select f1,g from int4_tbl a cross join (select a.f1 as g) ss; 5978ERROR: invalid reference to FROM-clause entry for table "a" 5979LINE 1: select f1,g from int4_tbl a cross join (select a.f1 as g) ss... 5980 ^ 5981HINT: There is an entry for table "a", but it cannot be referenced from this part of the query. 5982-- SQL:2008 says the left table is in scope but illegal to access here 5983select f1,g from int4_tbl a right join lateral generate_series(0, a.f1) g on true; 5984ERROR: invalid reference to FROM-clause entry for table "a" 5985LINE 1: ... int4_tbl a right join lateral generate_series(0, a.f1) g on... 5986 ^ 5987DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference. 5988select f1,g from int4_tbl a full join lateral generate_series(0, a.f1) g on true; 5989ERROR: invalid reference to FROM-clause entry for table "a" 5990LINE 1: ...m int4_tbl a full join lateral generate_series(0, a.f1) g on... 5991 ^ 5992DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference. 5993-- check we complain about ambiguous table references 5994select * from 5995 int8_tbl x cross join (int4_tbl x cross join lateral (select x.f1) ss); 5996ERROR: table reference "x" is ambiguous 5997LINE 2: ...cross join (int4_tbl x cross join lateral (select x.f1) ss); 5998 ^ 5999-- LATERAL can be used to put an aggregate into the FROM clause of its query 6000select 1 from tenk1 a, lateral (select max(a.unique1) from int4_tbl b) ss; 6001ERROR: aggregate functions are not allowed in FROM clause of their own query level 6002LINE 1: select 1 from tenk1 a, lateral (select max(a.unique1) from i... 6003 ^ 6004-- check behavior of LATERAL in UPDATE/DELETE 6005create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl; 6006-- error, can't do this: 6007update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; 6008ERROR: column "x1" does not exist 6009LINE 1: ... set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; 6010 ^ 6011HINT: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. 6012update xx1 set x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss; 6013ERROR: invalid reference to FROM-clause entry for table "xx1" 6014LINE 1: ...t x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss... 6015 ^ 6016HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. 6017-- can't do it even with LATERAL: 6018update xx1 set x2 = f1 from lateral (select * from int4_tbl where f1 = x1) ss; 6019ERROR: invalid reference to FROM-clause entry for table "xx1" 6020LINE 1: ...= f1 from lateral (select * from int4_tbl where f1 = x1) ss; 6021 ^ 6022HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. 6023-- we might in future allow something like this, but for now it's an error: 6024update xx1 set x2 = f1 from xx1, lateral (select * from int4_tbl where f1 = x1) ss; 6025ERROR: table name "xx1" specified more than once 6026-- also errors: 6027delete from xx1 using (select * from int4_tbl where f1 = x1) ss; 6028ERROR: column "x1" does not exist 6029LINE 1: ...te from xx1 using (select * from int4_tbl where f1 = x1) ss; 6030 ^ 6031HINT: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. 6032delete from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss; 6033ERROR: invalid reference to FROM-clause entry for table "xx1" 6034LINE 1: ...from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss... 6035 ^ 6036HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. 6037delete from xx1 using lateral (select * from int4_tbl where f1 = x1) ss; 6038ERROR: invalid reference to FROM-clause entry for table "xx1" 6039LINE 1: ...xx1 using lateral (select * from int4_tbl where f1 = x1) ss; 6040 ^ 6041HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. 6042-- 6043-- test LATERAL reference propagation down a multi-level inheritance hierarchy 6044-- produced for a multi-level partitioned table hierarchy. 6045-- 6046create table join_pt1 (a int, b int, c varchar) partition by range(a); 6047create table join_pt1p1 partition of join_pt1 for values from (0) to (100) partition by range(b); 6048create table join_pt1p2 partition of join_pt1 for values from (100) to (200); 6049create table join_pt1p1p1 partition of join_pt1p1 for values from (0) to (100); 6050insert into join_pt1 values (1, 1, 'x'), (101, 101, 'y'); 6051create table join_ut1 (a int, b int, c varchar); 6052insert into join_ut1 values (101, 101, 'y'), (2, 2, 'z'); 6053explain (verbose, costs off) 6054select t1.b, ss.phv from join_ut1 t1 left join lateral 6055 (select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv 6056 from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss 6057 on t1.a = ss.t2a order by t1.a; 6058 QUERY PLAN 6059-------------------------------------------------------------------- 6060 Sort 6061 Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a 6062 Sort Key: t1.a 6063 -> Nested Loop Left Join 6064 Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a 6065 -> Seq Scan on public.join_ut1 t1 6066 Output: t1.a, t1.b, t1.c 6067 -> Hash Join 6068 Output: t2.a, LEAST(t1.a, t2.a, t3.a) 6069 Hash Cond: (t3.b = t2.a) 6070 -> Seq Scan on public.join_ut1 t3 6071 Output: t3.a, t3.b, t3.c 6072 -> Hash 6073 Output: t2.a 6074 -> Append 6075 -> Seq Scan on public.join_pt1p1p1 t2_1 6076 Output: t2_1.a 6077 Filter: (t1.a = t2_1.a) 6078 -> Seq Scan on public.join_pt1p2 t2_2 6079 Output: t2_2.a 6080 Filter: (t1.a = t2_2.a) 6081(21 rows) 6082 6083select t1.b, ss.phv from join_ut1 t1 left join lateral 6084 (select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv 6085 from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss 6086 on t1.a = ss.t2a order by t1.a; 6087 b | phv 6088-----+----- 6089 2 | 6090 101 | 101 6091(2 rows) 6092 6093drop table join_pt1; 6094drop table join_ut1; 6095-- 6096-- test estimation behavior with multi-column foreign key and constant qual 6097-- 6098begin; 6099create table fkest (x integer, x10 integer, x10b integer, x100 integer); 6100insert into fkest select x, x/10, x/10, x/100 from generate_series(1,1000) x; 6101create unique index on fkest(x, x10, x100); 6102analyze fkest; 6103explain (costs off) 6104select * from fkest f1 6105 join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) 6106 join fkest f3 on f1.x = f3.x 6107 where f1.x100 = 2; 6108 QUERY PLAN 6109----------------------------------------------------------- 6110 Nested Loop 6111 -> Hash Join 6112 Hash Cond: ((f2.x = f1.x) AND (f2.x10b = f1.x10)) 6113 -> Seq Scan on fkest f2 6114 Filter: (x100 = 2) 6115 -> Hash 6116 -> Seq Scan on fkest f1 6117 Filter: (x100 = 2) 6118 -> Index Scan using fkest_x_x10_x100_idx on fkest f3 6119 Index Cond: (x = f1.x) 6120(10 rows) 6121 6122alter table fkest add constraint fk 6123 foreign key (x, x10b, x100) references fkest (x, x10, x100); 6124explain (costs off) 6125select * from fkest f1 6126 join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) 6127 join fkest f3 on f1.x = f3.x 6128 where f1.x100 = 2; 6129 QUERY PLAN 6130----------------------------------------------------- 6131 Hash Join 6132 Hash Cond: ((f2.x = f1.x) AND (f2.x10b = f1.x10)) 6133 -> Hash Join 6134 Hash Cond: (f3.x = f2.x) 6135 -> Seq Scan on fkest f3 6136 -> Hash 6137 -> Seq Scan on fkest f2 6138 Filter: (x100 = 2) 6139 -> Hash 6140 -> Seq Scan on fkest f1 6141 Filter: (x100 = 2) 6142(11 rows) 6143 6144rollback; 6145-- 6146-- test that foreign key join estimation performs sanely for outer joins 6147-- 6148begin; 6149create table fkest (a int, b int, c int unique, primary key(a,b)); 6150create table fkest1 (a int, b int, primary key(a,b)); 6151insert into fkest select x/10, x%10, x from generate_series(1,1000) x; 6152insert into fkest1 select x/10, x%10 from generate_series(1,1000) x; 6153alter table fkest1 6154 add constraint fkest1_a_b_fkey foreign key (a,b) references fkest; 6155analyze fkest; 6156analyze fkest1; 6157explain (costs off) 6158select * 6159from fkest f 6160 left join fkest1 f1 on f.a = f1.a and f.b = f1.b 6161 left join fkest1 f2 on f.a = f2.a and f.b = f2.b 6162 left join fkest1 f3 on f.a = f3.a and f.b = f3.b 6163where f.c = 1; 6164 QUERY PLAN 6165------------------------------------------------------------------ 6166 Nested Loop Left Join 6167 -> Nested Loop Left Join 6168 -> Nested Loop Left Join 6169 -> Index Scan using fkest_c_key on fkest f 6170 Index Cond: (c = 1) 6171 -> Index Only Scan using fkest1_pkey on fkest1 f1 6172 Index Cond: ((a = f.a) AND (b = f.b)) 6173 -> Index Only Scan using fkest1_pkey on fkest1 f2 6174 Index Cond: ((a = f.a) AND (b = f.b)) 6175 -> Index Only Scan using fkest1_pkey on fkest1 f3 6176 Index Cond: ((a = f.a) AND (b = f.b)) 6177(11 rows) 6178 6179rollback; 6180-- 6181-- test planner's ability to mark joins as unique 6182-- 6183create table j1 (id int primary key); 6184create table j2 (id int primary key); 6185create table j3 (id int); 6186insert into j1 values(1),(2),(3); 6187insert into j2 values(1),(2),(3); 6188insert into j3 values(1),(1); 6189analyze j1; 6190analyze j2; 6191analyze j3; 6192-- ensure join is properly marked as unique 6193explain (verbose, costs off) 6194select * from j1 inner join j2 on j1.id = j2.id; 6195 QUERY PLAN 6196----------------------------------- 6197 Hash Join 6198 Output: j1.id, j2.id 6199 Inner Unique: true 6200 Hash Cond: (j1.id = j2.id) 6201 -> Seq Scan on public.j1 6202 Output: j1.id 6203 -> Hash 6204 Output: j2.id 6205 -> Seq Scan on public.j2 6206 Output: j2.id 6207(10 rows) 6208 6209-- ensure join is not unique when not an equi-join 6210explain (verbose, costs off) 6211select * from j1 inner join j2 on j1.id > j2.id; 6212 QUERY PLAN 6213----------------------------------- 6214 Nested Loop 6215 Output: j1.id, j2.id 6216 Join Filter: (j1.id > j2.id) 6217 -> Seq Scan on public.j1 6218 Output: j1.id 6219 -> Materialize 6220 Output: j2.id 6221 -> Seq Scan on public.j2 6222 Output: j2.id 6223(9 rows) 6224 6225-- ensure non-unique rel is not chosen as inner 6226explain (verbose, costs off) 6227select * from j1 inner join j3 on j1.id = j3.id; 6228 QUERY PLAN 6229----------------------------------- 6230 Hash Join 6231 Output: j1.id, j3.id 6232 Inner Unique: true 6233 Hash Cond: (j3.id = j1.id) 6234 -> Seq Scan on public.j3 6235 Output: j3.id 6236 -> Hash 6237 Output: j1.id 6238 -> Seq Scan on public.j1 6239 Output: j1.id 6240(10 rows) 6241 6242-- ensure left join is marked as unique 6243explain (verbose, costs off) 6244select * from j1 left join j2 on j1.id = j2.id; 6245 QUERY PLAN 6246----------------------------------- 6247 Hash Left Join 6248 Output: j1.id, j2.id 6249 Inner Unique: true 6250 Hash Cond: (j1.id = j2.id) 6251 -> Seq Scan on public.j1 6252 Output: j1.id 6253 -> Hash 6254 Output: j2.id 6255 -> Seq Scan on public.j2 6256 Output: j2.id 6257(10 rows) 6258 6259-- ensure right join is marked as unique 6260explain (verbose, costs off) 6261select * from j1 right join j2 on j1.id = j2.id; 6262 QUERY PLAN 6263----------------------------------- 6264 Hash Left Join 6265 Output: j1.id, j2.id 6266 Inner Unique: true 6267 Hash Cond: (j2.id = j1.id) 6268 -> Seq Scan on public.j2 6269 Output: j2.id 6270 -> Hash 6271 Output: j1.id 6272 -> Seq Scan on public.j1 6273 Output: j1.id 6274(10 rows) 6275 6276-- ensure full join is marked as unique 6277explain (verbose, costs off) 6278select * from j1 full join j2 on j1.id = j2.id; 6279 QUERY PLAN 6280----------------------------------- 6281 Hash Full Join 6282 Output: j1.id, j2.id 6283 Inner Unique: true 6284 Hash Cond: (j1.id = j2.id) 6285 -> Seq Scan on public.j1 6286 Output: j1.id 6287 -> Hash 6288 Output: j2.id 6289 -> Seq Scan on public.j2 6290 Output: j2.id 6291(10 rows) 6292 6293-- a clauseless (cross) join can't be unique 6294explain (verbose, costs off) 6295select * from j1 cross join j2; 6296 QUERY PLAN 6297----------------------------------- 6298 Nested Loop 6299 Output: j1.id, j2.id 6300 -> Seq Scan on public.j1 6301 Output: j1.id 6302 -> Materialize 6303 Output: j2.id 6304 -> Seq Scan on public.j2 6305 Output: j2.id 6306(8 rows) 6307 6308-- ensure a natural join is marked as unique 6309explain (verbose, costs off) 6310select * from j1 natural join j2; 6311 QUERY PLAN 6312----------------------------------- 6313 Hash Join 6314 Output: j1.id 6315 Inner Unique: true 6316 Hash Cond: (j1.id = j2.id) 6317 -> Seq Scan on public.j1 6318 Output: j1.id 6319 -> Hash 6320 Output: j2.id 6321 -> Seq Scan on public.j2 6322 Output: j2.id 6323(10 rows) 6324 6325-- ensure a distinct clause allows the inner to become unique 6326explain (verbose, costs off) 6327select * from j1 6328inner join (select distinct id from j3) j3 on j1.id = j3.id; 6329 QUERY PLAN 6330----------------------------------------- 6331 Nested Loop 6332 Output: j1.id, j3.id 6333 Inner Unique: true 6334 Join Filter: (j1.id = j3.id) 6335 -> Unique 6336 Output: j3.id 6337 -> Sort 6338 Output: j3.id 6339 Sort Key: j3.id 6340 -> Seq Scan on public.j3 6341 Output: j3.id 6342 -> Seq Scan on public.j1 6343 Output: j1.id 6344(13 rows) 6345 6346-- ensure group by clause allows the inner to become unique 6347explain (verbose, costs off) 6348select * from j1 6349inner join (select id from j3 group by id) j3 on j1.id = j3.id; 6350 QUERY PLAN 6351----------------------------------------- 6352 Nested Loop 6353 Output: j1.id, j3.id 6354 Inner Unique: true 6355 Join Filter: (j1.id = j3.id) 6356 -> Group 6357 Output: j3.id 6358 Group Key: j3.id 6359 -> Sort 6360 Output: j3.id 6361 Sort Key: j3.id 6362 -> Seq Scan on public.j3 6363 Output: j3.id 6364 -> Seq Scan on public.j1 6365 Output: j1.id 6366(14 rows) 6367 6368drop table j1; 6369drop table j2; 6370drop table j3; 6371-- test more complex permutations of unique joins 6372create table j1 (id1 int, id2 int, primary key(id1,id2)); 6373create table j2 (id1 int, id2 int, primary key(id1,id2)); 6374create table j3 (id1 int, id2 int, primary key(id1,id2)); 6375insert into j1 values(1,1),(1,2); 6376insert into j2 values(1,1); 6377insert into j3 values(1,1); 6378analyze j1; 6379analyze j2; 6380analyze j3; 6381-- ensure there's no unique join when not all columns which are part of the 6382-- unique index are seen in the join clause 6383explain (verbose, costs off) 6384select * from j1 6385inner join j2 on j1.id1 = j2.id1; 6386 QUERY PLAN 6387------------------------------------------ 6388 Nested Loop 6389 Output: j1.id1, j1.id2, j2.id1, j2.id2 6390 Join Filter: (j1.id1 = j2.id1) 6391 -> Seq Scan on public.j2 6392 Output: j2.id1, j2.id2 6393 -> Seq Scan on public.j1 6394 Output: j1.id1, j1.id2 6395(7 rows) 6396 6397-- ensure proper unique detection with multiple join quals 6398explain (verbose, costs off) 6399select * from j1 6400inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2; 6401 QUERY PLAN 6402---------------------------------------------------------- 6403 Nested Loop 6404 Output: j1.id1, j1.id2, j2.id1, j2.id2 6405 Inner Unique: true 6406 Join Filter: ((j1.id1 = j2.id1) AND (j1.id2 = j2.id2)) 6407 -> Seq Scan on public.j2 6408 Output: j2.id1, j2.id2 6409 -> Seq Scan on public.j1 6410 Output: j1.id1, j1.id2 6411(8 rows) 6412 6413-- ensure we don't detect the join to be unique when quals are not part of the 6414-- join condition 6415explain (verbose, costs off) 6416select * from j1 6417inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; 6418 QUERY PLAN 6419------------------------------------------ 6420 Nested Loop 6421 Output: j1.id1, j1.id2, j2.id1, j2.id2 6422 Join Filter: (j1.id1 = j2.id1) 6423 -> Seq Scan on public.j1 6424 Output: j1.id1, j1.id2 6425 Filter: (j1.id2 = 1) 6426 -> Seq Scan on public.j2 6427 Output: j2.id1, j2.id2 6428(8 rows) 6429 6430-- as above, but for left joins. 6431explain (verbose, costs off) 6432select * from j1 6433left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; 6434 QUERY PLAN 6435------------------------------------------ 6436 Nested Loop Left Join 6437 Output: j1.id1, j1.id2, j2.id1, j2.id2 6438 Join Filter: (j1.id1 = j2.id1) 6439 -> Seq Scan on public.j1 6440 Output: j1.id1, j1.id2 6441 Filter: (j1.id2 = 1) 6442 -> Seq Scan on public.j2 6443 Output: j2.id1, j2.id2 6444(8 rows) 6445 6446-- validate logic in merge joins which skips mark and restore. 6447-- it should only do this if all quals which were used to detect the unique 6448-- are present as join quals, and not plain quals. 6449set enable_nestloop to 0; 6450set enable_hashjoin to 0; 6451set enable_sort to 0; 6452-- create indexes that will be preferred over the PKs to perform the join 6453create index j1_id1_idx on j1 (id1) where id1 % 1000 = 1; 6454create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1; 6455-- need an additional row in j2, if we want j2_id1_idx to be preferred 6456insert into j2 values(1,2); 6457analyze j2; 6458explain (costs off) select * from j1 6459inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 6460where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; 6461 QUERY PLAN 6462----------------------------------------- 6463 Merge Join 6464 Merge Cond: (j1.id1 = j2.id1) 6465 Join Filter: (j1.id2 = j2.id2) 6466 -> Index Scan using j1_id1_idx on j1 6467 -> Index Scan using j2_id1_idx on j2 6468(5 rows) 6469 6470select * from j1 6471inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 6472where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; 6473 id1 | id2 | id1 | id2 6474-----+-----+-----+----- 6475 1 | 1 | 1 | 1 6476 1 | 2 | 1 | 2 6477(2 rows) 6478 6479-- Exercise array keys mark/restore B-Tree code 6480explain (costs off) select * from j1 6481inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 6482where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 = any (array[1]); 6483 QUERY PLAN 6484---------------------------------------------------- 6485 Merge Join 6486 Merge Cond: (j1.id1 = j2.id1) 6487 Join Filter: (j1.id2 = j2.id2) 6488 -> Index Scan using j1_id1_idx on j1 6489 -> Index Scan using j2_id1_idx on j2 6490 Index Cond: (id1 = ANY ('{1}'::integer[])) 6491(6 rows) 6492 6493select * from j1 6494inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 6495where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 = any (array[1]); 6496 id1 | id2 | id1 | id2 6497-----+-----+-----+----- 6498 1 | 1 | 1 | 1 6499 1 | 2 | 1 | 2 6500(2 rows) 6501 6502-- Exercise array keys "find extreme element" B-Tree code 6503explain (costs off) select * from j1 6504inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 6505where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 >= any (array[1,5]); 6506 QUERY PLAN 6507------------------------------------------------------- 6508 Merge Join 6509 Merge Cond: (j1.id1 = j2.id1) 6510 Join Filter: (j1.id2 = j2.id2) 6511 -> Index Scan using j1_id1_idx on j1 6512 -> Index Only Scan using j2_pkey on j2 6513 Index Cond: (id1 >= ANY ('{1,5}'::integer[])) 6514 Filter: ((id1 % 1000) = 1) 6515(7 rows) 6516 6517select * from j1 6518inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 6519where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 >= any (array[1,5]); 6520 id1 | id2 | id1 | id2 6521-----+-----+-----+----- 6522 1 | 1 | 1 | 1 6523 1 | 2 | 1 | 2 6524(2 rows) 6525 6526reset enable_nestloop; 6527reset enable_hashjoin; 6528reset enable_sort; 6529drop table j1; 6530drop table j2; 6531drop table j3; 6532-- check that semijoin inner is not seen as unique for a portion of the outerrel 6533explain (verbose, costs off) 6534select t1.unique1, t2.hundred 6535from onek t1, tenk1 t2 6536where exists (select 1 from tenk1 t3 6537 where t3.thousand = t1.unique1 and t3.tenthous = t2.hundred) 6538 and t1.unique1 < 1; 6539 QUERY PLAN 6540--------------------------------------------------------------------------------- 6541 Nested Loop 6542 Output: t1.unique1, t2.hundred 6543 -> Hash Join 6544 Output: t1.unique1, t3.tenthous 6545 Hash Cond: (t3.thousand = t1.unique1) 6546 -> HashAggregate 6547 Output: t3.thousand, t3.tenthous 6548 Group Key: t3.thousand, t3.tenthous 6549 -> Index Only Scan using tenk1_thous_tenthous on public.tenk1 t3 6550 Output: t3.thousand, t3.tenthous 6551 -> Hash 6552 Output: t1.unique1 6553 -> Index Only Scan using onek_unique1 on public.onek t1 6554 Output: t1.unique1 6555 Index Cond: (t1.unique1 < 1) 6556 -> Index Only Scan using tenk1_hundred on public.tenk1 t2 6557 Output: t2.hundred 6558 Index Cond: (t2.hundred = t3.tenthous) 6559(18 rows) 6560 6561-- ... unless it actually is unique 6562create table j3 as select unique1, tenthous from onek; 6563vacuum analyze j3; 6564create unique index on j3(unique1, tenthous); 6565explain (verbose, costs off) 6566select t1.unique1, t2.hundred 6567from onek t1, tenk1 t2 6568where exists (select 1 from j3 6569 where j3.unique1 = t1.unique1 and j3.tenthous = t2.hundred) 6570 and t1.unique1 < 1; 6571 QUERY PLAN 6572------------------------------------------------------------------------ 6573 Nested Loop 6574 Output: t1.unique1, t2.hundred 6575 -> Nested Loop 6576 Output: t1.unique1, j3.tenthous 6577 -> Index Only Scan using onek_unique1 on public.onek t1 6578 Output: t1.unique1 6579 Index Cond: (t1.unique1 < 1) 6580 -> Index Only Scan using j3_unique1_tenthous_idx on public.j3 6581 Output: j3.unique1, j3.tenthous 6582 Index Cond: (j3.unique1 = t1.unique1) 6583 -> Index Only Scan using tenk1_hundred on public.tenk1 t2 6584 Output: t2.hundred 6585 Index Cond: (t2.hundred = j3.tenthous) 6586(13 rows) 6587 6588drop table j3; 6589