iOS4Life
iOS4Life

Reputation: 236

Objective C doesn't report ambiguous column name in sqlite3_prepare_v2

I'm having a hell of a time with a SQLite issue. I recently discovered an ambiguous column name issue in one of the views in my app's local database. It has been reeking havoc on some parts of my code and now that I have found it I want to know why Xcode / Objective C / the SQLite engine doesn't seem to report that as a SQL error?

I have code that reports against SQLite when other errors are reported (see below). But it doesn't capture the ambiguous column problem.

Bottom line, is there any way to capture a warning message from SQLite such as "ambiguous column name" from the sqlite3_prepare_v2 call?

@try
{
    //Prepare the SQL statement
    int sqlStatus = sqlite3_prepare_v2(dbConnection, [sqlString UTF8String], -1, &sqlStatement, nil);
    if(sqlStatus == SQLITE_OK)
    {
        //Do work
    }
    else
    {
        //Something went wrong
        NSLog(@"SQL PREPARE ERROR:%s\nSQL String:%@", sqlite3_errmsg(dbConnection), sqlString);
    }
}
@catch (NSException *exception)
{
    NSLog(@"SQL ERROR: %@:%@\nSQL String:%@", exception.name, exception.reason, sqlString);
}

UPDATE I guess my biggest question is why, when I run the sqlite in Terminal on my mac, I get the error below, but when I run the code, all the steps come back as SQLITE_ROW.

enter image description here

Upvotes: 0

Views: 206

Answers (1)

Tommy
Tommy

Reputation: 100622

Your call to sqlite3_prepare_v2 is perfectly formed. It's completely valid C and therefore completely valid Objective-C. That's why there's no compiler error or warning. Xcode's analysis is tightly bound to the compiler's (that's why Apple has been sponsoring LLVM; there's no point having two separate things both processing syntax) so it doesn't have a separate opinion.

The documentation for sqlite3_prepare_v2 says:

*ppStmt is left pointing to a compiled prepared statement that can be executed using sqlite3_step(). If there is an error, *ppStmt is set to NULL. [...]

On success, the sqlite3_prepare() family of routines return SQLITE_OK; otherwise an error code is returned.

You're testing against SQLITE_OK so presumably your statement is valid SQL even if nonsensical. That's seemingly all SQLite is checking.

What you apparently want is an analyser for SQL other than merely a "well done: syntax is valid". I don't think SQLite offers that. Sorry for the unhelpful answer.

Addendum: what you should potentially be doing is checking the result of sqlite3_step; that'll indicate whether an error occurred while actually attempting to run your statement. All prepare is going to flag up is errors in parsing it. I would dare guess that the ambiguous column name error occurs only when SQLite goes to inspect to the table, which doesn't happen until the attempt is made to process.

(and: your try/catch block is redundant; SQLite is plain C and won't throw Objective-C exceptions).

Upvotes: 3

Related Questions