summaryrefslogtreecommitdiffstats
path: root/Modules/_sqlite
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2017-09-20 14:36:18 (GMT)
committerGitHub <noreply@github.com>2017-09-20 14:36:18 (GMT)
commit525269430a3f9fbb7287e4bb6b365ac216004980 (patch)
tree2d773b5d8ee8582da1b90bcbd17bb3ffc9ce25f7 /Modules/_sqlite
parent0ad05c32cc41d4c21bfd78b9ffead519ead475a2 (diff)
downloadcpython-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.c6
-rw-r--r--Modules/_sqlite/cursor.c97
-rw-r--r--Modules/_sqlite/statement.c56
-rw-r--r--Modules/_sqlite/statement.h1
-rw-r--r--Modules/_sqlite/util.c12
-rw-r--r--Modules/_sqlite/util.h6
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