From a954cf73b0c9d59b764f12dd3239b2dad0cd38ec Mon Sep 17 00:00:00 2001 From: Sergeev Viktor Date: Fri, 3 Jul 2026 20:22:18 +0300 Subject: [PATCH 1/2] change sort function by jsonata realisation and remove test overrides --- .../java/com/dashjoin/jsonata/Functions.java | 77 ++++++++++++------- test/test-overrides.json | 10 --- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/dashjoin/jsonata/Functions.java b/src/main/java/com/dashjoin/jsonata/Functions.java index c564805..b7d3ea2 100644 --- a/src/main/java/com/dashjoin/jsonata/Functions.java +++ b/src/main/java/com/dashjoin/jsonata/Functions.java @@ -1950,38 +1950,59 @@ public static List sort(List arr, Object comparator) { return arr; } - List result = new ArrayList<>(arr); if (comparator != null) { - Comparator comp = new Comparator() { - - @Override - public int compare(Object o1, Object o2) { - try { - Boolean swap = toBoolean(funcApply(comparator, Arrays.asList(o1, o2))); - if (swap == null) - return 0; - if (swap) - return 1; - else - return -1; - } catch (Throwable e) { - // TODO Auto-generated catch block - //e.printStackTrace(); - throw new RuntimeException(e); - } - } - - }; - if (comparator instanceof Comparator) - result.sort((Comparator)comparator); - else - result.sort((Comparator)comp); - } else { - result.sort(null); + if (comparator instanceof Comparator) { + List sorted = new ArrayList<>(arr); + sorted.sort((Comparator) comparator); + return sorted; + } + + Object[] sorted = arr.toArray(); + Object[] buffer = new Object[sorted.length]; + mergeSort(sorted, buffer, 0, sorted.length - 1, comparator); + List result = new ArrayList<>(sorted.length); + Collections.addAll(result, sorted); + return result; } - return result; + List sorted = new ArrayList<>(arr); + sorted.sort(null); + return sorted; + } + + private static void mergeSort(Object[] sorted, Object[] buffer, int lo, int hi, Object jsonataComparator) { + if (lo >= hi) { + return; + } + int mid = (lo + hi) / 2; + mergeSort(sorted, buffer, lo, mid, jsonataComparator); + mergeSort(sorted, buffer, mid + 1, hi, jsonataComparator); + merge(sorted, buffer, lo, mid, hi, jsonataComparator); + } + + private static void merge(Object[] sorted, Object[] buffer, int lo, int mid, int hi, Object jsonataComparator) { + int left = lo, right = mid + 1, writePos = lo; + + while (left <= mid && right <= hi) { + boolean swap; + try { + Boolean sw = toBoolean(funcApply(jsonataComparator, Arrays.asList(sorted[left], sorted[right]))); + swap = Boolean.TRUE.equals(sw); + } catch (Throwable e) { + throw new RuntimeException(e); + } + + if (swap) { + buffer[writePos++] = sorted[right++]; + } else { + buffer[writePos++] = sorted[left++]; + } + } + while (left <= mid) buffer[writePos++] = sorted[left++]; + while (right <= hi) buffer[writePos++] = sorted[right++]; + + System.arraycopy(buffer, lo, sorted, lo, hi - lo + 1); } /** diff --git a/test/test-overrides.json b/test/test-overrides.json index 9ae3a7d..f7e9453 100644 --- a/test/test-overrides.json +++ b/test/test-overrides.json @@ -130,16 +130,6 @@ "alternateResult": "1e+20", "reason": "toString precision should be 15, handled differently by Java Bigdecimal(..., new MathContext(15)" }, - { - "name": "function-sort/case009.json", - "alternateResult": ["0406634348", "040657863", "0406654608", "0406654603"], - "reason": "the sort expression is evaluated correctly - however the sort algorithm seems to behave slightly different for equality - jsonata expects the native order to be preserved" - }, - { - "name": "function-sort/case010.json", - "alternateResult": ["0406634348", "0406654608", "040657863", "0406654603"], - "reason": "same as above, works if the condition is changed to >=" - }, { "name": "function-applications/case008.json", "ignoreError": true, From 9e3fcc74f6aa87ff3fdbb4d324d172b6ba41c61e Mon Sep 17 00:00:00 2001 From: Sergeev Viktor Date: Fri, 3 Jul 2026 20:45:08 +0300 Subject: [PATCH 2/2] add test with large array 81 element --- .../java/com/dashjoin/jsonata/ArrayTest.java | 16 +- test/ISSUE-114-largeArrayResult.json | 488 ++++++++++++++++++ test/ISSUE-114-largeArrayToSort.json | 488 ++++++++++++++++++ 3 files changed, 991 insertions(+), 1 deletion(-) create mode 100644 test/ISSUE-114-largeArrayResult.json create mode 100644 test/ISSUE-114-largeArrayToSort.json diff --git a/src/test/java/com/dashjoin/jsonata/ArrayTest.java b/src/test/java/com/dashjoin/jsonata/ArrayTest.java index c97e7b2..ba03285 100644 --- a/src/test/java/com/dashjoin/jsonata/ArrayTest.java +++ b/src/test/java/com/dashjoin/jsonata/ArrayTest.java @@ -4,11 +4,14 @@ import static java.util.Arrays.asList; import static java.util.Map.of; import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Map; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class ArrayTest { @@ -83,4 +86,15 @@ public void testSortTypes() { e = jsonata("[{'value': 'b'}, {'value': 'a'}] ^(