RESOLVED FIXED Bug 77374
IndexedDB: Raise exception during add/put call if autoIncrement key insertion will fail
https://bugs.webkit.org/show_bug.cgi?id=77374
Summary IndexedDB: Raise exception during add/put call if autoIncrement key insertion...
Joshua Bell
Reported 2012-01-30 15:12:40 PST
For generated keys (i.e. autoIncrement) the generation step should occur within the async task within the transaction (per discussion on mailing list). Currently the key injection call is deferred until the asynchronous task is executed during the transaction. This leaves open a hole where the value may not support key injection (e.g. the value is a string, on which properties can not be set). In this case, Chrome currently fires an error event at the IDBRequest. This may require that in put() we check to see if a value can be inserted (by inserting a dummy value?) and then in putInternal() we run the key generation step and actually insert the key.
Attachments
Patch (8.67 KB, patch)
2012-02-03 10:48 PST, Joshua Bell
no flags
Patch (8.44 KB, patch)
2012-02-03 15:38 PST, Joshua Bell
no flags
Patch (8.62 KB, patch)
2012-02-03 16:55 PST, Joshua Bell
no flags
Joshua Bell
Comment 1 2012-01-30 15:26:07 PST
Don't try and fix this until the refactoring in https://bugs.webkit.org/show_bug.cgi?id=76952 lands
Joshua Bell
Comment 2 2012-02-03 10:48:38 PST
David Grogan
Comment 3 2012-02-03 13:57:58 PST
Comment on attachment 125363 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=125363&action=review LGTM I think you can delete at least the FIXME at line 211. Can you change the line 214-217 if (!valueAfterInjection) clause to an ASSERT? I'm annoyed on behalf of the theoretical developer that we can't give error messages along with the exception so they don't have to consult the spec or other reference to figure out what, e.g., DATA_ERR actually means. > Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp:156 > + if (autoIncrement && !keyPathKey) { Bummer that we have to do another sync call out to the utility process while the renderer process is synchronously waiting for the browser process. Hopefully idb.next saves us from this madness soon. > Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp:-171 > - const bool hasKeyPath = !objectStore->m_keyPath.isNull(); sanity check: these are strictly stylistic? It seems lame that we assign objectStore = this and then use objectStore instead of just passing PassRefPtr<IDBObjectStoreBackendImpl>(this) to transaction->scheduleTask. Though maybe I'm missing a reason that that's not desirable.
Joshua Bell
Comment 4 2012-02-03 14:17:31 PST
Comment on attachment 125363 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=125363&action=review > I think you can delete at least the FIXME at line 211. Can you change the line 214-217 if (!valueAfterInjection) clause to an ASSERT? Will do. > I'm annoyed on behalf of the theoretical developer that we can't give error messages along with the exception so they don't have to consult the spec or other reference to figure out what, e.g., DATA_ERR actually means. No argument there. Even worse, in the latest revs of the spec several of the IDB-specific exception types are replaced with generic DOM4 exception types. Wheee. (I should file a bug on that, actually...) >> Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp:156 >> + if (autoIncrement && !keyPathKey) { > > Bummer that we have to do another sync call out to the utility process while the renderer process is synchronously waiting for the browser process. Hopefully idb.next saves us from this madness soon. Indeed. :( (As an aside, there's an incremental step we could consider: we could pull all of these precondition checks to the front end where they could be done in-proc. The only reason we can't do it trivially right now is that the metadata about the store is only stored in the back end and lookups like this->autoIncrement() are sync IPC call to the back end.) >> Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp:-171 >> - const bool hasKeyPath = !objectStore->m_keyPath.isNull(); > > sanity check: these are strictly stylistic? It seems lame that we assign objectStore = this and then use objectStore instead of just passing PassRefPtr<IDBObjectStoreBackendImpl>(this) to transaction->scheduleTask. Though maybe I'm missing a reason that that's not desirable. Yes, stylistic. Most of the uses in put() stem from my moving of checks from the static putInternal() function to the put() method. But the "objectStore = this" pattern is used throughout the IDB*BackendImpl.cpp files. The "objectStore = this" pattern is used in several methods; it would only be necessary if the scheduleTask call would deref |this| (which it would if the transaction was finished) and our refcount was already 0 (which it shouldn't be). I'm not sure it was put in for a reason, or just cargo cult programming.
David Grogan
Comment 5 2012-02-03 14:45:38 PST
(In reply to comment #4) > >> Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp:-171 > >> - const bool hasKeyPath = !objectStore->m_keyPath.isNull(); > > > > sanity check: these are strictly stylistic? It seems lame that we assign objectStore = this and then use objectStore instead of just passing PassRefPtr<IDBObjectStoreBackendImpl>(this) to transaction->scheduleTask. Though maybe I'm missing a reason that that's not desirable. > > Yes, stylistic. > > Most of the uses in put() stem from my moving of checks from the static putInternal() function to the put() method. But the "objectStore = this" pattern is used throughout the IDB*BackendImpl.cpp files. The "objectStore = this" pattern is used in several methods; it would only be necessary if the scheduleTask call would deref |this| (which it would if the transaction was finished) and our refcount was already 0 (which it shouldn't be). I'm not sure it was put in for a reason, or just cargo cult programming. I think the refcount on IDBObjectStoreBackendImpl can be decremented on the webkit thread in response to an incoming IPC message. The PassRefPtr needs to be used to guard against being deallocated in between scheduling the task and executing it. git blame directed me here: https://bugs.webkit.org/show_bug.cgi?id=46823 where Andrei talks about it.
Joshua Bell
Comment 6 2012-02-03 15:38:29 PST
Joshua Bell
Comment 7 2012-02-03 15:41:00 PST
(In reply to comment #5) > I think the refcount on IDBObjectStoreBackendImpl can be decremented on the webkit thread in response to an incoming IPC message. The PassRefPtr needs to be used to guard against being deallocated in between scheduling the task and executing it. *shakes fist at IPC* Okay. Although not necessary, I rolled back the stylistic changes in the latest patch so they're consistent. I added the ASSERT but left the "if" in place, changing the error type to UNKNOWN_ERR.
Joshua Bell
Comment 8 2012-02-03 16:55:45 PST
Joshua Bell
Comment 9 2012-02-03 16:57:58 PST
(In reply to comment #8) > Created an attachment (id=125448) [details] > Patch Rebased & fixed merge conflict with other patch. tony@, can you review?
WebKit Review Bot
Comment 10 2012-02-06 12:00:41 PST
Comment on attachment 125448 [details] Patch Clearing flags on attachment: 125448 Committed r106830: <http://trac.webkit.org/changeset/106830>
WebKit Review Bot
Comment 11 2012-02-06 12:00:45 PST
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.