From caeabf39309a91997d361b4104bda105d16ae720 Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Wed, 3 May 2023 11:27:33 +0200 Subject: [PATCH] Fix SynonymQuery equals implementation (#12260) The term member of TermAndBoost used to be a Term instance and became a BytesRef with #11941, which means its equals impl won't take the field name into account. The SynonymQuery equals impl needs to be updated accordingly to take the field into account as well, otherwise synonym queries with same term and boost across different fields are equal which is a bug. --- .../org/apache/lucene/search/SynonymQuery.java | 6 ++++-- .../apache/lucene/search/TestSynonymQuery.java | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java b/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java index ca32a7d7bb8..7e314870f9c 100644 --- a/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java @@ -113,7 +113,7 @@ public final class SynonymQuery extends Query { */ private SynonymQuery(TermAndBoost[] terms, String field) { this.terms = Objects.requireNonNull(terms); - this.field = field; + this.field = Objects.requireNonNull(field); } public List getTerms() { @@ -146,7 +146,9 @@ public final class SynonymQuery extends Query { @Override public boolean equals(Object other) { - return sameClassAs(other) && Arrays.equals(terms, ((SynonymQuery) other).terms); + return sameClassAs(other) + && field.equals(((SynonymQuery) other).field) + && Arrays.equals(terms, ((SynonymQuery) other).terms); } @Override diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java index 123307e75f8..ae026a87367 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java @@ -73,6 +73,18 @@ public class TestSynonymQuery extends LuceneTestCase { .addTerm(new Term("field", "c"), 0.2f) .addTerm(new Term("field", "d")) .build()); + + QueryUtils.checkUnequal( + new SynonymQuery.Builder("field").addTerm(new Term("field", "a"), 0.4f).build(), + new SynonymQuery.Builder("field").addTerm(new Term("field", "b"), 0.4f).build()); + + QueryUtils.checkUnequal( + new SynonymQuery.Builder("field").addTerm(new Term("field", "a"), 0.2f).build(), + new SynonymQuery.Builder("field").addTerm(new Term("field", "a"), 0.4f).build()); + + QueryUtils.checkUnequal( + new SynonymQuery.Builder("field1").addTerm(new Term("field1", "b"), 0.4f).build(), + new SynonymQuery.Builder("field2").addTerm(new Term("field2", "b"), 0.4f).build()); } public void testBogusParams() { @@ -127,6 +139,12 @@ public class TestSynonymQuery extends LuceneTestCase { () -> { new SynonymQuery.Builder("field1").addTerm(new Term("field1", "a"), -0f); }); + + expectThrows( + NullPointerException.class, + () -> new SynonymQuery.Builder(null).addTerm(new Term("field1", "a"), -0f)); + + expectThrows(NullPointerException.class, () -> new SynonymQuery.Builder(null).build()); } public void testToString() {