Skip to content

Commit 7656761

Browse files
Erlend Egeberg AaslandSamuelMarks
Erlend Egeberg Aasland
authored andcommitted
[3.8] bpo-40318: Migrate to SQLite3 trace v2 API (pythonGH-19581)
Ref. https://sqlite.org/c3ref/trace_v2.html Co-authored-by: Pablo Galindo <[email protected]> (cherry picked from commit 7f331c8) Co-authored-by: Erlend Egeberg Aasland <[email protected]>
1 parent 1341582 commit 7656761

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use SQLite3 trace v2 API, if it is available.

Modules/_sqlite/connection.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
#define HAVE_BACKUP_API
4646
#endif
4747

48+
#if SQLITE_VERSION_NUMBER >= 3014000
49+
#define HAVE_TRACE_V2
50+
#endif
51+
4852
_Py_IDENTIFIER(cursor);
4953

5054
static const char * const begin_statements[] = {
@@ -964,13 +968,29 @@ static int _progress_handler(void* user_arg)
964968
return rc;
965969
}
966970

971+
#ifdef HAVE_TRACE_V2
972+
/*
973+
* From https://sqlite.org/c3ref/trace_v2.html:
974+
* The integer return value from the callback is currently ignored, though this
975+
* may change in future releases. Callback implementations should return zero
976+
* to ensure future compatibility.
977+
*/
978+
static int _trace_callback(unsigned int type, void* user_arg, void* prepared_statement, void* statement_string)
979+
#else
967980
static void _trace_callback(void* user_arg, const char* statement_string)
981+
#endif
968982
{
969983
PyObject *py_statement = NULL;
970984
PyObject *ret = NULL;
971985

972986
PyGILState_STATE gilstate;
973987

988+
#ifdef HAVE_TRACE_V2
989+
if (type != SQLITE_TRACE_STMT) {
990+
return 0;
991+
}
992+
#endif
993+
974994
gilstate = PyGILState_Ensure();
975995
py_statement = PyUnicode_DecodeUTF8(statement_string,
976996
strlen(statement_string), "replace");
@@ -990,6 +1010,9 @@ static void _trace_callback(void* user_arg, const char* statement_string)
9901010
}
9911011

9921012
PyGILState_Release(gilstate);
1013+
#ifdef HAVE_TRACE_V2
1014+
return 0;
1015+
#endif
9931016
}
9941017

9951018
static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
@@ -1048,6 +1071,11 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s
10481071
Py_RETURN_NONE;
10491072
}
10501073

1074+
/*
1075+
* Ref.
1076+
* - https://sqlite.org/c3ref/c_trace.html
1077+
* - https://sqlite.org/c3ref/trace_v2.html
1078+
*/
10511079
static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
10521080
{
10531081
PyObject* trace_callback;
@@ -1065,10 +1093,18 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel
10651093

10661094
if (trace_callback == Py_None) {
10671095
/* None clears the trace callback previously set */
1096+
#ifdef HAVE_TRACE_V2
1097+
sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, 0, 0);
1098+
#else
10681099
sqlite3_trace(self->db, 0, (void*)0);
1100+
#endif
10691101
Py_XSETREF(self->function_pinboard_trace_callback, NULL);
10701102
} else {
1103+
#ifdef HAVE_TRACE_V2
1104+
sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, _trace_callback, trace_callback);
1105+
#else
10711106
sqlite3_trace(self->db, _trace_callback, trace_callback);
1107+
#endif
10721108
Py_INCREF(trace_callback);
10731109
Py_XSETREF(self->function_pinboard_trace_callback, trace_callback);
10741110
}

0 commit comments

Comments
 (0)