Skip to content

Commit e74d813

Browse files
committed
Bug 37160323 - [37156117->24.09.1] SafeComparator not honoring NullFirst argument
[git-p4: depot-paths = "//dev/coherence-ce/release/coherence-ce-v24.09/": change = 112801]
1 parent 4472e73 commit e74d813

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

prj/coherence-core/src/main/java/com/tangosol/util/comparator/SafeComparator.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
55
* https://oss.oracle.com/licenses/upl.
@@ -19,6 +19,7 @@
1919
import com.tangosol.util.ExternalizableHelper;
2020
import com.tangosol.util.QueryMap;
2121

22+
import com.tangosol.util.ValueExtractor;
2223
import com.tangosol.util.extractor.KeyExtractor;
2324

2425
import com.tangosol.util.function.Remote;
@@ -242,7 +243,15 @@ public static int compareSafe(Comparator comparator, Object o1, Object o2, boole
242243
{
243244
try
244245
{
245-
return comparator.compare(o1, o2);
246+
if (comparator instanceof ValueExtractor)
247+
{
248+
// honor NullFirst; the default abstract implementation goes to the static (with NullFirst == true always) version of compare()
249+
return compareSafe(null, ((ValueExtractor) comparator).extract(o1), ((ValueExtractor) comparator).extract(o2), fNullFirst);
250+
}
251+
else
252+
{
253+
return comparator.compare(o1, o2);
254+
}
246255
}
247256
catch (NullPointerException e) {}
248257
}

prj/test/functional/filter/src/main/java/filter/COH23114Tests.java renamed to prj/test/functional/filter/src/main/java/filter/MiscTests.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
55
* https://oss.oracle.com/licenses/upl.
@@ -8,6 +8,10 @@
88
package filter;
99

1010
import com.oracle.coherence.testing.AbstractFunctionalTest;
11+
import com.tangosol.coherence.config.Config;
12+
import com.tangosol.util.comparator.SafeComparator;
13+
import com.tangosol.util.filter.AlwaysFilter;
14+
import com.tangosol.util.filter.LimitFilter;
1115
import data.Person;
1216

1317
import com.tangosol.net.CacheFactory;
@@ -20,20 +24,24 @@
2024
import com.tangosol.util.filter.AllFilter;
2125
import com.tangosol.util.filter.BetweenFilter;
2226

27+
import java.util.Comparator;
2328
import java.util.HashMap;
2429
import java.util.Map;
2530

31+
import java.util.SortedSet;
2632
import org.junit.BeforeClass;
2733
import org.junit.Test;
34+
2835
import static junit.framework.Assert.fail;
36+
import static org.junit.Assert.assertEquals;
2937

30-
public class COH23114Tests
38+
public class MiscTests
3139
extends AbstractFunctionalTest
3240
{
3341
/**
3442
* Default constructor.
3543
*/
36-
public COH23114Tests()
44+
public MiscTests()
3745
{
3846
super();
3947
}
@@ -50,9 +58,39 @@ public static void _startup()
5058
}
5159

5260
// ----- test methods ---------------------------------------------------
61+
@Test
62+
public void testNullFirst()
63+
{
64+
NamedCache<String, data.repository.Person> cache = CacheFactory.getCache("dist");
65+
66+
Comparator compName = new SafeComparator(new ReflectionExtractor("getName"), false);
67+
68+
cache.clear();
69+
70+
// normal entries
71+
data.repository.Person person1 = new data.repository.Person("111");
72+
person1.setName("Aaaa");
73+
cache.put(person1.getSsn(), person1);
74+
data.repository.Person person2 = new data.repository.Person("222");
75+
person2.setName("Bbbb");
76+
cache.put(person2.getSsn(), person2);
77+
78+
// Person with null name
79+
data.repository.Person person = new data.repository.Person("999");
80+
cache.put(person.getSsn(), person);
81+
82+
SortedSet<Map.Entry<String, data.repository.Person>> s =
83+
(SortedSet) cache.entrySet(new LimitFilter(AlwaysFilter.INSTANCE(), 20), compName);
84+
85+
assertEquals(s.last().getValue().getName(), null);
86+
}
87+
88+
89+
5390
@Test
5491
public void testBetweenFilter()
5592
{
93+
// COH23114 test
5694
ValueExtractor extrFirst = new ReflectionExtractor("getFirstName");
5795
ValueExtractor extrLast = new ReflectionExtractor("getLastName");
5896
ValueExtractor extrYear = new ReflectionExtractor("getBirthYear");

0 commit comments

Comments
 (0)