Kage
Kage

Reputation: 795

Calling sqlite3_column_type returns SQLITE_INTEGER for a STRING column that contains only numbers causing an integer overflow

I'm working on a legacy project and have found an issue. The code is reading from an sqlite database. It performs a query and iterates over the statement and then for each column it gets the column name and the column value.

To get the value it calls sqlite3_column_type. Then it checks the types and uses sqlite3_column_int, sqlite3_column_double, sqlite3_column_text, etc. to read the value.

The issue is that there is a row in the DB that has a STRING column but the value contains only numbers (the value was set as 12 characters long, something like @"123456789012"). Calling sqlite3_column_type for this row returns SQLITE_INTEGER as it's only looking at the value of the column and not the declared column type. This means that the code will then read the value with sqlite3_column_int and I'll end up with an integer overflow and a number nothing like the original value contained in the DB.

Here is a quick example:

int columnType = sqlite3_column_type(statement, index);

if (columnType == SQLITE_INTEGER) {
    //use sqlite3_column_int(statement, index)
}
else if (columnType == SQLITE_FLOAT) {
    //use sqlite3_column_double(statement, index)
}
else if (columnType == SQLITE_TEXT) {
    //use sqlite3_column_text(statement, index)
}
///etc...

How can I make sure the the value I get out from a STRING column containing only numbers is treated correctly? Can I somehow check the declared column type (other than querying and parsing out the original create table sql)? Is there a better way to do this?

Upvotes: 1

Views: 3108

Answers (1)

Kage
Kage

Reputation: 795

Using column_decltype instead of column_type means that I get that declared column type (STRING) instead of the type of value. Then I can compare the result against STRING, TEXT, etc.to figure out how to read the value.

Upvotes: 1

Related Questions