]> granicus.if.org Git - python/commitdiff
- Added version checks in C code to make sure we don't trigger bugs in older
authorGerhard Häring <gh@ghaering.de>
Wed, 14 Jun 2006 22:28:37 +0000 (22:28 +0000)
committerGerhard Häring <gh@ghaering.de>
Wed, 14 Jun 2006 22:28:37 +0000 (22:28 +0000)
  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.

Lib/sqlite3/test/hooks.py
Lib/sqlite3/test/userfunctions.py
Modules/_sqlite/connection.c

index b10b3efb170d00625b7a5e453c466c9e087c431d..7deab983f8c378c24ebe2fe56b13b3e2d9a613cb 100644 (file)
@@ -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)
index 215178c02398f4245a663b1c8de08e3ffdcae0ce..587d39c876ba5d6c5bd90e56c5da3c57382bb75f 100644 (file)
@@ -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")
index bf74710f8c42a6c65b9d9f4e76e3ec03b890589d..f63d88c21da2a2243aa2f0ff7a98d171d23165e5 100644 (file)
 
 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);
     }