Index: matcher/orpostlist.h
===================================================================
--- matcher/orpostlist.h	(revision 14974)
+++ matcher/orpostlist.h	(working copy)
@@ -37,6 +37,7 @@
 class OrPostList : public BranchPostList {
     private:
         Xapian::docid lhead, rhead;
+	bool lvalid, rvalid;
         Xapian::weight lmax, rmax, minmax;
 	Xapian::doccount dbsize;
     public:
Index: matcher/orpostlist.cc
===================================================================
--- matcher/orpostlist.cc	(revision 14974)
+++ matcher/orpostlist.cc	(working copy)
@@ -37,7 +37,8 @@
 		       MultiMatch *matcher_,
 		       Xapian::doccount dbsize_)
 	: BranchPostList(left_, right_, matcher_),
-	  lhead(0), rhead(0), lmax(0), rmax(0), minmax(0), dbsize(dbsize_)
+	  lhead(0), rhead(0), lvalid(false), rvalid(false),
+	  lmax(0), rmax(0), minmax(0), dbsize(dbsize_)
 {
     LOGCALL_CTOR(MATCH, "OrPostList", left_ | right_ | matcher_ | dbsize_);
     AssertRel(left_->get_termfreq_est(),>=,right_->get_termfreq_est());
@@ -55,7 +56,7 @@
 		LOGLINE(MATCH, "OR -> AND");
 		ret = new MultiAndPostList(l, r, lmax, rmax, matcher, dbsize);
 		Xapian::docid newdocid = std::max(lhead, rhead);
-		if (lhead == rhead) {
+		if (newdocid == 0 || (lvalid && rvalid && lhead == rhead)) {
 		    ++newdocid;
 		}
 		skip_to_handling_prune(ret, newdocid, w_min, matcher);
@@ -91,11 +92,12 @@
     }
 
     bool ldry = false;
-    bool rnext = false;
+    bool rnext = !rvalid;
 
-    if (lhead <= rhead) {
+    if (!lvalid || lhead <= rhead) {
         if (lhead == rhead) rnext = true;
         next_handling_prune(l, w_min - rmax, matcher);
+	lvalid = true;
 	if (l->at_end()) ldry = true;
     } else {
 	rnext = true;
@@ -103,6 +105,7 @@
 
     if (rnext) {
         next_handling_prune(r, w_min - lmax, matcher);
+	rvalid = true;
         if (r->at_end()) {
 	    PostList *ret = l;
 	    l = NULL;
@@ -160,11 +163,13 @@
     bool ldry = false;
     if (lhead < did) {
 	skip_to_handling_prune(l, did, w_min - rmax, matcher);
+	lvalid = true;
 	ldry = l->at_end();
     }
 
     if (rhead < did) {
 	skip_to_handling_prune(r, did, w_min - lmax, matcher);
+	rvalid = true;
 
 	if (r->at_end()) {
 	    PostList *ret = l;
@@ -219,14 +224,14 @@
     }
 
     bool ldry = false;
-    bool lvalid = false;
-    bool rvalid = false;
-    if (lhead <= did) {
+    if (!lvalid || lhead < did) {
+	lvalid = false;
 	check_handling_prune(l, did, w_min - rmax, matcher, lvalid);
 	ldry = l->at_end();
     }
 
-    if (rhead <= did) {
+    if (!rvalid || rhead <= did) {
+	rvalid = false;
 	check_handling_prune(r, did, w_min - lmax, matcher, rvalid);
 
 	if (r->at_end()) {

