w3c / IndexedDB

Indexed Database API
https://w3c.github.io/IndexedDB/
Other
240 stars 62 forks source link

Clarify expected index key generation behavior when extracting a key from a value using a key path list #394

Closed iartemiev closed 1 year ago

iartemiev commented 1 year ago

I've noticed an IndexedDB implementation discrepancy between WebKit-based browsers and others (Chrome, FF, Opera) and would like to get clarification about which behavior is correct/expected.

Scenario

I have an index on my store with a key path list containing a single string:

const store = db.createObjectStore("store")
store.createIndex("byIdArrayKey", ["id"], { multiEntry: false }))

I insert a record into the store via putor add:

store.put({
  id: 1,
  title: "hello",
  description: "this is a test"
})

Discrepancy

On Chrome, FF, and Opera the index key that gets calculated from this record value has type array and value [1]

On WebKit-based browsers the index key has type number and value 1

The consequence of this difference in behavior is that when I go to retrieve the record from the index by key

Chrome, etc. expect an array key

const getRequest = index.get([1])

getRequest.onsuccess = (event) => {
  console.log(event.target.result) // successfully retrieves the record {id: 1, title: "hello", ...}
}

But on WebKit-based browsers the result of this request is undefined and I need to query by the number key index.get(1) in order to retrieve the record.

Note: if the key path list on my index contains > 1 string such as store.createIndex("byIdAndTitle", ["id", "title"])) then WebKit will expect an array key when calling get on the index. The issue is only present when the key path list contains a single string.

Question

Should an array key path always produce an array key?

Reading section 7.1 of the IndexedDB spec, specifically

1 If keyPath is a list of strings, then:

  1. Let result be a new Array object created as if by the expression [].

Seems to suggest that this is the case and that the WebKit implementation is incorrectly coercing the key to a scalar when the key path is a list containing a single value.

I would appreciate a definitive confirmation before I open a Bug Report with WebKit.

Thank you!

inexorabletash commented 1 year ago

It looks like a WebKit bug to me. As long as the index doesn't have multiEntry:true, I would expect the key to be [1] not 1.

iartemiev commented 1 year ago

Thanks for confirming. multiEntry is indeed false in my case. I'll add that to the description to make it more explicit.

inexorabletash commented 1 year ago

Do we have a web platform test validating this behavior? Seems like we should...

inexorabletash commented 1 year ago

Huh.... in WPT's IndexedDB dir, git grep createIndex | egrep '\[' | egrep -v multiEntry doesn't turn up any array keypaths with only a single entry. Want to make a WPT for this?

iartemiev commented 1 year ago

Sure! What are the requirements for a WPT? Just a repo demonstrating the issue? Or something more specific?

inexorabletash commented 1 year ago

Pull request against https://github.com/web-platform-tests/wpt/ and specifically follow the patterns already used in https://github.com/web-platform-tests/wpt/tree/master/IndexedDB (there are a lot of different patterns in use there so whatever floats your boat) - CC me on the PR and I can review/merge

iartemiev commented 1 year ago

Sounds good. Will get it done in the next day or two

iartemiev commented 1 year ago

PR opened: https://github.com/web-platform-tests/wpt/pull/36833 and you were auto-added as a reviewer.