Skip to content

Commit 3df0fc8

Browse files
author
Erlend Egeberg Aasland
authored
bpo-44976: Lazy creation of sqlite3 result rows (GH-27884)
1 parent 7cba231 commit 3df0fc8

File tree

2 files changed

+29
-58
lines changed

2 files changed

+29
-58
lines changed

Modules/_sqlite/cursor.c

+29-55
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self,
5353
Py_INCREF(connection);
5454
Py_XSETREF(self->connection, connection);
5555
Py_CLEAR(self->statement);
56-
Py_CLEAR(self->next_row);
5756
Py_CLEAR(self->row_cast_map);
5857

5958
Py_INCREF(Py_None);
@@ -94,7 +93,6 @@ cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg)
9493
Py_VISIT(self->lastrowid);
9594
Py_VISIT(self->row_factory);
9695
Py_VISIT(self->statement);
97-
Py_VISIT(self->next_row);
9896
return 0;
9997
}
10098

@@ -111,7 +109,6 @@ cursor_clear(pysqlite_Cursor *self)
111109
pysqlite_statement_reset(self->statement);
112110
Py_CLEAR(self->statement);
113111
}
114-
Py_CLEAR(self->next_row);
115112

116113
return 0;
117114
}
@@ -489,8 +486,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
489486
self->locked = 1;
490487
self->reset = 0;
491488

492-
Py_CLEAR(self->next_row);
493-
494489
if (multiple) {
495490
if (PyIter_Check(second_argument)) {
496491
/* iterator */
@@ -658,11 +653,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
658653
}
659654
}
660655

661-
if (rc == SQLITE_ROW) {
662-
self->next_row = _pysqlite_fetch_one_row(self);
663-
if (self->next_row == NULL)
664-
goto error;
665-
} else if (rc == SQLITE_DONE && !multiple) {
656+
if (rc == SQLITE_DONE && !multiple) {
666657
pysqlite_statement_reset(self->statement);
667658
Py_CLEAR(self->statement);
668659
}
@@ -821,10 +812,6 @@ pysqlite_cursor_executescript_impl(pysqlite_Cursor *self,
821812
static PyObject *
822813
pysqlite_cursor_iternext(pysqlite_Cursor *self)
823814
{
824-
PyObject* next_row_tuple;
825-
PyObject* next_row;
826-
int rc;
827-
828815
if (!check_cursor(self)) {
829816
return NULL;
830817
}
@@ -835,53 +822,40 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)
835822
return NULL;
836823
}
837824

838-
if (!self->next_row) {
839-
if (self->statement) {
840-
(void)pysqlite_statement_reset(self->statement);
841-
Py_CLEAR(self->statement);
842-
}
825+
if (self->statement == NULL) {
843826
return NULL;
844827
}
845828

846-
next_row_tuple = self->next_row;
847-
assert(next_row_tuple != NULL);
848-
self->next_row = NULL;
849-
850-
if (self->row_factory != Py_None) {
851-
next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple);
852-
if (next_row == NULL) {
853-
self->next_row = next_row_tuple;
854-
return NULL;
855-
}
856-
Py_DECREF(next_row_tuple);
857-
} else {
858-
next_row = next_row_tuple;
829+
sqlite3_stmt *stmt = self->statement->st;
830+
assert(stmt != NULL);
831+
if (sqlite3_data_count(stmt) == 0) {
832+
(void)pysqlite_statement_reset(self->statement);
833+
Py_CLEAR(self->statement);
834+
return NULL;
859835
}
860836

861-
if (self->statement) {
862-
rc = pysqlite_step(self->statement->st);
863-
if (PyErr_Occurred()) {
864-
(void)pysqlite_statement_reset(self->statement);
865-
Py_DECREF(next_row);
866-
return NULL;
867-
}
868-
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
869-
(void)pysqlite_statement_reset(self->statement);
870-
Py_DECREF(next_row);
871-
_pysqlite_seterror(self->connection->state, self->connection->db);
872-
return NULL;
873-
}
874-
875-
if (rc == SQLITE_ROW) {
876-
self->next_row = _pysqlite_fetch_one_row(self);
877-
if (self->next_row == NULL) {
878-
(void)pysqlite_statement_reset(self->statement);
879-
return NULL;
880-
}
881-
}
837+
PyObject *row = _pysqlite_fetch_one_row(self);
838+
if (row == NULL) {
839+
return NULL;
882840
}
883-
884-
return next_row;
841+
int rc = pysqlite_step(stmt);
842+
if (rc == SQLITE_DONE) {
843+
(void)pysqlite_statement_reset(self->statement);
844+
}
845+
else if (rc != SQLITE_ROW) {
846+
(void)_pysqlite_seterror(self->connection->state,
847+
self->connection->db);
848+
Py_DECREF(row);
849+
return NULL;
850+
}
851+
if (!Py_IsNone(self->row_factory)) {
852+
PyObject *factory = self->row_factory;
853+
PyObject *args[] = { (PyObject *)self, row, };
854+
PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL);
855+
Py_DECREF(row);
856+
row = new_row;
857+
}
858+
return row;
885859
}
886860

887861
/*[clinic input]

Modules/_sqlite/cursor.h

-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ typedef struct
4646
int locked;
4747
int initialized;
4848

49-
/* the next row to be returned, NULL if no next row available */
50-
PyObject* next_row;
51-
5249
PyObject* in_weakreflist; /* List of weak references */
5350
} pysqlite_Cursor;
5451

0 commit comments

Comments
 (0)