Sqlite FTS does not work when compiling with LLVM on iOS

I have been developing a corporate iPad app for a while. Since application development began almost 2 years ago, I needed to compile my own version of SQLite from the source code, because by default the SQLite library (sqlite3.dylib) did not have FTS by default.

Ok, since then everything has been working fine. I have always used GCC as a project compiler.

The thing is, now I'm trying to convert the whole project to use ARC . For this I need to use the Apple LLVM compiler .

What is it. When I change the compiler (from GCC 4.2 to LLVM 3.1 or 4.0, without converting to ARC and without changing anything else), my application builds fine, everything works fine, except for my FTS requests, which don't work at all. Even the simplest. They start and return always with no result (with the SQLITE_OK code, though).

I'm stuck here. I already spoke with an Apple engineer at WWDC'12, but we could not find a solution.

I guarantee that this is unlikely to be a garbled request or something like that, since the application works fine with GCC. In addition, I can run queries in the terminal version of SQLite (or use other applications, such as Base)

I also used the old version of SQLite, but I updated it to the latest version (3.7.13). Everything remains the same. I also noticed that now (I don't know since) the sqlite that comes with the Mac supports FTS (!!!), and I was able to uninstall my own version and use Apple alone. The fact is that I have the same behavior.

I was looking for a solution, but could not find it. I found some errors related to optimizing armv6 and the compiler (which can be fixed using the -mno-thumb flag), but this is not my case. I also noticed that when I parse my custom sqlite files using Clang, it points to a lot of “potential errors”.

I have this not a skeptical view, and I (still) don't think this is an LLVM or SQLite error. I prefer to check everything possible before contacting them with an error. Perhaps I forget to configure something or add some flag to the compiler, which I do not.

I appreciate any help. Again, the error only occurs in projects compiled with LLVM (even with default SQL code). If I run the same queries in the terminal version of sqlite3, everything will be fine.

UPDATE:

This code works. It creates a new database, a new virtual table using fts, inserts several items, and then performs a selection. I will try more complex queries later, but at the moment it seems that the problem with my application may be, as expected, an error in my code.

NSArray *dirPaths = dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docsDir = [dirPaths objectAtIndex:0]; sqlite3 *database; // Build the path to the database file NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"test.db"]]; NSFileManager *filemgr = [NSFileManager defaultManager]; NSError *error = nil; [filemgr removeItemAtPath:databasePath error:&error]; const char *dbpath = [databasePath UTF8String]; if (sqlite3_open(dbpath, &database) == SQLITE_OK) { char *errMsg; const char *sql_stmt = "CREATE VIRTUAL TABLE IF NOT EXISTS pages USING fts3(title, body);"; if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) { NSLog(@"Failed to create table"); } else { sql_stmt = "INSERT INTO pages(docid, title, body) VALUES(53, 'Home Page', 'SQLite is a software...');"; if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) { NSLog(@"Failed to insert"); } sql_stmt = "INSERT INTO pages(title, body) VALUES('Download', 'All SQLite source code...');"; if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) { NSLog(@"Failed to insert"); } } sqlite3_stmt *statement; const char *query_stmt = "select * from pages where body match 'soft*';"; if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK) { if (sqlite3_step(statement) == SQLITE_ROW) { NSLog(@"%@ - %@", [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)], [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)]); } else { NSLog(@"no results"); } sqlite3_finalize(statement); } sqlite3_close(database); } else { NSLog(@"Failed to open/create database"); } 
+4
source share
1 answer

In the end, I found a mistake. That was in my code. So what I found out: If I have something like this (I know this is weird / wrong):

 int a = 0; a = a++; NSLog(@"%d", a); 

the registered value will be 1 if this code is compiled with gcc and 0 if compiled with llvm.

I don't know why, but this is another question :)

+3
source

All Articles