diff options
author | Tom Lane | 2014-09-09 22:35:14 +0000 |
---|---|---|
committer | Tom Lane | 2014-09-09 22:35:31 +0000 |
commit | 1b4cc493d2b5216c14ba3ee781cbeff56f96d1b7 (patch) | |
tree | b3917cb1ce2344bbd8b2fee6a3fb9d81e3a4091e /src/backend/optimizer/util/orclauses.c | |
parent | 07c8651dd91d5aea38bee268acb582674ca4b5ea (diff) |
Preserve AND/OR flatness while extracting restriction OR clauses.
The code I added in commit f343a880d5555faf1dad0286c5632047c8f599ad was
careless about preserving AND/OR flatness: it could create a structure with
an OR node directly underneath another one. That breaks an assumption
that's fairly important for planning efficiency, not to mention triggering
various Asserts (as reported by Benjamin Smith). Add a trifle more logic
to handle the case properly.
Diffstat (limited to 'src/backend/optimizer/util/orclauses.c')
-rw-r--r-- | src/backend/optimizer/util/orclauses.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/backend/optimizer/util/orclauses.c b/src/backend/optimizer/util/orclauses.c index 9e954d0d35f..8fecabbcda1 100644 --- a/src/backend/optimizer/util/orclauses.c +++ b/src/backend/optimizer/util/orclauses.c @@ -178,6 +178,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel) { Node *orarg = (Node *) lfirst(lc); List *subclauses = NIL; + Node *subclause; /* OR arguments should be ANDs or sub-RestrictInfos */ if (and_clause(orarg)) @@ -226,9 +227,16 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel) /* * OK, add subclause(s) to the result OR. If we found more than one, - * we need an AND node. + * we need an AND node. But if we found only one, and it is itself an + * OR node, add its subclauses to the result instead; this is needed + * to preserve AND/OR flatness (ie, no OR directly underneath OR). */ - clauselist = lappend(clauselist, make_ands_explicit(subclauses)); + subclause = (Node *) make_ands_explicit(subclauses); + if (or_clause(subclause)) + clauselist = list_concat(clauselist, + list_copy(((BoolExpr *) subclause)->args)); + else + clauselist = lappend(clauselist, subclause); } /* |