diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-08-25 10:28:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-25 10:28:47 (GMT) |
commit | 3df0fc89bc2714f5ef03e36a926bc795dcd5e05a (patch) | |
tree | a37e5aea557d4f2dd3edca25495789771586e2a6 /Modules | |
parent | 7cba23164cf82f6619db002cd30021b5dfb1f809 (diff) | |
download | cpython-3df0fc89bc2714f5ef03e36a926bc795dcd5e05a.zip cpython-3df0fc89bc2714f5ef03e36a926bc795dcd5e05a.tar.gz cpython-3df0fc89bc2714f5ef03e36a926bc795dcd5e05a.tar.bz2 |
bpo-44976: Lazy creation of sqlite3 result rows (GH-27884)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_sqlite/cursor.c | 84 | ||||
-rw-r--r-- | Modules/_sqlite/cursor.h | 3 |
2 files changed, 29 insertions, 58 deletions
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index e418caf..8b830ec 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -53,7 +53,6 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self, Py_INCREF(connection); Py_XSETREF(self->connection, connection); Py_CLEAR(self->statement); - Py_CLEAR(self->next_row); Py_CLEAR(self->row_cast_map); Py_INCREF(Py_None); @@ -94,7 +93,6 @@ cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg) Py_VISIT(self->lastrowid); Py_VISIT(self->row_factory); Py_VISIT(self->statement); - Py_VISIT(self->next_row); return 0; } @@ -111,7 +109,6 @@ cursor_clear(pysqlite_Cursor *self) pysqlite_statement_reset(self->statement); Py_CLEAR(self->statement); } - Py_CLEAR(self->next_row); return 0; } @@ -489,8 +486,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation self->locked = 1; self->reset = 0; - Py_CLEAR(self->next_row); - if (multiple) { if (PyIter_Check(second_argument)) { /* iterator */ @@ -658,11 +653,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (rc == SQLITE_ROW) { - self->next_row = _pysqlite_fetch_one_row(self); - if (self->next_row == NULL) - goto error; - } else if (rc == SQLITE_DONE && !multiple) { + if (rc == SQLITE_DONE && !multiple) { pysqlite_statement_reset(self->statement); Py_CLEAR(self->statement); } @@ -821,10 +812,6 @@ error: static PyObject * pysqlite_cursor_iternext(pysqlite_Cursor *self) { - PyObject* next_row_tuple; - PyObject* next_row; - int rc; - if (!check_cursor(self)) { return NULL; } @@ -835,53 +822,40 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) return NULL; } - if (!self->next_row) { - if (self->statement) { - (void)pysqlite_statement_reset(self->statement); - Py_CLEAR(self->statement); - } + if (self->statement == NULL) { return NULL; } - next_row_tuple = self->next_row; - assert(next_row_tuple != NULL); - self->next_row = NULL; - - if (self->row_factory != Py_None) { - next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple); - if (next_row == NULL) { - self->next_row = next_row_tuple; - return NULL; - } - Py_DECREF(next_row_tuple); - } else { - next_row = next_row_tuple; + sqlite3_stmt *stmt = self->statement->st; + assert(stmt != NULL); + if (sqlite3_data_count(stmt) == 0) { + (void)pysqlite_statement_reset(self->statement); + Py_CLEAR(self->statement); + return NULL; } - if (self->statement) { - rc = pysqlite_step(self->statement->st); - if (PyErr_Occurred()) { - (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - return NULL; - } - if (rc != SQLITE_DONE && rc != SQLITE_ROW) { - (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - _pysqlite_seterror(self->connection->state, self->connection->db); - return NULL; - } - - if (rc == SQLITE_ROW) { - self->next_row = _pysqlite_fetch_one_row(self); - if (self->next_row == NULL) { - (void)pysqlite_statement_reset(self->statement); - return NULL; - } - } + PyObject *row = _pysqlite_fetch_one_row(self); + if (row == NULL) { + return NULL; } - - return next_row; + int rc = pysqlite_step(stmt); + if (rc == SQLITE_DONE) { + (void)pysqlite_statement_reset(self->statement); + } + else if (rc != SQLITE_ROW) { + (void)_pysqlite_seterror(self->connection->state, + self->connection->db); + Py_DECREF(row); + return NULL; + } + if (!Py_IsNone(self->row_factory)) { + PyObject *factory = self->row_factory; + PyObject *args[] = { (PyObject *)self, row, }; + PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL); + Py_DECREF(row); + row = new_row; + } + return row; } /*[clinic input] diff --git a/Modules/_sqlite/cursor.h b/Modules/_sqlite/cursor.h index 29f52b9..d26d20a 100644 --- a/Modules/_sqlite/cursor.h +++ b/Modules/_sqlite/cursor.h @@ -46,9 +46,6 @@ typedef struct int locked; int initialized; - /* the next row to be returned, NULL if no next row available */ - PyObject* next_row; - PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Cursor; |