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.c980
1 files changed, 530 insertions, 450 deletions
diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c
index 148f9638089..eac1eafa44f 100644
--- a/src/backend/optimizer/prep/prepqual.c
+++ b/src/backend/optimizer/prep/prepqual.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* prepqual.c--
- * Routines for preprocessing the parse tree qualification
+ * Routines for preprocessing the parse tree qualification
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.3 1997/08/20 14:53:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.4 1997/09/07 04:44:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,531 +24,608 @@
#include "utils/lsyscache.h"
-static Expr *pull_args(Expr *qual);
-static List *pull_ors(List *orlist);
-static List *pull_ands(List *andlist);
-static Expr *find_nots(Expr *qual);
-static Expr *push_nots(Expr *qual);
-static Expr *normalize(Expr *qual);
-static List *or_normalize(List *orlist);
-static List *distribute_args(List *item, List *args);
-static List *qualcleanup(Expr *qual);
-static List *remove_ands(Expr *qual);
-static List *remove_duplicates(List *list);
-
-/*
+static Expr *pull_args(Expr * qual);
+static List *pull_ors(List * orlist);
+static List *pull_ands(List * andlist);
+static Expr *find_nots(Expr * qual);
+static Expr *push_nots(Expr * qual);
+static Expr *normalize(Expr * qual);
+static List *or_normalize(List * orlist);
+static List *distribute_args(List * item, List * args);
+static List *qualcleanup(Expr * qual);
+static List *remove_ands(Expr * qual);
+static List *remove_duplicates(List * list);
+
+/*
* preprocess-qualification--
- * Driver routine for modifying the parse tree qualification.
- *
+ * Driver routine for modifying the parse tree qualification.
+ *
* Returns the new base qualification and the existential qualification
* in existentialQualPtr.
- *
- * XXX right now, update_clauses() does nothing so
- * preprocess-qualification simply converts the qual in conjunctive
- * normal form (see cnfify() below )
+ *
+ * XXX right now, update_clauses() does nothing so
+ * preprocess-qualification simply converts the qual in conjunctive
+ * normal form (see cnfify() below )
*/
-List *
-preprocess_qualification(Expr *qual, List *tlist, List **existentialQualPtr)
+List *
+preprocess_qualification(Expr * qual, List * tlist, List ** existentialQualPtr)
{
- List *cnf_qual = cnfify(qual, true);
+ List *cnf_qual = cnfify(qual, true);
+
/*
- List *existential_qual =
- update_clauses(intCons(_query_result_relation_,
- update_relations(tlist)),
- cnf_qual,
- _query_command_type_);
- if (existential_qual) {
- *existentialQualPtr = existential_qual;
- return set_difference(cnf_qual, existential_qual);
- } else {
+ List *existential_qual =
+ update_clauses(intCons(_query_result_relation_,
+ update_relations(tlist)),
+ cnf_qual,
+ _query_command_type_);
+ if (existential_qual) {
+ *existentialQualPtr = existential_qual;
+ return set_difference(cnf_qual, existential_qual);
+ } else {
+ *existentialQualPtr = NIL;
+ return cnf_qual;
+ }
+*/
+ /* update_clauses() is not working right now */
*existentialQualPtr = NIL;
return cnf_qual;
- }
-*/
- /* update_clauses() is not working right now */
- *existentialQualPtr = NIL;
- return cnf_qual;
}
/*****************************************************************************
*
- * CNF CONVERSION ROUTINES
- *
- * NOTES:
- * The basic algorithms for normalizing the qualification are taken
- * from ingres/source/qrymod/norml.c
- *
- * Remember that the initial qualification may consist of ARBITRARY
- * combinations of clauses. In addition, before this routine is called,
- * the qualification will contain explicit "AND"s.
- *
+ * CNF CONVERSION ROUTINES
+ *
+ * NOTES:
+ * The basic algorithms for normalizing the qualification are taken
+ * from ingres/source/qrymod/norml.c
+ *
+ * Remember that the initial qualification may consist of ARBITRARY
+ * combinations of clauses. In addition, before this routine is called,
+ * the qualification will contain explicit "AND"s.
+ *
*****************************************************************************/
-/*
+/*
* cnfify--
- * Convert a qualification to conjunctive normal form by applying
- * successive normalizations.
- *
+ * Convert a qualification to conjunctive normal form by applying
+ * successive normalizations.
+ *
* Returns the modified qualification with an extra level of nesting.
*
* If 'removeAndFlag' is true then it removes the explicit ANDs.
*
* NOTE: this routine is called by the planner (removeAndFlag = true)
- * and from the rule manager (removeAndFlag = false).
+ * and from the rule manager (removeAndFlag = false).
*
*/
-List *
-cnfify(Expr *qual, bool removeAndFlag)
+List *
+cnfify(Expr * qual, bool removeAndFlag)
{
- Expr *newqual = NULL;
-
- if (qual != NULL) {
- newqual = find_nots(pull_args(qual));
- newqual = normalize(pull_args(newqual));
- newqual = (Expr*)qualcleanup(pull_args(newqual));
- newqual = pull_args(newqual);;
-
- if (removeAndFlag) {
- if(and_clause((Node*)newqual))
- newqual=(Expr*)remove_ands(newqual);
- else
- newqual=(Expr*)remove_ands(make_andclause(lcons(newqual,NIL)));
- }
- }
- else if (qual!=NULL)
- newqual = (Expr*)lcons(qual, NIL);
-
- return (List*)(newqual);
+ Expr *newqual = NULL;
+
+ if (qual != NULL)
+ {
+ newqual = find_nots(pull_args(qual));
+ newqual = normalize(pull_args(newqual));
+ newqual = (Expr *) qualcleanup(pull_args(newqual));
+ newqual = pull_args(newqual);;
+
+ if (removeAndFlag)
+ {
+ if (and_clause((Node *) newqual))
+ newqual = (Expr *) remove_ands(newqual);
+ else
+ newqual = (Expr *) remove_ands(make_andclause(lcons(newqual, NIL)));
+ }
+ }
+ else if (qual != NULL)
+ newqual = (Expr *) lcons(qual, NIL);
+
+ return (List *) (newqual);
}
-/*
+/*
* pull-args--
- * Given a qualification, eliminate nested 'and' and 'or' clauses.
- *
+ * Given a qualification, eliminate nested 'and' and 'or' clauses.
+ *
* Returns the modified qualification.
- *
+ *
*/
-static Expr *
-pull_args(Expr *qual)
+static Expr *
+pull_args(Expr * qual)
{
- if (qual==NULL)
- return (NULL);
-
- if (is_opclause((Node*)qual)) {
- return(make_clause(qual->opType, qual->oper,
- lcons(pull_args((Expr*)get_leftop(qual)),
- lcons(pull_args((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args)
- t_list = lappend (t_list, pull_args(lfirst(temp)));
- return (make_andclause (pull_ands (t_list)));
- }else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args)
- t_list = lappend (t_list, pull_args(lfirst(temp)));
- return (make_orclause (pull_ors (t_list)));
- } else if (not_clause((Node*)qual)) {
- return (make_notclause (pull_args (get_notclausearg (qual))));
- } else {
- return (qual);
- }
+ if (qual == NULL)
+ return (NULL);
+
+ if (is_opclause((Node *) qual))
+ {
+ return (make_clause(qual->opType, qual->oper,
+ lcons(pull_args((Expr *) get_leftop(qual)),
+ lcons(pull_args((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, pull_args(lfirst(temp)));
+ return (make_andclause(pull_ands(t_list)));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, pull_args(lfirst(temp)));
+ return (make_orclause(pull_ors(t_list)));
+ }
+ else if (not_clause((Node *) qual))
+ {
+ return (make_notclause(pull_args(get_notclausearg(qual))));
+ }
+ else
+ {
+ return (qual);
+ }
}
-/*
+/*
* pull-ors--
- * Pull the arguments of an 'or' clause nested within another 'or'
- * clause up into the argument list of the parent.
- *
+ * Pull the arguments of an 'or' clause nested within another 'or'
+ * clause up into the argument list of the parent.
+ *
* Returns the modified list.
*/
-static List *
-pull_ors(List *orlist)
+static List *
+pull_ors(List * orlist)
{
- if (orlist==NIL)
- return (NIL);
+ if (orlist == NIL)
+ return (NIL);
- if (or_clause(lfirst(orlist))) {
- List *args = ((Expr*)lfirst(orlist))->args;
- return (pull_ors(nconc(copyObject((Node*)args),
- copyObject((Node*)lnext(orlist)))));
- } else {
- return (lcons(lfirst(orlist), pull_ors(lnext(orlist))));
- }
+ if (or_clause(lfirst(orlist)))
+ {
+ List *args = ((Expr *) lfirst(orlist))->args;
+
+ return (pull_ors(nconc(copyObject((Node *) args),
+ copyObject((Node *) lnext(orlist)))));
+ }
+ else
+ {
+ return (lcons(lfirst(orlist), pull_ors(lnext(orlist))));
+ }
}
-/*
+/*
* pull-ands--
- * Pull the arguments of an 'and' clause nested within another 'and'
- * clause up into the argument list of the parent.
- *
+ * Pull the arguments of an 'and' clause nested within another 'and'
+ * clause up into the argument list of the parent.
+ *
* Returns the modified list.
*/
-static List *
-pull_ands(List *andlist)
+static List *
+pull_ands(List * andlist)
{
- if (andlist==NIL)
- return (NIL);
+ if (andlist == NIL)
+ return (NIL);
+
+ if (and_clause(lfirst(andlist)))
+ {
+ List *args = ((Expr *) lfirst(andlist))->args;
- if (and_clause (lfirst(andlist))) {
- List *args = ((Expr*)lfirst(andlist))->args;
- return (pull_ands(nconc(copyObject((Node*)args),
- copyObject((Node*)lnext(andlist)))));
- } else {
- return (lcons(lfirst(andlist), pull_ands(lnext(andlist))));
- }
+ return (pull_ands(nconc(copyObject((Node *) args),
+ copyObject((Node *) lnext(andlist)))));
+ }
+ else
+ {
+ return (lcons(lfirst(andlist), pull_ands(lnext(andlist))));
+ }
}
-/*
+/*
* find-nots--
- * Traverse the qualification, looking for 'not's to take care of.
- * For 'not' clauses, remove the 'not' and push it down to the clauses'
- * descendants.
- * For all other clause types, simply recurse.
- *
+ * Traverse the qualification, looking for 'not's to take care of.
+ * For 'not' clauses, remove the 'not' and push it down to the clauses'
+ * descendants.
+ * For all other clause types, simply recurse.
+ *
* Returns the modified qualification.
- *
+ *
*/
-static Expr *
-find_nots(Expr *qual)
+static Expr *
+find_nots(Expr * qual)
{
- if (qual==NULL)
- return (NULL);
-
- if (is_opclause((Node*)qual)) {
- return (make_clause(qual->opType, qual->oper,
- lcons(find_nots((Expr*)get_leftop(qual)),
- lcons(find_nots((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause ((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args) {
- t_list = lappend(t_list,find_nots(lfirst(temp)));
- }
-
- return (make_andclause(t_list));
- } else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args) {
- t_list = lappend(t_list,find_nots(lfirst(temp)));
- }
- return (make_orclause (t_list));
- } else if (not_clause((Node*)qual))
- return (push_nots(get_notclausearg (qual)));
- else
- return (qual);
+ if (qual == NULL)
+ return (NULL);
+
+ if (is_opclause((Node *) qual))
+ {
+ return (make_clause(qual->opType, qual->oper,
+ lcons(find_nots((Expr *) get_leftop(qual)),
+ lcons(find_nots((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, find_nots(lfirst(temp)));
+ }
+
+ return (make_andclause(t_list));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, find_nots(lfirst(temp)));
+ }
+ return (make_orclause(t_list));
+ }
+ else if (not_clause((Node *) qual))
+ return (push_nots(get_notclausearg(qual)));
+ else
+ return (qual);
}
-/*
+/*
* push-nots--
- * Negate the descendants of a 'not' clause.
- *
+ * Negate the descendants of a 'not' clause.
+ *
* Returns the modified qualification.
- *
+ *
*/
-static Expr *
-push_nots(Expr *qual)
+static Expr *
+push_nots(Expr * qual)
{
- if (qual==NULL)
- return (NULL);
-
- /*
- * Negate an operator clause if possible:
- * ("NOT" (< A B)) => (> A B)
- * Otherwise, retain the clause as it is (the 'not' can't be pushed
- * down any farther).
- */
- if (is_opclause((Node*)qual)) {
- Oper *oper = (Oper*)((Expr*)qual)->oper;
- Oid negator = get_negator(oper->opno);
-
- if(negator) {
- Oper *op = (Oper*) makeOper(negator,
- InvalidOid,
- oper->opresulttype,
- 0, NULL);
- op->op_fcache = (FunctionCache *) NULL;
- return
- (make_opclause(op, get_leftop(qual), get_rightop(qual)));
- } else {
- return (make_notclause(qual));
- }
- } else if (and_clause((Node*)qual)) {
- /* Apply DeMorgan's Laws:
- * ("NOT" ("AND" A B)) => ("OR" ("NOT" A) ("NOT" B))
- * ("NOT" ("OR" A B)) => ("AND" ("NOT" A) ("NOT" B))
- * i.e., continue negating down through the clause's descendants.
- */
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach(temp, qual->args) {
- t_list = lappend(t_list,push_nots(lfirst(temp)));
- }
- return (make_orclause (t_list));
- } else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach(temp, qual->args) {
- t_list = lappend(t_list,push_nots(lfirst(temp)));
- }
- return (make_andclause (t_list));
- } else if (not_clause((Node*)qual))
- /* Another 'not' cancels this 'not', so eliminate the 'not' and
- * stop negating this branch.
- */
- return (find_nots (get_notclausearg (qual)));
- else
- /* We don't know how to negate anything else, place a 'not' at this
- * level.
+ if (qual == NULL)
+ return (NULL);
+
+ /*
+ * Negate an operator clause if possible: ("NOT" (< A B)) => (> A B)
+ * Otherwise, retain the clause as it is (the 'not' can't be pushed
+ * down any farther).
*/
- return (make_notclause (qual));
+ if (is_opclause((Node *) qual))
+ {
+ Oper *oper = (Oper *) ((Expr *) qual)->oper;
+ Oid negator = get_negator(oper->opno);
+
+ if (negator)
+ {
+ Oper *op = (Oper *) makeOper(negator,
+ InvalidOid,
+ oper->opresulttype,
+ 0, NULL);
+
+ op->op_fcache = (FunctionCache *) NULL;
+ return
+ (make_opclause(op, get_leftop(qual), get_rightop(qual)));
+ }
+ else
+ {
+ return (make_notclause(qual));
+ }
+ }
+ else if (and_clause((Node *) qual))
+ {
+
+ /*
+ * Apply DeMorgan's Laws: ("NOT" ("AND" A B)) => ("OR" ("NOT" A)
+ * ("NOT" B)) ("NOT" ("OR" A B)) => ("AND" ("NOT" A) ("NOT" B))
+ * i.e., continue negating down through the clause's descendants.
+ */
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, push_nots(lfirst(temp)));
+ }
+ return (make_orclause(t_list));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, push_nots(lfirst(temp)));
+ }
+ return (make_andclause(t_list));
+ }
+ else if (not_clause((Node *) qual))
+
+ /*
+ * Another 'not' cancels this 'not', so eliminate the 'not' and
+ * stop negating this branch.
+ */
+ return (find_nots(get_notclausearg(qual)));
+ else
+
+ /*
+ * We don't know how to negate anything else, place a 'not' at
+ * this level.
+ */
+ return (make_notclause(qual));
}
-/*
+/*
* normalize--
- * Given a qualification tree with the 'not's pushed down, convert it
- * to a tree in CNF by repeatedly applying the rule:
- * ("OR" A ("AND" B C)) => ("AND" ("OR" A B) ("OR" A C))
- * bottom-up.
- * Note that 'or' clauses will always be turned into 'and' clauses.
- *
+ * Given a qualification tree with the 'not's pushed down, convert it
+ * to a tree in CNF by repeatedly applying the rule:
+ * ("OR" A ("AND" B C)) => ("AND" ("OR" A B) ("OR" A C))
+ * bottom-up.
+ * Note that 'or' clauses will always be turned into 'and' clauses.
+ *
* Returns the modified qualification.
- *
+ *
*/
-static Expr *
-normalize(Expr *qual)
+static Expr *
+normalize(Expr * qual)
{
- if (qual==NULL)
- return (NULL);
-
- if (is_opclause((Node*)qual)) {
- Expr *expr = (Expr*)qual;
- return (make_clause(expr->opType, expr->oper,
- lcons(normalize((Expr*)get_leftop(qual)),
- lcons(normalize((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args) {
- t_list = lappend(t_list,normalize(lfirst(temp)));
- }
- return (make_andclause (t_list));
- } else if (or_clause((Node*)qual)) {
- /* XXX - let form, maybe incorrect */
- List *orlist = NIL;
- List *temp = NIL;
- bool has_andclause = FALSE;
-
- foreach(temp, qual->args) {
- orlist = lappend(orlist,normalize(lfirst(temp)));
- }
- foreach (temp, orlist) {
- if (and_clause (lfirst(temp))) {
- has_andclause = TRUE;
- break;
- }
- }
- if (has_andclause == TRUE)
- return (make_andclause(or_normalize(orlist)));
- else
- return (make_orclause(orlist));
-
- } else if (not_clause((Node*)qual))
- return (make_notclause (normalize (get_notclausearg (qual))));
- else
- return (qual);
+ if (qual == NULL)
+ return (NULL);
+
+ if (is_opclause((Node *) qual))
+ {
+ Expr *expr = (Expr *) qual;
+
+ return (make_clause(expr->opType, expr->oper,
+ lcons(normalize((Expr *) get_leftop(qual)),
+ lcons(normalize((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, normalize(lfirst(temp)));
+ }
+ return (make_andclause(t_list));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ /* XXX - let form, maybe incorrect */
+ List *orlist = NIL;
+ List *temp = NIL;
+ bool has_andclause = FALSE;
+
+ foreach(temp, qual->args)
+ {
+ orlist = lappend(orlist, normalize(lfirst(temp)));
+ }
+ foreach(temp, orlist)
+ {
+ if (and_clause(lfirst(temp)))
+ {
+ has_andclause = TRUE;
+ break;
+ }
+ }
+ if (has_andclause == TRUE)
+ return (make_andclause(or_normalize(orlist)));
+ else
+ return (make_orclause(orlist));
+
+ }
+ else if (not_clause((Node *) qual))
+ return (make_notclause(normalize(get_notclausearg(qual))));
+ else
+ return (qual);
}
-/*
+/*
* or-normalize--
- * Given a list of exprs which are 'or'ed together, distribute any
- * 'and' clauses.
- *
+ * Given a list of exprs which are 'or'ed together, distribute any
+ * 'and' clauses.
+ *
* Returns the modified list.
- *
+ *
*/
-static List *
-or_normalize(List *orlist)
+static List *
+or_normalize(List * orlist)
{
- List *distributable = NIL;
- List *new_orlist = NIL;
- List *temp = NIL;
-
- if (orlist==NIL)
- return NIL;
-
- foreach(temp, orlist) {
- if (and_clause(lfirst(temp)))
- distributable = lfirst(temp);
- }
- if (distributable)
- new_orlist = LispRemove(distributable,orlist);
-
- if(new_orlist) {
- return
- (or_normalize(lcons(distribute_args(lfirst(new_orlist),
- ((Expr*)distributable)->args),
- lnext(new_orlist))));
- }else {
- return (orlist);
- }
+ List *distributable = NIL;
+ List *new_orlist = NIL;
+ List *temp = NIL;
+
+ if (orlist == NIL)
+ return NIL;
+
+ foreach(temp, orlist)
+ {
+ if (and_clause(lfirst(temp)))
+ distributable = lfirst(temp);
+ }
+ if (distributable)
+ new_orlist = LispRemove(distributable, orlist);
+
+ if (new_orlist)
+ {
+ return
+ (or_normalize(lcons(distribute_args(lfirst(new_orlist),
+ ((Expr *) distributable)->args),
+ lnext(new_orlist))));
+ }
+ else
+ {
+ return (orlist);
+ }
}
-/*
+/*
* distribute-args--
- * Create new 'or' clauses by or'ing 'item' with each element of 'args'.
- * E.g.: (distribute-args A ("AND" B C)) => ("AND" ("OR" A B) ("OR" A C))
- *
+ * Create new 'or' clauses by or'ing 'item' with each element of 'args'.
+ * E.g.: (distribute-args A ("AND" B C)) => ("AND" ("OR" A B) ("OR" A C))
+ *
* Returns an 'and' clause.
- *
+ *
*/
-static List *
-distribute_args(List *item, List *args)
+static List *
+distribute_args(List * item, List * args)
{
- List *or_list = NIL;
- List *n_list = NIL;
- List *temp = NIL;
- List *t_list = NIL;
-
- if (args==NULL)
- return (item);
-
- foreach (temp,args) {
- n_list = or_normalize(pull_ors(lcons(item,
- lcons(lfirst(temp),NIL))));
- or_list = (List*)make_orclause(n_list);
- t_list = lappend(t_list,or_list);
- }
- return ((List*)make_andclause(t_list));
+ List *or_list = NIL;
+ List *n_list = NIL;
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ if (args == NULL)
+ return (item);
+
+ foreach(temp, args)
+ {
+ n_list = or_normalize(pull_ors(lcons(item,
+ lcons(lfirst(temp), NIL))));
+ or_list = (List *) make_orclause(n_list);
+ t_list = lappend(t_list, or_list);
+ }
+ return ((List *) make_andclause(t_list));
}
-/*
+/*
* qualcleanup--
- * Fix up a qualification by removing duplicate entries (left over from
- * normalization), and by removing 'and' and 'or' clauses which have only
- * one valid expr (e.g., ("AND" A) => A).
- *
+ * Fix up a qualification by removing duplicate entries (left over from
+ * normalization), and by removing 'and' and 'or' clauses which have only
+ * one valid expr (e.g., ("AND" A) => A).
+ *
* Returns the modified qualfication.
- *
+ *
*/
-static List *
-qualcleanup(Expr *qual)
+static List *
+qualcleanup(Expr * qual)
{
- if (qual==NULL)
- return (NIL);
-
- if (is_opclause((Node*)qual)) {
- return ((List*)make_clause(qual->opType, qual->oper,
- lcons(qualcleanup((Expr*)get_leftop(qual)),
- lcons(qualcleanup((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
- List *new_and_args = NIL;
-
- foreach(temp, qual->args)
- t_list = lappend(t_list,qualcleanup(lfirst(temp)));
-
- new_and_args = remove_duplicates(t_list);
-
- if(length (new_and_args) > 1)
- return ((List*)make_andclause(new_and_args));
- else
- return (lfirst(new_and_args));
- }
- else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
- List *new_or_args = NIL;
-
- foreach (temp, qual->args)
- t_list = lappend(t_list,qualcleanup(lfirst(temp)));
-
- new_or_args = remove_duplicates(t_list);
-
-
- if(length (new_or_args) > 1)
- return ((List*)make_orclause (new_or_args));
- else
- return (lfirst (new_or_args));
- } else if (not_clause((Node*)qual))
- return ((List*)make_notclause((Expr*)qualcleanup((Expr*)get_notclausearg(qual))));
-
- else
- return ((List*)qual);
+ if (qual == NULL)
+ return (NIL);
+
+ if (is_opclause((Node *) qual))
+ {
+ return ((List *) make_clause(qual->opType, qual->oper,
+ lcons(qualcleanup((Expr *) get_leftop(qual)),
+ lcons(qualcleanup((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+ List *new_and_args = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, qualcleanup(lfirst(temp)));
+
+ new_and_args = remove_duplicates(t_list);
+
+ if (length(new_and_args) > 1)
+ return ((List *) make_andclause(new_and_args));
+ else
+ return (lfirst(new_and_args));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+ List *new_or_args = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, qualcleanup(lfirst(temp)));
+
+ new_or_args = remove_duplicates(t_list);
+
+
+ if (length(new_or_args) > 1)
+ return ((List *) make_orclause(new_or_args));
+ else
+ return (lfirst(new_or_args));
+ }
+ else if (not_clause((Node *) qual))
+ return ((List *) make_notclause((Expr *) qualcleanup((Expr *) get_notclausearg(qual))));
+
+ else
+ return ((List *) qual);
}
-/*
+/*
* remove-ands--
- * Remove the explicit "AND"s from the qualification:
- * ("AND" A B) => (A B)
- *
+ * Remove the explicit "AND"s from the qualification:
+ * ("AND" A B) => (A B)
+ *
* RETURNS : qual
* MODIFIES: qual
*/
-static List *
-remove_ands(Expr *qual)
+static List *
+remove_ands(Expr * qual)
{
- List *t_list = NIL;
-
- if (qual==NULL)
- return (NIL);
- if (is_opclause((Node*)qual)) {
- return ((List*)make_clause(qual->opType, qual->oper,
- lcons(remove_ands((Expr*)get_leftop(qual)),
- lcons(remove_ands((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause((Node*)qual)) {
- List *temp = NIL;
- foreach (temp, qual->args)
- t_list = lappend(t_list,remove_ands(lfirst(temp)));
- return(t_list);
- } else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- foreach (temp, qual->args)
- t_list = lappend(t_list,remove_ands(lfirst(temp)));
- return ((List*)make_orclause((List*)t_list));
- } else if (not_clause((Node*)qual)) {
- return ((List*)make_notclause((Expr*)remove_ands((Expr*)get_notclausearg (qual))));
- } else {
- return ((List*)qual);
- }
+ List *t_list = NIL;
+
+ if (qual == NULL)
+ return (NIL);
+ if (is_opclause((Node *) qual))
+ {
+ return ((List *) make_clause(qual->opType, qual->oper,
+ lcons(remove_ands((Expr *) get_leftop(qual)),
+ lcons(remove_ands((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, remove_ands(lfirst(temp)));
+ return (t_list);
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, remove_ands(lfirst(temp)));
+ return ((List *) make_orclause((List *) t_list));
+ }
+ else if (not_clause((Node *) qual))
+ {
+ return ((List *) make_notclause((Expr *) remove_ands((Expr *) get_notclausearg(qual))));
+ }
+ else
+ {
+ return ((List *) qual);
+ }
}
/*****************************************************************************
*
- * EXISTENTIAL QUALIFICATIONS
+ * EXISTENTIAL QUALIFICATIONS
*
*****************************************************************************/
-/*
+/*
* update-relations--
- * Returns the range table indices (i.e., varnos) for all relations which
- * are referenced in the target list.
- *
+ * Returns the range table indices (i.e., varnos) for all relations which
+ * are referenced in the target list.
+ *
*/
-#ifdef NOT_USED
-static List *
-update_relations(List *tlist)
+#ifdef NOT_USED
+static List *
+update_relations(List * tlist)
{
- return(NIL);
+ return (NIL);
}
+
#endif
/*****************************************************************************
@@ -557,28 +634,31 @@ update_relations(List *tlist)
*
*****************************************************************************/
-static List *
-remove_duplicates(List *list)
+static List *
+remove_duplicates(List * list)
{
- List *i;
- List *j;
- List *result = NIL;
- bool there_exists_duplicate = false;
-
- if (length(list) == 1)
- return(list);
-
- foreach (i, list) {
- if (i != NIL) {
- foreach (j, lnext(i)) {
- if (equal(lfirst(i), lfirst(j)))
- there_exists_duplicate = true;
- }
- if (!there_exists_duplicate)
- result = lappend(result, lfirst(i));
-
- there_exists_duplicate = false;
- }
- }
- return(result);
+ List *i;
+ List *j;
+ List *result = NIL;
+ bool there_exists_duplicate = false;
+
+ if (length(list) == 1)
+ return (list);
+
+ foreach(i, list)
+ {
+ if (i != NIL)
+ {
+ foreach(j, lnext(i))
+ {
+ if (equal(lfirst(i), lfirst(j)))
+ there_exists_duplicate = true;
+ }
+ if (!there_exists_duplicate)
+ result = lappend(result, lfirst(i));
+
+ there_exists_duplicate = false;
+ }
+ }
+ return (result);
}