-
Type: Bug
-
Resolution: Works as Designed
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
Empty show more show less
-
Needed
Node.js driver drops some numeric types, such as Long when reading them from the database. For example, inserting this document to the database:
let doc_orig = { _id: new ObjectId(), long_value: new Long(123, 456), int_value: new Int32(123), decimal_value: Decimal128.fromString("12345678") };
, and reading it later causes long_value and int_value to be returned as Number and not as Long and Int32.
You can run a working example in the attached test, which will produce this output for new'ed document:
doc_orig: ObjectID method : 6081c05fe520b453f579a0df long_value ctor : Long long_value method : 456 int_value ctor : Int32 decimal_value ctor : Decimal128 JSON: { "_id": "6081c05fe520b453f579a0df", "long_value": { "low": 123, "high": 456, "unsigned": false }, "int_value": 123, "decimal_value": { "$numberDecimal": "12345678" } }
For a document it reads from the database, it will produce this output:
doc_db: ObjectID method : 6081c05fe520b453f579a0df long_value ctor : Number int_value ctor : Number decimal_value ctor : Decimal128 JSON: { "_id": "6081c05fe520b453f579a0df", "long_value": 1958505087099, "int_value": 123, "decimal_value": { "$numberDecimal": "12345678" } }
It retains some types, like ObjectId and Decimal129, but drops Long and Int32.
Mongo Shell produces correctly-typed results, except for Int32, but that's quite acceptable for shell, even though it could do better:
{ "_id" : ObjectId("6081bdff3ae672809ee0906c"), "long_value" : NumberLong("1958505087099"), "int_value" : 123, "decimal_value" : NumberDecimal("12345678") }
Compass correctly identifies all types, including Int32 and Int64.
Mongo C correctly identifies field types in BSON and returns appropriate values mapped to C++ types int32_t and int64_t from bson_as_json:
{ "_id" : { "$oid" : "6081bdff3ae672809ee0906c" }, "long_value" : 1958505087099, "int_value" : 123, "decimal_value" : { "$numberDecimal" : "12345678" } } key: _id type: 7 key: long_value type: 0x12 (BSON_TYPE_INT64) key: int_value type: 0x10 (BSON_TYPE_INT32) key: decimal_value type: 0x13 (BSON_TYPE_DECIMAL128)
This makes it impossible to reference Long values via its methods after documents are read from the database. Before inserting the document, I can call both of these and it works as expected:
console.log(`ObjectID method : ${doc_orig._id.toHexString()}`); console.log(`long_value method: ${doc_orig.long_value.getHighBits()}`);
After reading the document from the database the second one would crash because the field is constructed as Number.
Node.js driver shall evaluate the BSON field type and if it finds BSON_TYPE_INT64, it shall allocate Long and initialize the resulting object with the value coming from BSON.
- related to
-
NODE-3233 Clarify documentation around promoteValues
- Closed