diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/DoubleType.java b/presto-common/src/main/java/com/facebook/presto/common/type/DoubleType.java index 7f49c1f58680..235b27b07cf6 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/DoubleType.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/DoubleType.java @@ -22,6 +22,9 @@ import com.facebook.presto.common.function.SqlFunctionProperties; import static com.facebook.presto.common.type.TypeSignature.parseTypeSignature; +import static com.facebook.presto.common.type.TypeUtils.doubleCompare; +import static com.facebook.presto.common.type.TypeUtils.doubleEquals; +import static com.facebook.presto.common.type.TypeUtils.doubleHashCode; import static java.lang.Double.doubleToLongBits; import static java.lang.Double.longBitsToDouble; @@ -72,17 +75,19 @@ public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int { double leftValue = longBitsToDouble(leftBlock.getLong(leftPosition)); double rightValue = longBitsToDouble(rightBlock.getLong(rightPosition)); - - // direct equality is correct here - // noinspection FloatingPointEquality - return leftValue == rightValue; + if (!useNewNanDefintion) { + // direct equality is correct here + // noinspection FloatingPointEquality + return leftValue == rightValue; + } + return doubleEquals(leftValue, rightValue); } @Override public long hash(Block block, int position) { // convert to canonical NaN if necessary - return AbstractLongType.hash(doubleToLongBits(longBitsToDouble(block.getLong(position)))); + return doubleHashCode(longBitsToDouble(block.getLong(position))); } @Override @@ -90,7 +95,7 @@ public int compareTo(Block leftBlock, int leftPosition, Block rightBlock, int ri { double leftValue = longBitsToDouble(leftBlock.getLong(leftPosition)); double rightValue = longBitsToDouble(rightBlock.getLong(rightPosition)); - return Double.compare(leftValue, rightValue); + return doubleCompare(leftValue, rightValue); } @Override diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/RealType.java b/presto-common/src/main/java/com/facebook/presto/common/type/RealType.java index 3334994ce8bb..b38ba129780a 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/RealType.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/RealType.java @@ -19,7 +19,9 @@ import com.facebook.presto.common.function.SqlFunctionProperties; import static com.facebook.presto.common.type.TypeSignature.parseTypeSignature; -import static java.lang.Float.floatToIntBits; +import static com.facebook.presto.common.type.TypeUtils.realCompare; +import static com.facebook.presto.common.type.TypeUtils.realEquals; +import static com.facebook.presto.common.type.TypeUtils.realHashCode; import static java.lang.Float.intBitsToFloat; import static java.lang.Math.toIntExact; import static java.lang.String.format; @@ -51,17 +53,18 @@ public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int { float leftValue = intBitsToFloat(leftBlock.getInt(leftPosition)); float rightValue = intBitsToFloat(rightBlock.getInt(rightPosition)); - - // direct equality is correct here - // noinspection FloatingPointEquality - return leftValue == rightValue; + if (!useNewNanDefinition) { + // direct equality is correct here + // noinspection FloatingPointEquality + return leftValue == rightValue; + } + return realEquals(leftValue, rightValue); } @Override public long hash(Block block, int position) { - // convert to canonical NaN if necessary - return hash(floatToIntBits(intBitsToFloat(block.getInt(position)))); + return realHashCode(intBitsToFloat(block.getInt(position))); } @Override @@ -71,7 +74,7 @@ public int compareTo(Block leftBlock, int leftPosition, Block rightBlock, int ri // function being the equivalence of internal long representation. float leftValue = intBitsToFloat(leftBlock.getInt(leftPosition)); float rightValue = intBitsToFloat(rightBlock.getInt(rightPosition)); - return Float.compare(leftValue, rightValue); + return realCompare(leftValue, rightValue); } @Override diff --git a/presto-main/src/test/java/com/facebook/presto/operator/scalar/sql/TestMapKeyExists.java b/presto-main/src/test/java/com/facebook/presto/operator/scalar/sql/TestMapKeyExists.java index d0895c7e7f00..a383b5d0db68 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/scalar/sql/TestMapKeyExists.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/scalar/sql/TestMapKeyExists.java @@ -55,7 +55,7 @@ public void testBasic() assertFunction( "MAP_KEY_EXISTS(MAP(ARRAY[NAN(), 123.21], ARRAY['val1', 'val2']), NAN())", BOOLEAN, - false); + true); } @Test diff --git a/presto-main/src/test/java/com/facebook/presto/type/TestArrayOperators.java b/presto-main/src/test/java/com/facebook/presto/type/TestArrayOperators.java index 631e36fa1abb..8c95573583da 100644 --- a/presto-main/src/test/java/com/facebook/presto/type/TestArrayOperators.java +++ b/presto-main/src/test/java/com/facebook/presto/type/TestArrayOperators.java @@ -1632,8 +1632,8 @@ public void testArrayRemove() assertFunction("ARRAY_REMOVE(ARRAY [-1.23E0, 3.14E0], 3.14E0)", new ArrayType(DOUBLE), ImmutableList.of(-1.23)); assertFunction("ARRAY_REMOVE(ARRAY [3.14E0], 0.0E0)", new ArrayType(DOUBLE), ImmutableList.of(3.14)); assertFunction("ARRAY_REMOVE(ARRAY [sqrt(-1), 3.14E0], 3.14E0)", new ArrayType(DOUBLE), ImmutableList.of(NaN)); - assertFunction("ARRAY_REMOVE(ARRAY [-1.23E0, sqrt(-1)], nan())", new ArrayType(DOUBLE), ImmutableList.of(-1.23, NaN)); - assertFunction("ARRAY_REMOVE(ARRAY [-1.23E0, nan()], nan())", new ArrayType(DOUBLE), ImmutableList.of(-1.23, NaN)); + assertFunction("ARRAY_REMOVE(ARRAY [-1.23E0, sqrt(-1)], nan())", new ArrayType(DOUBLE), ImmutableList.of(-1.23)); + assertFunction("ARRAY_REMOVE(ARRAY [-1.23E0, nan()], nan())", new ArrayType(DOUBLE), ImmutableList.of(-1.23)); assertFunction("ARRAY_REMOVE(ARRAY [-1.23E0, infinity()], -1.23E0)", new ArrayType(DOUBLE), ImmutableList.of(POSITIVE_INFINITY)); assertFunction("ARRAY_REMOVE(ARRAY [infinity(), 3.14E0], infinity())", new ArrayType(DOUBLE), ImmutableList.of(3.14)); assertFunction("ARRAY_REMOVE(ARRAY [-1.23E0, NULL, 3.14E0], 3.14E0)", new ArrayType(DOUBLE), asList(-1.23, null)); diff --git a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestNanQueries.java b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestNanQueries.java index d4630828e5d0..dd3b868ede2e 100644 --- a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestNanQueries.java +++ b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestNanQueries.java @@ -14,6 +14,7 @@ package com.facebook.presto.tests; +import com.facebook.presto.Session; import org.intellij.lang.annotations.Language; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -34,6 +35,21 @@ public abstract class AbstractTestNanQueries public static final String REAL_NAN_MIDDLE_COLUMN = "_real_nan_middle"; public static final String REAL_NAN_LAST_COLUMN = "_real_nan_last"; + public static final String DISTINCT_TABLE_NAME = "distinct_nans_table"; + public static final String DOUBLE_DISTINCT1_COLUMN = "_double_distinct1"; + public static final String DOUBLE_DISTINCT2_COLUMN = "_double_distinct2"; + public static final String REAL_DISTINCT1_COLUMN = "_real_distinct1"; + public static final String REAL_DISTINCT2_COLUMN = "_real_distinct2"; + public static final String EXTRA_DISTINCT_COLUMN = "_extra_column"; + + public static final String ARRAY_TABLE_NAME = "array_nans_table"; + public static final String SIMPLE_DOUBLE_ARRAY_COLUMN = "simple_double_array"; + public static final String SIMPLE_REAL_ARRAY_COLUMN = "simple_real_array"; + + public static final String MAP_TABLE_NAME = "map_nans_table"; + public static final String DOUBLE_MAP_COLUMN = "double_map"; + public static final String REAL_MAP_COLUMN = "real_map"; + @BeforeClass public void setup() { @@ -54,6 +70,43 @@ public void setup() "(CAST(infinity() AS REAL), CAST(3 AS REAL), CAST(0 AS REAL))," + "( CAST(-4 AS REAL), CAST(2 AS REAL), CAST(nan() AS REAL))) as t (_real_nan_first, _real_nan_middle, _real_nan_last)"; assertUpdate(createFloatTableQuery, 4); + + @Language("SQL") String createDistinctTableQuery = "" + + "CREATE TABLE " + DISTINCT_TABLE_NAME + " AS " + + "SELECT * FROM (VALUES " + + "(nan(), DOUBLE '0.0', CAST(nan() as REAL), REAL '0.0', 'a'), " + + " (DOUBLE '0.0', nan(), REAL '0.0', CAST(nan() AS REAL), 'b'), " + + "(null, null, null, null, 'c'), " + + "(nan(), nan(), CAST(nan() as REAL), CAST(nan() as REAL), 'd'), " + + "(3.0, 3.0, REAL '3.0', REAL '3.0', 'e'), " + + "(0.0, 0.0, REAL '0.0', REAL '0.0', 'f'), " + + "(null, null, null, null, 'g'))" + + "AS t (" + DOUBLE_DISTINCT1_COLUMN + ", " + DOUBLE_DISTINCT2_COLUMN + ", " + REAL_DISTINCT1_COLUMN + ", " + REAL_DISTINCT2_COLUMN + ", " + EXTRA_DISTINCT_COLUMN + ")"; + assertUpdate(createDistinctTableQuery, 7); + + @Language("SQL") String createArrayTableQuery = "" + + "CREATE TABLE " + ARRAY_TABLE_NAME + " AS " + + "SELECT * FROM (VALUES " + + "(ARRAY[nan(), DOUBLE '0', DOUBLE '1', DOUBLE '-1'], ARRAY[cast(nan() AS REAL), REAL '0', REAL '1', REAL '-1']), " + + "(ARRAY[ DOUBLE '0', nan(), DOUBLE '1', DOUBLE '-1'], ARRAY[REAL '0', CAST(nan() AS REAL), REAL '1', REAL '-1']), " + + "(ARRAY[ DOUBLE '0', DOUBLE '1', DOUBLE '-1', nan()], ARRAY[REAL '0', REAL '1', REAL '-1', CAST(nan() AS REAL)]), " + + "(ARRAY[null, nan(), DOUBLE '200'], ARRAY[null, CAST(nan() AS REAL), REAL '200']), " + + "(null, null), " + + "(ARRAY[nan(), nan()], ARRAY[CAST(nan() AS REAL), CAST(nan() AS REAL)]), " + + "(ARRAY[DOUBLE '0', DOUBLE '1', nan(), DOUBLE '-1', nan(), DOUBLE '1', DOUBLE '1', DOUBLE'0'], ARRAY [REAL '0', REAL '1', CAST(nan() AS REAL), REAL '-1', CAST(nan() AS REAL), REAL '1', REAL '1', REAL '0'])) " + + "AS t (" + SIMPLE_DOUBLE_ARRAY_COLUMN + ", " + SIMPLE_REAL_ARRAY_COLUMN + ")"; + + assertUpdate(createArrayTableQuery, 7); + + @Language("SQL") String createMapTableQuery = "" + + "CREATE TABLE " + MAP_TABLE_NAME + " AS " + + "SELECT * FROM (VALUES " + + "(MAP(ARRAY[nan(), 1, 2], ARRAY[nan(), 100, 200]), MAP(ARRAY[CAST(nan() AS REAL), REAL '1', REAL '2'], ARRAY[CAST(nan() AS REAL), REAL '100', REAL '200']))," + + "(MAP(ARRAY[2, nan(), 1], ARRAY[200, nan(), 100]), MAP(ARRAY[REAL '2', CAST(nan() AS REAL), REAL '1'], ARRAY[REAL '200', CAST(nan() AS REAL), REAL '100'])), " + + "(MAP(ARRAY[2, 1, nan()], ARRAY[200, 100, nan()]), MAP(ARRAY[REAL '2', REAL '1', CAST(nan() AS REAL)], ARRAY[REAL '200', REAL '100', CAST(nan() AS REAL)]))) " + + "AS t(" + DOUBLE_MAP_COLUMN + ", " + REAL_MAP_COLUMN + ")"; + System.out.println(createMapTableQuery); + assertUpdate(createMapTableQuery, 3); } @AfterClass @@ -61,6 +114,9 @@ public void tearDown() { assertUpdate("DROP TABLE " + DOUBLE_NANS_TABLE_NAME); assertUpdate("DROP TABLE " + REAL_NANS_TABLE_NAME); + assertUpdate("DROP TABLE " + DISTINCT_TABLE_NAME); + assertUpdate("DROP TABLE " + ARRAY_TABLE_NAME); + assertUpdate("DROP TABLE " + MAP_TABLE_NAME); } @Test @@ -208,4 +264,1019 @@ public void testRealNotIn() assertQuery(format("SELECT CAST(nan() as REAL) NOT IN (REAL '1', REAL '2', _real_nan_first) FROM %s", REAL_NANS_TABLE_NAME), "SELECT * FROM (VALUES (false), (true), (true), (true))"); assertQuery(format("SELECT _real_nan_first NOT IN (CAST(nan() as REAL), 0, 6)FROM %s", REAL_NANS_TABLE_NAME), "SELECT * FROM (VALUES(false), (false), (true), (true))"); } + + @Test + public void testSelectDistinct() + { + assertQueryWithSameQueryRunner(format("SELECT DISTINCT _double_distinct1 FROM %s", DISTINCT_TABLE_NAME), "SELECT * FROM (VALUES(nan()), (0.0), (null), (3.0))"); + assertQueryWithSameQueryRunner(format("SELECT DISTINCT _real_distinct1 FROM %s", DISTINCT_TABLE_NAME), "SELECT * FROM (VALUES (CAST(nan() AS REAL)), (REAL '0.0'), (null), (REAL '3.0'))"); + } + + @Test + public void testSelectDistinctAggregations() + { + Session markDistinct = Session.builder(getQueryRunner().getDefaultSession()).setSystemProperty("use_mark_distinct", "true").build(); + assertQuery(markDistinct, format("SELECT count(DISTINCT _double_distinct1), count(_double_distinct1), count(*) FROM %s", DISTINCT_TABLE_NAME), "SELECT 3, 5, 7"); + assertQuery(markDistinct, format("SELECT count(DISTINCT _real_distinct1), count(_real_distinct1), count(*) FROM %s", DISTINCT_TABLE_NAME), "SELECT 3, 5, 7"); + + Session noMarkDistinct = Session.builder(getQueryRunner().getDefaultSession()).setSystemProperty("use_mark_distinct", "false").build(); + assertQuery(noMarkDistinct, format("SELECT count(DISTINCT _double_distinct1), count(_double_distinct1), count(*) FROM %s", DISTINCT_TABLE_NAME), "SELECT 3, 5, 7"); + assertQuery(noMarkDistinct, format("SELECT count(DISTINCT _real_distinct1), count(_real_distinct1), count(*) FROM %s", DISTINCT_TABLE_NAME), "SELECT 3, 5, 7"); + } + + @Test + public void testGroupBy() + { + assertQueryWithSameQueryRunner(format("SELECT _double_distinct1, count(*) FROM %s GROUP BY _double_distinct1", DISTINCT_TABLE_NAME), "SELECT * FROM (VALUES (nan(), BIGINT '2'), (0.0, BIGINT '2'), (null, BIGINT '2'), (3.0, BIGINT '1'))"); + assertQueryWithSameQueryRunner(format("SELECT _real_distinct1, count(*) FROM %s GROUP BY _real_distinct1", DISTINCT_TABLE_NAME), "SELECT * FROM (VALUES (CAST(nan() as REAL), BIGINT '2'), (REAL '0.0', BIGINT '2'), (null, BIGINT '2'), (REAL '3.0', BIGINT '1'))"); + } + + @Test + public void testMin() + { + assertQueryWithSameQueryRunner(format("SELECT min(%s), min(%s), min(%s) FROM %s", DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, DOUBLE_NANS_TABLE_NAME), "SELECT DOUBLE '-4.0', DOUBLE '0.0', DOUBLE '0.0'"); + assertQueryWithSameQueryRunner(format("SELECT min(%s), min(%s), min(%s) FROM %s", REAL_NAN_FIRST_COLUMN, REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, REAL_NANS_TABLE_NAME), "SELECT REAL '-4.0', REAL '0.0', REAL '0.0'"); + } + + @Test + public void testMax() + { + assertQueryWithSameQueryRunner(format("SELECT max(%s), max(%s), max(%s) FROM %s", DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, DOUBLE_NANS_TABLE_NAME), "SELECT nan(), nan(), nan()"); + assertQueryWithSameQueryRunner(format("SELECT max(%s), max(%s), max(%s) FROM %s", REAL_NAN_FIRST_COLUMN, REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, REAL_NANS_TABLE_NAME), "SELECT CAST(nan() AS REAL), CAST(nan() AS REAL), CAST(nan() AS REAL)"); + } + + @Test + public void testMinN() + { + assertQueryWithSameQueryRunner(format("SELECT min(%s, 2), min(%s, 2), min(%s, 2) FROM %s", DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, DOUBLE_NANS_TABLE_NAME), "SELECT ARRAY [DOUBLE '-4.0', DOUBLE '0.0'], Array [DOUBLE '0.0', DOUBLE '2.0'], ARRAY[DOUBLE '0.0', DOUBLE '1.0']"); + assertQueryWithSameQueryRunner(format("SELECT min(%s, 2), min(%s, 2), min(%s, 2) FROM %s", REAL_NAN_FIRST_COLUMN, REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, REAL_NANS_TABLE_NAME), "SELECT ARRAY [REAL '-4.0', REAL '0.0'], Array [REAL '0.0', REAL '2.0'], ARRAY[REAL '0.0', REAL '1.0']"); + } + + @Test + public void testMaxN() + { + assertQueryWithSameQueryRunner(format("SELECT max(%s, 2), max(%s, 2), max(%s, 2) FROM %s", DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, DOUBLE_NANS_TABLE_NAME), "SELECT ARRAY [nan(), infinity()], Array [nan(), 3.0], ARRAY[nan(), 2.0]"); + assertQueryWithSameQueryRunner(format("SELECT max(%s, 2), max(%s, 2), max(%s, 2) FROM %s", REAL_NAN_FIRST_COLUMN, REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, REAL_NANS_TABLE_NAME), "SELECT ARRAY [CAST(nan() AS REAL), CAST(infinity() AS REAL)], Array [CAST(nan() AS REAL), REAL '3.0'], ARRAY[CAST(nan() AS REAL), REAL '2.0']"); + } + + @Test + public void testMinBy() + { + assertQueryWithSameQueryRunner( + format("SELECT min_by(%s, %s), min_by(%s, %s), min_by(%s, %s) FROM %s", + DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NAN_MIDDLE_COLUMN, + DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, + DOUBLE_NAN_LAST_COLUMN, DOUBLE_NAN_FIRST_COLUMN, + DOUBLE_NANS_TABLE_NAME), + "SELECT nan(), DOUBLE '3.0', nan()"); + assertQueryWithSameQueryRunner( + format("SELECT min_by(%s, %s), min_by(%s, %s), min_by(%s, %s) FROM %s", + REAL_NAN_FIRST_COLUMN, REAL_NAN_MIDDLE_COLUMN, + REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, + REAL_NAN_LAST_COLUMN, REAL_NAN_FIRST_COLUMN, + REAL_NANS_TABLE_NAME), + "SELECT CAST(nan() AS REAL), REAL'3.0', CAST(nan() AS REAL)"); + } + + @Test + public void testMaxBy() + { + assertQueryWithSameQueryRunner( + format("SELECT max_by(%s, %s), max_by(%s, %s), max_by(%s, %s) FROM %s", + DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NAN_MIDDLE_COLUMN, + DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, + DOUBLE_NAN_LAST_COLUMN, DOUBLE_NAN_FIRST_COLUMN, + DOUBLE_NANS_TABLE_NAME), + "SELECT DOUBLE '0.0', DOUBLE '2.0', DOUBLE '1.0'"); + assertQueryWithSameQueryRunner( + format("SELECT max_by(%s, %s), max_by(%s, %s), max_by(%s, %s) FROM %s", + REAL_NAN_FIRST_COLUMN, REAL_NAN_MIDDLE_COLUMN, + REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, + REAL_NAN_LAST_COLUMN, REAL_NAN_FIRST_COLUMN, + REAL_NANS_TABLE_NAME), + "SELECT REAL '0.0', REAL'2.0', REAL '1.0'"); + } + + @Test + public void testMinByN() + { + assertQueryWithSameQueryRunner( + format("SELECT min_by(%s, %s, 2), min_by(%s, %s, 2), min_by(%s, %s, 2) FROM %s", + DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NAN_MIDDLE_COLUMN, + DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, + DOUBLE_NAN_LAST_COLUMN, DOUBLE_NAN_FIRST_COLUMN, + DOUBLE_NANS_TABLE_NAME), + "SELECT ARRAY[nan(), DOUBLE '-4.0'], ARRAY[DOUBLE '3.0', DOUBLE '0.0'], ARRAY[nan(), DOUBLE '2.0']"); + assertQueryWithSameQueryRunner( + format("SELECT min_by(%s, %s, 2), min_by(%s, %s, 2), min_by(%s, %s, 2) FROM %s", + REAL_NAN_FIRST_COLUMN, REAL_NAN_MIDDLE_COLUMN, + REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, + REAL_NAN_LAST_COLUMN, REAL_NAN_FIRST_COLUMN, + REAL_NANS_TABLE_NAME), + "SELECT ARRAY[CAST(nan() AS REAL), REAL '-4.0'], ARRAY[REAL '3.0', REAL '0.0'], ARRAY[CAST(nan() AS REAL), REAL '2.0']"); + } + + @Test + public void testMaxByN() + { + assertQueryWithSameQueryRunner( + format("SELECT max_by(%s, %s, 2), max_by(%s, %s, 2), max_by(%s, %s, 2) FROM %s", + DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NAN_MIDDLE_COLUMN, + DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, + DOUBLE_NAN_LAST_COLUMN, DOUBLE_NAN_FIRST_COLUMN, + DOUBLE_NANS_TABLE_NAME), + "SELECT ARRAY [DOUBLE '0.0', infinity()], ARRAY[DOUBLE '2.0', nan()], ARRAY[DOUBLE '1.0', DOUBLE '0.0']"); + assertQueryWithSameQueryRunner( + format("SELECT max_by(%s, %s, 2), max_by(%s, %s, 2), max_by(%s, %s, 2) FROM %s", + REAL_NAN_FIRST_COLUMN, REAL_NAN_MIDDLE_COLUMN, + REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, + REAL_NAN_LAST_COLUMN, REAL_NAN_FIRST_COLUMN, + REAL_NANS_TABLE_NAME), + "SELECT ARRAY [REAL '0.0', CAST(infinity() AS REAL)], ARRAY[REAL '2.0', CAST(nan() AS REAL)], ARRAY[REAL '1.0', REAL '0.0']"); + } + + @Test + public void testDoubleSetAgg() + { + assertQueryWithSameQueryRunner(format("SELECT set_agg(%s), set_agg(%s) FROM %s", DOUBLE_DISTINCT1_COLUMN, DOUBLE_DISTINCT2_COLUMN, DISTINCT_TABLE_NAME), "SELECT ARRAY[nan(), 0.0, null, 3.0], ARRAY[0, nan(), null, 3.0]"); + } + + @Test + public void testRealSetAgg() + { + assertQueryWithSameQueryRunner( + format("SELECT set_agg(%s), set_agg(%s) FROM %s", REAL_DISTINCT1_COLUMN, REAL_DISTINCT2_COLUMN, DISTINCT_TABLE_NAME), + "SELECT ARRAY[cast(nan() as REAL), 0.0, null, REAL '3.0'], ARRAY[REAL '0.0', cast(nan() as REAL), null, REAL '3.0']"); + } + + @Test + public void testDoubleSetUnion() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(set_union(%s)) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT ARRAY[-1, 0, 1, 200, nan(), null]"); + } + + @Test + public void testRealSetUnion() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(set_union(%s)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT ARRAY[REAL '-1', REAL '0', REAL '1', REAL '200', CAST(nan() AS REAL), null]"); + } + + @Test + public void testDoubleHistogram() + { + assertQueryWithSameQueryRunner(format("SELECT histogram(%s), histogram(%s) FROM %s", DOUBLE_DISTINCT1_COLUMN, DOUBLE_DISTINCT2_COLUMN, DISTINCT_TABLE_NAME), + "SELECT MAP(ARRAY[nan(), 0.0, 3.0], ARRAY[BIGINT '2', BIGINT '2', BIGINT '1']), MAP(ARRAY[0.0, nan(), 3.0], ARRAY[BIGINT '2', BIGINT '2', BIGINT '1'])"); + } + + @Test + public void testRealHistogram() + { + assertQueryWithSameQueryRunner(format("SELECT histogram(%s), histogram(%s) FROM %s", REAL_DISTINCT1_COLUMN, REAL_DISTINCT2_COLUMN, DISTINCT_TABLE_NAME), + "SELECT MAP(ARRAY[CAST(nan() AS REAL), REAL '0.0', 3.0], ARRAY[BIGINT '2', BIGINT '2', BIGINT '1']), MAP(ARRAY[REAL '0.0', CAST(nan() AS REAL), REAL '3.0'], ARRAY[BIGINT '2', BIGINT '2', BIGINT '1'])"); + } + + @Test + public void testDoubleMapAgg() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(map_keys(map_agg(%1$s, %3$s))), array_sort(map_keys(map_agg(%2$s, %3$s))) FROM %4$s WHERE %1$s IS NOT NULL AND %2$s IS NOT NULL", + DOUBLE_DISTINCT1_COLUMN, DOUBLE_DISTINCT2_COLUMN, EXTRA_DISTINCT_COLUMN, DISTINCT_TABLE_NAME), + "SELECT ARRAY[0.0, 3.0, nan()], ARRAY[0.0, 3.0, nan()]"); + } + + @Test + public void testRealMapAgg() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(map_keys(map_agg(%1$s, %3$s))), array_sort(map_keys(map_agg(%2$s, %3$s))) FROM %4$s WHERE %1$s IS NOT NULL AND %2$s IS NOT NULL", + REAL_DISTINCT1_COLUMN, REAL_DISTINCT2_COLUMN, EXTRA_DISTINCT_COLUMN, DISTINCT_TABLE_NAME), + "SELECT ARRAY[REAL '0.0', REAL '3.0', CAST(nan() AS REAL)], ARRAY[REAL '0.0', REAL '3.0', CAST(nan() AS REAL)]"); + } + + @Test + public void testDoubleMapUnion() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(map_keys(map_union(%s))) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT ARRAY[1, 2, nan()]"); + } + + @Test + public void testRealMapUnion() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(map_keys(map_union(%s))) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT ARRAY[REAL '1', REAL '2', CAST(nan() AS REAL)]"); + } + + @Test + public void testDoubleMapUnionSum() + { + assertQueryWithSameQueryRunner( + format("SELECT map_union_sum(%s) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT MAP(ARRAY[1, 2, nan()], ARRAY[300, 600, nan()])"); + } + + @Test + public void testRealMapUnionSum() + { + assertQueryWithSameQueryRunner( + format("SELECT map_union_sum(%s) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT MAP(ARRAY[REAL '1', REAL '2', CAST(nan() AS REAL)], ARRAY[REAL '300', REAL '600', CAST(nan() AS REAL)])"); + } + + @Test + public void testDoubleMultimapAgg() + { + assertQueryWithSameQueryRunner( + format("SELECT multimap_agg(%1$s, %3$s), multimap_agg(%2$s, %3$s) FROM %4$s WHERE %1$s IS NOT NULL AND %2$s IS NOT NULL", + DOUBLE_DISTINCT1_COLUMN, DOUBLE_DISTINCT2_COLUMN, EXTRA_DISTINCT_COLUMN, DISTINCT_TABLE_NAME), + "SELECT MAP(ARRAY[nan(), 0.0, 3.0], ARRAY[ARRAY['a', 'd'], ARRAY['b', 'f'], ARRAY['e']]), MAP(ARRAY[0.0, nan(), 3.0], ARRAY[ARRAY['a', 'f'], ARRAY['b', 'd'], ARRAY['e']])"); + } + + @Test + public void testRealMultimapAgg() + { + assertQueryWithSameQueryRunner( + format("SELECT multimap_agg(%1$s, %3$s), multimap_agg(%2$s, %3$s) FROM %4$s WHERE %1$s IS NOT NULL AND %2$s IS NOT NULL", + REAL_DISTINCT1_COLUMN, REAL_DISTINCT2_COLUMN, EXTRA_DISTINCT_COLUMN, DISTINCT_TABLE_NAME), + "SELECT " + + "MAP(ARRAY[CAST(nan() AS REAL), REAL '0.0', REAL '3.0'], ARRAY[ARRAY['a', 'd'], ARRAY['b', 'f'], ARRAY['e']]), " + + "MAP(ARRAY[REAL '0.0', CAST(nan() AS REAL), REAL '3.0'], ARRAY[ARRAY['a', 'f'], ARRAY['b', 'd'], ARRAY['e']])"); + } + + @Test + public void testDoubleAllMatch() + { + assertQueryWithSameQueryRunner( + format("SELECT all_match(%s, x -> x = nan()) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (false), (false), (false), (null), (false), (true), (false))"); + } + + @Test + public void testRealAllMatch() + { + assertQueryWithSameQueryRunner( + format("SELECT all_match(%s, x -> x = nan()) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (false), (false), (false), (null), (false), (true), (false))"); + } + + @Test + public void testDoubleAnyMatch() + { + assertQueryWithSameQueryRunner( + format("SELECT any_match(%s, x -> x = nan()) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true), (null), (true), (true), (true))"); + } + + @Test + public void testRealAnyMatch() + { + assertQueryWithSameQueryRunner( + format("SELECT any_match(%s, x -> x = nan()) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true), (null), (true), (true), (true))"); + } + + @Test + public void testDoubleArrayDistinct() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_distinct(%s)) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[-1, 0, 1, nan()]), (ARRAY[-1, 0, 1, nan()]), (ARRAY[-1, 0, 1, nan()]), (ARRAY[200, nan(), null]), (null), (ARRAY[nan()]), (ARRAY[-1, 0, 1, nan()]))"); + } + + @Test + public void testRealArrayDistinct() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_distinct(%s)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '200', CAST(nan() AS REAL), null]), (null), (ARRAY[CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]))"); + } + + @Test + public void testDoubleArrayDuplicates() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_duplicates(%s)) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[]), (ARRAY[]), (ARRAY[]), (ARRAY[]), (null), (ARRAY[nan()]), (ARRAY[0, 1, nan()]))"); + } + + @Test + public void testRealArrayDuplicates() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_duplicates(%s)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[]), (ARRAY[]), (ARRAY[]), (ARRAY[]), (null), (ARRAY[CAST(nan() AS REAL)]), (ARRAY[REAL '0', REAL '1', CAST(nan() AS REAL)]))"); + } + + @Test + public void testDoubleArrayExcept() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_except(%s, ARRAY[nan()])) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1']), (ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1']), (ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1']), (ARRAY[DOUBLE '200', null]), (null), (ARRAY[]), (ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1']))"); + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_except(ARRAY[nan()], %s)) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[]), (ARRAY[]), (ARRAY[]), (ARRAY[]), (null), (ARRAY[]), (ARRAY[]))"); + } + + @Test + public void testRealArrayExcept() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_except(%s, ARRAY[CAST(nan() AS REAL)])) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM " + + "(VALUES (ARRAY[REAL '-1', REAL '0', REAL '1']), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1']), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1']), (ARRAY[REAL '200', null]), " + + "(null), " + + "(ARRAY[]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1']))"); + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_except(ARRAY[cast(nan() AS REAL)], %s)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[]), (ARRAY[]), (ARRAY[]), (ARRAY[]), (null), (ARRAY[]), (ARRAY[]))"); + } + + @Test + public void testDoubleArrayFrequency() + { + assertQueryWithSameQueryRunner( + format("SELECT array_frequency(filter(%s, x -> x IS NOT NULL)) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(map(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()], ARRAY[1, 1, 1, 1])), " + + "(map(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()], ARRAY[1, 1, 1, 1])), " + + "(map(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()], ARRAY[1, 1, 1, 1])), " + + "(map(ARRAY[DOUBLE '200', nan()], ARRAY[1, 1])), " + + "(null), " + + "(map(ARRAY[nan()], ARRAY[2])), " + + "(map(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()], ARRAY[1, 2, 3, 2])))"); + } + + @Test + public void testRealArrayFrequency() + { + assertQueryWithSameQueryRunner( + format("SELECT array_frequency(filter(%s, x -> x IS NOT NULL)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(map(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)], ARRAY[1, 1, 1, 1])), " + + "(map(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)], ARRAY[1, 1, 1, 1])), " + + "(map(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)], ARRAY[1, 1, 1, 1])), " + + "(map(ARRAY[REAL '200', CAST(nan() AS REAL)], ARRAY[1, 1])), " + + "(null), " + + "(map(ARRAY[CAST(nan() AS REAL)], ARRAY[2])), " + + "(map(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)], ARRAY[1, 2, 3, 2])))"); + } + + @Test + public void testDoubleArrayHasDuplicates() + { + assertQueryWithSameQueryRunner( + format("SELECT array_has_duplicates(%s) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (false), (false), (false), (false), (null), (true), (true))"); + } + + @Test + public void testRealArrayHasDuplicates() + { + assertQueryWithSameQueryRunner( + format("SELECT array_has_duplicates(%s) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (false), (false), (false), (false), (null), (true), (true))"); + } + + @Test + public void testDoubleArrayIntersect1() + { + // Testing the two argument function signature + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_intersect(%s, ARRAY[nan()])) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan()]), (ARRAY[nan()]), (ARRAY[nan()]), (ARRAY[nan()]), (null), (ARRAY[nan()]), (ARRAY[nan()]))"); + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_intersect(ARRAY[nan()], %s)) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan()]), (ARRAY[nan()]), (ARRAY[nan()]), (ARRAY[nan()]), (null), (ARRAY[nan()]), (ARRAY[nan()]))"); + } + + @Test + public void testRealArrayIntersect() + { + // Testing the two argument function signature + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_intersect(%s, ARRAY[nan()])) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan()]), (ARRAY[nan()]), (ARRAY[nan()]), (ARRAY[nan()]), (null), (ARRAY[nan()]), (ARRAY[nan()]))"); + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_intersect(ARRAY[nan()], %s)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan()]), (ARRAY[nan()]), (ARRAY[nan()]), (ARRAY[nan()]), (null), (ARRAY[nan()]), (ARRAY[nan()]))"); + } + + @Test + public void testDoubleArrayIntersect2() + { + // Test the array of arrays function signature + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_intersect(array_agg(%s))) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan()]))"); + } + + @Test + public void testRealArrayIntersect2() + { + // Test the array of arrays function signature + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_intersect(array_agg(%s))) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[CAST(nan() AS REAL)]))"); + } + + @Test + public void testDoubleArrayLeastFrequent() + { + assertQueryWithSameQueryRunner( + format("SELECT array_least_frequent(%s) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[-1]), (ARRAY[-1]), (ARRAY[-1]), (ARRAY[200]), (null), (ARRAY[nan()]), (ARRAY[-1]))"); + } + + @Test + public void testRealArrayLeastFrequent() + { + assertQueryWithSameQueryRunner( + format("SELECT array_least_frequent(%s) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[REAL '-1']), (ARRAY[REAL '-1']), (ARRAY[REAL '-1']), (ARRAY[REAL '200']), (null), (ARRAY[CAST(nan() AS REAL)]), (ARRAY[REAL '-1']))"); + } + + @Test + public void testDoubleArrayLeastFrequentN() + { + assertQueryWithSameQueryRunner( + format("SELECT array_least_frequent(%s, 3) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[-1, 0 , 1]), (ARRAY[-1, 0, 1]), (ARRAY[-1, 0, 1]), (ARRAY[200, nan()]), (null), (ARRAY[nan()]), (ARRAY[-1, 0, nan()]))"); + } + + @Test + public void testRealArrayLeastFrequentN() + { + assertQueryWithSameQueryRunner( + format("SELECT array_least_frequent(%s, 3) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[REAL '-1', REAL '0' , REAL '1']), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1']), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1']), " + + "(ARRAY[REAL '200', CAST(nan() AS REAL)]), " + + "(null), " + + "(ARRAY[CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', CAST(nan() AS REAL)]))"); + } + + @Test + public void testDoubleArrayMax() + { + assertQueryWithSameQueryRunner( + format("SELECT array_max(%s) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (nan()), (nan()), (nan()), (null), (null), (nan()), (nan()))"); + } + + @Test + public void testRealArrayMax() + { + assertQueryWithSameQueryRunner( + format("SELECT array_max(%s) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (CAST(nan() AS REAL)), (CAST(nan() AS REAL)), (CAST(nan() AS REAL)), (null), (null), (CAST(nan() AS REAL)), (CAST(nan() AS REAL)))"); + } + + @Test + public void testDoubleArrayMaxBy() + { + assertQueryWithSameQueryRunner( + format("SELECT array_max_by(%s, x -> x + 1) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (nan()), (nan()), (nan()), (null), (null), (nan()), (nan()))"); + } + + @Test + public void testRealArrayMaxBy() + { + assertQueryWithSameQueryRunner( + format("SELECT array_max_by(%s, x -> x +1) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (CAST(nan() AS REAL)), (CAST(nan() AS REAL)), (CAST(nan() AS REAL)), (null), (null), (CAST(nan() AS REAL)), (CAST(nan() AS REAL)))"); + } + + @Test + public void testDoubleArrayMin() + { + assertQueryWithSameQueryRunner( + format("SELECT array_min(%s) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (-1), (-1), (-1), (null), (null), (nan()), (-1))"); + } + + @Test + public void testRealArrayMin() + { + assertQueryWithSameQueryRunner( + format("SELECT array_min(%s) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (REAL '-1'), (REAL '-1'), (REAL '-1'), (null), (null), (CAST(nan() AS REAL)), (REAL '-1'))"); + } + + @Test + public void testDoubleArrayMinBy() + { + assertQueryWithSameQueryRunner( + format("SELECT array_min_by(%s, x -> x + 1) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (-1), (-1), (-1), (null), (null), (nan()), (-1))"); + } + + @Test + public void testRealArrayMinBy() + { + assertQueryWithSameQueryRunner( + format("SELECT array_min_by(%s, x -> x + 1) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (REAL '-1'), (REAL '-1'), (REAL '-1'), (null), (null), (CAST(nan() AS REAL)), (REAL '-1'))"); + } + + @Test + public void testDoubleArrayPosition() + { + assertQueryWithSameQueryRunner( + format("SELECT array_position(%s, nan()) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (BIGINT '1'), (BIGINT '2'), (BIGINT '4'), (BIGINT '2'), (null), (BIGINT '1'), (BIGINT '3'))"); + } + + @Test + public void testRealArrayPosition() + { + assertQueryWithSameQueryRunner( + format("SELECT array_position(%s, nan()) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (BIGINT '1'), (BIGINT '2'), (BIGINT '4'), (BIGINT '2'), (null), (BIGINT '1'), (BIGINT '3'))"); + } + + @Test + public void testDoubleArrayPositionI() + { + assertQueryWithSameQueryRunner( + format("SELECT array_position(%s, nan(), 2) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (BIGINT '0'), (BIGINT '0'), (BIGINT '0'), (BIGINT '0'), (null), (BIGINT '2'), (BIGINT '5'))"); + } + + @Test + public void testRealArrayPositionI() + { + assertQueryWithSameQueryRunner( + format("SELECT array_position(%s, nan(), 2) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (BIGINT '0'), (BIGINT '0'), (BIGINT '0'), (BIGINT '0'), (null), (BIGINT '2'), (BIGINT '5'))"); + } + + @Test + public void testDoubleArrayRemove() + { + assertQueryWithSameQueryRunner( + format("SELECT array_remove(%s, nan()) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[DOUBLE '0', DOUBLE '1', DOUBLE '-1']), " + + "(ARRAY[DOUBLE '0', DOUBLE '1', DOUBLE '-1']), " + + "(ARRAY[DOUBLE '0', DOUBLE '1', DOUBLE '-1']), " + + "(ARRAY[null, DOUBLE '200']), " + + "(null), " + + "(ARRAY[]), " + + "(ARRAY[DOUBLE '0', DOUBLE '1', DOUBLE '-1', DOUBLE '1', DOUBLE '1', DOUBLE '0']))"); + } + + @Test + public void testRealArrayRemove() + { + assertQueryWithSameQueryRunner( + format("SELECT array_remove(%s, CAST(nan() AS REAL)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[REAL '0', REAL '1', REAL '-1']), " + + "(ARRAY[REAL '0', REAL '1', REAL '-1']), " + + "(ARRAY[REAL '0', REAL '1', REAL '-1']), " + + "(ARRAY[null, REAL '200']), " + + "(null), " + + "(ARRAY[]), " + + "(ARRAY[REAL '0', REAL '1', REAL '-1', REAL '1', REAL '1', REAL '0']))"); + } + + @Test + public void testDoubleArraySort() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(%s) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[-1, 0, 1, nan()]), (ARRAY[-1, 0, 1, nan()]), (ARRAY[-1, 0, 1, nan()]), (ARRAY[200, nan(), null]), (null), (ARRAY[nan(), nan()]), (ARRAY[-1, 0, 0, 1, 1, 1, nan(), nan()]))"); + } + + @Test + public void testRealArraySort() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(%s) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '200', CAST(nan() AS REAL), null]), " + + "(null), " + + "(ARRAY[CAST(nan() AS REAL), CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '0', REAL '1', REAL '1', REAL '1', CAST(nan() AS REAL), CAST(nan() AS REAL)]))"); + } + + @Test + public void testDoubleArraySortLambda() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(%s, (x, y) -> IF(x > y, 1, IF(x = y, 0, -1))) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[-1, 0, 1, nan()]), (ARRAY[-1, 0, 1, nan()]), (ARRAY[-1, 0, 1, nan()]), (ARRAY[200, nan(), null]), (null), (ARRAY[nan(), nan()]), (ARRAY[-1, 0, 0, 1, 1, 1, nan(), nan()]))"); + } + + @Test + public void testRealArraySortLambda() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(%s, (x, y) -> IF(x > y, 1, IF(x = y, 0, -1))) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '200', CAST(nan() AS REAL), null]), " + + "(null), (ARRAY[CAST(nan() AS REAL), CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '0', REAL'1', REAL '1', REAL '1', CAST(nan() AS REAL), CAST(nan() AS REAL)]))"); + } + + @Test + public void testDoubleArraySortDesc() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort_desc(%s) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan(), 1, 0, -1]), (ARRAY[nan(), 1, 0, -1]), (ARRAY[nan(), 1, 0, -1]), (ARRAY[nan(), 200, null]), (null), (ARRAY[nan(), nan()]), (ARRAY[nan(), nan(), 1, 1, 1, 0, 0, -1]))"); + } + + @Test + public void testRealArraySortDesc() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort_desc(%s) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[CAST(nan() AS REAL), REAL '1', REAL '0', REAL '-1']), " + + "(ARRAY[CAST(nan() AS REAL), REAL '1', REAL '0', REAL '-1']), " + + "(ARRAY[CAST(nan() AS REAL), REAL '1', REAL '0', REAL '-1']), " + + "(ARRAY[CAST(nan() AS REAL), REAL '200', null])," + + " (null)," + + " (ARRAY[CAST(nan() AS REAL), CAST(nan() AS REAL)]), " + + "(ARRAY[CAST(nan() AS REAL), CAST(nan() AS REAL), REAL '1', REAL '1', REAL '1', REAL '0', REAL '0', REAL '-1']))"); + } + + @Test + public void testDoubleArrayTopN() + { + assertQueryWithSameQueryRunner( + format("SELECT array_top_n(%s, 2) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan(), 1]), (ARRAY[nan(), 1]), (ARRAY[nan(), 1]), (ARRAY[nan(), 200]), (null), (ARRAY[nan(), nan()]), (ARRAY[nan(), nan()]))"); + } + + @Test + public void testRealArrayTopN() + { + assertQueryWithSameQueryRunner( + format("SELECT array_top_n(%s, 2) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[CAST(nan() AS REAL), REAL '1']), " + + "(ARRAY[CAST(nan() AS REAL), REAL '1']), " + + "(ARRAY[CAST(nan() AS REAL), REAL '1']), " + + "(ARRAY[CAST(nan() AS REAL), REAL '200'])," + + " (null)," + + " (ARRAY[CAST(nan() AS REAL), CAST(nan() AS REAL)]), " + + "(ARRAY[CAST(nan() AS REAL), CAST(nan() AS REAL)]))"); + } + + @Test + public void testDoubleArraysOverlap() + { + assertQueryWithSameQueryRunner( + format("SELECT arrays_overlap(%s, ARRAY[nan()]) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true), (true), (null), (true), (true))"); + assertQueryWithSameQueryRunner( + format("SELECT arrays_overlap(ARRAY[nan()], %s) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true), (true), (null), (true), (true))"); + } + + @Test + public void testRealArraysOverlap() + { + assertQueryWithSameQueryRunner( + format("SELECT arrays_overlap(%s, ARRAY[nan()]) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true), (true), (null), (true), (true))"); + assertQueryWithSameQueryRunner( + format("SELECT arrays_overlap(ARRAY[nan()], %s) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true), (true), (null), (true), (true))"); + } + + @Test + public void testDoubleArrayUnion() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_union(%s, ARRAY[nan()])) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()]), " + + "(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()]), " + + "(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()]), " + + "(ARRAY[DOUBLE '200', nan(), null]), " + + "(null), " + + "(ARRAY[nan()]), " + + "(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()]))"); + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_union(ARRAY[nan()], %s)) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()]), " + + "(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()]), " + + "(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()]), " + + "(ARRAY[DOUBLE '200', nan(), null]), " + + "(null), " + + "(ARRAY[nan()]), " + + "(ARRAY[DOUBLE '-1', DOUBLE '0', DOUBLE '1', nan()]))"); + } + + @Test + public void testRealArrayUnion() + { + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_union(%s, ARRAY[CAST(nan() AS REAL)])) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '200', CAST(nan() AS REAL), null]), " + + "(null), " + + "(ARRAY[CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]))"); + assertQueryWithSameQueryRunner( + format("SELECT array_sort(array_union(ARRAY[CAST(nan() AS REAL)], %s)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '200', CAST(nan() AS REAL), null]), " + + "(null), " + + "(ARRAY[CAST(nan() AS REAL)]), " + + "(ARRAY[REAL '-1', REAL '0', REAL '1', CAST(nan() AS REAL)]))"); + } + + @Test + public void testDoubleContains() + { + assertQueryWithSameQueryRunner( + format("SELECT contains(%s, nan()) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true), (true), (null), (true), (true))"); + } + + @Test + public void testRealContains() + { + assertQueryWithSameQueryRunner( + format("SELECT contains(%s, CAST(nan() AS REAL)) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true), (true), (null), (true), (true))"); + } + + @Test + public void testDoubleNoneMatch() + { + assertQueryWithSameQueryRunner( + format("SELECT none_match(%s, x -> x = nan()) FROM %s", SIMPLE_DOUBLE_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (false), (false), (false), (null), (false), (false), (false))"); + } + + @Test + public void testRealNoneMatch() + { + assertQueryWithSameQueryRunner( + format("SELECT none_match(%s, x -> x = nan()) FROM %s", SIMPLE_REAL_ARRAY_COLUMN, ARRAY_TABLE_NAME), + "SELECT * FROM (VALUES (false), (false), (false), (null), (false), (false), (false))"); + } + + @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "Duplicate map keys \\(NaN\\) are not allowed") + public void testDoubleMapDuplicateKeys() + { + computeActual("select MAP(array[1, nan(), nan()], array['a', 'b','c'])"); + } + + @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "Duplicate map keys \\(NaN\\) are not allowed") + public void testRealMapDuplicateKeys() + { + computeActual("select MAP(array[REAL '1', CAST(nan() AS REAL), CAST(nan() AS REAL)], array['a', 'b','c'])"); + } + + @Test + public void testDoubleMapAccessor() + { + assertQueryWithSameQueryRunner(format("SELECT %s[nan()] FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (nan()), (nan()), (nan()))"); + } + + @Test + public void testRealMapAccessor() + { + assertQueryWithSameQueryRunner(format("SELECT %s[CAST(nan() AS REAL)] FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (CAST(nan() AS REAL)), CAST(nan() AS REAL), CAST(nan() AS REAL))"); + } + + @Test + public void testDoubleElementAt() + { + assertQueryWithSameQueryRunner(format("SELECT element_at(%s, nan()) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (nan()), (nan()), (nan()))"); + } + + @Test + public void testRealElementAt() + { + assertQueryWithSameQueryRunner(format("SELECT element_at(%s, nan()) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (CAST(nan() AS REAL)), CAST(nan() AS REAL), CAST(nan() AS REAL))"); + } + + @Test + public void testDoubleMapSubset() + { + assertQueryWithSameQueryRunner(format("SELECT map_subset(%s, ARRAY[nan()]) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (MAP(ARRAY[nan()], ARRAY[nan()])), (MAP(ARRAY[nan()], ARRAY[nan()])), (MAP(ARRAY[nan()], ARRAY[nan()])))"); + } + + @Test + public void testRealMapSubset() + { + assertQueryWithSameQueryRunner(format("SELECT map_subset(%s, ARRAY[CAST(nan() AS REAL)]) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (MAP(ARRAY[CAST(nan() AS REAL)], ARRAY[CAST(nan() AS REAL)])), (MAP(ARRAY[CAST(nan() AS REAL)], ARRAY[CAST(nan() AS REAL)])), (MAP(ARRAY[CAST(nan() AS REAL)], ARRAY[CAST(nan() AS REAL)])))"); + } + + @Test + public void testDoubleMapKeyExists() + { + assertQueryWithSameQueryRunner(format("SELECT map_key_exists(%s, nan()) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true))"); + } + + @Test + public void testRealMapKeyExists() + { + assertQueryWithSameQueryRunner(format("SELECT map_key_exists(%s, CAST(nan() AS REAL)) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (true), (true), (true))"); + } + + @Test + public void testDoubleMapToNKeys() + { + assertQueryWithSameQueryRunner(format("SELECT map_top_n_keys(%s, 2) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan(), 2]), (ARRAY[nan(), 2]), (ARRAY[nan(), 2]))"); + } + + @Test + public void testRealMapToNKey() + { + assertQueryWithSameQueryRunner(format("SELECT map_top_n_keys(%s, 2) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[CAST(nan() AS REAL), REAL '2']), (ARRAY[CAST(nan() AS REAL), REAL '2']), (ARRAY[CAST(nan() AS REAL), REAL '2']))"); + } + + @Test + public void testDoubleMapKeysByTopNValues() + { + assertQueryWithSameQueryRunner(format("SELECT map_keys_by_top_n_values(%s, 2) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan(), 2]), (ARRAY[nan(), 2]), (ARRAY[nan(), 2]))"); + } + + @Test + public void testRealMapKeysByTopNValues() + { + assertQueryWithSameQueryRunner(format("SELECT map_keys_by_top_n_values(%s, 2) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[CAST(nan() AS REAL), REAL '2']), (ARRAY[CAST(nan() AS REAL), REAL '2']), (ARRAY[CAST(nan() AS REAL), REAL '2']))"); + } + + @Test + public void testDoubleMapToN() + { + assertQueryWithSameQueryRunner(format("SELECT map_top_n(%s, 2) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (MAP(ARRAY[nan(), 2], ARRAY[nan(), 200])), (MAP(ARRAY[nan(), 2], ARRAY[nan(), 200])), (MAP(ARRAY[nan(), 2], ARRAY[nan(), 200])))"); + } + + @Test + public void testRealMapToN() + { + assertQueryWithSameQueryRunner(format("SELECT map_top_n(%s, 2) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES " + + "(MAP(ARRAY[CAST(nan() AS REAL), REAL '2'], ARRAY[CAST(nan() AS REAL), REAL '200'])), " + + "(MAP(ARRAY[CAST(nan() AS REAL), REAL '2'], ARRAY[CAST(nan() AS REAL), REAL '200'])), " + + "(MAP(ARRAY[CAST(nan() AS REAL), REAL '2'], ARRAY[CAST(nan() AS REAL), REAL '200'])))"); + } + + @Test + public void testRealMapToNKeys() + { + assertQueryWithSameQueryRunner(format("SELECT map_top_n_keys(%s, 2) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[CAST(nan() AS REAL), REAL '2']), (ARRAY[CAST(nan() AS REAL), REAL '2']), (ARRAY[CAST(nan() AS REAL), REAL '2']))"); + } + + @Test + public void testDoubleMapToNValues() + { + assertQueryWithSameQueryRunner(format("SELECT map_top_n_values(%s, 2) FROM %s", DOUBLE_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[nan(), 200]), (ARRAY[nan(), 200]), (ARRAY[nan(), 200]))"); + } + + @Test + public void testRealMapToNValues() + { + assertQueryWithSameQueryRunner(format("SELECT map_top_n_values(%s, 2) FROM %s", REAL_MAP_COLUMN, MAP_TABLE_NAME), + "SELECT * FROM (VALUES (ARRAY[CAST(nan() AS REAL), REAL '200']), (ARRAY[CAST(nan() AS REAL), REAL '200']), (ARRAY[CAST(nan() AS REAL), REAL '200']))"); + } + + @Test + public void testDoubleOrderBy() + { + assertQueryOrderedWithSameQueryRunner(format("SELECT %s FROM %s ORDER BY 1", DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(-4), (0), (infinity()), (nan()))"); + assertQueryOrderedWithSameQueryRunner(format("SELECT %s FROM %s ORDER BY 1 DESC", DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(nan()), (infinity()), (0), (-4))"); + } + + @Test + public void testRealOrderBy() + { + assertQueryOrderedWithSameQueryRunner(format("SELECT %s FROM %s ORDER BY 1", REAL_NAN_FIRST_COLUMN, REAL_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(REAL '-4'), (REAL '0'), (CAST(infinity() AS REAL)), (CAST(nan() AS REAL)))"); + assertQueryOrderedWithSameQueryRunner(format("SELECT %s FROM %s ORDER BY 1 DESC", REAL_NAN_FIRST_COLUMN, REAL_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(CAST(nan() AS REAL)), (CAST(infinity() AS REAL)), (REAL '0'), (REAL '-4'))"); + } + + @Test + public void testDoubleOrderByLimit() + { + assertQueryOrderedWithSameQueryRunner(format("SELECT %s FROM %s ORDER BY 1 LIMIT 2", DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(DOUBLE '-4.0'), (DOUBLE '0.0'))"); + assertQueryOrderedWithSameQueryRunner(format("SELECT %s FROM %s ORDER BY 1 DESC LIMIT 2", DOUBLE_NAN_FIRST_COLUMN, DOUBLE_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(nan()), (infinity()))"); + } + + @Test + public void testRealOrderByLimit() + { + assertQueryOrderedWithSameQueryRunner(format("SELECT %s FROM %s ORDER BY 1 LIMIT 2", REAL_NAN_FIRST_COLUMN, REAL_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(REAL '-4'), (REAL '0'))"); + assertQueryOrderedWithSameQueryRunner(format("SELECT %s FROM %s ORDER BY 1 DESC LIMIT 2", REAL_NAN_FIRST_COLUMN, REAL_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(CAST(nan() AS REAL)), (CAST(infinity() AS REAL)))"); + } + + @Test + public void testDoubleInnerJoin() + { + assertQueryWithSameQueryRunner(format("SELECT %1$s FROM (SELECT %1$s from %3$s) JOIN (SELECT %2$s FROM %3$s) on %1$s = %2$s", DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, DOUBLE_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(DOUBLE '0'), (DOUBLE '2'), (nan()))"); + } + + @Test + public void testRealInnerJoin() + { + assertQueryWithSameQueryRunner(format("SELECT %1$s FROM (SELECT %1$s from %3$s) JOIN (SELECT %2$s FROM %3$s) on %1$s = %2$s", REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, REAL_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(REAL '0'), (REAL '2'), (CAST(nan() AS REAL)))"); + } + + @Test + public void testDoubleLeftJoin() + { + assertQueryWithSameQueryRunner(format("SELECT %1$s, %2$s FROM (SELECT %1$s from %3$s) LEFT JOIN (SELECT %2$s FROM %3$s) on %1$s = %2$s", DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, DOUBLE_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(DOUBLE '0', DOUBLE '0'), (DOUBLE '2', DOUBLE '2'), (nan(), nan()), (DOUBLE '3', null))"); + } + + @Test + public void testRealLeftJoin() + { + assertQueryWithSameQueryRunner(format("SELECT %1$s, %2$s FROM (SELECT %1$s from %3$s) LEFT JOIN (SELECT %2$s FROM %3$s) on %1$s = %2$s", REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, REAL_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(REAL '0', REAL '0'), (REAL '2', REAL '2'), (CAST(nan() AS REAL), CAST(nan() AS REAL)), (REAL '3', null))"); + } + + @Test + public void testDoubleRightJoin() + { + assertQueryWithSameQueryRunner(format("SELECT %1$s, %2$s FROM (SELECT %1$s from %3$s) RIGHT JOIN (SELECT %2$s FROM %3$s) on %1$s = %2$s", DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, DOUBLE_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(DOUBLE '0', DOUBLE '0'), (DOUBLE '2', DOUBLE '2'), (nan(), nan()), (null, DOUBLE '1'))"); + } + + @Test + public void testRealRightJoin() + { + assertQueryWithSameQueryRunner(format("SELECT %1$s, %2$s FROM (SELECT %1$s from %3$s) RIGHT JOIN (SELECT %2$s FROM %3$s) on %1$s = %2$s", REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, REAL_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(REAL '0', REAL '0'), (REAL '2', REAL '2'), (CAST(nan() AS REAL), CAST(nan() AS REAL)), (null, REAL '1'))"); + } + + @Test + public void testDoubleFullJoin() + { + assertQueryWithSameQueryRunner(format("SELECT %1$s, %2$s FROM (SELECT %1$s from %3$s) FULL OUTER JOIN (SELECT %2$s FROM %3$s) on %1$s = %2$s", DOUBLE_NAN_MIDDLE_COLUMN, DOUBLE_NAN_LAST_COLUMN, DOUBLE_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(DOUBLE '0', DOUBLE '0'), (DOUBLE '2', DOUBLE '2'), (nan(), nan()), (DOUBLE '3', null), (null, DOUBLE '1'))"); + } + + @Test + public void testRealFullJoin() + { + assertQueryWithSameQueryRunner(format("SELECT %1$s, %2$s FROM (SELECT %1$s from %3$s) FULL OUTER JOIN (SELECT %2$s FROM %3$s) on %1$s = %2$s", REAL_NAN_MIDDLE_COLUMN, REAL_NAN_LAST_COLUMN, REAL_NANS_TABLE_NAME), + "SELECT * FROM (VALUES(REAL '0', REAL '0'), (REAL '2', REAL '2'), (CAST(nan() AS REAL), CAST(nan() AS REAL)), (REAL '3', null), (null, REAL '1'))"); + } } diff --git a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueryFramework.java b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueryFramework.java index 69ae6efc20b9..42a0639c030b 100644 --- a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueryFramework.java +++ b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueryFramework.java @@ -176,6 +176,12 @@ protected void assertQueryWithSameQueryRunner(Session session, @Language("SQL") QueryAssertions.assertQuery(queryRunner, session, actual, queryRunner, expected, false, false); } + protected void assertQueryOrderedWithSameQueryRunner(@Language("SQL") String actual, @Language("SQL") String expected) + { + checkArgument(!actual.equals(expected)); + QueryAssertions.assertQuery(queryRunner, getSession(), actual, queryRunner, expected, true, false); + } + protected void assertQueryWithSameQueryRunner(Session actualSession, @Language("SQL") String query, Session expectedSession) { QueryAssertions.assertQuery(queryRunner, actualSession, query, queryRunner, expectedSession, query, false, false);