@@ -464,10 +464,9 @@ extract_actual_join_clauses(List *restrictinfo_list,
464
464
* outer join, as that would change the results (rows would be suppressed
465
465
* rather than being null-extended).
466
466
*
467
- * Also the target relation must not be in the clause's nullable_relids, i.e.,
468
- * there must not be an outer join below the clause that would null the Vars
469
- * coming from the target relation. Otherwise the clause might give results
470
- * different from what it would give at its normal semantic level.
467
+ * Also there must not be an outer join below the clause that would null the
468
+ * Vars coming from the target relation. Otherwise the clause might give
469
+ * results different from what it would give at its normal semantic level.
471
470
*
472
471
* Also, the join clause must not use any relations that have LATERAL
473
472
* references to the target relation, since we could not put such rels on
@@ -516,10 +515,31 @@ join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel)
516
515
* not pushing the clause into its outer-join outer side, nor down into
517
516
* a lower outer join's inner side.
518
517
*
518
+ * The check about pushing a clause down into a lower outer join's inner side
519
+ * is only approximate; it sometimes returns "false" when actually it would
520
+ * be safe to use the clause here because we're still above the outer join
521
+ * in question. This is okay as long as the answers at different join levels
522
+ * are consistent: it just means we might sometimes fail to push a clause as
523
+ * far down as it could safely be pushed. It's unclear whether it would be
524
+ * worthwhile to do this more precisely. (But if it's ever fixed to be
525
+ * exactly accurate, there's an Assert in get_joinrel_parampathinfo() that
526
+ * should be re-enabled.)
527
+ *
519
528
* There's no check here equivalent to join_clause_is_movable_to's test on
520
529
* lateral_referencers. We assume the caller wouldn't be inquiring unless
521
530
* it'd verified that the proposed outer rels don't have lateral references
522
- * to the current rel(s).
531
+ * to the current rel(s). (If we are considering join paths with the outer
532
+ * rels on the outside and the current rels on the inside, then this should
533
+ * have been checked at the outset of such consideration; see join_is_legal
534
+ * and the path parameterization checks in joinpath.c.) On the other hand,
535
+ * in join_clause_is_movable_to we are asking whether the clause could be
536
+ * moved for some valid set of outer rels, so we don't have the benefit of
537
+ * relying on prior checks for lateral-reference validity.
538
+ *
539
+ * Note: if this returns true, it means that the clause could be moved to
540
+ * this join relation, but that doesn't mean that this is the lowest join
541
+ * it could be moved to. Caller may need to make additional calls to verify
542
+ * that this doesn't succeed on either of the inputs of a proposed join.
523
543
*
524
544
* Note: get_joinrel_parampathinfo depends on the fact that if
525
545
* current_and_outer is NULL, this function will always return false
@@ -534,15 +554,20 @@ join_clause_is_movable_into(RestrictInfo *rinfo,
534
554
if (!bms_is_subset (rinfo -> clause_relids , current_and_outer ))
535
555
return false;
536
556
537
- /* Clause must physically reference target rel(s) */
557
+ /* Clause must physically reference at least one target rel */
538
558
if (!bms_overlap (currentrelids , rinfo -> clause_relids ))
539
559
return false;
540
560
541
561
/* Cannot move an outer-join clause into the join's outer side */
542
562
if (bms_overlap (currentrelids , rinfo -> outer_relids ))
543
563
return false;
544
564
545
- /* Target rel(s) must not be nullable below the clause */
565
+ /*
566
+ * Target rel(s) must not be nullable below the clause. This is
567
+ * approximate, in the safe direction, because the current join might be
568
+ * above the join where the nulling would happen, in which case the clause
569
+ * would work correctly here. But we don't have enough info to be sure.
570
+ */
546
571
if (bms_overlap (currentrelids , rinfo -> nullable_relids ))
547
572
return false;
548
573
0 commit comments