|  | 
| 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