diff options
author | Benjamin Peterson <benjamin@python.org> | 2017-09-20 14:36:18 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-20 14:36:18 (GMT) |
commit | 525269430a3f9fbb7287e4bb6b365ac216004980 (patch) | |
tree | 2d773b5d8ee8582da1b90bcbd17bb3ffc9ce25f7 /Modules/_sqlite | |
parent | 0ad05c32cc41d4c21bfd78b9ffead519ead475a2 (diff) | |
download | cpython-525269430a3f9fbb7287e4bb6b365ac216004980.zip cpython-525269430a3f9fbb7287e4bb6b365ac216004980.tar.gz cpython-525269430a3f9fbb7287e4bb6b365ac216004980.tar.bz2 |
closes bpo-31525: require sqlite3_prepare_v2 (#3666)
This is based on
https://github.com/ghaering/pysqlite/commit/40b349cadbd87c42f70fc92e5e1aee6d02564c6d#diff-0489411409cd2934730e88bf7767790,
though we can be a bit more aggressive about deleting code.
Diffstat (limited to 'Modules/_sqlite')
-rw-r--r-- | Modules/_sqlite/connection.c | 6 | ||||
-rw-r--r-- | Modules/_sqlite/cursor.c | 97 | ||||
-rw-r--r-- | Modules/_sqlite/statement.c | 56 | ||||
-rw-r--r-- | Modules/_sqlite/statement.h | 1 | ||||
-rw-r--r-- | Modules/_sqlite/util.c | 12 | ||||
-rw-r--r-- | Modules/_sqlite/util.h | 6 |
6 files changed, 43 insertions, 135 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index f596bcf..2759116 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -375,7 +375,7 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self) sqlite3_stmt* statement; Py_BEGIN_ALLOW_THREADS - rc = SQLITE3_PREPARE(self->db, self->begin_statement, -1, &statement, &tail); + rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement, &tail); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { @@ -417,7 +417,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args) if (!sqlite3_get_autocommit(self->db)) { Py_BEGIN_ALLOW_THREADS - rc = SQLITE3_PREPARE(self->db, "COMMIT", -1, &statement, &tail); + rc = sqlite3_prepare_v2(self->db, "COMMIT", -1, &statement, &tail); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); @@ -460,7 +460,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args pysqlite_do_all_statements(self, ACTION_RESET, 1); Py_BEGIN_ALLOW_THREADS - rc = SQLITE3_PREPARE(self->db, "ROLLBACK", -1, &statement, &tail); + rc = sqlite3_prepare_v2(self->db, "ROLLBACK", -1, &statement, &tail); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index ba6e52d..cfe2627 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -536,47 +536,19 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* goto error; } - /* Keep trying the SQL statement until the schema stops changing. */ - while (1) { - /* Actually execute the SQL statement. */ - rc = pysqlite_step(self->statement->st, self->connection); + rc = pysqlite_step(self->statement->st, self->connection); + if (rc != SQLITE_DONE && rc != SQLITE_ROW) { if (PyErr_Occurred()) { - (void)pysqlite_statement_reset(self->statement); - goto error; - } - if (rc == SQLITE_DONE || rc == SQLITE_ROW) { - /* If it worked, let's get out of the loop */ - break; - } -#if SQLITE_VERSION_NUMBER < 3003009 - /* Something went wrong. Re-set the statement and try again. */ - rc = pysqlite_statement_reset(self->statement); -#endif - if (rc == SQLITE_SCHEMA) { - /* If this was a result of the schema changing, let's try - again. */ - rc = pysqlite_statement_recompile(self->statement, parameters); - if (rc == SQLITE_OK) { - continue; + /* there was an error that occurred in a user-defined callback */ + if (_enable_callback_tracebacks) { + PyErr_Print(); } else { - /* If the database gave us an error, promote it to Python. */ - (void)pysqlite_statement_reset(self->statement); - _pysqlite_seterror(self->connection->db, NULL); - goto error; - } - } else { - if (PyErr_Occurred()) { - /* there was an error that occurred in a user-defined callback */ - if (_enable_callback_tracebacks) { - PyErr_Print(); - } else { - PyErr_Clear(); - } + PyErr_Clear(); } - (void)pysqlite_statement_reset(self->statement); - _pysqlite_seterror(self->connection->db, NULL); - goto error; } + (void)pysqlite_statement_reset(self->statement); + _pysqlite_seterror(self->connection->db, NULL); + goto error; } if (pysqlite_build_row_cast_map(self) != 0) { @@ -584,29 +556,28 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* goto error; } - if (rc == SQLITE_ROW || rc == SQLITE_DONE) { - Py_BEGIN_ALLOW_THREADS - numcols = sqlite3_column_count(self->statement->st); - Py_END_ALLOW_THREADS - if (self->description == Py_None && numcols > 0) { - Py_SETREF(self->description, PyTuple_New(numcols)); - if (!self->description) { + assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + Py_BEGIN_ALLOW_THREADS + numcols = sqlite3_column_count(self->statement->st); + Py_END_ALLOW_THREADS + if (self->description == Py_None && numcols > 0) { + Py_SETREF(self->description, PyTuple_New(numcols)); + if (!self->description) { + goto error; + } + for (i = 0; i < numcols; i++) { + descriptor = PyTuple_New(7); + if (!descriptor) { goto error; } - for (i = 0; i < numcols; i++) { - descriptor = PyTuple_New(7); - if (!descriptor) { - goto error; - } - PyTuple_SetItem(descriptor, 0, _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i))); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None); - PyTuple_SetItem(self->description, i, descriptor); - } + PyTuple_SetItem(descriptor, 0, _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i))); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None); + PyTuple_SetItem(self->description, i, descriptor); } } @@ -708,11 +679,11 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) while (1) { Py_BEGIN_ALLOW_THREADS - rc = SQLITE3_PREPARE(self->connection->db, - script_cstr, - -1, - &statement, - &script_cstr); + rc = sqlite3_prepare_v2(self->connection->db, + script_cstr, + -1, + &statement, + &script_cstr); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->connection->db, NULL); diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index bc0d940..3869088 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -93,11 +93,11 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con } Py_BEGIN_ALLOW_THREADS - rc = SQLITE3_PREPARE(connection->db, - sql_cstr, - -1, - &self->st, - &tail); + rc = sqlite3_prepare_v2(connection->db, + sql_cstr, + -1, + &self->st, + &tail); Py_END_ALLOW_THREADS self->db = connection->db; @@ -319,52 +319,6 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para } } -int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* params) -{ - const char* tail; - int rc; - const char* sql_cstr; - Py_ssize_t sql_len; - sqlite3_stmt* new_st; - - sql_cstr = PyUnicode_AsUTF8AndSize(self->sql, &sql_len); - if (sql_cstr == NULL) { - rc = PYSQLITE_SQL_WRONG_TYPE; - return rc; - } - - Py_BEGIN_ALLOW_THREADS - rc = SQLITE3_PREPARE(self->db, - sql_cstr, - -1, - &new_st, - &tail); - Py_END_ALLOW_THREADS - - if (rc == SQLITE_OK) { - /* The efficient sqlite3_transfer_bindings is only available in SQLite - * version 3.2.2 or later. For older SQLite releases, that might not - * even define SQLITE_VERSION_NUMBER, we do it the manual way. - */ - #ifdef SQLITE_VERSION_NUMBER - #if SQLITE_VERSION_NUMBER >= 3002002 - /* The check for the number of parameters is necessary to not trigger a - * bug in certain SQLite versions (experienced in 3.2.8 and 3.3.4). */ - if (sqlite3_bind_parameter_count(self->st) > 0) { - (void)sqlite3_transfer_bindings(self->st, new_st); - } - #endif - #else - statement_bind_parameters(self, params); - #endif - - (void)sqlite3_finalize(self->st); - self->st = new_st; - } - - return rc; -} - int pysqlite_statement_finalize(pysqlite_Statement* self) { int rc; diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index 8db10f6..fd88d7d 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -50,7 +50,6 @@ void pysqlite_statement_dealloc(pysqlite_Statement* self); int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter); void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters); -int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* parameters); int pysqlite_statement_finalize(pysqlite_Statement* self); int pysqlite_statement_reset(pysqlite_Statement* self); void pysqlite_statement_mark_dirty(pysqlite_Statement* self); diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index b371aed..3fa671d 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -47,17 +47,7 @@ int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection) */ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st) { - int errorcode; - -#if SQLITE_VERSION_NUMBER < 3003009 - /* SQLite often doesn't report anything useful, unless you reset the statement first. - When using sqlite3_prepare_v2 this is not needed. */ - if (st != NULL) { - (void)sqlite3_reset(st); - } -#endif - - errorcode = sqlite3_errcode(db); + int errorcode = sqlite3_errcode(db); switch (errorcode) { diff --git a/Modules/_sqlite/util.h b/Modules/_sqlite/util.h index 9106fca..abaefd8 100644 --- a/Modules/_sqlite/util.h +++ b/Modules/_sqlite/util.h @@ -39,12 +39,6 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st); PyObject * _pysqlite_long_from_int64(sqlite_int64 value); sqlite_int64 _pysqlite_long_as_int64(PyObject * value); -#if SQLITE_VERSION_NUMBER >= 3003009 -#define SQLITE3_PREPARE sqlite3_prepare_v2 -#else -#define SQLITE3_PREPARE sqlite3_prepare -#endif - #if SQLITE_VERSION_NUMBER >= 3007014 #define SQLITE3_CLOSE sqlite3_close_v2 #else |