|
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 <gh@ghaering.de> |
| 4 | +# Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de> |
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