aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-04-07 17:05:39 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-04-07 17:05:39 +0000
commit2f8a7bf2909f7434402a9066d258f74f3e132eb4 (patch)
treedce7d88e089068b25fbcedfe4c87a1b35862617c /src
parent0914ae1c1481c2721d57d1c4c3da95a1e0582f7a (diff)
downloadpostgresql-2f8a7bf2909f7434402a9066d258f74f3e132eb4.tar.gz
postgresql-2f8a7bf2909f7434402a9066d258f74f3e132eb4.zip
Fix make_restrictinfo_from_bitmapqual() to preserve AND/OR flatness of its
output, ie, no OR immediately below an OR. Otherwise we get Asserts or wrong answers for cases such as select * from tenk1 a, tenk1 b where (a.ten = b.ten and (a.unique1 = 100 or a.unique1 = 101)) or (a.hundred = b.hundred and a.unique1 = 42); Per report from Rafael Martinez Guerrero.
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/util/restrictinfo.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index ec7e488b48b..606f77bf900 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.46 2006/03/05 15:58:32 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.47 2006/04/07 17:05:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -160,13 +160,44 @@ make_restrictinfo_from_bitmapqual(Path *bitmapqual,
*/
return NIL;
}
- /* Create AND subclause with RestrictInfos */
- withris = lappend(withris,
- make_ands_explicit(sublist));
- /* And one without */
- sublist = get_actual_clauses(sublist);
- withoutris = lappend(withoutris,
- make_ands_explicit(sublist));
+ /*
+ * If the sublist contains multiple RestrictInfos, we create an
+ * AND subclause. If there's just one, we have to check if it's
+ * an OR clause, and if so flatten it to preserve AND/OR flatness
+ * of our output.
+ *
+ * We construct lists with and without sub-RestrictInfos, so
+ * as not to have to regenerate duplicate RestrictInfos below.
+ */
+ if (list_length(sublist) > 1)
+ {
+ withris = lappend(withris, make_andclause(sublist));
+ sublist = get_actual_clauses(sublist);
+ withoutris = lappend(withoutris, make_andclause(sublist));
+ }
+ else
+ {
+ RestrictInfo *subri = (RestrictInfo *) linitial(sublist);
+
+ Assert(IsA(subri, RestrictInfo));
+ if (restriction_is_or_clause(subri))
+ {
+ BoolExpr *subor = (BoolExpr *) subri->orclause;
+
+ Assert(or_clause((Node *) subor));
+ withris = list_concat(withris,
+ list_copy(subor->args));
+ subor = (BoolExpr *) subri->clause;
+ Assert(or_clause((Node *) subor));
+ withoutris = list_concat(withoutris,
+ list_copy(subor->args));
+ }
+ else
+ {
+ withris = lappend(withris, subri);
+ withoutris = lappend(withoutris, subri->clause);
+ }
+ }
}
/*