bpo-44976: Lazy creation of sqlite3 result rows (GH-27884) · python/cpython@3df0fc8

GitHub

@@ -53,7 +53,6 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self,

5353Py_INCREF(connection);

5454Py_XSETREF(self->connection, connection);

5555Py_CLEAR(self->statement);

56-Py_CLEAR(self->next_row);

5756Py_CLEAR(self->row_cast_map);

58575958Py_INCREF(Py_None);

@@ -94,7 +93,6 @@ cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg)

9493Py_VISIT(self->lastrowid);

9594Py_VISIT(self->row_factory);

9695Py_VISIT(self->statement);

97-Py_VISIT(self->next_row);

9896return0;

9997}

10098@@ -111,7 +109,6 @@ cursor_clear(pysqlite_Cursor *self)

111109pysqlite_statement_reset(self->statement);

112110Py_CLEAR(self->statement);

113111 }

114-Py_CLEAR(self->next_row);

115112116113return0;

117114}

@@ -489,8 +486,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation

489486self->locked=1;

490487self->reset=0;

491488492-Py_CLEAR(self->next_row);

493-494489if (multiple) {

495490if (PyIter_Check(second_argument)) {

496491/* iterator */

@@ -658,11 +653,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation

658653 }

659654 }

660655661-if (rc==SQLITE_ROW) {

662-self->next_row=_pysqlite_fetch_one_row(self);

663-if (self->next_row==NULL)

664- goto error;

665- } elseif (rc==SQLITE_DONE&& !multiple) {

656+if (rc==SQLITE_DONE&& !multiple) {

666657pysqlite_statement_reset(self->statement);

667658Py_CLEAR(self->statement);

668659 }

@@ -821,10 +812,6 @@ pysqlite_cursor_executescript_impl(pysqlite_Cursor *self,

821812staticPyObject*

822813pysqlite_cursor_iternext(pysqlite_Cursor*self)

823814{

824-PyObject*next_row_tuple;

825-PyObject*next_row;

826-intrc;

827-828815if (!check_cursor(self)) {

829816returnNULL;

830817 }

@@ -835,53 +822,40 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)

835822returnNULL;

836823 }

837824838-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) {

843826returnNULL;

844827 }

845828846-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-returnNULL;

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+returnNULL;

859835 }

860836861-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-returnNULL;

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-returnNULL;

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-returnNULL;

880- }

881- }

837+PyObject*row=_pysqlite_fetch_one_row(self);

838+if (row==NULL) {

839+returnNULL;

882840 }

883-884-returnnext_row;

841+intrc=pysqlite_step(stmt);

842+if (rc==SQLITE_DONE) {

843+ (void)pysqlite_statement_reset(self->statement);

844+ }

845+elseif (rc!=SQLITE_ROW) {

846+ (void)_pysqlite_seterror(self->connection->state,

847+self->connection->db);

848+Py_DECREF(row);

849+returnNULL;

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+returnrow;

885859}

886860887861/*[clinic input]