Fix #42 - Wrong behaviour of negative constraints in and-Groups of VCs

Change-Id: Ibfc07544d98c5b169ec337d5d8b7b4ae683d15b8
diff --git a/Changes b/Changes
index 74f0474..4ec8f1c 100644
--- a/Changes
+++ b/Changes
@@ -1,12 +1,17 @@
-0.58.0 2018-08-13
-    - Implemented referencing cached collection (margaretha)
-    - Implemented deserialization of collection with array values and cache option (margaretha)
-    - Implemented caching collection (margaretha)
-    - Implemented KrillCollection cache clearing (margaretha)
-    - Implemented auto-caching (margaretha)
-    - Implemented serializable doc bits vector for caching on disk (margaretha)
-    - Added check for non-existing doc bit vector in the cache (margaretha)
-    - Implemented custom namedVC path (margaretha)
+0.58.0 2018-08-15
+    - [feature] Implemented referencing cached collection (margaretha)
+    - [feature] Implemented deserialization of collection with array values
+      and cache option (margaretha)
+    - [feature] Implemented caching collection (margaretha)
+    - [feature] Implemented KrillCollection cache clearing (margaretha)
+    - [feature] Implemented auto-caching for VC (margaretha)
+    - [feature] Implemented serializable doc bits vector for VC caching
+      on disk (margaretha)
+    - [feature] Added check for non-existing doc bit vector in the cache
+      (margaretha)
+    - [feature] Implemented custom namedVC path (margaretha)
+    - [bugfix] Fix wrong behaviour of negative constraints in and-Groups
+      of VCs (#42; diewald)
 
 0.57 2018-04-05
     - [feature] Support text queries in metadata
diff --git a/src/main/java/de/ids_mannheim/korap/collection/BooleanGroupFilter.java b/src/main/java/de/ids_mannheim/korap/collection/BooleanGroupFilter.java
index 475b5be..5791703 100644
--- a/src/main/java/de/ids_mannheim/korap/collection/BooleanGroupFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/collection/BooleanGroupFilter.java
@@ -122,14 +122,6 @@
     };
 
 
-    /*
-    @Override
-    public String toString (String str) {
-        return this.toString();
-    };
-    */
-
-
     @Override
     public DocIdSet getDocIdSet (LeafReaderContext context, Bits acceptDocs)
             throws IOException {
@@ -160,22 +152,22 @@
                 // Filter matches
                 if (operand.isNegative) {
 
-                    // This means, everything is allowed
-                    if (this.isOptional) {
+					if (DEBUG) {
+						// OR - This means, everything is allowed
+						if (this.isOptional) {
+                            log.debug("- Filter to allow all documents (OR NEG NULL)");
 
-                        // Everything is allowed
-                        if (DEBUG)
-                            log.debug("- Filter to allow all documents");
+						}
+						// AND - The negation is irrelevant
+						else {
+							log.debug("- Filter to allow all documents (AND NEG NULL)");
+						};
+					};
 
-                        bitset.set(0, maxDoc);
-                        return BitsFilteredDocIdSet
-                                .wrap(new BitDocIdSet(bitset), acceptDocs);
-                    };
 
-                    // There is no possible match
-                    if (DEBUG)
-                        log.debug("- Filter to allow no documents (1)");
-                    return null;
+					bitset.set(0, maxDoc);
+					return BitsFilteredDocIdSet
+						.wrap(new BitDocIdSet(bitset), acceptDocs);
                 }
 
                 // The result is unimportant
diff --git a/src/test/java/de/ids_mannheim/korap/collection/TestCollectionBuilder.java b/src/test/java/de/ids_mannheim/korap/collection/TestCollectionBuilder.java
index 4207e6c..c9c7711 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestCollectionBuilder.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestCollectionBuilder.java
@@ -123,6 +123,14 @@
                         .with(kc.term("title", "name")).toString());
     };
 
+    @Test
+    public void builderAndCombinedNeg () throws IOException {
+        CollectionBuilder kc = new CollectionBuilder();
+        assertEquals("AndGroup(author:tree -title:name)",
+                kc.andGroup().with(kc.term("author", "tree"))
+					 .with(kc.term("title", "name").not()).toString());
+    };
+	
 
     @Test
     public void builderAndNestedSimple () throws IOException {
diff --git a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
index 9a55e65..d874905 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
@@ -809,6 +809,54 @@
         assertEquals("Paragraphs", 75, ki.numberOf("paragraphs"));
     };
 
+	@Test
+    public void testKrillCollectionWithNonexistingNegation () throws IOException {
+        ki = new KrillIndex();
+        ki.addDoc(createDoc1()); // nachricht kultur reisen
+        ki.addDoc(createDoc3()); // reisen finanzen
+        ki.commit();
+
+        KrillCollection kc = new KrillCollection(ki);
+        CollectionBuilder cb = kc.build();
+
+		kc.fromBuilder(cb.term("textClass","reisen"));
+		assertEquals(kc.toString(), "textClass:reisen");
+        assertEquals("Documents", 2, kc.numberOf("documents"));
+
+		kc.fromBuilder(cb.andGroup().with(
+						   cb.term("textClass","reisen")
+						   ).with(
+							   cb.term("textClass","nachricht").not()
+							   ));
+		assertEquals(kc.toString(), "AndGroup(textClass:reisen -textClass:nachricht)");
+        assertEquals("Documents", 1, kc.numberOf("documents"));
+
+		
+		kc.fromBuilder(cb.andGroup().with(
+						   cb.term("textClass","reisen")
+						   ).with(
+							   cb.term("textClass","reisen").not()
+							   ));
+		assertEquals(kc.toString(), "AndGroup(textClass:reisen -textClass:reisen)");
+        assertEquals("Documents", 0, kc.numberOf("documents"));
+
+		kc.fromBuilder(cb.andGroup().with(
+						   cb.term("textClass","kultur")
+						   ).with(
+							   cb.term("textClass","finanzen").not()
+							   ));
+		assertEquals(kc.toString(), "AndGroup(textClass:kultur -textClass:finanzen)");
+        assertEquals("Documents", 1, kc.numberOf("documents"));
+
+		kc.fromBuilder(cb.andGroup().with(
+						   cb.term("textClass","reisen")
+						   ).with(
+							   cb.term("textClass","Blabla").not()
+							   ));
+		assertEquals(kc.toString(), "AndGroup(textClass:reisen -textClass:Blabla)");
+        assertEquals("Documents", 2, kc.numberOf("documents"));
+    }
+
 
     private FieldDocument createDoc1 () {
         FieldDocument fd = new FieldDocument();