aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/prep/prepqual.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/prep/prepqual.c')
-rw-r--r--src/backend/optimizer/prep/prepqual.c183
1 files changed, 98 insertions, 85 deletions
diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c
index 4016ba476de..24ea1316e11 100644
--- a/src/backend/optimizer/prep/prepqual.c
+++ b/src/backend/optimizer/prep/prepqual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.34 2002/12/12 15:49:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.35 2003/05/28 22:32:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,8 +21,12 @@
#include "utils/lsyscache.h"
static Expr *flatten_andors(Expr *qual);
-static List *pull_ors(List *orlist);
+static void flatten_andors_and_walker(FastList *out_list, List *andlist);
+static void flatten_andors_or_walker(FastList *out_list, List *orlist);
static List *pull_ands(List *andlist);
+static void pull_ands_walker(FastList *out_list, List *andlist);
+static List *pull_ors(List *orlist);
+static void pull_ors_walker(FastList *out_list, List *orlist);
static Expr *find_nots(Expr *qual);
static Expr *push_nots(Expr *qual);
static Expr *find_ors(Expr *qual);
@@ -291,47 +295,19 @@ flatten_andors(Expr *qual)
if (and_clause((Node *) qual))
{
- List *out_list = NIL;
- List *arg;
+ FastList out_list;
- foreach(arg, ((BoolExpr *) qual)->args)
- {
- Expr *subexpr = flatten_andors((Expr *) lfirst(arg));
-
- /*
- * Note: we can destructively nconc the subexpression's
- * arglist because we know the recursive invocation of
- * flatten_andors will have built a new arglist not shared
- * with any other expr. Otherwise we'd need a listCopy here.
- */
- if (and_clause((Node *) subexpr))
- out_list = nconc(out_list, ((BoolExpr *) subexpr)->args);
- else
- out_list = lappend(out_list, subexpr);
- }
- return make_andclause(out_list);
+ FastListInit(&out_list);
+ flatten_andors_and_walker(&out_list, ((BoolExpr *) qual)->args);
+ return make_andclause(FastListValue(&out_list));
}
else if (or_clause((Node *) qual))
{
- List *out_list = NIL;
- List *arg;
+ FastList out_list;
- foreach(arg, ((BoolExpr *) qual)->args)
- {
- Expr *subexpr = flatten_andors((Expr *) lfirst(arg));
-
- /*
- * Note: we can destructively nconc the subexpression's
- * arglist because we know the recursive invocation of
- * flatten_andors will have built a new arglist not shared
- * with any other expr. Otherwise we'd need a listCopy here.
- */
- if (or_clause((Node *) subexpr))
- out_list = nconc(out_list, ((BoolExpr *) subexpr)->args);
- else
- out_list = lappend(out_list, subexpr);
- }
- return make_orclause(out_list);
+ FastListInit(&out_list);
+ flatten_andors_or_walker(&out_list, ((BoolExpr *) qual)->args);
+ return make_orclause(FastListValue(&out_list));
}
else if (not_clause((Node *) qual))
return make_notclause(flatten_andors(get_notclausearg(qual)));
@@ -351,69 +327,102 @@ flatten_andors(Expr *qual)
return qual;
}
-/*
- * pull_ors
- * Pull the arguments of an 'or' clause nested within another 'or'
- * clause up into the argument list of the parent.
- *
- * Input is the arglist of an OR clause.
- * Returns the rebuilt arglist (note original list structure is not touched).
- */
-static List *
-pull_ors(List *orlist)
+static void
+flatten_andors_and_walker(FastList *out_list, List *andlist)
+{
+ List *arg;
+
+ foreach(arg, andlist)
+ {
+ Expr *subexpr = (Expr *) lfirst(arg);
+
+ if (and_clause((Node *) subexpr))
+ flatten_andors_and_walker(out_list, ((BoolExpr *) subexpr)->args);
+ else
+ FastAppend(out_list, flatten_andors(subexpr));
+ }
+}
+
+static void
+flatten_andors_or_walker(FastList *out_list, List *orlist)
{
- List *out_list = NIL;
List *arg;
foreach(arg, orlist)
{
Expr *subexpr = (Expr *) lfirst(arg);
- /*
- * Note: we can destructively nconc the subexpression's arglist
- * because we know the recursive invocation of pull_ors will have
- * built a new arglist not shared with any other expr. Otherwise
- * we'd need a listCopy here.
- */
if (or_clause((Node *) subexpr))
- out_list = nconc(out_list,
- pull_ors(((BoolExpr *) subexpr)->args));
+ flatten_andors_or_walker(out_list, ((BoolExpr *) subexpr)->args);
else
- out_list = lappend(out_list, subexpr);
+ FastAppend(out_list, flatten_andors(subexpr));
}
- return out_list;
}
/*
* pull_ands
- * Pull the arguments of an 'and' clause nested within another 'and'
- * clause up into the argument list of the parent.
+ * Recursively flatten nested AND clauses into a single and-clause list.
*
- * Returns the modified list.
+ * Input is the arglist of an AND clause.
+ * Returns the rebuilt arglist (note original list structure is not touched).
*/
static List *
pull_ands(List *andlist)
{
- List *out_list = NIL;
+ FastList out_list;
+
+ FastListInit(&out_list);
+ pull_ands_walker(&out_list, andlist);
+ return FastListValue(&out_list);
+}
+
+static void
+pull_ands_walker(FastList *out_list, List *andlist)
+{
List *arg;
foreach(arg, andlist)
{
Expr *subexpr = (Expr *) lfirst(arg);
- /*
- * Note: we can destructively nconc the subexpression's arglist
- * because we know the recursive invocation of pull_ands will have
- * built a new arglist not shared with any other expr. Otherwise
- * we'd need a listCopy here.
- */
if (and_clause((Node *) subexpr))
- out_list = nconc(out_list,
- pull_ands(((BoolExpr *) subexpr)->args));
+ pull_ands_walker(out_list, ((BoolExpr *) subexpr)->args);
+ else
+ FastAppend(out_list, subexpr);
+ }
+}
+
+/*
+ * pull_ors
+ * Recursively flatten nested OR clauses into a single or-clause list.
+ *
+ * Input is the arglist of an OR clause.
+ * Returns the rebuilt arglist (note original list structure is not touched).
+ */
+static List *
+pull_ors(List *orlist)
+{
+ FastList out_list;
+
+ FastListInit(&out_list);
+ pull_ors_walker(&out_list, orlist);
+ return FastListValue(&out_list);
+}
+
+static void
+pull_ors_walker(FastList *out_list, List *orlist)
+{
+ List *arg;
+
+ foreach(arg, orlist)
+ {
+ Expr *subexpr = (Expr *) lfirst(arg);
+
+ if (or_clause((Node *) subexpr))
+ pull_ors_walker(out_list, ((BoolExpr *) subexpr)->args);
else
- out_list = lappend(out_list, subexpr);
+ FastAppend(out_list, subexpr);
}
- return out_list;
}
/*
@@ -447,21 +456,23 @@ find_nots(Expr *qual)
#endif
if (and_clause((Node *) qual))
{
- List *t_list = NIL;
+ FastList t_list;
List *temp;
+ FastListInit(&t_list);
foreach(temp, ((BoolExpr *) qual)->args)
- t_list = lappend(t_list, find_nots(lfirst(temp)));
- return make_andclause(pull_ands(t_list));
+ FastAppend(&t_list, find_nots(lfirst(temp)));
+ return make_andclause(pull_ands(FastListValue(&t_list)));
}
else if (or_clause((Node *) qual))
{
- List *t_list = NIL;
+ FastList t_list;
List *temp;
+ FastListInit(&t_list);
foreach(temp, ((BoolExpr *) qual)->args)
- t_list = lappend(t_list, find_nots(lfirst(temp)));
- return make_orclause(pull_ors(t_list));
+ FastAppend(&t_list, find_nots(lfirst(temp)));
+ return make_orclause(pull_ors(FastListValue(&t_list)));
}
else if (not_clause((Node *) qual))
return push_nots(get_notclausearg(qual));
@@ -511,21 +522,23 @@ push_nots(Expr *qual)
* i.e., swap AND for OR and negate all the subclauses.
*--------------------
*/
- List *t_list = NIL;
+ FastList t_list;
List *temp;
+ FastListInit(&t_list);
foreach(temp, ((BoolExpr *) qual)->args)
- t_list = lappend(t_list, push_nots(lfirst(temp)));
- return make_orclause(pull_ors(t_list));
+ FastAppend(&t_list, push_nots(lfirst(temp)));
+ return make_orclause(pull_ors(FastListValue(&t_list)));
}
else if (or_clause((Node *) qual))
{
- List *t_list = NIL;
+ FastList t_list;
List *temp;
+ FastListInit(&t_list);
foreach(temp, ((BoolExpr *) qual)->args)
- t_list = lappend(t_list, push_nots(lfirst(temp)));
- return make_andclause(pull_ands(t_list));
+ FastAppend(&t_list, push_nots(lfirst(temp)));
+ return make_andclause(pull_ands(FastListValue(&t_list)));
}
else if (not_clause((Node *) qual))
{