Skip to content

Commit 4ef0f7a

Browse files
committed
Fix ARRAYS_OVERLAP function bug
In some arrays containing arrays that contain null values, arrays_overlap was not properly comparing values. Switch to array_overlap to set based implementation. Resolves: #23730
1 parent 27eb666 commit 4ef0f7a

2 files changed

Lines changed: 5 additions & 40 deletions

File tree

presto-main/src/main/java/com/facebook/presto/operator/scalar/ArraysOverlapFunction.java

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
@Description("Returns true if arrays have common elements")
2828
public final class ArraysOverlapFunction
2929
{
30-
private static final int NESTED_LOOP_THRESHOLD = 200;
31-
3230
private ArraysOverlapFunction() {}
3331

3432
@TypeParameter("T")
@@ -38,41 +36,6 @@ public static Boolean arraysOverlap(
3836
@TypeParameter("T") Type elementType,
3937
@SqlType("array(T)") Block leftArray,
4038
@SqlType("array(T)") Block rightArray)
41-
{
42-
if (leftArray.getPositionCount() == 0 || rightArray.getPositionCount() == 0) {
43-
return false;
44-
}
45-
46-
if (Math.max(rightArray.getPositionCount(), leftArray.getPositionCount()) >= NESTED_LOOP_THRESHOLD) {
47-
return arraysOverlapSetBased(elementType, leftArray, rightArray);
48-
}
49-
50-
boolean hasNull = false;
51-
for (int i = 0; i < leftArray.getPositionCount(); i++) {
52-
if (leftArray.isNull(i)) {
53-
hasNull = true;
54-
continue;
55-
}
56-
57-
for (int j = 0; j < rightArray.getPositionCount(); j++) {
58-
if (rightArray.isNull(j)) {
59-
hasNull = true;
60-
continue;
61-
}
62-
if (elementType.equalTo(leftArray, i, rightArray, j)) {
63-
return true;
64-
}
65-
}
66-
}
67-
if (hasNull) {
68-
return null;
69-
}
70-
return false;
71-
}
72-
73-
private static Boolean arraysOverlapSetBased(Type type,
74-
Block leftArray,
75-
Block rightArray)
7639
{
7740
int leftPositionCount = leftArray.getPositionCount();
7841
int rightPositionCount = rightArray.getPositionCount();
@@ -89,7 +52,7 @@ private static Boolean arraysOverlapSetBased(Type type,
8952
}
9053

9154
boolean itrArrHasNull = false;
92-
TypedSet typedSet = new TypedSet(type, lookArray.getPositionCount(), "arraysOverlap");
55+
TypedSet typedSet = new TypedSet(elementType, lookArray.getPositionCount(), "arraysOverlap");
9356
for (int i = 0; i < lookArray.getPositionCount(); i++) {
9457
typedSet.add(lookArray, i);
9558
}

presto-main/src/test/java/com/facebook/presto/type/TestArrayOperators.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,8 @@ public void testArraysOverlap()
12951295
assertFunction("ARRAYS_OVERLAP(ARRAY [NULL, 3], ARRAY [2, 1])", BooleanType.BOOLEAN, null);
12961296
assertFunction("ARRAYS_OVERLAP(ARRAY [3, NULL], ARRAY [2, 1])", BooleanType.BOOLEAN, null);
12971297
assertFunction("ARRAYS_OVERLAP(ARRAY [3, NULL], ARRAY [2, 1, NULL])", BooleanType.BOOLEAN, null);
1298+
assertFunction("ARRAYS_OVERLAP(ARRAY[ARRAY[1, 2], ARRAY[1, NULL]], ARRAY[ARRAY[1, 2]])", BooleanType.BOOLEAN, true);
1299+
assertFunction("ARRAYS_OVERLAP(ARRAY[ARRAY[1, NULL], ARRAY[1, 2]], ARRAY[ARRAY[1, 2]])", BooleanType.BOOLEAN, true);
12981300

12991301
assertFunction("ARRAYS_OVERLAP(ARRAY [CAST(1 AS BIGINT), 2], ARRAY [NULL, CAST(2 AS BIGINT)])", BooleanType.BOOLEAN, true);
13001302
assertFunction("ARRAYS_OVERLAP(ARRAY [CAST(1 AS BIGINT), 2], ARRAY [CAST(2 AS BIGINT), NULL])", BooleanType.BOOLEAN, true);
@@ -1405,8 +1407,8 @@ public void testComparison()
14051407
assertFunction("ARRAY [1, 2, null] != ARRAY [1, 2, null]", BOOLEAN, null);
14061408
assertFunction("ARRAY [1, 2, null] != ARRAY [1, null]", BOOLEAN, true);
14071409
assertFunction("ARRAY [1, 3, null] != ARRAY [1, 2, null]", BOOLEAN, true);
1408-
assertFunction("ARRAY [ARRAY[1], ARRAY[null], ARRAY[2]] != ARRAY [ARRAY[1], ARRAY[2], ARRAY[3]]", BOOLEAN, true);
1409-
assertFunction("ARRAY [ARRAY[1], ARRAY[null], ARRAY[3]] != ARRAY [ARRAY[1], ARRAY[2], ARRAY[3]]", BOOLEAN, null);
1410+
assertFunction("ARRAY [ARRAY [1], ARRAY [null], ARRAY [2]] != ARRAY [ARRAY [1], ARRAY [2], ARRAY [3]]", BOOLEAN, true);
1411+
assertFunction("ARRAY [ARRAY [1], ARRAY [null], ARRAY [3]] != ARRAY [ARRAY [1], ARRAY [2], ARRAY [3]]", BOOLEAN, null);
14101412

14111413
assertFunction("ARRAY [10, 20, 30] < ARRAY [10, 20, 40, 50]", BOOLEAN, true);
14121414
assertFunction("ARRAY [10, 20, 30] >= ARRAY [10, 20, 40, 50]", BOOLEAN, false);

0 commit comments

Comments
 (0)