This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: sqlite3 connection built from apsw connection should raise IntegrityError, not DatabaseError
Type: behavior Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: ghaering Nosy List: ghaering, ned.deily, wtonkin
Priority: normal Keywords:

Created on 2014-09-10 18:30 by wtonkin, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg226704 - (view) Author: william tonkin (wtonkin) Date: 2014-09-10 18:30
python
Python 2.7.6 (default, Dec 23 2013, 13:16:30)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>


-----
test script
-----
import apsw
import sqlite3

print 'sqlite3.version:', sqlite3.version
print 'sqlite3.sqlite_version:', sqlite3.sqlite_version
print 'apsw.apswversion:', apsw.apswversion()

sqlite3_not_from_apsw = sqlite3.connect(':memory:')
apsw_conn = apsw.Connection(':memory:')
sqlite3_from_apsw = sqlite3.connect(apsw_conn)
cursor_not_from_apsw = sqlite3_not_from_apsw.cursor()
cursor_from_apsw = sqlite3_from_apsw.cursor()

sqlite3_not_from_apsw.execute(
    "create table foo ( a timestamp check(datetime(a) is not null))")

try:
    sqlite3_not_from_apsw.execute(
    "insert into foo values (?)", ('',))
except sqlite3.DatabaseError as foo:
    print 'not from apsw, repr(foo)', repr(foo)

sqlite3_from_apsw.execute(
    "create table foo ( a timestamp check(datetime(a) is not null))")

try:
    sqlite3_from_apsw.execute(
    "insert into foo values (?)", ('',))
except sqlite3.DatabaseError as foo:
    print 'from apsw, repr(foo)', repr(foo)

-------------
output:

sqlite3.version: 2.6.0
sqlite3.sqlite_version: 3.8.2
apsw.apswversion: 3.8.2-r1
not from apsw, repr(foo) IntegrityError('CHECK constraint failed: foo',)
from apsw, repr(foo) DatabaseError('CHECK constraint failed: foo',)

--------
Note that when the sqlite3 connection is built from an apsw connection the insert statement that violates the check constraint raises 'DatabaseError' and not 'IntegrityError'.
msg226705 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2014-09-10 18:41
If you are reporting an issue with how apsw behaves, be aware that it is a third-party project, not in the Python standard library.  As such, you should report the issue to its bug tracker (https://github.com/rogerbinns/apsw/issues) as listed in its PyPI entry:  https://pypi.python.org/pypi/apsw/

If not about apsw, feel free to elaborate and reopen this issue.
msg226780 - (view) Author: william tonkin (wtonkin) Date: 2014-09-11 14:43
sqlite3 allows a connection to be built from an apsw.Connection().  Using an apsw.Connection() to build an sqlite3.connect() implies that the underlying sqlite database engine will have extended error codes turned on (the default if for them to be turned off.)

The problem is that Modules/_sqlite/util.c:_pysqlite_seterror() is not extended error code aware.  In particular, the extended error code SQLITE_CONSTRAINT_CHECK will not be recognized as a kind of constraint violation and will fall into the "default:" arm of the case statement.  This will result in raising the exception DatabaseError when the correct exception to raise is IntegrityError.

One simple solution would be to convert the extended error code back to the base error code, that is:
 "errorcode = 0xffu % sqlite3_errcode(db);"
msg226800 - (view) Author: william tonkin (wtonkin) Date: 2014-09-11 20:17
The following worked for me:


--- util.c      2014-09-11 15:15:11.480266548 -0400
+++ util.c.fixed        2014-09-11 15:17:19.214878592 -0400
@@ -54,7 +54,7 @@
         (void)sqlite3_reset(st);
     }

-    errorcode = sqlite3_errcode(db);
+    errorcode = 0xffu & sqlite3_errcode(db);

     switch (errorcode)
     {
msg233386 - (view) Author: Gerhard Häring (ghaering) * (Python committer) Date: 2015-01-04 03:16
Reusing the apsw connection in the sqlite3 module was deprecated a long time ago. It is simply not supported, even if there is still code left in the module that supports this somewhat.

This code should then be removed.

This closing as wontfix.
History
Date User Action Args
2022-04-11 14:58:07adminsetgithub: 66576
2015-01-04 03:16:01ghaeringsetstatus: open -> closed
assignee: ghaering
resolution: third party -> wont fix
messages: + msg233386
2014-09-18 13:11:46wtonkinsetnosy: + ghaering
2014-09-11 20:17:08wtonkinsetmessages: + msg226800
2014-09-11 14:43:46wtonkinsetstatus: closed -> open
type: behavior
messages: + msg226780
2014-09-10 18:41:54ned.deilysetstatus: open -> closed

nosy: + ned.deily
messages: + msg226705

resolution: third party
stage: resolved
2014-09-10 18:30:15wtonkincreate