Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5252694

Browse files
authored
closes bpo-31525: require sqlite3_prepare_v2 (#3666)
This is based on ghaering/pysqlite@40b349c#diff-0489411409cd2934730e88bf7767790, though we can be a bit more aggressive about deleting code.
1 parent 0ad05c3 commit 5252694

7 files changed

Lines changed: 44 additions & 135 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
In the sqlite module, require the sqlite3_prepare_v2 API. Thus, the sqlite module now requires sqlite version at least 3.3.9.

Modules/_sqlite/connection.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
375375
sqlite3_stmt* statement;
376376

377377
Py_BEGIN_ALLOW_THREADS
378-
rc = SQLITE3_PREPARE(self->db, self->begin_statement, -1, &statement, &tail);
378+
rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement, &tail);
379379
Py_END_ALLOW_THREADS
380380

381381
if (rc != SQLITE_OK) {
@@ -417,7 +417,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
417417
if (!sqlite3_get_autocommit(self->db)) {
418418

419419
Py_BEGIN_ALLOW_THREADS
420-
rc = SQLITE3_PREPARE(self->db, "COMMIT", -1, &statement, &tail);
420+
rc = sqlite3_prepare_v2(self->db, "COMMIT", -1, &statement, &tail);
421421
Py_END_ALLOW_THREADS
422422
if (rc != SQLITE_OK) {
423423
_pysqlite_seterror(self->db, NULL);
@@ -460,7 +460,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
460460
pysqlite_do_all_statements(self, ACTION_RESET, 1);
461461

462462
Py_BEGIN_ALLOW_THREADS
463-
rc = SQLITE3_PREPARE(self->db, "ROLLBACK", -1, &statement, &tail);
463+
rc = sqlite3_prepare_v2(self->db, "ROLLBACK", -1, &statement, &tail);
464464
Py_END_ALLOW_THREADS
465465
if (rc != SQLITE_OK) {
466466
_pysqlite_seterror(self->db, NULL);

Modules/_sqlite/cursor.c

Lines changed: 34 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -536,77 +536,48 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
536536
goto error;
537537
}
538538

539-
/* Keep trying the SQL statement until the schema stops changing. */
540-
while (1) {
541-
/* Actually execute the SQL statement. */
542-
rc = pysqlite_step(self->statement->st, self->connection);
539+
rc = pysqlite_step(self->statement->st, self->connection);
540+
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
543541
if (PyErr_Occurred()) {
544-
(void)pysqlite_statement_reset(self->statement);
545-
goto error;
546-
}
547-
if (rc == SQLITE_DONE || rc == SQLITE_ROW) {
548-
/* If it worked, let's get out of the loop */
549-
break;
550-
}
551-
#if SQLITE_VERSION_NUMBER < 3003009
552-
/* Something went wrong. Re-set the statement and try again. */
553-
rc = pysqlite_statement_reset(self->statement);
554-
#endif
555-
if (rc == SQLITE_SCHEMA) {
556-
/* If this was a result of the schema changing, let's try
557-
again. */
558-
rc = pysqlite_statement_recompile(self->statement, parameters);
559-
if (rc == SQLITE_OK) {
560-
continue;
542+
/* there was an error that occurred in a user-defined callback */
543+
if (_enable_callback_tracebacks) {
544+
PyErr_Print();
561545
} else {
562-
/* If the database gave us an error, promote it to Python. */
563-
(void)pysqlite_statement_reset(self->statement);
564-
_pysqlite_seterror(self->connection->db, NULL);
565-
goto error;
566-
}
567-
} else {
568-
if (PyErr_Occurred()) {
569-
/* there was an error that occurred in a user-defined callback */
570-
if (_enable_callback_tracebacks) {
571-
PyErr_Print();
572-
} else {
573-
PyErr_Clear();
574-
}
546+
PyErr_Clear();
575547
}
576-
(void)pysqlite_statement_reset(self->statement);
577-
_pysqlite_seterror(self->connection->db, NULL);
578-
goto error;
579548
}
549+
(void)pysqlite_statement_reset(self->statement);
550+
_pysqlite_seterror(self->connection->db, NULL);
551+
goto error;
580552
}
581553

582554
if (pysqlite_build_row_cast_map(self) != 0) {
583555
PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map");
584556
goto error;
585557
}
586558

587-
if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
588-
Py_BEGIN_ALLOW_THREADS
589-
numcols = sqlite3_column_count(self->statement->st);
590-
Py_END_ALLOW_THREADS
591-
if (self->description == Py_None && numcols > 0) {
592-
Py_SETREF(self->description, PyTuple_New(numcols));
593-
if (!self->description) {
559+
assert(rc == SQLITE_ROW || rc == SQLITE_DONE);
560+
Py_BEGIN_ALLOW_THREADS
561+
numcols = sqlite3_column_count(self->statement->st);
562+
Py_END_ALLOW_THREADS
563+
if (self->description == Py_None && numcols > 0) {
564+
Py_SETREF(self->description, PyTuple_New(numcols));
565+
if (!self->description) {
566+
goto error;
567+
}
568+
for (i = 0; i < numcols; i++) {
569+
descriptor = PyTuple_New(7);
570+
if (!descriptor) {
594571
goto error;
595572
}
596-
for (i = 0; i < numcols; i++) {
597-
descriptor = PyTuple_New(7);
598-
if (!descriptor) {
599-
goto error;
600-
}
601-
PyTuple_SetItem(descriptor, 0, _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i)));
602-
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
603-
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
604-
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None);
605-
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None);
606-
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None);
607-
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None);
608-
PyTuple_SetItem(self->description, i, descriptor);
609-
}
573+
PyTuple_SetItem(descriptor, 0, _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i)));
574+
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
575+
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
576+
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None);
577+
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None);
578+
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None);
579+
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None);
580+
PyTuple_SetItem(self->description, i, descriptor);
610581
}
611582
}
612583

@@ -708,11 +679,11 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
708679

709680
while (1) {
710681
Py_BEGIN_ALLOW_THREADS
711-
rc = SQLITE3_PREPARE(self->connection->db,
712-
script_cstr,
713-
-1,
714-
&statement,
715-
&script_cstr);
682+
rc = sqlite3_prepare_v2(self->connection->db,
683+
script_cstr,
684+
-1,
685+
&statement,
686+
&script_cstr);
716687
Py_END_ALLOW_THREADS
717688
if (rc != SQLITE_OK) {
718689
_pysqlite_seterror(self->connection->db, NULL);

Modules/_sqlite/statement.c

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
9393
}
9494

9595
Py_BEGIN_ALLOW_THREADS
96-
rc = SQLITE3_PREPARE(connection->db,
97-
sql_cstr,
98-
-1,
99-
&self->st,
100-
&tail);
96+
rc = sqlite3_prepare_v2(connection->db,
97+
sql_cstr,
98+
-1,
99+
&self->st,
100+
&tail);
101101
Py_END_ALLOW_THREADS
102102

103103
self->db = connection->db;
@@ -319,52 +319,6 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
319319
}
320320
}
321321

322-
int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* params)
323-
{
324-
const char* tail;
325-
int rc;
326-
const char* sql_cstr;
327-
Py_ssize_t sql_len;
328-
sqlite3_stmt* new_st;
329-
330-
sql_cstr = PyUnicode_AsUTF8AndSize(self->sql, &sql_len);
331-
if (sql_cstr == NULL) {
332-
rc = PYSQLITE_SQL_WRONG_TYPE;
333-
return rc;
334-
}
335-
336-
Py_BEGIN_ALLOW_THREADS
337-
rc = SQLITE3_PREPARE(self->db,
338-
sql_cstr,
339-
-1,
340-
&new_st,
341-
&tail);
342-
Py_END_ALLOW_THREADS
343-
344-
if (rc == SQLITE_OK) {
345-
/* The efficient sqlite3_transfer_bindings is only available in SQLite
346-
* version 3.2.2 or later. For older SQLite releases, that might not
347-
* even define SQLITE_VERSION_NUMBER, we do it the manual way.
348-
*/
349-
#ifdef SQLITE_VERSION_NUMBER
350-
#if SQLITE_VERSION_NUMBER >= 3002002
351-
/* The check for the number of parameters is necessary to not trigger a
352-
* bug in certain SQLite versions (experienced in 3.2.8 and 3.3.4). */
353-
if (sqlite3_bind_parameter_count(self->st) > 0) {
354-
(void)sqlite3_transfer_bindings(self->st, new_st);
355-
}
356-
#endif
357-
#else
358-
statement_bind_parameters(self, params);
359-
#endif
360-
361-
(void)sqlite3_finalize(self->st);
362-
self->st = new_st;
363-
}
364-
365-
return rc;
366-
}
367-
368322
int pysqlite_statement_finalize(pysqlite_Statement* self)
369323
{
370324
int rc;

Modules/_sqlite/statement.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ void pysqlite_statement_dealloc(pysqlite_Statement* self);
5050
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter);
5151
void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters);
5252

53-
int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* parameters);
5453
int pysqlite_statement_finalize(pysqlite_Statement* self);
5554
int pysqlite_statement_reset(pysqlite_Statement* self);
5655
void pysqlite_statement_mark_dirty(pysqlite_Statement* self);

Modules/_sqlite/util.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,7 @@ int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection)
4747
*/
4848
int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
4949
{
50-
int errorcode;
51-
52-
#if SQLITE_VERSION_NUMBER < 3003009
53-
/* SQLite often doesn't report anything useful, unless you reset the statement first.
54-
When using sqlite3_prepare_v2 this is not needed. */
55-
if (st != NULL) {
56-
(void)sqlite3_reset(st);
57-
}
58-
#endif
59-
60-
errorcode = sqlite3_errcode(db);
50+
int errorcode = sqlite3_errcode(db);
6151

6252
switch (errorcode)
6353
{

Modules/_sqlite/util.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st);
3939
PyObject * _pysqlite_long_from_int64(sqlite_int64 value);
4040
sqlite_int64 _pysqlite_long_as_int64(PyObject * value);
4141

42-
#if SQLITE_VERSION_NUMBER >= 3003009
43-
#define SQLITE3_PREPARE sqlite3_prepare_v2
44-
#else
45-
#define SQLITE3_PREPARE sqlite3_prepare
46-
#endif
47-
4842
#if SQLITE_VERSION_NUMBER >= 3007014
4943
#define SQLITE3_CLOSE sqlite3_close_v2
5044
#else

0 commit comments

Comments
 (0)