SQLite3 segmentation at prepare statement

Charles Hixson charleshixsn at earthlink.net
Thu Sep 19 12:38:28 PDT 2013


You're right about the finalize, but changing the line to:
rc    =    sqlite3_prepare(db, toStringz(sql), cast(int)sql.length + 
1000, &stmt, null);
results in the compile time error:
sqlitetest.d(39): Error: function etc.c.sqlite3.sqlite3_prepare 
(sqlite3* db, const(char)* zSql, int nByte, sqlite3_stmt** ppStmt, 
const(char*)* pzTail) is not callable using argument types (sqlite3*, 
immutable(char)*, int, sqlite3_stmt***, typeof(null))

On 09/18/2013 09:29 PM, growler wrote:
> On Wednesday, 18 September 2013 at 21:31:00 UTC, Charles Hixson wrote:
>> I'm trying to use SQLite3 in D, but am getting a segmentation fault 
>> when I attempt to replace the exec statement with a prepare 
>> statement.  What am I doing wrong?
>>
>> If the prepare statement is commented out, and the exec statement is 
>> uncommented, the program runs successfully. (There's no data yet in 
>> the database file.)
>>
>> The test program is:
>>
>> pragma    (lib, "sqlite3");
>>
>>
>> import    etc.c.sqlite3;
>> import    std.exception;
>> import    std.stdio;
>> import    std.string;
>>
>> /**    int function(void*, int, char**, char**) callback    */
>> extern(C)
>> int    callback    (void* notUsed, int argc, char** argv, char** 
>> azColName)
>> {
>>     for    (int i = 0;    i < argc;    i++)
>>     {    printf ("%s = %s\n", azColName[i], argv[i] ? argv[i] : 
>> "null");    }
>>     printf    ("\n");
>>     return    0;
>> }
>>
>> void    main()
>> {    sqlite3*    db;
>>     int        rc;
>>     char*        zErrMsg    =    null;
>>     sqlite3_stmt**    stmt;
>>
>>     rc    =    sqlite3_open (toStringz("data/sqlitetest.db"), &db);
>>     if    (SQLITE_OK != rc)
>>     {    printf ("DB create error: %s\n", sqlite3_errmsg(db) );
>>    }
>>
>>     string    sql    =
>>         "create table if not exists wrds (name text primary key, id 
>> int)\0";
>>     rc    =    sqlite3_exec(db, sql.ptr, &callback, cast(void*)0, 
>> &zErrMsg);
>>     if    (SQLITE_OK != rc)
>>     {    printf ("DB create table error: %s\n", sqlite3_errmsg(db) );
>>         printf    ("sql = <<%s>>\n", sql);
>>     }
>>
>>     sql    =    "select * from wrds\0";
>>     rc    =    sqlite3_prepare(db, toStringz(sql), 
>> cast(int)sql.length, stmt, null);
>> //    if    (SQLITE_OK != rc)
>> //    {    printf ("DB prepare statement error: %s\n", 
>> sqlite3_errmsg(db) );
>> //        printf    ("sql = <<%s>>\n", sql);
>> //    }
>> //    rc    =    sqlite3_step(*stmt);
>> //    if    (SQLITE_OK != rc)
>> //    {    printf ("DB statement step error: %s\n", 
>> sqlite3_errmsg(db) );
>> //        printf    ("sql = <<%s>>\n", sql);
>> //    }
>> //
>> //    rc    =    sqlite3_exec(db, sql.ptr, &callback, cast(void*)0, 
>> &zErrMsg);
>> //    if    (SQLITE_OK != rc)
>> //    {    printf ("DB select error: %s\n", sqlite3_errmsg(db) );
>> //        printf    ("sql = <<%s>>\n", sql);
>> //    }
>> //
>>     rc    =    sqlite3_close    (db);
>>     enforce    (rc == SQLITE_OK);
>> }
>
> Sorry I'm not a sqlite3 expert, nor do I have access to DMD at the 
> moment so cannot fully test but that sqlite3_stmt** looks wrong, try 
> this:
>
> change:
> ---
> sqlite3_stmt**    stmt;
> ...
> rc= sqlite3_prepare(db, toStringz(sql), cast(int)sql.length, stmt, null);
> ...
> rc=    sqlite3_step(*stmt);
> ---
>
> to:
> ---
> sqlite3_stmt*    stmt;
> ...
> rc= sqlite3_prepare(db, toStringz(sql), cast(int)sql.length, &stmt, 
> null);
> ...
> rc=    sqlite3_step(stmt);
> ---
>
> I think (from ancient memory) that you also need to clean up the 
> statement with something like:
>
> sqlite_finalize(stmt);
>
> but don't quote me on that :D
>


-- 
Charles Hixson



More information about the Digitalmars-d-learn mailing list