[plt-scheme] problem with arity?

From: Mike (mikee at mikee.ath.cx)
Date: Wed May 31 14:18:05 EDT 2006

This must be my problem, but I don't see it.  I'm trying my hand
at creating an extension interface to sqlite. I have the extension
working now I'm trying to allow one of the routines to allow for
errors. My intent is the scheme code could look like

(define db (sqlite:open "howard"))
(sqlite:do db "drop table geek")	; this could cause an error and abort
(sqlite:do db "drop table geek" 'error)	; same as above
(sqlite:do db "drop table geek" 'warn)	; throw a warning and continue
(sqlite:do db "drop table geek" 'ignore)	; ignore any errors

My scheme code so far is:

(define (show o)
  (display o)(newline))
(load-extension "sqlite.so")
(define db (sqlite:open "howard"))
(show db)
(display "dropping table geek=")(show (sqlite:do db "drop table geek"))

The error I get is:

sqlite:query: expects type <symbol (optional: 'warn, 'error)> as 3rd argument, given: "dropping table geek="; other arguments were: #dbi:sqlite "drop table geek"

It looks like the string "dropping table geek=" is passed as the third argument.
I thought the values of argc and argv would only be the parameters passed
to sch_dbdo. Am I to check argc and argv some different way?

(This is not homework. :)


My c code reload routine:

/* add interrupt, last inserted rowid, nrows, ncols */
Scheme_Object *scheme_reload(Scheme_Env *env)
    Scheme_Object *proc;

    /* create object types for SQL objects */
    dbtype = scheme_make_type(dbtypestr);       /* database object */
    stmttype = scheme_make_type(stmtstr);       /* SQL statement object */
    resultstype = scheme_make_type(resultsstr); /* results object */

    /* register all functions */
    proc = scheme_make_prim_w_arity(sch_dbopen, "sqlite:open", 1, 1);
    scheme_add_global("sqlite:open", proc, env);
    proc = scheme_make_prim_w_arity(sch_dbclose, "sqlite:close", 1, 1);
    scheme_add_global("sqlite:close", proc, env);
    proc = scheme_make_prim_w_arity(sch_dbclosed, "sqlite:closed?", 1, 1);
    scheme_add_global("sqlite:closed?", proc, env);
    proc = scheme_make_prim_w_arity(sch_dbquery, "sqlite:query", 2, 2);
    scheme_add_global("sqlite:query", proc, env);
    proc = scheme_make_prim_w_arity(sch_dbfetch, "sqlite:fetch", 1, 1);
    scheme_add_global("sqlite:fetch", proc, env);
    proc = scheme_make_prim_w_arity(sch_dbcurrow, "sqlite:currow", 1, 1);
    scheme_add_global("sqlite:currow", proc, env);
    proc = scheme_make_prim_w_arity(sch_dbqueryAndFetch, "sqlite:fetchall", 2, 2);
    scheme_add_global("sqlite:fetchall", proc, env);
    proc = scheme_make_prim_w_arity(sch_dbfinalize, "sqlite:finalize", 1, 1);
    scheme_add_global("sqlite:finalize", proc, env);
    proc = scheme_make_prim_w_arity(sch_dbdo, "sqlite:do", 2, 3);
    scheme_add_global("sqlite:do", proc, env);

    return scheme_void;

and my sch_dbdo() routine:

static Scheme_Object *sch_dbdo(int argc, Scheme_Object **argv)
    DB *dbo;
    sqlite3 *db;
    sqlite3_stmt *stmt;
    char *msg;
    const char **data, **name;
    const char *sql;
    Scheme_Object *so;
    int rc, ncol, ignore;

    /* check the arguments */
    if(SCHEME_TYPE(argv[0]) != dbtype) {
        scheme_wrong_type("sqlite:close", dbtypestr, 0, argc, argv);
    if(!SCHEME_CHAR_STRINGP(argv[1])) {
        scheme_wrong_type("sqlite:query", "string", 1, argc, argv);
    ignore = 0;
    if(argc == 2) {
        if(SCHEME_SYMBOLP(argv[2])) {
            if(SCHEME_SYMBOLP(argv[2]) && !strcmp(SCHEME_SYM_VAL(argv[2]), "warn")) {
                ignore = 1;
            } else if(SCHEME_SYMBOLP(argv[2]) && !strcmp(SCHEME_SYM_VAL(argv[2]), "error")) {
                ignore = 2;
            } else {
                scheme_signal_error("sqlite:do: invalid keyword, must be 'warn or 'error if present\n");
        } else {
            scheme_wrong_type("sqlite:query", "symbol (optional: 'warn, 'error)", 2, argc, argv);

    /* intialize */
    so = scheme_false;


Posted on the users mailing list.