summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/sqlite3.rst13
-rw-r--r--Lib/sqlite3/test/types.py17
-rw-r--r--Modules/_sqlite/cursor.c6
3 files changed, 26 insertions, 10 deletions
diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst
index 85925f4..5408630 100644
--- a/Doc/library/sqlite3.rst
+++ b/Doc/library/sqlite3.rst
@@ -114,10 +114,11 @@ Module functions and constants
:func:`connect` function.
Setting it makes the :mod:`sqlite3` module parse the declared type for each
- column it returns. It will parse out the first word of the declared type, i. e.
- for "integer primary key", it will parse out "integer". Then for that column, it
- will look into the converters dictionary and use the converter function
- registered for that type there. Converter names are case-sensitive!
+ column it returns. It will parse out the first word of the declared type,
+ i. e. for "integer primary key", it will parse out "integer", or for
+ "number(10)" it will parse out "number". Then for that column, it will look
+ into the converters dictionary and use the converter function registered for
+ that type there.
.. data:: PARSE_COLNAMES
@@ -666,10 +667,6 @@ and constructs a :class:`Point` object from it.
Converter functions **always** get called with a string, no matter under which
data type you sent the value to SQLite.
-.. note::
-
- Converter names are looked up in a case-sensitive manner.
-
::
def convert_point(s):
diff --git a/Lib/sqlite3/test/types.py b/Lib/sqlite3/test/types.py
index 1970401..471425d 100644
--- a/Lib/sqlite3/test/types.py
+++ b/Lib/sqlite3/test/types.py
@@ -98,7 +98,7 @@ class DeclTypesTests(unittest.TestCase):
def setUp(self):
self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
self.cur = self.con.cursor()
- self.cur.execute("create table test(i int, s str, f float, b bool, u unicode, foo foo, bin blob)")
+ self.cur.execute("create table test(i int, s str, f float, b bool, u unicode, foo foo, bin blob, n1 number, n2 number(5))")
# override float, make them always return the same number
sqlite.converters["FLOAT"] = lambda x: 47.2
@@ -107,11 +107,13 @@ class DeclTypesTests(unittest.TestCase):
sqlite.converters["BOOL"] = lambda x: bool(int(x))
sqlite.converters["FOO"] = DeclTypesTests.Foo
sqlite.converters["WRONG"] = lambda x: "WRONG"
+ sqlite.converters["NUMBER"] = float
def tearDown(self):
del sqlite.converters["FLOAT"]
del sqlite.converters["BOOL"]
del sqlite.converters["FOO"]
+ del sqlite.converters["NUMBER"]
self.cur.close()
self.con.close()
@@ -203,6 +205,19 @@ class DeclTypesTests(unittest.TestCase):
row = self.cur.fetchone()
self.failUnlessEqual(row[0], val)
+ def CheckNumber1(self):
+ self.cur.execute("insert into test(n1) values (5)")
+ value = self.cur.execute("select n1 from test").fetchone()[0]
+ # if the converter is not used, it's an int instead of a float
+ self.failUnlessEqual(type(value), float)
+
+ def CheckNumber2(self):
+ """Checks wether converter names are cut off at '(' characters"""
+ self.cur.execute("insert into test(n2) values (5)")
+ value = self.cur.execute("select n2 from test").fetchone()[0]
+ # if the converter is not used, it's an int instead of a float
+ self.failUnlessEqual(type(value), float)
+
class ColNamesTests(unittest.TestCase):
def setUp(self):
self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index 2681fc7..308823c 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -202,7 +202,11 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
decltype = sqlite3_column_decltype(self->statement->st, i);
if (decltype) {
for (pos = decltype;;pos++) {
- if (*pos == ' ' || *pos == 0) {
+ /* Converter names are split at '(' and blanks.
+ * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and
+ * 'NUMBER(10)' to be treated as 'NUMBER', for example.
+ * In other words, it will work as people expect it to work.*/
+ if (*pos == ' ' || *pos == '(' || *pos == 0) {
py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
if (!py_decltype) {
return -1;