*
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.93 2008/08/14 18:47:59 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.94 2008/08/17 19:40:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 static bool has_join_restriction(PlannerInfo *root, RelOptInfo *rel);
 static bool has_legal_joinclause(PlannerInfo *root, RelOptInfo *rel);
 static bool is_dummy_rel(RelOptInfo *rel);
-static void mark_dummy_join(RelOptInfo *rel);
+static void mark_dummy_rel(RelOptInfo *rel);
+static bool restriction_is_constant_false(List *restrictlist);
 
 
 /*
     * this way since it's conceivable that dummy-ness of a multi-element
     * join might only be noticeable for certain construction paths.)
     *
+    * Also, a provably constant-false join restriction typically means that
+    * we can skip evaluating one or both sides of the join.  We do this
+    * by marking the appropriate rel as dummy.
+    *
     * We need only consider the jointypes that appear in join_info_list,
     * plus JOIN_INNER.
     */
    switch (sjinfo->jointype)
    {
        case JOIN_INNER:
-           if (is_dummy_rel(rel1) || is_dummy_rel(rel2))
+           if (is_dummy_rel(rel1) || is_dummy_rel(rel2) ||
+               restriction_is_constant_false(restrictlist))
            {
-               mark_dummy_join(joinrel);
+               mark_dummy_rel(joinrel);
                break;
            }
            add_paths_to_joinrel(root, joinrel, rel1, rel2,
        case JOIN_LEFT:
            if (is_dummy_rel(rel1))
            {
-               mark_dummy_join(joinrel);
+               mark_dummy_rel(joinrel);
                break;
            }
+           if (restriction_is_constant_false(restrictlist) &&
+               bms_is_subset(rel2->relids, sjinfo->syn_righthand))
+               mark_dummy_rel(rel2);
            add_paths_to_joinrel(root, joinrel, rel1, rel2,
                                 JOIN_LEFT, sjinfo,
                                 restrictlist);
        case JOIN_FULL:
            if (is_dummy_rel(rel1) && is_dummy_rel(rel2))
            {
-               mark_dummy_join(joinrel);
+               mark_dummy_rel(joinrel);
                break;
            }
            add_paths_to_joinrel(root, joinrel, rel1, rel2,
                                 restrictlist);
            break;
        case JOIN_SEMI:
-           if (is_dummy_rel(rel1) || is_dummy_rel(rel2))
+           if (is_dummy_rel(rel1) || is_dummy_rel(rel2) ||
+               restriction_is_constant_false(restrictlist))
            {
-               mark_dummy_join(joinrel);
+               mark_dummy_rel(joinrel);
                break;
            }
            add_paths_to_joinrel(root, joinrel, rel1, rel2,
        case JOIN_ANTI:
            if (is_dummy_rel(rel1))
            {
-               mark_dummy_join(joinrel);
+               mark_dummy_rel(joinrel);
                break;
            }
+           if (restriction_is_constant_false(restrictlist) &&
+               bms_is_subset(rel2->relids, sjinfo->syn_righthand))
+               mark_dummy_rel(rel2);
            add_paths_to_joinrel(root, joinrel, rel1, rel2,
                                 JOIN_ANTI, sjinfo,
                                 restrictlist);
 }
 
 /*
- * Mark a joinrel as proven empty.
+ * Mark a rel as proven empty.
  */
 static void
-mark_dummy_join(RelOptInfo *rel)
+mark_dummy_rel(RelOptInfo *rel)
 {
    /* Set dummy size estimate */
    rel->rows = 0;
    /* Set up the dummy path */
    add_path(rel, (Path *) create_append_path(rel, NIL));
 
+   /* Set or update cheapest_total_path */
+   set_cheapest(rel);
+}
+
+
+/*
+ * restriction_is_constant_false --- is a restrictlist just FALSE?
+ *
+ * In cases where a qual is provably constant FALSE, eval_const_expressions
+ * will generally have thrown away anything that's ANDed with it.  In outer
+ * join situations this will leave us computing cartesian products only to
+ * decide there's no match for an outer row, which is pretty stupid.  So,
+ * we need to detect the case.
+ */
+static bool
+restriction_is_constant_false(List *restrictlist)
+{
+   ListCell   *lc;
+
    /*
-    * Although set_cheapest will be done again later, we do it immediately
-    * in order to keep is_dummy_rel as cheap as possible (ie, not have
-    * to examine the pathlist).
+    * Despite the above comment, the restriction list we see here might
+    * possibly have other members besides the FALSE constant, since other
+    * quals could get "pushed down" to the outer join level.  So we check
+    * each member of the list.
     */
-   set_cheapest(rel);
+   foreach(lc, restrictlist)
+   {
+       RestrictInfo   *rinfo = (RestrictInfo *) lfirst(lc);
+
+       Assert(IsA(rinfo, RestrictInfo));
+       if (rinfo->clause && IsA(rinfo->clause, Const))
+       {
+           Const  *con = (Const *) rinfo->clause;
+
+           /* constant NULL is as good as constant FALSE for our purposes */
+           if (con->constisnull)
+               return true;
+           if (!DatumGetBool(con->constvalue))
+               return true;
+       }
+   }
+   return false;
 }