88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.149 2009/01/01 17:23:44 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.150 2009/02/27 00:06:27 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -765,19 +765,34 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
765765 */
766766oldcontext = MemoryContextSwitchTo (root -> planner_cxt );
767767
768- /*
768+ /*----------
769769 * Look to see whether the semijoin's join quals consist of AND'ed
770770 * equality operators, with (only) RHS variables on only one side of
771771 * each one. If so, we can figure out how to enforce uniqueness for
772772 * the RHS.
773773 *
774+ * Note that the input join_quals list is the list of quals that are
775+ * *syntactically* associated with the semijoin, which in practice means
776+ * the synthesized comparison list for an IN or the WHERE of an EXISTS.
777+ * Particularly in the latter case, it might contain clauses that aren't
778+ * *semantically* associated with the join, but refer to just one side or
779+ * the other. We can ignore such clauses here, as they will just drop
780+ * down to be processed within one side or the other. (It is okay to
781+ * consider only the syntactically-associated clauses here because for a
782+ * semijoin, no higher-level quals could refer to the RHS, and so there
783+ * can be no other quals that are semantically associated with this join.
784+ * We do things this way because it is useful to be able to run this test
785+ * before we have extracted the list of quals that are actually
786+ * semantically associated with the particular join.)
787+ *
774788 * Note that the in_operators list consists of the joinqual operators
775789 * themselves (but commuted if needed to put the RHS value on the right).
776790 * These could be cross-type operators, in which case the operator
777791 * actually needed for uniqueness is a related single-type operator.
778792 * We assume here that that operator will be available from the btree
779793 * or hash opclass when the time comes ... if not, create_unique_plan()
780794 * will fail.
795+ *----------
781796 */
782797in_operators = NIL ;
783798uniq_exprs = NIL ;
@@ -791,19 +806,52 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
791806Node * right_expr ;
792807Relids left_varnos ;
793808Relids right_varnos ;
809+ Relids all_varnos ;
794810
795- /* must be binary opclause... */
796- if (!IsA (op ,OpExpr ))
797- gotono_unique_path ;
798- if (list_length (op -> args )!= 2 )
811+ /* Is it a binary opclause? */
812+ if (!IsA (op ,OpExpr )||
813+ list_length (op -> args )!= 2 )
814+ {
815+ /* No, but does it reference both sides? */
816+ all_varnos = pull_varnos ((Node * )op );
817+ if (!bms_overlap (all_varnos ,sjinfo -> syn_righthand )||
818+ bms_is_subset (all_varnos ,sjinfo -> syn_righthand ))
819+ {
820+ /*
821+ * Clause refers to only one rel, so ignore it --- unless it
822+ * contains volatile functions, in which case we'd better
823+ * punt.
824+ */
825+ if (contain_volatile_functions ((Node * )op ))
826+ gotono_unique_path ;
827+ continue ;
828+ }
829+ /* Non-operator clause referencing both sides, must punt */
799830gotono_unique_path ;
831+ }
832+
833+ /* Extract data from binary opclause */
800834opno = op -> opno ;
801835left_expr = linitial (op -> args );
802836right_expr = lsecond (op -> args );
803-
804- /* check rel membership of arguments */
805837left_varnos = pull_varnos (left_expr );
806838right_varnos = pull_varnos (right_expr );
839+ all_varnos = bms_union (left_varnos ,right_varnos );
840+
841+ /* Does it reference both sides? */
842+ if (!bms_overlap (all_varnos ,sjinfo -> syn_righthand )||
843+ bms_is_subset (all_varnos ,sjinfo -> syn_righthand ))
844+ {
845+ /*
846+ * Clause refers to only one rel, so ignore it --- unless it
847+ * contains volatile functions, in which case we'd better punt.
848+ */
849+ if (contain_volatile_functions ((Node * )op ))
850+ gotono_unique_path ;
851+ continue ;
852+ }
853+
854+ /* check rel membership of arguments */
807855if (!bms_is_empty (right_varnos )&&
808856bms_is_subset (right_varnos ,sjinfo -> syn_righthand )&&
809857!bms_overlap (left_varnos ,sjinfo -> syn_righthand ))
@@ -845,6 +893,10 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
845893uniq_exprs = lappend (uniq_exprs ,copyObject (right_expr ));
846894}
847895
896+ /* Punt if we didn't find at least one column to unique-ify */
897+ if (uniq_exprs == NIL )
898+ gotono_unique_path ;
899+
848900/*
849901 * The expressions we'd need to unique-ify mustn't be volatile.
850902 */