diff options
author | David Hatch <david.hatch@mongodb.com> | 2015-07-31 16:19:20 -0400 |
---|---|---|
committer | Raymond Jacobson <raymond.jacobson@10gen.com> | 2015-08-13 11:34:59 -0400 |
commit | 8fc4cbc675b90f96759b844ddfc4c52868a144f2 (patch) | |
tree | 1e5a687b2f9ce2e027d9fb0d20d7f58fd4016240 /src/mongo/db/ops | |
parent | 9a81b7f1a6a8e0773703f2007c5a7268eb182b91 (diff) | |
download | mongo-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.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/ops/modifier_inc_test.cpp | 123 |
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(); |