summaryrefslogtreecommitdiff
path: root/src/mongo/db/ops
diff options
context:
space:
mode:
authorDavid Hatch <david.hatch@mongodb.com>2015-07-31 16:19:20 -0400
committerRaymond Jacobson <raymond.jacobson@10gen.com>2015-08-13 11:34:59 -0400
commit8fc4cbc675b90f96759b844ddfc4c52868a144f2 (patch)
tree1e5a687b2f9ce2e027d9fb0d20d7f58fd4016240 /src/mongo/db/ops
parent9a81b7f1a6a8e0773703f2007c5a7268eb182b91 (diff)
downloadmongo-8fc4cbc675b90f96759b844ddfc4c52868a144f2.tar.gz
SERVER-19628 Add Decimal128 type support to update/delete code paths
Diffstat (limited to 'src/mongo/db/ops')
-rw-r--r--src/mongo/db/ops/modifier_bit_test.cpp9
-rw-r--r--src/mongo/db/ops/modifier_inc_test.cpp123
2 files changed, 131 insertions, 1 deletions
diff --git a/src/mongo/db/ops/modifier_bit_test.cpp b/src/mongo/db/ops/modifier_bit_test.cpp
index b6a4fb38a7b..2e63dbe4953 100644
--- a/src/mongo/db/ops/modifier_bit_test.cpp
+++ b/src/mongo/db/ops/modifier_bit_test.cpp
@@ -37,11 +37,13 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
#include "mongo/db/ops/log_builder.h"
+#include "mongo/platform/decimal128.h"
#include "mongo/unittest/unittest.h"
namespace {
using mongo::BSONObj;
+using mongo::Decimal128;
using mongo::LogBuilder;
using mongo::ModifierBit;
using mongo::ModifierInterface;
@@ -116,6 +118,13 @@ TEST(Init, FailToInitWithInvalidValue) {
modObj = fromjson("{ $bit : { a : { or : 1.0 } } }");
ASSERT_NOT_OK(mod.init(modObj["$bit"].embeddedObject().firstElement(),
ModifierInterface::Options::normal()));
+
+ if (mongo::Decimal128::enabled) {
+ // The argument to the sub-operator must be integral
+ modObj = fromjson("{ $bit : { a : { or : NumberDecimal(\"1.0\") } } }");
+ ASSERT_NOT_OK(mod.init(modObj["$bit"].embeddedObject().firstElement(),
+ ModifierInterface::Options::normal()));
+ }
}
TEST(Init, ParsesAndInt) {
diff --git a/src/mongo/db/ops/modifier_inc_test.cpp b/src/mongo/db/ops/modifier_inc_test.cpp
index 6a0e3a332bd..52c829f7842 100644
--- a/src/mongo/db/ops/modifier_inc_test.cpp
+++ b/src/mongo/db/ops/modifier_inc_test.cpp
@@ -39,11 +39,13 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
#include "mongo/db/ops/log_builder.h"
+#include "mongo/platform/decimal128.h"
#include "mongo/unittest/unittest.h"
namespace {
using mongo::BSONObj;
+using mongo::Decimal128;
using mongo::LogBuilder;
using mongo::ModifierInc;
using mongo::ModifierInterface;
@@ -122,6 +124,12 @@ TEST(Init, InitParsesNumberDouble) {
Mod incMod(BSON("$inc" << BSON("a" << 1.0)));
}
+TEST(Init, InitParsesNumberDecimal) {
+ if (mongo::Decimal128::enabled) {
+ Mod incMod(BSON("$inc" << BSON("a" << Decimal128(1.0))));
+ }
+}
+
TEST(SimpleMod, PrepareSimpleOK) {
Document doc(fromjson("{ a : 1 }"));
Mod incMod(fromjson("{ $inc: { a : 1 }}"));
@@ -275,6 +283,16 @@ TEST(NoOp, Double) {
ASSERT_TRUE(execInfo.noOp);
}
+TEST(NoOp, Decimal) {
+ if (mongo::Decimal128::enabled) {
+ Document doc(BSON("a" << Decimal128("1.0")));
+ Mod incMod(BSON("$inc" << BSON("a" << Decimal128("0.0"))));
+ ModifierInterface::ExecInfo execInfo;
+ ASSERT_OK(incMod.prepare(doc.root(), "", &execInfo));
+ ASSERT_TRUE(execInfo.noOp);
+ }
+}
+
TEST(Upcasting, UpcastIntToLong) {
// Checks that $inc : NumberLong(0) turns a NumberInt into a NumberLong and logs it
// correctly.
@@ -370,9 +388,112 @@ TEST(Upcasting, DoublesStayDoubles) {
ASSERT_EQUALS(mongo::NumberDouble, logDoc.root()["$set"]["a"].getType());
}
+TEST(Upcasting, UpcastIntToDecimal) {
+ if (mongo::Decimal128::enabled) {
+ // Checks that $inc : NumberDecimal(0) turns a NumberInt into a NumberDecimal and logs it
+ // correctly.
+ Document doc(BSON("a" << static_cast<int>(1)));
+ ASSERT_EQUALS(mongo::NumberInt, doc.root()["a"].getType());
+
+ Mod incMod(fromjson("{ $inc : { a : NumberDecimal(\"0\") }}"));
+
+ ModifierInterface::ExecInfo execInfo;
+ ASSERT_OK(incMod.prepare(doc.root(), "", &execInfo));
+ ASSERT_FALSE(execInfo.noOp);
+
+ ASSERT_OK(incMod.apply());
+ ASSERT_FALSE(doc.isInPlaceModeEnabled());
+ ASSERT_EQUALS(fromjson("{ a : NumberDecimal(\"1.0\") }"), doc);
+ ASSERT_EQUALS(mongo::NumberDecimal, doc.root()["a"].getType());
+
+ Document logDoc;
+ LogBuilder logBuilder(logDoc.root());
+ ASSERT_OK(incMod.log(&logBuilder));
+ ASSERT_EQUALS(fromjson("{ $set : { a : NumberDecimal(\"1.0\") }}"), logDoc);
+ ASSERT_EQUALS(mongo::NumberDecimal, logDoc.root()["$set"]["a"].getType());
+ }
+}
+
+TEST(Upcasting, UpcastLongToDecimal) {
+ if (mongo::Decimal128::enabled) {
+ // Checks that $inc : NumberDecimal(0) turns a NumberLong into a NumberDecimal and logs it
+ // correctly.
+ Document doc(BSON("a" << static_cast<long long>(1)));
+ ASSERT_EQUALS(mongo::NumberLong, doc.root()["a"].getType());
+
+ Mod incMod(fromjson("{ $inc : { a : NumberDecimal(\"0\") }}"));
+
+ ModifierInterface::ExecInfo execInfo;
+ ASSERT_OK(incMod.prepare(doc.root(), "", &execInfo));
+ ASSERT_FALSE(execInfo.noOp);
+
+ ASSERT_OK(incMod.apply());
+ ASSERT_FALSE(doc.isInPlaceModeEnabled());
+ ASSERT_EQUALS(fromjson("{ a : NumberDecimal(\"1.0\") }"), doc);
+ ASSERT_EQUALS(mongo::NumberDecimal, doc.root()["a"].getType());
+
+ Document logDoc;
+ LogBuilder logBuilder(logDoc.root());
+ ASSERT_OK(incMod.log(&logBuilder));
+ ASSERT_EQUALS(fromjson("{ $set : { a : NumberDecimal(\"1.0\") }}"), logDoc);
+ ASSERT_EQUALS(mongo::NumberDecimal, logDoc.root()["$set"]["a"].getType());
+ }
+}
+
+TEST(Upcasting, UpcastDoubleToDecimal) {
+ if (mongo::Decimal128::enabled) {
+ // Checks that $inc : NumberDecimal(0) turns a double into a NumberDecimal and logs it
+ // correctly.
+ Document doc(BSON("a" << static_cast<double>(1.0)));
+ ASSERT_EQUALS(mongo::NumberDouble, doc.root()["a"].getType());
+
+ Mod incMod(fromjson("{ $inc : { a : NumberDecimal(\"0\") }}"));
+
+ ModifierInterface::ExecInfo execInfo;
+ ASSERT_OK(incMod.prepare(doc.root(), "", &execInfo));
+ ASSERT_FALSE(execInfo.noOp);
+
+ ASSERT_OK(incMod.apply());
+ ASSERT_FALSE(doc.isInPlaceModeEnabled());
+ ASSERT_EQUALS(fromjson("{ a : NumberDecimal(\"1.0\") }"), doc);
+ ASSERT_EQUALS(mongo::NumberDecimal, doc.root()["a"].getType());
+
+ Document logDoc;
+ LogBuilder logBuilder(logDoc.root());
+ ASSERT_OK(incMod.log(&logBuilder));
+ ASSERT_EQUALS(fromjson("{ $set : { a : NumberDecimal(\"1.0\") }}"), logDoc);
+ ASSERT_EQUALS(mongo::NumberDecimal, logDoc.root()["$set"]["a"].getType());
+ }
+}
+
+TEST(Upcasting, DecimalsStayDecimals) {
+ if (mongo::Decimal128::enabled) {
+ // Checks that $inc : NumberDecimal(1) keeps a NumberDecimal as a NumberDecimal and logs it
+ // correctly.
+ Document doc(BSON("a" << mongo::Decimal128("1.0")));
+ ASSERT_EQUALS(mongo::NumberDecimal, doc.root()["a"].getType());
+
+ Mod incMod(fromjson("{ $inc : { a : NumberDecimal(\"1\") }}"));
+
+ ModifierInterface::ExecInfo execInfo;
+ ASSERT_OK(incMod.prepare(doc.root(), "", &execInfo));
+ ASSERT_FALSE(execInfo.noOp);
+
+ ASSERT_OK(incMod.apply());
+ ASSERT_TRUE(doc.isInPlaceModeEnabled());
+ ASSERT_EQUALS(fromjson("{ a : NumberDecimal(\"2.0\") }"), doc);
+ ASSERT_EQUALS(mongo::NumberDecimal, doc.root()["a"].getType());
+
+ Document logDoc;
+ LogBuilder logBuilder(logDoc.root());
+ ASSERT_OK(incMod.log(&logBuilder));
+ ASSERT_EQUALS(fromjson("{ $set : { a : NumberDecimal(\"2.0\") }}"), logDoc);
+ ASSERT_EQUALS(mongo::NumberDecimal, logDoc.root()["$set"]["a"].getType());
+ }
+}
+
// The only interesting overflow cases are int->long via increment: we never overflow to
// double, and we never decrease precision on decrement.
-
TEST(Spilling, OverflowIntToLong) {
const int initial_value = std::numeric_limits<int32_t>::max();