[3.10] bpo-42972: Track sqlite3 statement objects (GH-26475) (GH-26515) · python/cpython@84d80f5
@@ -48,35 +48,45 @@ typedef enum {
4848TYPE_UNKNOWN
4949} parameter_type;
505051-int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql)
51+pysqlite_Statement *
52+pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
5253{
5354const char* tail;
5455int rc;
5556const char* sql_cstr;
5657Py_ssize_t sql_cstr_len;
5758const char* p;
585959-self->st = NULL;
60-self->in_use = 0;
61-6260assert(PyUnicode_Check(sql));
63616462sql_cstr = PyUnicode_AsUTF8AndSize(sql, &sql_cstr_len);
6563if (sql_cstr == NULL) {
66-rc = PYSQLITE_SQL_WRONG_TYPE;
67-return rc;
64+PyErr_Format(pysqlite_Warning,
65+"SQL is of wrong type ('%s'). Must be string.",
66+Py_TYPE(sql)->tp_name);
67+return NULL;
6868 }
6969if (strlen(sql_cstr) != (size_t)sql_cstr_len) {
70-PyErr_SetString(PyExc_ValueError, "the query contains a null character");
71-return PYSQLITE_SQL_WRONG_TYPE;
70+PyErr_SetString(PyExc_ValueError,
71+"the query contains a null character");
72+return NULL;
7273 }
737474-self->in_weakreflist = NULL;
75+pysqlite_Statement *self = PyObject_GC_New(pysqlite_Statement,
76+pysqlite_StatementType);
77+if (self == NULL) {
78+return NULL;
79+ }
80+81+self->db = connection->db;
82+self->st = NULL;
7583self->sql = Py_NewRef(sql);
84+self->in_use = 0;
85+self->is_dml = 0;
86+self->in_weakreflist = NULL;
76877788/* Determine if the statement is a DML statement.
7889 SELECT is the only exception. See #9924. */
79-self->is_dml = 0;
8090for (p = sql_cstr; *p != 0; p++) {
8191switch (*p) {
8292case ' ':
@@ -94,22 +104,33 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
94104 }
9510596106Py_BEGIN_ALLOW_THREADS
97-rc = sqlite3_prepare_v2(connection->db,
107+rc = sqlite3_prepare_v2(self->db,
98108sql_cstr,
99109-1,
100110&self->st,
101111&tail);
102112Py_END_ALLOW_THREADS
103113104-self->db = connection->db;
114+PyObject_GC_Track(self);
115+116+if (rc != SQLITE_OK) {
117+_pysqlite_seterror(self->db, NULL);
118+ goto error;
119+ }
105120106121if (rc == SQLITE_OK && pysqlite_check_remaining_sql(tail)) {
107122 (void)sqlite3_finalize(self->st);
108123self->st = NULL;
109-rc = PYSQLITE_TOO_MUCH_SQL;
124+PyErr_SetString(pysqlite_Warning,
125+"You can only execute one statement at a time.");
126+ goto error;
110127 }
111128112-return rc;
129+return self;
130+131+error:
132+Py_DECREF(self);
133+return NULL;
113134}
114135115136int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter)