From 979b23cbe44071b056ff524c0aa20e5d9794b5b0 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Fri, 19 Feb 2021 12:20:32 +0100 Subject: bpo-43258: Don't allocate sqlite3 aggregate context for empty queries (GH-24569) --- Lib/sqlite3/test/userfunctions.py | 5 +++++ Misc/NEWS.d/next/Library/2021-02-18-23-30-52.bpo-43258.LeU-q8.rst | 2 ++ Modules/_sqlite/connection.c | 8 ++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-02-18-23-30-52.bpo-43258.LeU-q8.rst diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 2285abd..749ea04 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -429,6 +429,11 @@ class AggregateTests(unittest.TestCase): val = cur.fetchone()[0] self.assertEqual(val, 60) + def test_aggr_no_match(self): + cur = self.con.execute("select mysum(i) from (select 1 as i) where i == 0") + val = cur.fetchone()[0] + self.assertIsNone(val) + class AuthorizerTests(unittest.TestCase): @staticmethod def authorizer_cb(action, arg1, arg2, dbname, source): diff --git a/Misc/NEWS.d/next/Library/2021-02-18-23-30-52.bpo-43258.LeU-q8.rst b/Misc/NEWS.d/next/Library/2021-02-18-23-30-52.bpo-43258.LeU-q8.rst new file mode 100644 index 0000000..0529214 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-02-18-23-30-52.bpo-43258.LeU-q8.rst @@ -0,0 +1,2 @@ +Prevent needless allocation of :mod:`sqlite3` aggregate function context +when no rows match an aggregate query. Patch by Erlend E. Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 63fcb00..39b55fc 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -708,8 +708,12 @@ void _pysqlite_final_callback(sqlite3_context* context) threadstate = PyGILState_Ensure(); - aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); - if (!*aggregate_instance) { + aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, 0); + if (aggregate_instance == NULL) { + /* No rows matched the query; the step handler was never called. */ + goto error; + } + else if (!*aggregate_instance) { /* this branch is executed if there was an exception in the aggregate's * __init__ */ -- cgit v0.12