`Text` won't round-trip for integer values
goertzenator opened this issue · 4 comments
When saving a Text
containing an integer (ie, mytxt = "200"
) to a field in a table, reading the Text
back will produce the following error:
ConversionFailed {errSQLType = "INTEGER", errHaskellType = "Text", errMessage = "need a text"}
To troubleshoot this I read the problem field back as SQLData
and got SQLInteger 200
... so Text
s that look like integers get saved as integers, and FromField Text
cannot handle this.
This is a nasty bug: consider an existing application that has a "First Name" field. If you enter "123" the database will be poisoned with an SQLInteger
value and then the app will fail upon reading it back.
At a minimum, Text
should always save as SQLText
regardless of content. Optionally FromField Text
could be made more flexible to accept SQLInteger
and other types.
Here's a patch I'm using to cope with a database that has already been poisoned with Integer values in what is supposed to be a text column.
@goertzenator can you make a PR? I'll test it over the weekend
I did some experimentation with storing strings like "123" and it seems to be the underlying C sqlite library itself that is converting those strings to number types.
My method involves dumping a sqlite database with the shell strings
command. Data saved as strings is easily visible, data saved as integers is not. Using the sqlite3
program I wrote the values "hello123" and "123" to the same STRING column. strings
showed "hello123", but "123" was absent.
Further investigation has revealed the root cause of all my headaches. One thing I never mentioned is how I created these tables that are causing me problems:
CREATE TABLE books (name STRING)
It turns out STRING
is not a valid SQL data type (I should have used TEXT
). Sqlite will happily accept this type without error, and any column that ends up with an unrecognized type will get NUMERIC
affinity :( ... and that is why my strings were saving as integers.
Using the STRICT
table creation option is supposed to catch this. Lesson learned.