summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASE-NOTES.txt3
-rw-r--r--pom.xml3
-rw-r--r--src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java65
3 files changed, 66 insertions, 5 deletions
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index c09c49f..f25363b 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -9,7 +9,8 @@ Carbonado change history
to support desired ordering.
- Support mapping JDBC numeric column to short or byte.
- Index removal is now batched - reducing memory requirements when removing
- large indexes
+ large indexes.
+- Fixed bug when filtering against negative floating point values.
1.1-BETA8 to 1.1-BETA9
-------------------------------
diff --git a/pom.xml b/pom.xml
index 6af176f..6dd7224 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
<artifactId>carbonado</artifactId>
<packaging>jar</packaging>
<name>Carbonado</name>
- <version>1.1-BETA9</version>
+ <version>1.1-BETA10</version>
<description>
Extensible, high performance persistence abstraction layer for Java applications with a relational view to the underlying persistence technology.
</description>
@@ -85,6 +85,7 @@
<name>Doug Treder</name>
<organization>Amazon Technologies, Inc.</organization>
</developer>
+
<developer>
<name>Tom Keller</name>
<organization>Amazon Technologies, Inc.</organization>
diff --git a/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java b/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java
index ea1baa8..4514865 100644
--- a/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java
+++ b/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java
@@ -282,7 +282,7 @@ class FilteredCursorGenerator {
b.loadConstant(mPropertyOrdinal);
b.loadFromArray(OBJECT);
b.checkCast(type.toObjectType());
- b.convert(type.toObjectType(), fieldType, CodeAssembler.CONVERT_FP_BITS);
+ convertProperty(b, type.toObjectType(), fieldType);
b.storeField(fieldName, fieldType);
// Add code to load property value to stack.
@@ -457,10 +457,10 @@ class FilteredCursorGenerator {
// Floating point values are compared based on actual
// bits. This allows NaN to be considered in the comparison.
if (primitiveType == FLOAT) {
- b.convert(primitiveType, INT, CodeBuilder.CONVERT_FP_BITS);
+ convertProperty(b, primitiveType, INT);
primitiveType = INT;
} else if (primitiveType == DOUBLE) {
- b.convert(primitiveType, LONG, CodeBuilder.CONVERT_FP_BITS);
+ convertProperty(b, primitiveType, LONG);
primitiveType = LONG;
}
@@ -506,6 +506,65 @@ class FilteredCursorGenerator {
}
/**
+ * Converts property value on the stack.
+ */
+ private void convertProperty(CodeBuilder b, TypeDesc fromType, TypeDesc toType) {
+ TypeDesc fromPrimType = fromType.toPrimitiveType();
+
+ if (fromPrimType != TypeDesc.FLOAT && fromPrimType != TypeDesc.DOUBLE) {
+ // Not converting floating point, so just convert as normal.
+ b.convert(fromType, toType);
+ return;
+ }
+
+ TypeDesc toPrimType = toType.toPrimitiveType();
+
+ if (toPrimType != TypeDesc.INT && toPrimType != TypeDesc.LONG) {
+ // Floating point not being converted to bits, so just convert as normal.
+ b.convert(fromType, toType);
+ return;
+ }
+
+ Label done = b.createLabel();
+
+ if (!fromType.isPrimitive() && !toType.isPrimitive()) {
+ b.dup();
+ Label notNull = b.createLabel();
+ b.ifNullBranch(notNull, false);
+ // Need to replace one null with another null.
+ b.pop();
+ b.loadNull();
+ b.branch(done);
+ notNull.setLocation();
+ }
+
+ b.convert(fromType, toPrimType, CodeAssembler.CONVERT_FP_BITS);
+
+ Label box = b.createLabel();
+
+ // Floating point bits need to be flipped for negative values.
+
+ if (toPrimType == TypeDesc.INT) {
+ b.dup();
+ b.ifZeroComparisonBranch(box, ">=");
+ b.loadConstant(0x7fffffff);
+ b.math(Opcode.IXOR);
+ } else {
+ b.dup2();
+ b.loadConstant(0L);
+ b.math(Opcode.LCMP);
+ b.ifZeroComparisonBranch(box, ">=");
+ b.loadConstant(0x7fffffffffffffffL);
+ b.math(Opcode.LXOR);
+ }
+
+ box.setLocation();
+ b.convert(toPrimType, toType);
+
+ done.setLocation();
+ }
+
+ /**
* Defines boolean logic branching scope.
*/
private static class Scope {