summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2010-03-01 09:26:35 -0800
committerAaron <aaron@10gen.com>2010-03-01 09:26:35 -0800
commit89f3e6d65b0d0daa5e70a9dc97a60297ed167678 (patch)
treee5ec78078f679f106cb5e8595beac09cb5163b89
parent45d3cfbfcf6176d70f7ea4be7b136eb1213f0c4a (diff)
downloadmongo-89f3e6d65b0d0daa5e70a9dc97a60297ed167678.tar.gz
SERVER-677 add floatApprox sm
-rw-r--r--dbtests/jstests.cpp22
-rw-r--r--scripting/engine_spidermonkey.cpp22
2 files changed, 36 insertions, 8 deletions
diff --git a/dbtests/jstests.cpp b/dbtests/jstests.cpp
index d38081eafd9..e7077707caa 100644
--- a/dbtests/jstests.cpp
+++ b/dbtests/jstests.cpp
@@ -528,7 +528,7 @@ namespace JSTests {
BSONObj out = s->getObject( "a" );
ASSERT_EQUALS( mongo::NumberLong, out.firstElement().type() );
- ASSERT( s->exec( "b = {b:a.a}", "foo", false, true, false ) );
+ ASSERT( s->exec( "printjson( a ); b = {b:a.a}", "foo", false, true, false ) );
out = s->getObject( "b" );
ASSERT_EQUALS( mongo::NumberLong, out.firstElement().type() );
ASSERT_EQUALS( val, out.firstElement().numberLong() );
@@ -543,6 +543,26 @@ namespace JSTests {
out = s->getObject( "d" );
ASSERT_EQUALS( NumberDouble, out.firstElement().type() );
ASSERT_EQUALS( double( val ), out.firstElement().number() );
+
+ ASSERT( s->exec( "e = {e:a.a.floatApprox}", "foo", false, true, false ) );
+ out = s->getObject( "e" );
+ ASSERT_EQUALS( NumberDouble, out.firstElement().type() );
+ ASSERT_EQUALS( double( val ), out.firstElement().number() );
+
+ ASSERT( s->exec( "f = {f:a.a.top}", "foo", false, true, false ) );
+ out = s->getObject( "f" );
+ ASSERT_EQUALS( NumberDouble, out.firstElement().type() );
+
+ s->setObject( "z", BSON( "z" << (long long)( 4 ) ) );
+ ASSERT( s->exec( "y = {y:z.z.top}", "foo", false, true, false ) );
+ out = s->getObject( "y" );
+ ASSERT_EQUALS( Undefined, out.firstElement().type() );
+
+ ASSERT( s->exec( "x = {x:z.z.floatApprox}", "foo", false, true, false ) );
+ out = s->getObject( "x" );
+ ASSERT_EQUALS( NumberDouble, out.firstElement().type() );
+ ASSERT_EQUALS( double( 4 ), out.firstElement().number() );
+
}
};
diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp
index 294431c6e35..51ba1ca1c4f 100644
--- a/scripting/engine_spidermonkey.cpp
+++ b/scripting/engine_spidermonkey.cpp
@@ -160,9 +160,14 @@ namespace mongo {
// NOTE No validation of passed in object
long long toNumberLongUnsafe( JSObject *o ) {
- boost::uint64_t val =
- ( (boost::uint64_t)(boost::uint32_t)getNumber( o , "top" ) << 32 ) +
- ( boost::uint32_t)( getNumber( o , "bottom" ) );
+ boost::uint64_t val;
+ if ( hasProperty( o, "top" ) ) {
+ val =
+ ( (boost::uint64_t)(boost::uint32_t)getNumber( o , "top" ) << 32 ) +
+ ( boost::uint32_t)( getNumber( o , "bottom" ) );
+ } else {
+ val = getNumber( o, "floatApprox" );
+ }
return val;
}
@@ -566,10 +571,13 @@ namespace mongo {
case NumberLong: {
boost::uint64_t val = (boost::uint64_t)e.numberLong();
JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 );
- // using 2 doubles here instead of a single double because certain double
- // bit patterns represent undefined values and sm might trash them
- setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) );
- setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) );
+ setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) );
+ if ( val != boost::uint64_t( double( val ) ) ) {
+ // using 2 doubles here instead of a single double because certain double
+ // bit patterns represent undefined values and sm might trash them
+ setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) );
+ setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) );
+ }
return OBJECT_TO_JSVAL( o );
}
case DBRef: {