- Added version checks in C code to make sure we don't trigger bugs in older
SQLite versions. - Added version checks in test suite so that we don't execute tests that we know will fail with older (buggy) SQLite versions. Now, all tests should run against all SQLite versions from 3.0.8 until 3.3.6 (latest one now). The sqlite3 module can be built against all these SQLite versions and the sqlite3 module does its best to not trigger bugs in SQLite, but using SQLite 3.3.3 or later is recommended.
This commit is contained in:
parent
69f6168b76
commit
b2e8816403
|
@ -48,6 +48,8 @@ class CollationTests(unittest.TestCase):
|
|||
pass
|
||||
|
||||
def CheckCollationIsUsed(self):
|
||||
if sqlite.version_info < (3, 2, 1): # old SQLite versions crash on this test
|
||||
return
|
||||
def mycoll(x, y):
|
||||
# reverse order
|
||||
return -cmp(x, y)
|
||||
|
|
|
@ -200,6 +200,8 @@ class FunctionTests(unittest.TestCase):
|
|||
self.failUnlessEqual(val, buffer("blob"))
|
||||
|
||||
def CheckFuncException(self):
|
||||
if sqlite.version_info < (3, 3, 3): # don't raise bug in earlier SQLite versions
|
||||
return
|
||||
cur = self.con.cursor()
|
||||
try:
|
||||
cur.execute("select raiseexception()")
|
||||
|
@ -283,6 +285,8 @@ class AggregateTests(unittest.TestCase):
|
|||
self.failUnlessEqual(e.args[0], "AggrNoStep instance has no attribute 'step'")
|
||||
|
||||
def CheckAggrNoFinalize(self):
|
||||
if sqlite.version_info < (3, 3, 3): # don't raise bug in earlier SQLite versions
|
||||
return
|
||||
cur = self.con.cursor()
|
||||
try:
|
||||
cur.execute("select nofinalize(t) from test")
|
||||
|
@ -292,6 +296,8 @@ class AggregateTests(unittest.TestCase):
|
|||
self.failUnlessEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error")
|
||||
|
||||
def CheckAggrExceptionInInit(self):
|
||||
if sqlite.version_info < (3, 3, 3): # don't raise bug in earlier SQLite versions
|
||||
return
|
||||
cur = self.con.cursor()
|
||||
try:
|
||||
cur.execute("select excInit(t) from test")
|
||||
|
@ -301,6 +307,8 @@ class AggregateTests(unittest.TestCase):
|
|||
self.failUnlessEqual(e.args[0], "user-defined aggregate's '__init__' method raised error")
|
||||
|
||||
def CheckAggrExceptionInStep(self):
|
||||
if sqlite.version_info < (3, 3, 3): # don't raise bug in earlier SQLite versions
|
||||
return
|
||||
cur = self.con.cursor()
|
||||
try:
|
||||
cur.execute("select excStep(t) from test")
|
||||
|
@ -310,6 +318,8 @@ class AggregateTests(unittest.TestCase):
|
|||
self.failUnlessEqual(e.args[0], "user-defined aggregate's 'step' method raised error")
|
||||
|
||||
def CheckAggrExceptionInFinalize(self):
|
||||
if sqlite.version_info < (3, 3, 3): # don't raise bug in earlier SQLite versions
|
||||
return
|
||||
cur = self.con.cursor()
|
||||
try:
|
||||
cur.execute("select excFinalize(t) from test")
|
||||
|
|
|
@ -34,6 +34,17 @@
|
|||
|
||||
static int connection_set_isolation_level(Connection* self, PyObject* isolation_level);
|
||||
|
||||
|
||||
void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len)
|
||||
{
|
||||
/* in older SQLite versions, calling sqlite3_result_error in callbacks
|
||||
* triggers a bug in SQLite that leads either to irritating results or
|
||||
* segfaults, depending on the SQLite version */
|
||||
#if SQLITE_VERSION_NUMBER >= 3003003
|
||||
sqlite3_result_error(ctx, errmsg, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
|
||||
{
|
||||
static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
|
||||
|
@ -526,7 +537,7 @@ void _func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
|
|||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
sqlite3_result_error(context, "user-defined function raised exception", -1);
|
||||
_sqlite3_result_error(context, "user-defined function raised exception", -1);
|
||||
}
|
||||
|
||||
PyGILState_Release(threadstate);
|
||||
|
@ -558,7 +569,7 @@ static void _step_callback(sqlite3_context *context, int argc, sqlite3_value** p
|
|||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1);
|
||||
_sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
@ -582,7 +593,7 @@ static void _step_callback(sqlite3_context *context, int argc, sqlite3_value** p
|
|||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1);
|
||||
_sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1);
|
||||
}
|
||||
|
||||
error:
|
||||
|
@ -619,7 +630,7 @@ void _final_callback(sqlite3_context* context)
|
|||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
|
||||
_sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
|
||||
} else {
|
||||
_set_result(context, function_result);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue