|
1 | | -#-*- coding: iso-8859-1 -*- |
2 | 1 | # pysqlite2/test/userfunctions.py: tests for user-defined functions and |
3 | 2 | # aggregates. |
4 | 3 | # |
5 | | -# Copyright (C) 2005-2007 Gerhard Häring <[email protected]> |
| 4 | +# Copyright (C) 2005-2007 Gerhard Häring <[email protected]> |
6 | 5 | # |
7 | 6 | # This file is part of pysqlite. |
8 | 7 | # |
@@ -158,6 +157,7 @@ def setUp(self): |
158 | 157 | self.con.create_function("isblob", 1, func_isblob) |
159 | 158 | self.con.create_function("islonglong", 1, func_islonglong) |
160 | 159 | self.con.create_function("spam", -1, func) |
| 160 | + self.con.execute("create table test(t text)") |
161 | 161 |
|
162 | 162 | def tearDown(self): |
163 | 163 | self.con.close() |
@@ -276,18 +276,36 @@ def CheckAnyArguments(self): |
276 | 276 | val = cur.fetchone()[0] |
277 | 277 | self.assertEqual(val, 2) |
278 | 278 |
|
| 279 | + # Regarding deterministic functions: |
| 280 | + # |
| 281 | + # Between 3.8.3 and 3.15.0, deterministic functions were only used to |
| 282 | + # optimize inner loops, so for those versions we can only test if the |
| 283 | + # sqlite machinery has factored out a call or not. From 3.15.0 and onward, |
| 284 | + # deterministic functions were permitted in WHERE clauses of partial |
| 285 | + # indices, which allows testing based on syntax, iso. the query optimizer. |
| 286 | + @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") |
279 | 287 | def CheckFuncNonDeterministic(self): |
280 | 288 | mock = unittest.mock.Mock(return_value=None) |
281 | | - self.con.create_function("deterministic", 0, mock, deterministic=False) |
282 | | - self.con.execute("select deterministic() = deterministic()") |
283 | | - self.assertEqual(mock.call_count, 2) |
284 | | - |
285 | | - @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "deterministic parameter not supported") |
| 289 | + self.con.create_function("nondeterministic", 0, mock, deterministic=False) |
| 290 | + if sqlite.sqlite_version_info < (3, 15, 0): |
| 291 | + self.con.execute("select nondeterministic() = nondeterministic()") |
| 292 | + self.assertEqual(mock.call_count, 2) |
| 293 | + else: |
| 294 | + with self.assertRaises(sqlite.OperationalError): |
| 295 | + self.con.execute("create index t on test(t) where nondeterministic() is not null") |
| 296 | + |
| 297 | + @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") |
286 | 298 | def CheckFuncDeterministic(self): |
287 | 299 | mock = unittest.mock.Mock(return_value=None) |
288 | 300 | self.con.create_function("deterministic", 0, mock, deterministic=True) |
289 | | - self.con.execute("select deterministic() = deterministic()") |
290 | | - self.assertEqual(mock.call_count, 1) |
| 301 | + if sqlite.sqlite_version_info < (3, 15, 0): |
| 302 | + self.con.execute("select deterministic() = deterministic()") |
| 303 | + self.assertEqual(mock.call_count, 1) |
| 304 | + else: |
| 305 | + try: |
| 306 | + self.con.execute("create index t on test(t) where deterministic() is not null") |
| 307 | + except sqlite.OperationalError: |
| 308 | + self.fail("Unexpected failure while creating partial index") |
291 | 309 |
|
292 | 310 | @unittest.skipIf(sqlite.sqlite_version_info >= (3, 8, 3), "SQLite < 3.8.3 needed") |
293 | 311 | def CheckFuncDeterministicNotSupported(self): |
|
0 commit comments