@@ -651,10 +651,9 @@ extract_actual_join_clauses(List *restrictinfo_list,
651
651
* outer join, as that would change the results (rows would be suppressed
652
652
* rather than being null-extended).
653
653
*
654
- * Also the target relation must not be in the clause's nullable_relids, i.e.,
655
- * there must not be an outer join below the clause that would null the Vars
656
- * coming from the target relation. Otherwise the clause might give results
657
- * different from what it would give at its normal semantic level.
654
+ * Also there must not be an outer join below the clause that would null the
655
+ * Vars coming from the target relation. Otherwise the clause might give
656
+ * results different from what it would give at its normal semantic level.
658
657
*
659
658
* Also, the join clause must not use any relations that have LATERAL
660
659
* references to the target relation, since we could not put such rels on
@@ -703,10 +702,31 @@ join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel)
703
702
* not pushing the clause into its outer-join outer side, nor down into
704
703
* a lower outer join's inner side.
705
704
*
705
+ * The check about pushing a clause down into a lower outer join's inner side
706
+ * is only approximate; it sometimes returns "false" when actually it would
707
+ * be safe to use the clause here because we're still above the outer join
708
+ * in question. This is okay as long as the answers at different join levels
709
+ * are consistent: it just means we might sometimes fail to push a clause as
710
+ * far down as it could safely be pushed. It's unclear whether it would be
711
+ * worthwhile to do this more precisely. (But if it's ever fixed to be
712
+ * exactly accurate, there's an Assert in get_joinrel_parampathinfo() that
713
+ * should be re-enabled.)
714
+ *
706
715
* There's no check here equivalent to join_clause_is_movable_to's test on
707
716
* lateral_referencers. We assume the caller wouldn't be inquiring unless
708
717
* it'd verified that the proposed outer rels don't have lateral references
709
- * to the current rel(s).
718
+ * to the current rel(s). (If we are considering join paths with the outer
719
+ * rels on the outside and the current rels on the inside, then this should
720
+ * have been checked at the outset of such consideration; see join_is_legal
721
+ * and the path parameterization checks in joinpath.c.) On the other hand,
722
+ * in join_clause_is_movable_to we are asking whether the clause could be
723
+ * moved for some valid set of outer rels, so we don't have the benefit of
724
+ * relying on prior checks for lateral-reference validity.
725
+ *
726
+ * Note: if this returns true, it means that the clause could be moved to
727
+ * this join relation, but that doesn't mean that this is the lowest join
728
+ * it could be moved to. Caller may need to make additional calls to verify
729
+ * that this doesn't succeed on either of the inputs of a proposed join.
710
730
*
711
731
* Note: get_joinrel_parampathinfo depends on the fact that if
712
732
* current_and_outer is NULL, this function will always return false
@@ -721,15 +741,20 @@ join_clause_is_movable_into(RestrictInfo *rinfo,
721
741
if (!bms_is_subset (rinfo -> clause_relids , current_and_outer ))
722
742
return false;
723
743
724
- /* Clause must physically reference target rel(s) */
744
+ /* Clause must physically reference at least one target rel */
725
745
if (!bms_overlap (currentrelids , rinfo -> clause_relids ))
726
746
return false;
727
747
728
748
/* Cannot move an outer-join clause into the join's outer side */
729
749
if (bms_overlap (currentrelids , rinfo -> outer_relids ))
730
750
return false;
731
751
732
- /* Target rel(s) must not be nullable below the clause */
752
+ /*
753
+ * Target rel(s) must not be nullable below the clause. This is
754
+ * approximate, in the safe direction, because the current join might be
755
+ * above the join where the nulling would happen, in which case the clause
756
+ * would work correctly here. But we don't have enough info to be sure.
757
+ */
733
758
if (bms_overlap (currentrelids , rinfo -> nullable_relids ))
734
759
return false;
735
760
0 commit comments