SQLite3 segmentation at prepare statement

growler growlercab at gmail.com
Wed Sep 18 21:29:11 PDT 2013


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


More information about the Digitalmars-d-learn mailing list