*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.82 2001/11/05 17:46:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.83 2001/12/10 22:54:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* checking that seems more work than it's worth. In any case, a
* plain DISTINCT is safe to push down past.)
*
- * 3. We do not push down clauses that contain subselects, mainly because
+ * 3. If the subquery has any ITER nodes (ie, functions returning sets)
+ * in its target list, we do not push down any quals, since the quals
+ * might refer to those tlist items, which would mean we'd introduce
+ * functions-returning-sets into the subquery's WHERE/HAVING quals.
+ * (It'd be sufficient to not push down quals that refer to those
+ * particular tlist items, but that's much clumsier to check.)
+ *
+ * 4. We do not push down clauses that contain subselects, mainly because
* I'm not sure it will work correctly (the subplan hasn't yet
* transformed sublinks to subselects).
*
if (subquery->setOperations == NULL &&
subquery->limitOffset == NULL &&
subquery->limitCount == NULL &&
- !has_distinct_on_clause(subquery))
+ !has_distinct_on_clause(subquery) &&
+ !contain_iter_clause((Node *) subquery->targetList))
{
/* OK to consider pushing down individual quals */
List *upperrestrictlist = NIL;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.113 2001/11/05 17:46:26 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.114 2001/12/10 22:54:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
subquery->limitCount)
return false;
+ /*
+ * Don't pull up a subquery that has any set-returning functions in
+ * its targetlist. Otherwise we might well wind up inserting
+ * set-returning functions into places where they mustn't go,
+ * such as quals of higher queries.
+ */
+ if (contain_iter_clause((Node *) subquery->targetList))
+ return false;
+
/*
* Hack: don't try to pull up a subquery with an empty jointree.
* query_planner() will correctly generate a Result plan for a
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.91 2001/11/05 17:46:26 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.92 2001/12/10 22:54:12 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
static bool contain_agg_clause_walker(Node *node, void *context);
static bool pull_agg_clause_walker(Node *node, List **listptr);
+static bool contain_iter_clause_walker(Node *node, void *context);
static bool contain_subplans_walker(Node *node, void *context);
static bool pull_subplans_walker(Node *node, List **listptr);
static bool check_subplans_for_ungrouped_vars_walker(Node *node,
}
+/*****************************************************************************
+ * Iter clause manipulation
+ *****************************************************************************/
+
+/*
+ * contain_iter_clause
+ * Recursively search for Iter nodes within a clause.
+ *
+ * Returns true if any Iter found.
+ *
+ * XXX Iter is a crock. It'd be better to look directly at each function
+ * or operator to see if it can return a set. However, that would require
+ * a lot of extra cycles as things presently stand. The return-type info
+ * for function and operator nodes should be extended to include whether
+ * the return is a set.
+ */
+bool
+contain_iter_clause(Node *clause)
+{
+ return contain_iter_clause_walker(clause, NULL);
+}
+
+static bool
+contain_iter_clause_walker(Node *node, void *context)
+{
+ if (node == NULL)
+ return false;
+ if (IsA(node, Iter))
+ return true; /* abort the tree traversal and return
+ * true */
+ return expression_tree_walker(node, contain_iter_clause_walker, context);
+}
+
/*****************************************************************************
* Subplan clause manipulation
*****************************************************************************/
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: clauses.h,v 1.49 2001/11/05 17:46:34 momjian Exp $
+ * $Id: clauses.h,v 1.50 2001/12/10 22:54:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern bool contain_agg_clause(Node *clause);
extern List *pull_agg_clause(Node *clause);
+extern bool contain_iter_clause(Node *clause);
+
extern bool contain_subplans(Node *clause);
extern List *pull_subplans(Node *clause);
extern void check_subplans_for_ungrouped_vars(Query *query);