diff options
| author | AlexSm <[email protected]> | 2024-02-16 11:51:30 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-16 11:51:30 +0100 |
| commit | 506ecaee93b52cc12c2e2f97c3d42e3ca2a7f59e (patch) | |
| tree | d096fb9eb988fbb0ca1ba970041773207ce3aa70 /contrib/tools/python3/src/Modules/_sqlite/cursor.c | |
| parent | 4749b9e5d260714490997e6f5ee1ee8c1c8fc46c (diff) | |
| parent | f200f72c9d7a89c1018e3dc6b46c49fe2ecf84fb (diff) | |
Merge pull request #1940 from dcherednik/importlib
Library import 14
Diffstat (limited to 'contrib/tools/python3/src/Modules/_sqlite/cursor.c')
| -rw-r--r-- | contrib/tools/python3/src/Modules/_sqlite/cursor.c | 86 |
1 files changed, 38 insertions, 48 deletions
diff --git a/contrib/tools/python3/src/Modules/_sqlite/cursor.c b/contrib/tools/python3/src/Modules/_sqlite/cursor.c index 3f5cfef0c32..caeedbddb8d 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cursor.c +++ b/contrib/tools/python3/src/Modules/_sqlite/cursor.c @@ -130,14 +130,10 @@ stmt_reset(pysqlite_Statement *self) { int rc = SQLITE_OK; - if (self->in_use && self->st) { + if (self->st != NULL) { Py_BEGIN_ALLOW_THREADS rc = sqlite3_reset(self->st); Py_END_ALLOW_THREADS - - if (rc == SQLITE_OK) { - self->in_use = 0; - } } return rc; @@ -666,6 +662,19 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, return; } for (i = 0; i < num_params; i++) { + const char *name = sqlite3_bind_parameter_name(self->st, i+1); + if (name != NULL) { + int ret = PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "Binding %d ('%s') is a named parameter, but you " + "supplied a sequence which requires nameless (qmark) " + "placeholders. Starting with Python 3.14 an " + "sqlite3.ProgrammingError will be raised.", + i+1, name); + if (ret < 0) { + return; + } + } + if (PyTuple_CheckExact(parameters)) { PyObject *item = PyTuple_GET_ITEM(parameters, i); current_param = Py_NewRef(item); @@ -696,11 +705,10 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, Py_DECREF(adapted); if (rc != SQLITE_OK) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); sqlite3 *db = sqlite3_db_handle(self->st); _pysqlite_seterror(state, db); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); return; } } @@ -756,11 +764,10 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, Py_DECREF(adapted); if (rc != SQLITE_OK) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); sqlite3 *db = sqlite3_db_handle(self->st); _pysqlite_seterror(state, db); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); return; } } @@ -770,12 +777,6 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, } } -static inline void -stmt_mark_dirty(pysqlite_Statement *self) -{ - self->in_use = 1; -} - PyObject * _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) { @@ -830,16 +831,12 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (self->statement != NULL) { - /* There is an active statement */ - stmt_reset(self->statement); - } - /* reset description */ Py_INCREF(Py_None); Py_SETREF(self->description, Py_None); if (self->statement) { + // Reset pending statements on this cursor. (void)stmt_reset(self->statement); } @@ -856,7 +853,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation goto error; } - if (self->statement->in_use) { + if (sqlite3_stmt_busy(self->statement->st)) { Py_SETREF(self->statement, pysqlite_statement_create(self->connection, operation)); if (self->statement == NULL) { @@ -864,13 +861,13 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - stmt_reset(self->statement); - stmt_mark_dirty(self->statement); + (void)stmt_reset(self->statement); self->rowcount = self->statement->is_dml ? 0L : -1L; /* We start a transaction implicitly before a DML statement. SELECT is the only exception. See #9924. */ - if (self->connection->isolation_level + if (self->connection->autocommit == AUTOCOMMIT_LEGACY + && self->connection->isolation_level && self->statement->is_dml && sqlite3_get_autocommit(self->connection->db)) { @@ -879,14 +876,13 @@ _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) { break; } - stmt_mark_dirty(self->statement); - bind_parameters(state, self->statement, parameters); if (PyErr_Occurred()) { goto error; @@ -902,7 +898,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation PyErr_Clear(); } } - (void)stmt_reset(self->statement); _pysqlite_seterror(state, self->connection->db); goto error; } @@ -944,16 +939,8 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (rc == SQLITE_DONE && !multiple) { + if (rc == SQLITE_DONE) { if (self->statement->is_dml) { - self->rowcount = (long)sqlite3_changes(self->connection->db); - } - stmt_reset(self->statement); - Py_CLEAR(self->statement); - } - - if (multiple) { - if (self->statement->is_dml && rc == SQLITE_DONE) { self->rowcount += (long)sqlite3_changes(self->connection->db); } stmt_reset(self->statement); @@ -980,11 +967,17 @@ error: self->locked = 0; if (PyErr_Occurred()) { + if (self->statement) { + (void)stmt_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] @@ -1052,7 +1045,9 @@ pysqlite_cursor_executescript_impl(pysqlite_Cursor *self, // Commit if needed sqlite3 *db = self->connection->db; - if (!sqlite3_get_autocommit(db)) { + if (self->connection->autocommit == AUTOCOMMIT_LEGACY + && !sqlite3_get_autocommit(db)) + { int rc = SQLITE_OK; Py_BEGIN_ALLOW_THREADS @@ -1111,11 +1106,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) sqlite3_stmt *stmt = self->statement->st; assert(stmt != NULL); - if (sqlite3_data_count(stmt) == 0) { - (void)stmt_reset(self->statement); - Py_CLEAR(self->statement); - return NULL; - } + assert(sqlite3_data_count(stmt) != 0); self->locked = 1; // GH-80254: Prevent recursive use of cursors. PyObject *row = _pysqlite_fetch_one_row(self); @@ -1143,8 +1134,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) PyObject *factory = self->row_factory; PyObject *args[] = { (PyObject *)self, row, }; PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL); - Py_DECREF(row); - row = new_row; + Py_SETREF(row, new_row); } return row; } |
