From c959d36ece7613f647c3ab9df42a7c05a5aed67e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 18 Apr 2020 13:31:44 +0200 Subject: [PATCH 1/3] Use new sqlite3_trace_v2() API if possible Ref. https://sqlite.org/c3ref/trace_v2.html --- Modules/_sqlite/connection.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 958be7d869794a..ac6585dc472751 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -43,6 +43,10 @@ #define HAVE_BACKUP_API #endif +#if SQLITE_VERSION_NUMBER >= 3014000 +#define HAVE_TRACE_V2 +#endif + _Py_IDENTIFIER(cursor); static const char * const begin_statements[] = { @@ -962,13 +966,28 @@ static int _progress_handler(void* user_arg) return rc; } +#ifdef HAVE_TRACE_V2 +/* + * From https://sqlite.org/c3ref/trace_v2.html: + * The integer return value from the callback is currently ignored, though this + * may change in future releases. Callback implementations should return zero + * to ensure future compatibility. + */ +static int _trace_callback(unsigned int type, void* user_arg, void* prepared_statement, void* statement_string) +#else static void _trace_callback(void* user_arg, const char* statement_string) +#endif { PyObject *py_statement = NULL; PyObject *ret = NULL; PyGILState_STATE gilstate; +#ifdef HAVE_TRACE_V2 + if (type != SQLITE_TRACE_STMT) + return 0; +#endif + gilstate = PyGILState_Ensure(); py_statement = PyUnicode_DecodeUTF8(statement_string, strlen(statement_string), "replace"); @@ -988,6 +1007,9 @@ static void _trace_callback(void* user_arg, const char* statement_string) } PyGILState_Release(gilstate); +#ifdef HAVE_TRACE_V2 + return 0; +#endif } static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) @@ -1046,6 +1068,11 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s Py_RETURN_NONE; } +/* + * Ref. + * - https://sqlite.org/c3ref/c_trace.html + * - https://sqlite.org/c3ref/trace_v2.html + */ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* trace_callback; @@ -1063,10 +1090,18 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel if (trace_callback == Py_None) { /* None clears the trace callback previously set */ +#ifdef HAVE_TRACE_V2 + sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, 0, 0); +#else sqlite3_trace(self->db, 0, (void*)0); +#endif Py_XSETREF(self->function_pinboard_trace_callback, NULL); } else { +#ifdef HAVE_TRACE_V2 + sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, _trace_callback, trace_callback); +#else sqlite3_trace(self->db, _trace_callback, trace_callback); +#endif Py_INCREF(trace_callback); Py_XSETREF(self->function_pinboard_trace_callback, trace_callback); } From f1ae11cdf7dec16d99d9eca315cf533ff9ace0bb Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 18 Apr 2020 14:16:54 +0200 Subject: [PATCH 2/3] Add NEWS entry --- .../NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst diff --git a/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst b/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst new file mode 100644 index 00000000000000..3d5fcfb74a0fe5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst @@ -0,0 +1 @@ +Use SQLite3 trace v2 API, if it is available. From 8980855d15ab216658a1e22b3770ccdcdd34dd32 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 5 Sep 2020 20:46:02 +0100 Subject: [PATCH 3/3] Update Modules/_sqlite/connection.c --- Modules/_sqlite/connection.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index ac6585dc472751..1bf9710763a5ab 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -984,8 +984,9 @@ static void _trace_callback(void* user_arg, const char* statement_string) PyGILState_STATE gilstate; #ifdef HAVE_TRACE_V2 - if (type != SQLITE_TRACE_STMT) + if (type != SQLITE_TRACE_STMT) { return 0; + } #endif gilstate = PyGILState_Ensure();