{"record":{"id":"ad11d2ed56842763","repo":"prestodb/presto","slug":"invalid-function-argument-ad11d2","errorCode":"INVALID_FUNCTION_ARGUMENT","errorMessage":"Lambda comparator violates the comparator contract","messagePattern":"Lambda comparator violates the comparator contract","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/operator/scalar/ArraySortComparatorFunction.java","lineNumber":163,"sourceCode":"    private void initPositionsList(int arrayLength)\n    {\n        if (positions.size() < arrayLength) {\n            positions = Ints.asList(new int[arrayLength]);\n        }\n        for (int i = 0; i < arrayLength; i++) {\n            positions.set(i, i);\n        }\n    }\n\n    private void sortPositions(int arrayLength, Comparator<Integer> comparator)\n    {\n        List<Integer> list = positions.subList(0, arrayLength);\n\n        try {\n            list.sort(comparator);\n        }\n        catch (IllegalArgumentException e) {\n            throw new PrestoException(INVALID_FUNCTION_ARGUMENT, \"Lambda comparator violates the comparator contract\", e);\n        }\n    }\n\n    private Block computeResultBlock(Type type, Block block, int arrayLength)\n    {\n        BlockBuilder blockBuilder = type.createBlockBuilder(null, arrayLength);\n\n        for (int i = 0; i < arrayLength; ++i) {\n            type.appendTo(block, positions.get(i), blockBuilder);\n        }\n\n        return blockBuilder.build();\n    }\n\n    private static int comparatorResult(Long result)\n    {\n        checkCondition(\n                (result != null) && ((result == -1) || (result == 0) || (result == 1)),","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/operator/scalar/ArraySortComparatorFunction.java#L145-L181","documentation":"array_sort with a lambda comparator requires the comparator to satisfy the java.util.Comparator contract (antisymmetry, transitivity, consistency). When List.sort detects a contract violation it throws IllegalArgumentException, which Presto rethrows as INVALID_FUNCTION_ARGUMENT.","triggerScenarios":"Calling sort(array, (a, b) -> comparatorLambda) where the lambda returns inconsistent signs, e.g. returns 0 for unequal elements, reverses sign non-symmetrically, or uses arithmetic that overflows (like (int)(a-b) on large values).","commonSituations":"Comparator written as (a,b) -> a - b causing integer overflow on large values; comparators referencing non-deterministic data; NULL handling that flips ordering between comparisons.","solutions":["Rewrite the lambda to use Integer.compare/Long.compare instead of subtraction to avoid overflow","Ensure the comparator returns 0 only for equal elements and opposite signs for swapped arguments","Make the comparator deterministic (no dependence on mutable/external state)","Test the comparator on representative data before running on large arrays"],"exampleFix":"// before\nsort(arr, (a, b) -> a - b)\n// after\nsort(arr, (a, b) -> Integer.compare(a, b))","handlingStrategy":"validation","validationCode":"-- test comparator determinism on sample data\nSELECT sort(sample_arr, (a, b) -> Integer.compare(a, b)) FROM t LIMIT 100;","typeGuard":null,"tryCatchPattern":"try(sort(arr, (a, b) -> a - b)) -- returns NULL on contract violation; better: fix comparator with compare()","preventionTips":["Always use Integer.compare/Long.compare/Double.compare, never subtraction, in lambdas","Ensure comparator returns opposite signs for swapped args and 0 only for equals","Avoid NULL-unsafe expressions inside comparators; handle NULL explicitly","Unit-test comparators with edge values (MIN/MAX, equal elements)"],"tags":["presto","sql","array-sort","comparator"],"backgroundTag":"comparator-contract-violation","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}