*
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.104.4.1 2005/09/28 21:17:23 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.104.4.2 2007/10/04 20:45:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
        }
 }
 
+/*
+ * add_IN_vars_to_tlists
+ *       Add targetlist entries for each var needed in InClauseInfo entries
+ *       to the appropriate base relations.
+ *
+ * Normally this is a waste of time because scanning of the WHERE clause
+ * will have added them.  But it is possible that eval_const_expressions()
+ * simplified away all references to the vars after the InClauseInfos were
+ * made.  We need the IN's righthand-side vars to be available at the join
+ * anyway, in case we try to unique-ify the subselect's outputs.  (The only
+ * known case that provokes this is "WHERE false AND foo IN (SELECT ...)".
+ * We don't try to be very smart about such cases, just correct.)
+ */
+void
+add_IN_vars_to_tlists(Query *root)
+{
+       ListCell   *l;
+
+       foreach(l, root->in_info_list)
+       {
+               InClauseInfo *ininfo = (InClauseInfo *) lfirst(l);
+               List       *in_vars;
+
+               in_vars = pull_var_clause((Node *) ininfo->sub_targetlist, false);
+               if (in_vars != NIL)
+               {
+                       add_vars_to_targetlist(root, in_vars,
+                                                                  bms_union(ininfo->lefthand,
+                                                                                        ininfo->righthand));
+                       list_free(in_vars);
+               }
+       }
+}
+
 /*
  * add_vars_to_targetlist
  *       For each variable appearing in the list, add it to the owning
 
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.81.4.1 2005/09/28 21:17:23 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.81.4.2 2007/10/04 20:45:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
        (void) distribute_quals_to_rels(root, (Node *) root->jointree, false);
 
+       /*
+        * Vars mentioned in InClauseInfo items also have to be added to baserel
+        * targetlists.  Nearly always, they'd have got there from the original
+        * WHERE qual, but in corner cases maybe not.
+        */
+       add_IN_vars_to_tlists(root);
+
        /*
         * Use the completed lists of equijoined keys to deduce any implied
         * but unstated equalities (for example, A=B and B=C imply A=C).
 
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.79.4.1 2005/09/28 21:17:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.79.4.2 2007/10/04 20:45:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
  */
 extern void add_base_rels_to_query(Query *root, Node *jtnode);
 extern void build_base_rel_tlists(Query *root, List *final_tlist);
+extern void add_IN_vars_to_tlists(Query *root);
 extern Relids distribute_quals_to_rels(Query *root, Node *jtnode,
                                                                           bool below_outer_join);
 extern void process_implied_equality(Query *root,