From 27483a11b591e9aa02a7efdbcc8bb8cabe040b1e Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 28 Jan 2007 21:25:21 +0000 Subject: Fixed bug when filtering against negative floating point values. --- RELEASE-NOTES.txt | 3 +- pom.xml | 3 +- .../carbonado/cursor/FilteredCursorGenerator.java | 65 +++++++++++++++++++++- 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 @@ carbonado jar Carbonado - 1.1-BETA9 + 1.1-BETA10 Extensible, high performance persistence abstraction layer for Java applications with a relational view to the underlying persistence technology. @@ -85,6 +85,7 @@ Doug Treder Amazon Technologies, Inc. + Tom Keller Amazon Technologies, Inc. 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; } @@ -505,6 +505,65 @@ class FilteredCursorGenerator { return type; } + /** + * 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. */ -- cgit v1.2.3