[3.10] bpo-42972: Track sqlite3 statement objects (GH-26475) (GH-26515)
Allocate and track statement objects in pysqlite_statement_create.
By allocating and tracking creation of statement object in
pysqlite_statement_create(), the caller does not need to worry about GC
syncronization, and eliminates the possibility of getting a badly
created object. All related fault handling is moved to
pysqlite_statement_create().
Co-authored-by: Victor Stinner <vstinner@python.org>.
(cherry picked from commit fffa0f92adaaed0bcb3907d982506f78925e9052)
Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 3b287b0..e124b17 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -1337,7 +1337,6 @@ pysqlite_connection_call(pysqlite_Connection *self, PyObject *args,
PyObject* sql;
pysqlite_Statement* statement;
PyObject* weakref;
- int rc;
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
@@ -1351,31 +1350,11 @@ pysqlite_connection_call(pysqlite_Connection *self, PyObject *args,
_pysqlite_drop_unused_statement_references(self);
- statement = PyObject_GC_New(pysqlite_Statement, pysqlite_StatementType);
- if (!statement) {
+ statement = pysqlite_statement_create(self, sql);
+ if (statement == NULL) {
return NULL;
}
- statement->db = NULL;
- statement->st = NULL;
- statement->sql = NULL;
- statement->in_use = 0;
- statement->in_weakreflist = NULL;
-
- rc = pysqlite_statement_create(statement, self, sql);
- if (rc != SQLITE_OK) {
- if (rc == PYSQLITE_TOO_MUCH_SQL) {
- PyErr_SetString(pysqlite_Warning, "You can only execute one statement at a time.");
- } else if (rc == PYSQLITE_SQL_WRONG_TYPE) {
- if (PyErr_ExceptionMatches(PyExc_TypeError))
- PyErr_SetString(pysqlite_Warning, "SQL is of wrong type. Must be string.");
- } else {
- (void)pysqlite_statement_reset(statement);
- _pysqlite_seterror(self->db, NULL);
- }
- goto error;
- }
-
weakref = PyWeakref_NewRef((PyObject*)statement, NULL);
if (weakref == NULL)
goto error;