Skip to content

Commit e801e88

Browse files
author
Erlend Egeberg Aasland
authored
bpo-45138: Revert GH-28240: Expand traced SQL statements (GH-31788)
This reverts commit d177751. Automerge-Triggered-By: GH:JelleZijlstra
1 parent 23dcea5 commit e801e88

File tree

5 files changed

+15
-108
lines changed

5 files changed

+15
-108
lines changed

Doc/library/sqlite3.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -560,9 +560,6 @@ Connection Objects
560560

561561
Passing :const:`None` as *trace_callback* will disable the trace callback.
562562

563-
For SQLite 3.14.0 and newer, bound parameters are expanded in the passed
564-
statement string.
565-
566563
.. note::
567564
Exceptions raised in the trace callback are not propagated. As a
568565
development and debugging aid, use
@@ -571,9 +568,6 @@ Connection Objects
571568

572569
.. versionadded:: 3.3
573570

574-
.. versionchanged:: 3.11
575-
Added support for expanded SQL statements.
576-
577571

578572
.. method:: enable_load_extension(enabled)
579573

Doc/whatsnew/3.11.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,6 @@ sqlite3
334334
Instead we leave it to the SQLite library to handle these cases.
335335
(Contributed by Erlend E. Aasland in :issue:`44092`.)
336336

337-
* For SQLite 3.14.0 and newer, bound parameters are expanded in the statement
338-
string passed to the trace callback. See :meth:`~sqlite3.Connection.set_trace_callback`.
339-
(Contributed by Erlend E. Aasland in :issue:`45138`.)
340-
341337

342338
sys
343339
---

Lib/test/test_sqlite3/test_hooks.py

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,12 @@
2020
# misrepresented as being the original software.
2121
# 3. This notice may not be removed or altered from any source distribution.
2222

23-
import contextlib
24-
import sqlite3 as sqlite
2523
import unittest
24+
import sqlite3 as sqlite
2625

2726
from test.support.os_helper import TESTFN, unlink
28-
29-
from test.test_sqlite3.test_dbapi import memory_database, cx_limit
3027
from test.test_sqlite3.test_userfunctions import with_tracebacks
3128

32-
3329
class CollationTests(unittest.TestCase):
3430
def test_create_collation_not_string(self):
3531
con = sqlite.connect(":memory:")
@@ -228,16 +224,6 @@ def bad_progress():
228224

229225

230226
class TraceCallbackTests(unittest.TestCase):
231-
@contextlib.contextmanager
232-
def check_stmt_trace(self, cx, expected):
233-
try:
234-
traced = []
235-
cx.set_trace_callback(lambda stmt: traced.append(stmt))
236-
yield
237-
finally:
238-
self.assertEqual(traced, expected)
239-
cx.set_trace_callback(None)
240-
241227
def test_trace_callback_used(self):
242228
"""
243229
Test that the trace callback is invoked once it is set.
@@ -303,51 +289,6 @@ def trace(statement):
303289
con2.close()
304290
self.assertEqual(traced_statements, queries)
305291

306-
@unittest.skipIf(sqlite.sqlite_version_info < (3, 14, 0),
307-
"Requires SQLite 3.14.0 or newer")
308-
def test_trace_expanded_sql(self):
309-
expected = [
310-
"create table t(t)",
311-
"BEGIN ",
312-
"insert into t values(0)",
313-
"insert into t values(1)",
314-
"insert into t values(2)",
315-
"COMMIT",
316-
]
317-
with memory_database() as cx, self.check_stmt_trace(cx, expected):
318-
with cx:
319-
cx.execute("create table t(t)")
320-
cx.executemany("insert into t values(?)", ((v,) for v in range(3)))
321-
322-
@with_tracebacks(
323-
sqlite.DataError,
324-
regex="Expanded SQL string exceeds the maximum string length"
325-
)
326-
def test_trace_too_much_expanded_sql(self):
327-
# If the expanded string is too large, we'll fall back to the
328-
# unexpanded SQL statement. The resulting string length is limited by
329-
# SQLITE_LIMIT_LENGTH.
330-
template = "select 'b' as \"a\" from sqlite_master where \"a\"="
331-
category = sqlite.SQLITE_LIMIT_LENGTH
332-
with memory_database() as cx, cx_limit(cx, category=category) as lim:
333-
nextra = lim - (len(template) + 2) - 1
334-
ok_param = "a" * nextra
335-
bad_param = "a" * (nextra + 1)
336-
337-
unexpanded_query = template + "?"
338-
with self.check_stmt_trace(cx, [unexpanded_query]):
339-
cx.execute(unexpanded_query, (bad_param,))
340-
341-
expanded_query = f"{template}'{ok_param}'"
342-
with self.check_stmt_trace(cx, [expanded_query]):
343-
cx.execute(unexpanded_query, (ok_param,))
344-
345-
@with_tracebacks(ZeroDivisionError, regex="division by zero")
346-
def test_trace_bad_handler(self):
347-
with memory_database() as cx:
348-
cx.set_trace_callback(lambda stmt: 5/0)
349-
cx.execute("select 1")
350-
351292

352293
if __name__ == "__main__":
353294
unittest.main()

Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst

Lines changed: 0 additions & 3 deletions
This file was deleted.

Modules/_sqlite/connection.c

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,10 +1079,11 @@ progress_callback(void *ctx)
10791079
* to ensure future compatibility.
10801080
*/
10811081
static int
1082-
trace_callback(unsigned int type, void *ctx, void *stmt, void *sql)
1082+
trace_callback(unsigned int type, void *ctx, void *prepared_statement,
1083+
void *statement_string)
10831084
#else
10841085
static void
1085-
trace_callback(void *ctx, const char *sql)
1086+
trace_callback(void *ctx, const char *statement_string)
10861087
#endif
10871088
{
10881089
#ifdef HAVE_TRACE_V2
@@ -1093,46 +1094,24 @@ trace_callback(void *ctx, const char *sql)
10931094

10941095
PyGILState_STATE gilstate = PyGILState_Ensure();
10951096

1096-
assert(ctx != NULL);
10971097
PyObject *py_statement = NULL;
1098-
#ifdef HAVE_TRACE_V2
1099-
assert(stmt != NULL);
1100-
const char *expanded_sql = sqlite3_expanded_sql((sqlite3_stmt *)stmt);
1101-
if (expanded_sql == NULL) {
1102-
sqlite3 *db = sqlite3_db_handle((sqlite3_stmt *)stmt);
1103-
if (sqlite3_errcode(db) == SQLITE_NOMEM) {
1104-
(void)PyErr_NoMemory();
1105-
goto exit;
1106-
}
1107-
1108-
pysqlite_state *state = ((callback_context *)ctx)->state;
1109-
assert(state != NULL);
1110-
PyErr_SetString(state->DataError,
1111-
"Expanded SQL string exceeds the maximum string "
1112-
"length");
1113-
print_or_clear_traceback((callback_context *)ctx);
1114-
1115-
// Fall back to unexpanded sql
1116-
py_statement = PyUnicode_FromString((const char *)sql);
1117-
}
1118-
else {
1119-
py_statement = PyUnicode_FromString(expanded_sql);
1120-
sqlite3_free((void *)expanded_sql);
1121-
}
1122-
#else
1123-
py_statement = PyUnicode_FromString(sql);
1124-
#endif
1098+
PyObject *ret = NULL;
1099+
py_statement = PyUnicode_DecodeUTF8(statement_string,
1100+
strlen(statement_string), "replace");
1101+
assert(ctx != NULL);
11251102
if (py_statement) {
11261103
PyObject *callable = ((callback_context *)ctx)->callable;
1127-
PyObject *ret = PyObject_CallOneArg(callable, py_statement);
1104+
ret = PyObject_CallOneArg(callable, py_statement);
11281105
Py_DECREF(py_statement);
1129-
Py_XDECREF(ret);
11301106
}
11311107

1132-
exit:
1133-
if (PyErr_Occurred()) {
1134-
print_or_clear_traceback((callback_context *)ctx);
1108+
if (ret) {
1109+
Py_DECREF(ret);
11351110
}
1111+
else {
1112+
print_or_clear_traceback(ctx);
1113+
}
1114+
11361115
PyGILState_Release(gilstate);
11371116
#ifdef HAVE_TRACE_V2
11381117
return 0;

0 commit comments

Comments
 (0)