summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2021-08-25 10:28:47 (GMT)
committerGitHub <noreply@github.com>2021-08-25 10:28:47 (GMT)
commit3df0fc89bc2714f5ef03e36a926bc795dcd5e05a (patch)
treea37e5aea557d4f2dd3edca25495789771586e2a6 /Modules
parent7cba23164cf82f6619db002cd30021b5dfb1f809 (diff)
downloadcpython-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.c84
-rw-r--r--Modules/_sqlite/cursor.h3
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;