Index: src/backend/optimizer/prep/prepjointree.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/optimizer/prep/prepjointree.c,v retrieving revision 1.7 diff -u -r1.7 prepjointree.c --- src/backend/optimizer/prep/prepjointree.c 2003/03/10 03:53:50 1.7 +++ src/backend/optimizer/prep/prepjointree.c 2003/05/03 07:25:10 @@ -745,10 +745,7 @@ * * We don't use expression_tree_walker here because we don't want to * descend through very many kinds of nodes; only the ones we can be sure - * are strict. We can descend through the top level of implicit AND'ing, - * but not through any explicit ANDs (or ORs) below that, since those are not - * strict constructs. The List case handles the top-level implicit AND list - * as well as lists of arguments to strict operators/functions. + * are strict. */ static Relids find_nonnullable_rels(Node *node, bool top_level) @@ -791,10 +788,45 @@ else if (IsA(node, BoolExpr)) { BoolExpr *expr = (BoolExpr *) node; + List *l; - /* NOT is strict, others are not */ - if (expr->boolop == NOT_EXPR) - result = find_nonnullable_rels((Node *) expr->args, false); + switch (expr->boolop) { + case AND_EXPR: + /* All nonnullable rels from the AND are nonnullable at this + * level. + */ + foreach(l, expr->args) + { + result = bms_join(result, find_nonnullable_rels(lfirst(l), + top_level)); + } + break; + case OR_EXPR: + /* For OR, a rel is nonnullable only if it is nonnullable for + * all of the expressions making up the BoolExpr. + */ + result = find_nonnullable_rels(lfirst(expr->args), + top_level); + foreach(l, lnext(expr->args)) + { + /* If the set is empty, then nothing further will help */ + if (bms_is_empty(result)) + break; + + result = bms_int_members(result, find_nonnullable_rels(lfirst(l), + top_level)); + } + break; + case NOT_EXPR: + /* The NOT doesn't change the nullability of the rels, except + * for IS NOT NULL, which is handled below + */ + result = find_nonnullable_rels((Node *) expr->args, false); + break; + default: + elog(ERROR, "find_nonnullable_rels: unknown boolop %d", + expr->boolop); + } } else if (IsA(node, RelabelType)) {