88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.93 2008/08/14 18:47:59 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.94 2008/08/17 19:40:11 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -28,7 +28,8 @@ static List *make_rels_by_clauseless_joins(PlannerInfo *root,
2828static bool has_join_restriction (PlannerInfo * root ,RelOptInfo * rel );
2929static bool has_legal_joinclause (PlannerInfo * root ,RelOptInfo * rel );
3030static bool is_dummy_rel (RelOptInfo * rel );
31- static void mark_dummy_join (RelOptInfo * rel );
31+ static void mark_dummy_rel (RelOptInfo * rel );
32+ static bool restriction_is_constant_false (List * restrictlist );
3233
3334
3435/*
@@ -558,15 +559,20 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
558559 * this way since it's conceivable that dummy-ness of a multi-element
559560 * join might only be noticeable for certain construction paths.)
560561 *
562+ * Also, a provably constant-false join restriction typically means that
563+ * we can skip evaluating one or both sides of the join. We do this
564+ * by marking the appropriate rel as dummy.
565+ *
561566 * We need only consider the jointypes that appear in join_info_list,
562567 * plus JOIN_INNER.
563568 */
564569switch (sjinfo -> jointype )
565570{
566571case JOIN_INNER :
567- if (is_dummy_rel (rel1 )|| is_dummy_rel (rel2 ))
572+ if (is_dummy_rel (rel1 )|| is_dummy_rel (rel2 )||
573+ restriction_is_constant_false (restrictlist ))
568574{
569- mark_dummy_join (joinrel );
575+ mark_dummy_rel (joinrel );
570576break ;
571577}
572578add_paths_to_joinrel (root ,joinrel ,rel1 ,rel2 ,
@@ -579,9 +585,12 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
579585case JOIN_LEFT :
580586if (is_dummy_rel (rel1 ))
581587{
582- mark_dummy_join (joinrel );
588+ mark_dummy_rel (joinrel );
583589break ;
584590}
591+ if (restriction_is_constant_false (restrictlist )&&
592+ bms_is_subset (rel2 -> relids ,sjinfo -> syn_righthand ))
593+ mark_dummy_rel (rel2 );
585594add_paths_to_joinrel (root ,joinrel ,rel1 ,rel2 ,
586595JOIN_LEFT ,sjinfo ,
587596restrictlist );
@@ -592,7 +601,7 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
592601case JOIN_FULL :
593602if (is_dummy_rel (rel1 )&& is_dummy_rel (rel2 ))
594603{
595- mark_dummy_join (joinrel );
604+ mark_dummy_rel (joinrel );
596605break ;
597606}
598607add_paths_to_joinrel (root ,joinrel ,rel1 ,rel2 ,
@@ -603,9 +612,10 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
603612restrictlist );
604613break ;
605614case JOIN_SEMI :
606- if (is_dummy_rel (rel1 )|| is_dummy_rel (rel2 ))
615+ if (is_dummy_rel (rel1 )|| is_dummy_rel (rel2 )||
616+ restriction_is_constant_false (restrictlist ))
607617{
608- mark_dummy_join (joinrel );
618+ mark_dummy_rel (joinrel );
609619break ;
610620}
611621add_paths_to_joinrel (root ,joinrel ,rel1 ,rel2 ,
@@ -632,9 +642,12 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
632642case JOIN_ANTI :
633643if (is_dummy_rel (rel1 ))
634644{
635- mark_dummy_join (joinrel );
645+ mark_dummy_rel (joinrel );
636646break ;
637647}
648+ if (restriction_is_constant_false (restrictlist )&&
649+ bms_is_subset (rel2 -> relids ,sjinfo -> syn_righthand ))
650+ mark_dummy_rel (rel2 );
638651add_paths_to_joinrel (root ,joinrel ,rel1 ,rel2 ,
639652JOIN_ANTI ,sjinfo ,
640653restrictlist );
@@ -851,10 +864,10 @@ is_dummy_rel(RelOptInfo *rel)
851864}
852865
853866/*
854- * Mark ajoinrel as proven empty.
867+ * Mark arel as proven empty.
855868 */
856869static void
857- mark_dummy_join (RelOptInfo * rel )
870+ mark_dummy_rel (RelOptInfo * rel )
858871{
859872/* Set dummy size estimate */
860873rel -> rows = 0 ;
@@ -865,10 +878,46 @@ mark_dummy_join(RelOptInfo *rel)
865878/* Set up the dummy path */
866879add_path (rel , (Path * )create_append_path (rel ,NIL ));
867880
881+ /* Set or update cheapest_total_path */
882+ set_cheapest (rel );
883+ }
884+
885+
886+ /*
887+ * restriction_is_constant_false --- is a restrictlist just FALSE?
888+ *
889+ * In cases where a qual is provably constant FALSE, eval_const_expressions
890+ * will generally have thrown away anything that's ANDed with it. In outer
891+ * join situations this will leave us computing cartesian products only to
892+ * decide there's no match for an outer row, which is pretty stupid. So,
893+ * we need to detect the case.
894+ */
895+ static bool
896+ restriction_is_constant_false (List * restrictlist )
897+ {
898+ ListCell * lc ;
899+
868900/*
869- * Although set_cheapest will be done again later, we do it immediately
870- * in order to keep is_dummy_rel as cheap as possible (ie, not have
871- * to examine the pathlist).
901+ * Despite the above comment, the restriction list we see here might
902+ * possibly have other members besides the FALSE constant, since other
903+ * quals could get "pushed down" to the outer join level. So we check
904+ * each member of the list.
872905 */
873- set_cheapest (rel );
906+ foreach (lc ,restrictlist )
907+ {
908+ RestrictInfo * rinfo = (RestrictInfo * )lfirst (lc );
909+
910+ Assert (IsA (rinfo ,RestrictInfo ));
911+ if (rinfo -> clause && IsA (rinfo -> clause ,Const ))
912+ {
913+ Const * con = (Const * )rinfo -> clause ;
914+
915+ /* constant NULL is as good as constant FALSE for our purposes */
916+ if (con -> constisnull )
917+ return true;
918+ if (!DatumGetBool (con -> constvalue ))
919+ return true;
920+ }
921+ }
922+ return false;
874923}