[SERVER-2667] Cannot compare different instances of ObjectIds with same value Created: 02/Mar/11  Updated: 06/Apr/23  Resolved: 09/May/16

Status: Closed
Project: Core Server
Component/s: JavaScript
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Yuriy Bogdanov Assignee: DO NOT USE - Backlog - Platform Team
Resolution: Won't Fix Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

shell


Issue Links:
Related
related to SERVER-8246 Min/MaxKey on V8 are not comparable Closed
related to SERVER-1672 (new NumberLong(3754)==new NumberLong... Closed
is related to SERVER-2844 Shell inserts integers as doubles Closed
is related to SERVER-854 Way to create an integer in javascript Closed
is related to SERVER-776 way to create long in js Closed
is related to SERVER-3383 NumberInt(1) != NumberInt(1), is that... Closed
Backwards Compatibility: Fully Compatible
Operating System: ALL
Participants:

 Description   

Simple test:

> a = ObjectId() 
ObjectId("4d6e43c970953cc4bf43b8cc") 
> db.test.insert({a:a}) 
> doc = db.test.findOne() 
{ 
        "_id" : ObjectId("4d6e43d170953cc4bf43b8cd"), 
        "a" : ObjectId("4d6e43c970953cc4bf43b8cc") 
} 
> doc.a.equals(a) 
true 
> doc.a.toString() === a.toString() 
true 
> doc.a === a 
false
> doc.a == a     
false
> db.version() 
1.7.4 

For example, PHP driver works great with it:

<?php
$id = new MongoID();
$sameId = new MongoID((string)$id);
 
var_dump($id == $sameId); // bool(true)
var_dump($id === $sameId); // bool(false)

Followed by discussion in groups:
http://groups.google.com/group/mongodb-user/browse_thread/thread/77c0c55e24e97a08



 Comments   
Comment by Mira Carey [ 09/May/16 ]

Unfortunately, it's not possible to provide a custom overload for equality in SpiderMonkey, so the asked for functionality isn't possible.

Comment by Ben Becker [ 19/Feb/13 ]

Simply modifying the runtime is not enough to implement custom equality support. The following simple cases of equality comparison do not enter the runtime:

(function() {
    var a = new ObjectId("512311194e31f2f9af7a3e35");
    var b = new ObjectId("512311194e31f2f9af7a3e35");
    print(a == b);
})();
 
(function() {
    var a = {a:1};
    var b = {a:1};
    print(a == b);
})();

When comparing objects, it looks like CompareStub::Generate() and ICCompareStub::GenerateObject() have a fast case which compares the pointer locations of the two operand registers (rax and rdx for x64). These cases immediately return 0 or 1 for the equality operator. Under certain conditions (e.g. boolean == object), these stubs invoke the EQUALS() built-in (in runtime.js). It seems feasible to modify this code to either compare a hidden Map entry, or call a custom built-in.

Comment by Ben Becker [ 16/Feb/13 ]

v8 doesn't support custom object comparisons, but it may be be possible to modify v8. I'll review the code to see how feasible this is, and what additional runtime costs we would incur for a simple implementation.

Some quick notes:
I think this would require changes to the built-in JS EQUALS() function, and possibly FullCodeGenerator::EmitObjectEquals() and HGraphBuilder::GenerateObjectEquals(). I'm not yet sure if Lithium would require modification.

Other options:
  1. Add a comparison function (e.g. '.equals()') to our custom types and require users to explicitly utilize these comparison functions.
  2. For immutable objects, every time we create a new custom object (e.g. ObjectId/NumberLong/etc.), set the prototype to an existing instance of the same value (if one exists). I believe this is a bad idea – it would be slow and consume excessive amounts of memory. I don't think it's even possible for mutable instances.
Comment by Eliot Horowitz (Inactive) [ 16/Feb/13 ]

Ben - anyway to do this in v8?

Comment by Scott Lowe [ 12/Feb/13 ]

Any update on this? It's making life difficult because it's currently impossible to do indexOf on an array of object ids - I'm going to have to either store as strings for now or use a very slow comparison function.

Comment by Eliot Horowitz (Inactive) [ 03/Mar/11 ]

Not sure if its possible to make this work in spidermonkey or v8.
Will look into it

Generated at Thu Feb 08 03:00:50 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.