You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ju...@apache.org on 2021/07/16 20:22:22 UTC

[lucene-solr] branch branch_8x updated: LUCENE-10026: Fix CombinedFieldQuery equals and hashCode (#212) The previous equals and hashCode methods only compared query terms. This meant that queries on different fields, or with different field weights, were considered the same

This is an automated email from the ASF dual-hosted git repository.

julietibs pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/branch_8x by this push:
     new 2ad2867  LUCENE-10026: Fix CombinedFieldQuery equals and hashCode (#212) The previous equals and hashCode methods only compared query terms. This meant that queries on different fields, or with different field weights, were considered the same
2ad2867 is described below

commit 2ad2867bf28ded4ee3ba00bad04f9ae9fa076de6
Author: Julie Tibshirani <ju...@gmail.com>
AuthorDate: Fri Jul 16 10:07:56 2021 -0700

    LUCENE-10026: Fix CombinedFieldQuery equals and hashCode (#212)
    The previous equals and hashCode methods only compared query terms. This meant
    that queries on different fields, or with different field weights, were
    considered the same
    
    During boolean query rewrites, duplicate clauses are removed. So because equals/
    hashCode was incorrect, rewrites could accidentally drop CombinedFieldQuery
    clauses.
---
 .../apache/lucene/search/CombinedFieldQuery.java   | 29 ++++++++++++++---
 .../lucene/search/TestCombinedFieldQuery.java      | 36 ++++++++++++++++++++++
 2 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/CombinedFieldQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/CombinedFieldQuery.java
index f673711..23d5047 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/CombinedFieldQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/CombinedFieldQuery.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.TreeMap;
 import org.apache.lucene.index.IndexReader;
@@ -128,6 +129,19 @@ public final class CombinedFieldQuery extends Query implements Accountable {
       this.field = field;
       this.weight = weight;
     }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+      FieldAndWeight that = (FieldAndWeight) o;
+      return Float.compare(that.weight, weight) == 0 && Objects.equals(field, that.field);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(field, weight);
+    }
   }
 
   // sorted map for fields.
@@ -193,13 +207,20 @@ public final class CombinedFieldQuery extends Query implements Accountable {
   }
 
   @Override
-  public int hashCode() {
-    return 31 * classHash() + Arrays.hashCode(terms);
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (sameClassAs(o) == false) return false;
+    CombinedFieldQuery that = (CombinedFieldQuery) o;
+    return Objects.equals(fieldAndWeights, that.fieldAndWeights)
+        && Arrays.equals(terms, that.terms);
   }
 
   @Override
-  public boolean equals(Object other) {
-    return sameClassAs(other) && Arrays.equals(terms, ((CombinedFieldQuery) other).terms);
+  public int hashCode() {
+    int result = classHash();
+    result += Objects.hash(fieldAndWeights);
+    result = 31 * result + Arrays.hashCode(terms);
+    return result;
   }
 
   @Override
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestCombinedFieldQuery.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestCombinedFieldQuery.java
index e3bb6a6..0a1880f 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestCombinedFieldQuery.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/search/TestCombinedFieldQuery.java
@@ -73,6 +73,42 @@ public class TestCombinedFieldQuery extends LuceneTestCase {
     assertEquals(actual, query);
   }
 
+  public void testEqualsAndHashCode() {
+    CombinedFieldQuery query1 =
+        new CombinedFieldQuery.Builder()
+            .addField("field1")
+            .addField("field2")
+            .addTerm(new BytesRef("value"))
+            .build();
+
+    CombinedFieldQuery query2 =
+        new CombinedFieldQuery.Builder()
+            .addField("field1")
+            .addField("field2", 1.3f)
+            .addTerm(new BytesRef("value"))
+            .build();
+    assertNotEquals(query1, query2);
+    assertNotEquals(query1.hashCode(), query2.hashCode());
+
+    CombinedFieldQuery query3 =
+        new CombinedFieldQuery.Builder()
+            .addField("field3")
+            .addField("field4")
+            .addTerm(new BytesRef("value"))
+            .build();
+    assertNotEquals(query1, query3);
+    assertNotEquals(query1.hashCode(), query2.hashCode());
+
+    CombinedFieldQuery duplicateQuery1 =
+        new CombinedFieldQuery.Builder()
+            .addField("field1")
+            .addField("field2")
+            .addTerm(new BytesRef("value"))
+            .build();
+    assertEquals(query1, duplicateQuery1);
+    assertEquals(query1.hashCode(), duplicateQuery1.hashCode());
+  }
+
   public void testToString() {
     assertEquals("CombinedFieldQuery(()())", new CombinedFieldQuery.Builder().build().toString());
     CombinedFieldQuery.Builder builder = new CombinedFieldQuery.Builder();