gh-89301: Fix regression with bound values in traced SQLite statements (#92053)

This commit is contained in:
Erlend Egeberg Aasland 2022-05-02 08:14:35 -06:00 committed by GitHub
parent 6811bdef63
commit 721aa96540
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 105 additions and 16 deletions

View file

@ -20,12 +20,16 @@
# misrepresented as being the original software.
# 3. This notice may not be removed or altered from any source distribution.
import unittest
import contextlib
import sqlite3 as sqlite
import unittest
from test.support.os_helper import TESTFN, unlink
from test.test_sqlite3.test_dbapi import memory_database, cx_limit
from test.test_sqlite3.test_userfunctions import with_tracebacks
class CollationTests(unittest.TestCase):
def test_create_collation_not_string(self):
con = sqlite.connect(":memory:")
@ -224,6 +228,16 @@ class ProgressTests(unittest.TestCase):
class TraceCallbackTests(unittest.TestCase):
@contextlib.contextmanager
def check_stmt_trace(self, cx, expected):
try:
traced = []
cx.set_trace_callback(lambda stmt: traced.append(stmt))
yield
finally:
self.assertEqual(traced, expected)
cx.set_trace_callback(None)
def test_trace_callback_used(self):
"""
Test that the trace callback is invoked once it is set.
@ -289,6 +303,52 @@ class TraceCallbackTests(unittest.TestCase):
con2.close()
self.assertEqual(traced_statements, queries)
def test_trace_expanded_sql(self):
expected = [
"create table t(t)",
"BEGIN ",
"insert into t values(0)",
"insert into t values(1)",
"insert into t values(2)",
"COMMIT",
]
with memory_database() as cx, self.check_stmt_trace(cx, expected):
with cx:
cx.execute("create table t(t)")
cx.executemany("insert into t values(?)", ((v,) for v in range(3)))
@with_tracebacks(
sqlite.DataError,
regex="Expanded SQL string exceeds the maximum string length"
)
def test_trace_too_much_expanded_sql(self):
# If the expanded string is too large, we'll fall back to the
# unexpanded SQL statement (for SQLite 3.14.0 and newer).
# The resulting string length is limited by the runtime limit
# SQLITE_LIMIT_LENGTH.
template = "select 1 as a where a="
category = sqlite.SQLITE_LIMIT_LENGTH
with memory_database() as cx, cx_limit(cx, category=category) as lim:
ok_param = "a"
bad_param = "a" * lim
unexpanded_query = template + "?"
expected = [unexpanded_query]
if sqlite.sqlite_version_info < (3, 14, 0):
expected = []
with self.check_stmt_trace(cx, expected):
cx.execute(unexpanded_query, (bad_param,))
expanded_query = f"{template}'{ok_param}'"
with self.check_stmt_trace(cx, [expanded_query]):
cx.execute(unexpanded_query, (ok_param,))
@with_tracebacks(ZeroDivisionError, regex="division by zero")
def test_trace_bad_handler(self):
with memory_database() as cx:
cx.set_trace_callback(lambda stmt: 5/0)
cx.execute("select 1")
if __name__ == "__main__":
unittest.main()