From 40542badbcf5fee982e555bc690073d1e1da52e2 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 27 May 2020 12:20:32 +0200 Subject: [PATCH 1/8] Fix sqlite3 deterministic test --- Lib/sqlite3/test/userfunctions.py | 19 +++++++++++++------ .../2020-05-27-11-17-02.bpo-40784.hYEBjs.rst | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 9501f535c49999..43911f8518b931 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -158,6 +158,7 @@ def setUp(self): self.con.create_function("isblob", 1, func_isblob) self.con.create_function("islonglong", 1, func_islonglong) self.con.create_function("spam", -1, func) + self.con.execute("create table test(t text)") def tearDown(self): self.con.close() @@ -276,18 +277,24 @@ def CheckAnyArguments(self): val = cur.fetchone()[0] self.assertEqual(val, 2) + @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") def CheckFuncNonDeterministic(self): + """Non-deterministic functions cannot be used with partial indices""" mock = unittest.mock.Mock(return_value=None) - self.con.create_function("deterministic", 0, mock, deterministic=False) - self.con.execute("select deterministic() = deterministic()") - self.assertEqual(mock.call_count, 2) + self.con.create_function("nondeterministic", 0, mock, deterministic=False) + with self.assertRaises(sqlite.OperationalError) as cm: + self.con.execute("create index t on test(t) where nondeterministic() is not null") + self.assertEqual(str(cm.exception), "non-deterministic functions prohibited in partial index WHERE clauses") - @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "deterministic parameter not supported") + @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") def CheckFuncDeterministic(self): + """Deterministic functions can be used with partial indices""" mock = unittest.mock.Mock(return_value=None) self.con.create_function("deterministic", 0, mock, deterministic=True) - self.con.execute("select deterministic() = deterministic()") - self.assertEqual(mock.call_count, 1) + try: + self.con.execute("create index t on test(t) where deterministic() is not null") + except sqlite.OperationalError: + self.fail("Unexpected failure while creating partial index") @unittest.skipIf(sqlite.sqlite_version_info >= (3, 8, 3), "SQLite < 3.8.3 needed") def CheckFuncDeterministicNotSupported(self): diff --git a/Misc/NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst b/Misc/NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst new file mode 100644 index 00000000000000..46459c8b8f1f2f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst @@ -0,0 +1 @@ +Fix :mod:`sqlite3` unit test for deterministic functions. From f7f9ef1a2423fe4e31e0f881fdaaf0816baf4d35 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Wed, 27 May 2020 14:50:45 +0200 Subject: [PATCH 2/8] Update Lib/sqlite3/test/userfunctions.py Co-authored-by: Victor Stinner --- Lib/sqlite3/test/userfunctions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 43911f8518b931..500737ca98e6a6 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -2,7 +2,7 @@ # pysqlite2/test/userfunctions.py: tests for user-defined functions and # aggregates. # -# Copyright (C) 2005-2007 Gerhard Häring +# Copyright (C) 2005-2007 Gerhard Häring # # This file is part of pysqlite. # @@ -284,7 +284,8 @@ def CheckFuncNonDeterministic(self): self.con.create_function("nondeterministic", 0, mock, deterministic=False) with self.assertRaises(sqlite.OperationalError) as cm: self.con.execute("create index t on test(t) where nondeterministic() is not null") - self.assertEqual(str(cm.exception), "non-deterministic functions prohibited in partial index WHERE clauses") + # non-deterministic functions prohibited in partial index WHERE clauses + self.assertIn("non-deterministic functions prohibited", str(cm.exception)) @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") def CheckFuncDeterministic(self): From 46642792956cbba07903ae66ae26e21a4462d16f Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 27 May 2020 15:08:26 +0200 Subject: [PATCH 3/8] Revert non-ascii change in header --- Lib/sqlite3/test/userfunctions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 500737ca98e6a6..478d2629643a84 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -2,7 +2,7 @@ # pysqlite2/test/userfunctions.py: tests for user-defined functions and # aggregates. # -# Copyright (C) 2005-2007 Gerhard Häring +# Copyright (C) 2005-2007 Gerhard Häring # # This file is part of pysqlite. # From b969ae5a60d984dde146e01e903b9d0bacf909a7 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 27 May 2020 15:35:44 +0200 Subject: [PATCH 4/8] Use old test for sqlite < 3.15.0 --- Lib/sqlite3/test/userfunctions.py | 34 ++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 478d2629643a84..5ed35492609b01 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -277,25 +277,39 @@ def CheckAnyArguments(self): val = cur.fetchone()[0] self.assertEqual(val, 2) + + # + # Regarding deterministic functions: + # + # Between 3.8.3 and 3.15.0, deterministic functions were only used to + # optimize inner loops, so for those versions we can only test if the + # sqlite machinery has factored out a call or not. From 3.15.0 and onward, + # deterministic functions were permitted in WHERE clauses of partial + # indices, which allows testing based on syntax, iso. the query optimizer. + # @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") def CheckFuncNonDeterministic(self): - """Non-deterministic functions cannot be used with partial indices""" mock = unittest.mock.Mock(return_value=None) self.con.create_function("nondeterministic", 0, mock, deterministic=False) - with self.assertRaises(sqlite.OperationalError) as cm: - self.con.execute("create index t on test(t) where nondeterministic() is not null") - # non-deterministic functions prohibited in partial index WHERE clauses - self.assertIn("non-deterministic functions prohibited", str(cm.exception)) + if sqlite.sqlite_version_info < (3, 15, 0): + self.con.execute("select nondeterministic() = nondeterministic()") + self.assertEqual(mock.call_count, 2) + else: + with self.assertRaises(sqlite.OperationalError): + self.con.execute("create index t on test(t) where nondeterministic() is not null") @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") def CheckFuncDeterministic(self): - """Deterministic functions can be used with partial indices""" mock = unittest.mock.Mock(return_value=None) self.con.create_function("deterministic", 0, mock, deterministic=True) - try: - self.con.execute("create index t on test(t) where deterministic() is not null") - except sqlite.OperationalError: - self.fail("Unexpected failure while creating partial index") + if sqlite.sqlite_version_info < (3, 15, 0): + self.con.execute("select deterministic() = deterministic()") + self.assertEqual(mock.call_count, 1) + else: + try: + self.con.execute("create index t on test(t) where deterministic() is not null") + except sqlite.OperationalError: + self.fail("Unexpected failure while creating partial index") @unittest.skipIf(sqlite.sqlite_version_info >= (3, 8, 3), "SQLite < 3.8.3 needed") def CheckFuncDeterministicNotSupported(self): From 96d52a824435adfd95a84badeac83d491717ea88 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 28 May 2020 17:27:35 +0200 Subject: [PATCH 5/8] Remove NEWS entry --- .../NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Misc/NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst diff --git a/Misc/NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst b/Misc/NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst deleted file mode 100644 index 46459c8b8f1f2f..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-27-11-17-02.bpo-40784.hYEBjs.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :mod:`sqlite3` unit test for deterministic functions. From f5706584c0e785e3a3b91645dec8329bc9b257f6 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 28 May 2020 19:21:14 +0300 Subject: [PATCH 6/8] Update userfunctions.py --- Lib/sqlite3/test/userfunctions.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 5ed35492609b01..f365fedb1bf7b0 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -2,7 +2,7 @@ # pysqlite2/test/userfunctions.py: tests for user-defined functions and # aggregates. # -# Copyright (C) 2005-2007 Gerhard Häring +# Copyright (C) 2005-2007 Gerhard Häring # # This file is part of pysqlite. # @@ -277,8 +277,6 @@ def CheckAnyArguments(self): val = cur.fetchone()[0] self.assertEqual(val, 2) - - # # Regarding deterministic functions: # # Between 3.8.3 and 3.15.0, deterministic functions were only used to @@ -286,7 +284,6 @@ def CheckAnyArguments(self): # sqlite machinery has factored out a call or not. From 3.15.0 and onward, # deterministic functions were permitted in WHERE clauses of partial # indices, which allows testing based on syntax, iso. the query optimizer. - # @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") def CheckFuncNonDeterministic(self): mock = unittest.mock.Mock(return_value=None) From 44fa9e4aa2dc89fa50e7b297a3f9b4576b584ea9 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 28 May 2020 19:28:48 +0200 Subject: [PATCH 7/8] Convert userfunctions.py to UTF-8 --- Lib/sqlite3/test/userfunctions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index f365fedb1bf7b0..ffbb23d183e52e 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -1,4 +1,4 @@ -#-*- coding: iso-8859-1 -*- +# # pysqlite2/test/userfunctions.py: tests for user-defined functions and # aggregates. # From ad7206e06349771e88ade634128c015a1517411d Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Fri, 29 May 2020 01:38:18 +0300 Subject: [PATCH 8/8] Update userfunctions.py --- Lib/sqlite3/test/userfunctions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index ffbb23d183e52e..c11c82e1275778 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -1,4 +1,3 @@ -# # pysqlite2/test/userfunctions.py: tests for user-defined functions and # aggregates. #