gh-129346: Handle allocation errors for SQLite aggregate context#129347
gh-129346: Handle allocation errors for SQLite aggregate context#129347erlend-aasland merged 3 commits intopython:mainfrom
Conversation
|
@serhiy-storchaka I would not bother with backporting this. It is not a bug. |
|
I'll let this sit until tomorrow before landing (unless Serhiy gives a thumbs up before that time). |
|
I think that there is a bug. The first call of https://www.sqlite.org/c3ref/aggregate_context.html
If we can determine what the call was first, we can raise MemoryError for the first call and RuntimeError for the subsequent calls. Otherwise we should always raise MemoryError, it is simpler and safer. |
|
I'll go through this again; will ping you later Serhiy. |
The step callback is almost always the first, unless in some special circumstances where we'll go straight to the final callback (we've got a least one test case for this for aggregate functions in the test suite). I think your suggestion makes sense, Serhiy. |
IIRC, the only subsequent callback will be the final callback if the first step callback fails. |
| if (aggregate_instance == NULL) { | ||
| (void)PyErr_NoMemory(); | ||
| set_sqlite_error(context, "unable to allocate SQLite aggregate context"); | ||
| goto error; | ||
| } |
There was a problem hiding this comment.
If we had a way to hook into the SQLite memory allocator, we could simulate out-of-memory, but unfortunately the sqlite3 extension module does not support this (yet).
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Should not we add checks also after other calls? Just for the case.
The query will be aborted if we set an SQLite error in step. We will go straight to final in that case; there will be no subsequent step callback (nor value nor inverse). |
|
Quoting the example code the SQLite docs for the inverse callback: The comment from the value callback is not as explicit, though. |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
There are four calls of sqlite3_aggregate_context(). One (in final_callback) is checked for NULL. Two (in inverse_callback and value_callback) have asserts. Can we guarantee that they never fail?
It is my understanding that the value and inverse callbacks will not be invoked after a failed step callback. I think it would be a breaking change if SQLite changed this behaviour. I think the |
|
I worry about the case when |
final can be called for the case where no rows was returned by the SQL query. If no rows was returned, the value and inverse callbacks has no meaning at all. |
This comment has been minimized.
This comment has been minimized.
pythonGH-129347) (cherry picked from commit 379ab85) Co-authored-by: Erlend E. Aasland <erlend@python.org>
|
GH-129372 is a backport of this pull request to the 3.13 branch. |
pythonGH-129347) (cherry picked from commit 379ab85) Co-authored-by: Erlend E. Aasland <erlend@python.org>
|
GH-129373 is a backport of this pull request to the 3.12 branch. |
connection.c#129346