Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,30 @@ Query termsQuery(String field, List<Object> values) {
return HalfFloatPoint.newSetQuery(field, v);
}

private float nextDown(float f) {
// HalfFloatPoint.nextDown considers that -0 is the same as +0
// while point ranges are consistent with Float.compare, so
// they consider that -0 < +0, so we explicitly make sure
// that nextDown(+0) returns -0
if (Float.floatToIntBits(f) == Float.floatToIntBits(0f)) {
return -0f;
} else {
return HalfFloatPoint.nextDown(f);
}
}

private float nextUp(float f) {
// HalfFloatPoint.nextUp considers that -0 is the same as +0
// while point ranges are consistent with Float.compare, so
// they consider that -0 < +0, so we explicitly make sure
// that nextUp(-0) returns +0
if (Float.floatToIntBits(f) == Float.floatToIntBits(-0f)) {
return +0f;
} else {
return HalfFloatPoint.nextUp(f);
}
}

@Override
Query rangeQuery(String field, Object lowerTerm, Object upperTerm,
boolean includeLower, boolean includeUpper) {
Expand All @@ -194,16 +218,16 @@ Query rangeQuery(String field, Object lowerTerm, Object upperTerm,
if (lowerTerm != null) {
l = parse(lowerTerm);
if (includeLower) {
l = Math.nextDown(l);
l = nextDown(l);
}
l = HalfFloatPoint.nextUp(l);
}
if (upperTerm != null) {
u = parse(upperTerm);
if (includeUpper) {
u = Math.nextUp(u);
u = nextUp(u);
}
u = HalfFloatPoint.nextDown(u);
u = nextDown(u);
}
return HalfFloatPoint.newRangeQuery(field, l, u);
}
Expand Down Expand Up @@ -276,6 +300,30 @@ Query termsQuery(String field, List<Object> values) {
return FloatPoint.newSetQuery(field, v);
}

private float nextDown(float f) {
// Math.nextDown considers that -0 is the same as +0
// while point ranges are consistent with Float.compare, so
// they consider that -0 < +0, so we explicitly make sure
// that nextDown(+0) returns -0
if (Float.floatToIntBits(f) == Float.floatToIntBits(0f)) {
return -0f;
} else {
return Math.nextDown(f);
}
}

private float nextUp(float f) {
// Math.nextUp considers that -0 is the same as +0
// while point ranges are consistent with Float.compare, so
// they consider that -0 < +0, so we explicitly make sure
// that nextUp(-0) returns +0
if (Float.floatToIntBits(f) == Float.floatToIntBits(-0f)) {
return +0f;
} else {
return Math.nextUp(f);
}
}

@Override
Query rangeQuery(String field, Object lowerTerm, Object upperTerm,
boolean includeLower, boolean includeUpper) {
Expand All @@ -284,13 +332,13 @@ Query rangeQuery(String field, Object lowerTerm, Object upperTerm,
if (lowerTerm != null) {
l = parse(lowerTerm);
if (includeLower == false) {
l = Math.nextUp(l);
l = nextUp(l);
}
}
if (upperTerm != null) {
u = parse(upperTerm);
if (includeUpper == false) {
u = Math.nextDown(u);
u = nextDown(u);
}
}
return FloatPoint.newRangeQuery(field, l, u);
Expand Down Expand Up @@ -364,6 +412,30 @@ Query termsQuery(String field, List<Object> values) {
return DoublePoint.newSetQuery(field, v);
}

private double nextDown(double d) {
// Math.nextDown considers that -0 is the same as +0
// while point ranges are consistent with Double.compare, so
// they consider that -0 < +0, so we explicitly make sure
// that nextDown(+0) returns -0
if (Double.doubleToLongBits(d) == Double.doubleToLongBits(0d)) {
return -0d;
} else {
return Math.nextDown(d);
}
}

private double nextUp(double d) {
// Math.nextUp considers that -0 is the same as +0
// while point ranges are consistent with Double.compare, so
// they consider that -0 < +0, so we explicitly make sure
// that nextUp(-0) returns +0
if (Double.doubleToLongBits(d) == Double.doubleToLongBits(-0d)) {
return +0d;
} else {
return Math.nextUp(d);
}
}

@Override
Query rangeQuery(String field, Object lowerTerm, Object upperTerm,
boolean includeLower, boolean includeUpper) {
Expand All @@ -372,13 +444,13 @@ Query rangeQuery(String field, Object lowerTerm, Object upperTerm,
if (lowerTerm != null) {
l = parse(lowerTerm);
if (includeLower == false) {
l = Math.nextUp(l);
l = nextUp(l);
}
}
if (upperTerm != null) {
u = parse(upperTerm);
if (includeUpper == false) {
u = Math.nextDown(u);
u = nextDown(u);
}
}
return DoublePoint.newRangeQuery(field, l, u);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,20 @@ public void testHalfFloatRange() throws IOException {
}
IOUtils.close(reader, dir);
}

public void testNegativeZero() {
assertEquals(
NumberType.DOUBLE.rangeQuery("field", null, -0d, true, true),
NumberType.DOUBLE.rangeQuery("field", null, +0d, true, false));
assertEquals(
NumberType.FLOAT.rangeQuery("field", null, -0f, true, true),
NumberType.FLOAT.rangeQuery("field", null, +0f, true, false));
assertEquals(
NumberType.HALF_FLOAT.rangeQuery("field", null, -0f, true, true),
NumberType.HALF_FLOAT.rangeQuery("field", null, +0f, true, false));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should also test nextUp(-0f) ?:

assertEquals(
            NumberFieldMapper.NumberType.DOUBLE.rangeQuery("field", -0f, null, false, false),
            NumberFieldMapper.NumberType.DOUBLE.rangeQuery("field", +0f, null, true, false));

assertFalse(NumberType.DOUBLE.termQuery("field", -0d).equals(NumberType.DOUBLE.termQuery("field", +0d)));
assertFalse(NumberType.FLOAT.termQuery("field", -0f).equals(NumberType.FLOAT.termQuery("field", +0f)));
assertFalse(NumberType.HALF_FLOAT.termQuery("field", -0f).equals(NumberType.HALF_FLOAT.termQuery("field", +0f)));
}
}
6 changes: 6 additions & 0 deletions docs/reference/mapping/types/numeric.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ PUT my_index
--------------------------------------------------
// CONSOLE

NOTE: The `double`, `float` and `half_float` types consider that `-0.0` and
`+0.0` are different values. As a consequence, doing a `term` query on
`-0.0` will not match `+0.0` and vice-versa. Same is true for range queries:
if the upper bound is `-0.0` then `+0.0` will not match, and if the lower
bound is `+0.0` then `-0.0` will not match.

==== Which type should I use?

As far as integer types (`byte`, `short`, `integer` and `long`) are concerned,
Expand Down