[w3c/IndexedDB] Key generator behavior with explicit keys above 2^53 (#147)

cc: @bevis-tseng @aliams @beidson

@brettz9 noticed this in #144 as a spec oversight, but implementations are inconsistent and the desired behavior is not obvious to me, so calling this out separately. 

Test case is included in https://github.com/w3c/web-platform-tests/pull/4814

As background, if you have a key generator (stored created with `autoIncrement: true`) you can explicitly advance the generator, e.g.
```js
store.put(value); // gets generated key, e.g. 1
store.put(value, 1000); // gets explicit key and sets generator to 1000
store.put(value); // gets generated key, i.e. 1001
store.put(value, 555); // gets explicit key but is < generator so no change to generator
store.put(value); // gets generated key, i.e. 1002
```
So far so good.

Now what happens in the following cases:

* Explicit key is greater than the max generator value (2^53 i.e. Number.MAX_SAFE_INTEGER)
* Explicit key is at 2^63 (max int64_t)
* Explicit key is at 2^64 (max uint64_t)
* Explicit key is greater than 2^64
* Explicit key is Infinity

e.g. for Infinity:
```js
store.put(value, Infinity); // gets explicit key and sets generator to ????
store.put(value).onsuccess = e => console.log(e.target.result); // ????
store.put(value).onsuccess = e => console.log(e.target.result); // ????
```

It looks like implementations are inconsistent and outright buggy here. With Infinity:

* Firefox generates -9223372036854776000 as the next key (!), then ConstraintError for subsequent puts (!!)
* Safari resets the generator to 0, so you start getting 1, 2, 3, etc. again (!)
* Chrome does not modify the generator, but that's only "by accident".

For reference, Chrome internally coerces the input Number (double) to an int64_t before checking to see if it should increment the generator (also an int64_t) so our behavior goes wonky above the 53 bit mark but at the 63 bit mark it ends up being ignored. Wheee.

There are two possible behaviors for any of these ranges of values:

1. Update generator to maximum value (same as if maximum value was passed)
2. Do not modify the generator (same as if a anything lower than current number was passed)

I definitely think treating bleeding implementation details and treating different finite values above the generator range inconsistently is bad. (i.e. I want to fix Chrome here). I don't particularly care what we do for finite vs. infinite values - they could both be (1), or (2), or differ. 

Thoughts?


-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/IndexedDB/issues/147

Received on Monday, 13 February 2017 21:56:13 UTC