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 235b27b07cf6..877d14b916bb 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 @@ -86,8 +86,12 @@ public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int @Override public long hash(Block block, int position) { - // convert to canonical NaN if necessary - return doubleHashCode(longBitsToDouble(block.getLong(position))); + Double doubleValue = longBitsToDouble(block.getLong(position)); + if (!useNewNanDefintion) { + // convert to canonical NaN if necessary + return AbstractLongType.hash(doubleToLongBits(doubleValue)); + } + return doubleHashCode(doubleValue); } @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 b38ba129780a..5bb530043b46 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 @@ -22,6 +22,7 @@ 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.floatToIntBits; import static java.lang.Float.intBitsToFloat; import static java.lang.Math.toIntExact; import static java.lang.String.format; @@ -64,7 +65,12 @@ public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int @Override public long hash(Block block, int position) { - return realHashCode(intBitsToFloat(block.getInt(position))); + float value = intBitsToFloat(block.getInt(position)); + if (!useNewNanDefinition) { + // convert to canonical NaN if necessary + return AbstractIntType.hash(floatToIntBits(value)); + } + return realHashCode(value); } @Override diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/TypeUtils.java b/presto-common/src/main/java/com/facebook/presto/common/type/TypeUtils.java index 5dc6372daf70..2a0144f1bf70 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/TypeUtils.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/TypeUtils.java @@ -274,7 +274,7 @@ public static long realHashCode(float value) // canonicalize +0 and -0 to a single value value = value == -0 ? 0 : value; // floatToIntBits converts all NaNs to the same representation - return AbstractLongType.hash(floatToIntBits(value)); + return AbstractIntType.hash(floatToIntBits(value)); } public static int realCompare(float a, float b) diff --git a/presto-main/src/test/java/com/facebook/presto/type/TestDoubleType.java b/presto-main/src/test/java/com/facebook/presto/type/TestDoubleType.java index e1aac2377f0f..a075fbf19a5d 100644 --- a/presto-main/src/test/java/com/facebook/presto/type/TestDoubleType.java +++ b/presto-main/src/test/java/com/facebook/presto/type/TestDoubleType.java @@ -19,9 +19,12 @@ import org.testng.annotations.Test; import static com.facebook.presto.common.type.DoubleType.DOUBLE; +import static com.facebook.presto.common.type.DoubleType.OLD_NAN_DOUBLE; +import static com.facebook.presto.common.type.RealType.OLD_NAN_REAL; import static java.lang.Double.doubleToLongBits; import static java.lang.Double.doubleToRawLongBits; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotEquals; public class TestDoubleType extends AbstractTestType @@ -68,4 +71,22 @@ public void testNaNHash() assertEquals(DOUBLE.hash(blockBuilder, 0), DOUBLE.hash(blockBuilder, 2)); assertEquals(DOUBLE.hash(blockBuilder, 0), DOUBLE.hash(blockBuilder, 3)); } + + @Test + public void testLegacyDoubleHash() + { + BlockBuilder blockBuilder = new LongArrayBlockBuilder(null, 4); + blockBuilder.writeLong(doubleToLongBits(Double.parseDouble("-0"))); + blockBuilder.writeLong(doubleToLongBits(Double.parseDouble("0"))); + assertNotEquals(OLD_NAN_DOUBLE.hash(blockBuilder, 0), OLD_NAN_REAL.hash(blockBuilder, 1)); + } + + @Test + public void testDoubleHash() + { + BlockBuilder blockBuilder = new LongArrayBlockBuilder(null, 4); + blockBuilder.writeLong(doubleToLongBits(Double.parseDouble("-0"))); + blockBuilder.writeLong(doubleToLongBits(Double.parseDouble("0"))); + assertEquals(DOUBLE.hash(blockBuilder, 0), DOUBLE.hash(blockBuilder, 1)); + } } diff --git a/presto-main/src/test/java/com/facebook/presto/type/TestRealType.java b/presto-main/src/test/java/com/facebook/presto/type/TestRealType.java index c81577292596..8673bd51be35 100644 --- a/presto-main/src/test/java/com/facebook/presto/type/TestRealType.java +++ b/presto-main/src/test/java/com/facebook/presto/type/TestRealType.java @@ -18,11 +18,13 @@ import com.facebook.presto.common.block.IntArrayBlockBuilder; import org.testng.annotations.Test; +import static com.facebook.presto.common.type.RealType.OLD_NAN_REAL; import static com.facebook.presto.common.type.RealType.REAL; import static java.lang.Float.floatToIntBits; import static java.lang.Float.floatToRawIntBits; import static java.lang.Float.intBitsToFloat; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotEquals; public class TestRealType extends AbstractTestType @@ -71,4 +73,22 @@ public void testNaNHash() assertEquals(REAL.hash(blockBuilder, 0), REAL.hash(blockBuilder, 2)); assertEquals(REAL.hash(blockBuilder, 0), REAL.hash(blockBuilder, 3)); } + + @Test + public void testLegacyRealHash() + { + BlockBuilder blockBuilder = new IntArrayBlockBuilder(null, 4); + blockBuilder.writeInt(floatToIntBits(Float.parseFloat("-0"))); + blockBuilder.writeInt(floatToIntBits(Float.parseFloat("0"))); + assertNotEquals(OLD_NAN_REAL.hash(blockBuilder, 0), OLD_NAN_REAL.hash(blockBuilder, 1)); + } + + @Test + public void testRealHash() + { + BlockBuilder blockBuilder = new IntArrayBlockBuilder(null, 4); + blockBuilder.writeInt(floatToIntBits(Float.parseFloat("-0"))); + blockBuilder.writeInt(floatToIntBits(Float.parseFloat("0"))); + assertEquals(REAL.hash(blockBuilder, 0), REAL.hash(blockBuilder, 1)); + } }