blob: 44974b008b9cb5dcfc3c44689762ff95af271818 [file] [log] [blame]
Petri Lehtinen8b945142013-02-23 19:05:09 +01001#-*- coding: iso-8859-1 -*-
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002# pysqlite2/test/regression.py: pysqlite regression tests
3#
Gerhard Häringf9cee222010-03-05 15:20:03 +00004# Copyright (C) 2006-2010 Gerhard Häring <gh@ghaering.de>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005#
6# This file is part of pysqlite.
7#
8# This software is provided 'as-is', without any express or implied
9# warranty. In no event will the authors be held liable for any damages
10# arising from the use of this software.
11#
12# Permission is granted to anyone to use this software for any purpose,
13# including commercial applications, and to alter it and redistribute it
14# freely, subject to the following restrictions:
15#
16# 1. The origin of this software must not be misrepresented; you must not
17# claim that you wrote the original software. If you use this software
18# in a product, an acknowledgment in the product documentation would be
19# appreciated but is not required.
20# 2. Altered source versions must be plainly marked as such, and must not be
21# misrepresented as being the original software.
22# 3. This notice may not be removed or altered from any source distribution.
23
Gerhard Häringe7ea7452008-03-29 00:45:29 +000024import datetime
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000025import unittest
Thomas Wouters477c8d52006-05-27 19:21:47 +000026import sqlite3 as sqlite
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000027
28class RegressionTests(unittest.TestCase):
29 def setUp(self):
30 self.con = sqlite.connect(":memory:")
31
32 def tearDown(self):
33 self.con.close()
34
35 def CheckPragmaUserVersion(self):
36 # This used to crash pysqlite because this pragma command returns NULL for the column name
37 cur = self.con.cursor()
38 cur.execute("pragma user_version")
39
Thomas Wouters477c8d52006-05-27 19:21:47 +000040 def CheckPragmaSchemaVersion(self):
41 # This still crashed pysqlite <= 2.2.1
42 con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)
43 try:
44 cur = self.con.cursor()
45 cur.execute("pragma schema_version")
46 finally:
47 cur.close()
48 con.close()
49
50 def CheckStatementReset(self):
51 # pysqlite 2.1.0 to 2.2.0 have the problem that not all statements are
52 # reset before a rollback, but only those that are still in the
53 # statement cache. The others are not accessible from the connection object.
54 con = sqlite.connect(":memory:", cached_statements=5)
Guido van Rossum805365e2007-05-07 22:24:25 +000055 cursors = [con.cursor() for x in range(5)]
Thomas Wouters477c8d52006-05-27 19:21:47 +000056 cursors[0].execute("create table test(x)")
57 for i in range(10):
Guido van Rossum805365e2007-05-07 22:24:25 +000058 cursors[0].executemany("insert into test(x) values (?)", [(x,) for x in range(10)])
Thomas Wouters477c8d52006-05-27 19:21:47 +000059
60 for i in range(5):
61 cursors[i].execute(" " * i + "select x from test")
62
63 con.rollback()
64
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065 def CheckColumnNameWithSpaces(self):
66 cur = self.con.cursor()
67 cur.execute('select 1 as "foo bar [datetime]"')
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000068 self.assertEqual(cur.description[0][0], "foo bar")
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069
70 cur.execute('select 1 as "foo baz"')
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000071 self.assertEqual(cur.description[0][0], "foo baz")
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072
Gerhard Häringe7ea7452008-03-29 00:45:29 +000073 def CheckStatementFinalizationOnCloseDb(self):
74 # pysqlite versions <= 2.3.3 only finalized statements in the statement
75 # cache when closing the database. statements that were still
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +030076 # referenced in cursors weren't closed and could provoke "
Gerhard Häringe7ea7452008-03-29 00:45:29 +000077 # "OperationalError: Unable to close due to unfinalised statements".
78 con = sqlite.connect(":memory:")
79 cursors = []
80 # default statement cache size is 100
81 for i in range(105):
82 cur = con.cursor()
83 cursors.append(cur)
84 cur.execute("select 1 x union select " + str(i))
85 con.close()
86
Berker Peksagf85bce72016-06-14 14:19:02 +030087 @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2), 'needs sqlite 3.2.2 or newer')
Gerhard Häringe7ea7452008-03-29 00:45:29 +000088 def CheckOnConflictRollback(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +000089 con = sqlite.connect(":memory:")
90 con.execute("create table foo(x, unique(x) on conflict rollback)")
91 con.execute("insert into foo(x) values (1)")
92 try:
93 con.execute("insert into foo(x) values (1)")
94 except sqlite.DatabaseError:
95 pass
96 con.execute("insert into foo(x) values (2)")
97 try:
98 con.commit()
99 except sqlite.OperationalError:
100 self.fail("pysqlite knew nothing about the implicit ROLLBACK")
101
102 def CheckWorkaroundForBuggySqliteTransferBindings(self):
103 """
104 pysqlite would crash with older SQLite versions unless
105 a workaround is implemented.
106 """
107 self.con.execute("create table foo(bar)")
108 self.con.execute("drop table foo")
109 self.con.execute("create table foo(bar)")
110
111 def CheckEmptyStatement(self):
112 """
113 pysqlite used to segfault with SQLite versions 3.5.x. These return NULL
114 for "no-operation" statements
115 """
116 self.con.execute("")
117
118 def CheckTypeMapUsage(self):
119 """
120 pysqlite until 2.4.1 did not rebuild the row_cast_map when recompiling
121 a statement. This test exhibits the problem.
122 """
123 SELECT = "select * from foo"
124 con = sqlite.connect(":memory:",detect_types=sqlite.PARSE_DECLTYPES)
125 con.execute("create table foo(bar timestamp)")
126 con.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),))
127 con.execute(SELECT)
128 con.execute("drop table foo")
129 con.execute("create table foo(bar integer)")
130 con.execute("insert into foo(bar) values (5)")
131 con.execute(SELECT)
132
Gerhard Häring873d9ff2008-02-29 22:22:09 +0000133 def CheckErrorMsgDecodeError(self):
134 # When porting the module to Python 3.0, the error message about
135 # decoding errors disappeared. This verifies they're back again.
Berker Peksag48b5c982016-06-14 00:42:50 +0300136 with self.assertRaises(sqlite.OperationalError) as cm:
Georg Brandl3dbca812008-07-23 16:10:53 +0000137 self.con.execute("select 'xxx' || ? || 'yyy' colname",
138 (bytes(bytearray([250])),)).fetchone()
Berker Peksag48b5c982016-06-14 00:42:50 +0300139 msg = "Could not decode to UTF-8 column 'colname' with text 'xxx"
140 self.assertIn(msg, str(cm.exception))
Gerhard Häring873d9ff2008-02-29 22:22:09 +0000141
Georg Brandl3dbca812008-07-23 16:10:53 +0000142 def CheckRegisterAdapter(self):
143 """
144 See issue 3312.
145 """
146 self.assertRaises(TypeError, sqlite.register_adapter, {}, None)
147
148 def CheckSetIsolationLevel(self):
149 """
150 See issue 3312.
151 """
152 con = sqlite.connect(":memory:")
153 setattr(con, "isolation_level", "\xe9")
154
Gerhard Häringf9cee222010-03-05 15:20:03 +0000155 def CheckCursorConstructorCallCheck(self):
156 """
Ezio Melottib5bc3532013-08-17 16:11:40 +0300157 Verifies that cursor methods check whether base class __init__ was
158 called.
Gerhard Häringf9cee222010-03-05 15:20:03 +0000159 """
160 class Cursor(sqlite.Cursor):
161 def __init__(self, con):
162 pass
163
164 con = sqlite.connect(":memory:")
165 cur = Cursor(con)
Berker Peksag1003b342016-06-12 22:34:49 +0300166 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000167 cur.execute("select 4+5").fetchall()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000168
Gerhard Häring6117f422008-09-22 06:04:51 +0000169 def CheckStrSubclass(self):
170 """
171 The Python 3.0 port of the module didn't cope with values of subclasses of str.
172 """
173 class MyStr(str): pass
174 self.con.execute("select ?", (MyStr("abc"),))
Georg Brandl3dbca812008-07-23 16:10:53 +0000175
Gerhard Häringf9cee222010-03-05 15:20:03 +0000176 def CheckConnectionConstructorCallCheck(self):
177 """
Ezio Melottib5bc3532013-08-17 16:11:40 +0300178 Verifies that connection methods check whether base class __init__ was
179 called.
Gerhard Häringf9cee222010-03-05 15:20:03 +0000180 """
181 class Connection(sqlite.Connection):
182 def __init__(self, name):
183 pass
184
185 con = Connection(":memory:")
Berker Peksag1003b342016-06-12 22:34:49 +0300186 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000187 cur = con.cursor()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000188
189 def CheckCursorRegistration(self):
190 """
191 Verifies that subclassed cursor classes are correctly registered with
192 the connection object, too. (fetch-across-rollback problem)
193 """
194 class Connection(sqlite.Connection):
195 def cursor(self):
196 return Cursor(self)
197
198 class Cursor(sqlite.Cursor):
199 def __init__(self, con):
200 sqlite.Cursor.__init__(self, con)
201
202 con = Connection(":memory:")
203 cur = con.cursor()
204 cur.execute("create table foo(x)")
205 cur.executemany("insert into foo(x) values (?)", [(3,), (4,), (5,)])
206 cur.execute("select x from foo")
207 con.rollback()
Berker Peksag1003b342016-06-12 22:34:49 +0300208 with self.assertRaises(sqlite.InterfaceError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000209 cur.fetchall()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000210
211 def CheckAutoCommit(self):
212 """
213 Verifies that creating a connection in autocommit mode works.
214 2.5.3 introduced a regression so that these could no longer
215 be created.
216 """
217 con = sqlite.connect(":memory:", isolation_level=None)
218
219 def CheckPragmaAutocommit(self):
220 """
221 Verifies that running a PRAGMA statement that does an autocommit does
222 work. This did not work in 2.5.3/2.5.4.
223 """
Victor Stinner0201f442010-03-13 03:28:34 +0000224 cur = self.con.cursor()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000225 cur.execute("create table foo(bar)")
226 cur.execute("insert into foo(bar) values (5)")
227
228 cur.execute("pragma page_size")
229 row = cur.fetchone()
230
231 def CheckSetDict(self):
232 """
233 See http://bugs.python.org/issue7478
234
235 It was possible to successfully register callbacks that could not be
236 hashed. Return codes of PyDict_SetItem were not checked properly.
237 """
238 class NotHashable:
239 def __call__(self, *args, **kw):
240 pass
241 def __hash__(self):
242 raise TypeError()
243 var = NotHashable()
Victor Stinner0201f442010-03-13 03:28:34 +0000244 self.assertRaises(TypeError, self.con.create_function, var)
245 self.assertRaises(TypeError, self.con.create_aggregate, var)
246 self.assertRaises(TypeError, self.con.set_authorizer, var)
247 self.assertRaises(TypeError, self.con.set_progress_handler, var)
248
249 def CheckConnectionCall(self):
250 """
251 Call a connection with a non-string SQL request: check error handling
252 of the statement constructor.
253 """
254 self.assertRaises(sqlite.Warning, self.con, 1)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000255
Victor Stinner35466c52010-04-22 11:23:23 +0000256 def CheckCollation(self):
257 def collation_cb(a, b):
258 return 1
259 self.assertRaises(sqlite.ProgrammingError, self.con.create_collation,
260 # Lone surrogate cannot be encoded to the default encoding (utf8)
261 "\uDC80", collation_cb)
262
Petri Lehtinen4a84f582011-05-09 12:24:09 +0200263 def CheckRecursiveCursorUse(self):
264 """
265 http://bugs.python.org/issue10811
266
267 Recursively using a cursor, such as when reusing it from a generator led to segfaults.
268 Now we catch recursive cursor usage and raise a ProgrammingError.
269 """
270 con = sqlite.connect(":memory:")
271
272 cur = con.cursor()
273 cur.execute("create table a (bar)")
274 cur.execute("create table b (baz)")
275
276 def foo():
277 cur.execute("insert into a (bar) values (?)", (1,))
278 yield 1
279
280 with self.assertRaises(sqlite.ProgrammingError):
281 cur.executemany("insert into b (baz) values (?)",
282 ((i,) for i in foo()))
283
Petri Lehtinen8b945142013-02-23 19:05:09 +0100284 def CheckConvertTimestampMicrosecondPadding(self):
285 """
286 http://bugs.python.org/issue14720
287
288 The microsecond parsing of convert_timestamp() should pad with zeros,
289 since the microsecond string "456" actually represents "456000".
290 """
291
292 con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
293 cur = con.cursor()
294 cur.execute("CREATE TABLE t (x TIMESTAMP)")
Petri Lehtinen8b945142013-02-23 19:05:09 +0100295
Petri Lehtinen5f794092013-02-26 21:32:02 +0200296 # Microseconds should be 456000
297 cur.execute("INSERT INTO t (x) VALUES ('2012-04-04 15:06:00.456')")
298
299 # Microseconds should be truncated to 123456
300 cur.execute("INSERT INTO t (x) VALUES ('2012-04-04 15:06:00.123456789')")
301
302 cur.execute("SELECT * FROM t")
303 values = [x[0] for x in cur.fetchall()]
304
305 self.assertEqual(values, [
306 datetime.datetime(2012, 4, 4, 15, 6, 0, 456000),
307 datetime.datetime(2012, 4, 4, 15, 6, 0, 123456),
308 ])
Petri Lehtinen8b945142013-02-23 19:05:09 +0100309
Victor Stinnercb1f74e2013-12-19 16:38:03 +0100310 def CheckInvalidIsolationLevelType(self):
311 # isolation level is a string, not an integer
312 self.assertRaises(TypeError,
313 sqlite.connect, ":memory:", isolation_level=123)
314
Petri Lehtinen4a84f582011-05-09 12:24:09 +0200315
Serhiy Storchaka42d67af2014-09-11 13:29:05 +0300316 def CheckNullCharacter(self):
317 # Issue #21147
318 con = sqlite.connect(":memory:")
319 self.assertRaises(ValueError, con, "\0select 1")
320 self.assertRaises(ValueError, con, "select 1\0")
321 cur = con.cursor()
322 self.assertRaises(ValueError, cur.execute, " \0select 2")
323 self.assertRaises(ValueError, cur.execute, "select 2\0")
324
325
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000326def suite():
327 regression_suite = unittest.makeSuite(RegressionTests, "Check")
328 return unittest.TestSuite((regression_suite,))
329
330def test():
331 runner = unittest.TextTestRunner()
332 runner.run(suite())
333
334if __name__ == "__main__":
335 test()