Skip to content

Commit 7f331c8

Browse files
Erlend Egeberg Aaslandpablogsal
Erlend Egeberg Aasland
andauthored
bpo-40318: Migrate to SQLite3 trace v2 API (GH-19581)
Ref. https://sqlite.org/c3ref/trace_v2.html Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
1 parent 8c0be6f commit 7f331c8

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed
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

+36
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
#define HAVE_BACKUP_API
4444
#endif
4545

46+
#if SQLITE_VERSION_NUMBER >= 3014000
47+
#define HAVE_TRACE_V2
48+
#endif
49+
4650
_Py_IDENTIFIER(cursor);
4751

4852
static const char * const begin_statements[] = {
@@ -962,13 +966,29 @@ static int _progress_handler(void* user_arg)
962966
return rc;
963967
}
964968

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

970984
PyGILState_STATE gilstate;
971985

986+
#ifdef HAVE_TRACE_V2
987+
if (type != SQLITE_TRACE_STMT) {
988+
return 0;
989+
}
990+
#endif
991+
972992
gilstate = PyGILState_Ensure();
973993
py_statement = PyUnicode_DecodeUTF8(statement_string,
974994
strlen(statement_string), "replace");
@@ -988,6 +1008,9 @@ static void _trace_callback(void* user_arg, const char* statement_string)
9881008
}
9891009

9901010
PyGILState_Release(gilstate);
1011+
#ifdef HAVE_TRACE_V2
1012+
return 0;
1013+
#endif
9911014
}
9921015

9931016
static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
@@ -1046,6 +1069,11 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s
10461069
Py_RETURN_NONE;
10471070
}
10481071

1072+
/*
1073+
* Ref.
1074+
* - https://sqlite.org/c3ref/c_trace.html
1075+
* - https://sqlite.org/c3ref/trace_v2.html
1076+
*/
10491077
static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
10501078
{
10511079
PyObject* trace_callback;
@@ -1063,10 +1091,18 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel
10631091

10641092
if (trace_callback == Py_None) {
10651093
/* None clears the trace callback previously set */
1094+
#ifdef HAVE_TRACE_V2
1095+
sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, 0, 0);
1096+
#else
10661097
sqlite3_trace(self->db, 0, (void*)0);
1098+
#endif
10671099
Py_XSETREF(self->function_pinboard_trace_callback, NULL);
10681100
} else {
1101+
#ifdef HAVE_TRACE_V2
1102+
sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, _trace_callback, trace_callback);
1103+
#else
10691104
sqlite3_trace(self->db, _trace_callback, trace_callback);
1105+
#endif
10701106
Py_INCREF(trace_callback);
10711107
Py_XSETREF(self->function_pinboard_trace_callback, trace_callback);
10721108
}

0 commit comments

Comments
 (0)