From de2299c6e60753d0b5774380fde32f693a6a0bd5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 23 Sep 2021 12:17:22 +0200 Subject: [PATCH 1/3] bpo-44958: Always reset SQLite statements when we're done with them --- Modules/_sqlite/cursor.c | 49 ++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index e475d933b53159..b09fb952c6b064 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -521,17 +521,13 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (self->statement != NULL) { - /* There is an active statement */ - pysqlite_statement_reset(self->statement); - } - /* reset description and rowcount */ Py_INCREF(Py_None); Py_SETREF(self->description, Py_None); self->rowcount = 0L; if (self->statement) { + // Reset pending statements on this cursor. (void)pysqlite_statement_reset(self->statement); } @@ -570,6 +566,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } + assert(!sqlite3_stmt_busy(self->statement->st)); while (1) { parameters = PyIter_Next(parameters_iter); if (!parameters) { @@ -593,7 +590,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation PyErr_Clear(); } } - (void)pysqlite_statement_reset(self->statement); _pysqlite_seterror(state, self->connection->db); goto error; } @@ -651,13 +647,8 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (rc == SQLITE_DONE && !multiple) { - pysqlite_statement_reset(self->statement); - Py_CLEAR(self->statement); - } - - if (multiple) { - pysqlite_statement_reset(self->statement); + if (rc == SQLITE_DONE) { + (void)pysqlite_statement_reset(self->statement); } Py_XDECREF(parameters); } @@ -670,11 +661,17 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation self->locked = 0; if (PyErr_Occurred()) { + if (self->statement) { + (void)pysqlite_statement_reset(self->statement); + Py_CLEAR(self->statement); + } self->rowcount = -1L; return NULL; - } else { - return Py_NewRef((PyObject *)self); } + if (self->statement && !sqlite3_stmt_busy(self->statement->st)) { + Py_CLEAR(self->statement); + } + return Py_NewRef((PyObject *)self); } /*[clinic input] @@ -809,25 +806,23 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) 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; - } + assert(sqlite3_data_count(stmt) != 0); PyObject *row = _pysqlite_fetch_one_row(self); if (row == NULL) { return NULL; } int rc = pysqlite_step(stmt); - if (rc == SQLITE_DONE) { + if (rc != SQLITE_ROW) { (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; + Py_CLEAR(self->statement); + + if (rc != SQLITE_DONE) { + (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; From 317607b65e9f667257f7667c6307a37ecbca585c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 20 Jun 2022 22:03:39 +0200 Subject: [PATCH 2/3] Fix merge --- Modules/_sqlite/cursor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 3de8afafba3ade..03aaae762f4da3 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -969,7 +969,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation if (PyErr_Occurred()) { if (self->statement) { - (void)pysqlite_statement_reset(self->statement); + (void)stmt_reset(self->statement); Py_CLEAR(self->statement); } self->rowcount = -1L; @@ -1118,7 +1118,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) if (self->statement->is_dml) { self->rowcount = (long)sqlite3_changes(self->connection->db); } - (void)pysqlite_statement_reset(self->statement); + (void)stmt_reset(self->statement); Py_CLEAR(self->statement); } else if (rc != SQLITE_ROW) { From 12bb96e071e7877a43557e0c02ff6aa5514ab3ae Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 20 Jun 2022 22:43:12 +0200 Subject: [PATCH 3/3] Reset in iternext on error path --- Modules/_sqlite/cursor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 03aaae762f4da3..8d9f20da530b23 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -1124,6 +1124,8 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) else if (rc != SQLITE_ROW) { (void)_pysqlite_seterror(self->connection->state, self->connection->db); + (void)stmt_reset(self->statement); + Py_CLEAR(self->statement); Py_DECREF(row); return NULL; }