aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/orclauses.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/orclauses.c')
-rw-r--r--src/backend/optimizer/util/orclauses.c12
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);
}
/*