summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/clauses.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/clauses.c')
-rw-r--r--src/backend/optimizer/util/clauses.c136
1 files changed, 103 insertions, 33 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 8d4dae486ac..d429db93a03 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.63 2000/03/21 05:12:12 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.64 2000/04/04 01:21:46 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -43,6 +43,8 @@
static bool contain_agg_clause_walker(Node *node, void *context);
static bool pull_agg_clause_walker(Node *node, List **listptr);
+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,
Query *context);
static int is_single_func(Node *node);
@@ -358,39 +360,9 @@ make_ands_implicit(Expr *clause)
/*****************************************************************************
- * *
- * General clause-manipulating routines *
- * *
+ * Aggregate-function clause manipulation
*****************************************************************************/
-
-/*
- * pull_constant_clauses
- * Scans through a list of qualifications and find those that
- * contain no variables (of the current query level).
- *
- * Returns a list of the constant clauses in constantQual and the remaining
- * quals as the return value.
- *
- */
-List *
-pull_constant_clauses(List *quals, List **constantQual)
-{
- List *q;
- List *constqual = NIL;
- List *restqual = NIL;
-
- foreach(q, quals)
- {
- if (!contain_var_clause(lfirst(q)))
- constqual = lcons(lfirst(q), constqual);
- else
- restqual = lcons(lfirst(q), restqual);
- }
- *constantQual = constqual;
- return restqual;
-}
-
/*
* contain_agg_clause
* Recursively search for Aggref nodes within a clause.
@@ -454,6 +426,68 @@ pull_agg_clause_walker(Node *node, List **listptr)
(void *) listptr);
}
+
+/*****************************************************************************
+ * Subplan clause manipulation
+ *****************************************************************************/
+
+/*
+ * contain_subplans
+ * Recursively search for subplan nodes within a clause.
+ *
+ * If we see a SubLink node, we will return TRUE. This is only possible if
+ * the expression tree hasn't yet been transformed by subselect.c. We do not
+ * know whether the node will produce a true subplan or just an initplan,
+ * but we make the conservative assumption that it will be a subplan.
+ *
+ * Returns true if any subplan found.
+ */
+bool
+contain_subplans(Node *clause)
+{
+ return contain_subplans_walker(clause, NULL);
+}
+
+static bool
+contain_subplans_walker(Node *node, void *context)
+{
+ if (node == NULL)
+ return false;
+ if (is_subplan(node) || IsA(node, SubLink))
+ return true; /* abort the tree traversal and return true */
+ return expression_tree_walker(node, contain_subplans_walker, context);
+}
+
+/*
+ * pull_subplans
+ * Recursively pulls all subplans from an expression tree.
+ *
+ * Returns list of subplan nodes found. Note the nodes themselves are not
+ * copied, only referenced.
+ */
+List *
+pull_subplans(Node *clause)
+{
+ List *result = NIL;
+
+ pull_subplans_walker(clause, &result);
+ return result;
+}
+
+static bool
+pull_subplans_walker(Node *node, List **listptr)
+{
+ if (node == NULL)
+ return false;
+ if (is_subplan(node))
+ {
+ *listptr = lappend(*listptr, ((Expr *) node)->oper);
+ /* fall through to check args to subplan */
+ }
+ return expression_tree_walker(node, pull_subplans_walker,
+ (void *) listptr);
+}
+
/*
* check_subplans_for_ungrouped_vars
* Check for subplans that are being passed ungrouped variables as
@@ -556,6 +590,41 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
}
+/*****************************************************************************
+ * *
+ * General clause-manipulating routines *
+ * *
+ *****************************************************************************/
+
+
+/*
+ * pull_constant_clauses
+ * Scans through a list of qualifications and find those that
+ * contain no variables (of the current query level).
+ *
+ * Returns a list of the constant clauses in constantQual and the remaining
+ * quals as the return value.
+ *
+ */
+List *
+pull_constant_clauses(List *quals, List **constantQual)
+{
+ List *q;
+ List *constqual = NIL;
+ List *restqual = NIL;
+
+ foreach(q, quals)
+ {
+ if (!contain_var_clause(lfirst(q)))
+ constqual = lcons(lfirst(q), constqual);
+ else
+ restqual = lcons(lfirst(q), restqual);
+ }
+ *constantQual = constqual;
+ return restqual;
+}
+
+
/*
* clause_relids_vars
* Retrieves distinct relids and vars appearing within a clause.
@@ -726,7 +795,8 @@ default_results:
* If the given expression is a function of a single relation,
* return the relation number; else return 0
*/
-static int is_single_func(Node *node)
+static int
+is_single_func(Node *node)
{
if (is_funcclause(node))
{