chicken-janitors
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-janitors] #1553: sqlite3: The PREPARE procedure does not make i


From: Chicken Trac
Subject: [Chicken-janitors] #1553: sqlite3: The PREPARE procedure does not make it clear when it has and has not parsed a statement from a string.
Date: Sun, 21 Oct 2018 11:10:01 -0000

#1553: sqlite3: The PREPARE procedure does not make it clear when it has and has
not parsed a statement from a string.
-------------------------+--------------------------------
 Reporter:  nxg          |                 Owner:
     Type:  enhancement  |                Status:  new
 Priority:  major        |             Milestone:  someday
Component:  extensions   |               Version:  4.13.0
 Keywords:  sqlite3      |  Estimated difficulty:  easy
-------------------------+--------------------------------
 The PREPARE procedure does not make it clear when it has and has not
 parsed a statement from a string.

 The calls `(prepare db "")` and `(prepare db "select 1;"))` (note no
 trailing whitespace) both produce a `sqlite3:statement` and `""`, and
 there is no way of distinguishing between these.  In the former case, the
 statement displays as `#<sqlite3:statement zombie>`, but there is no way
 of detecting this in code.

 The documentation for PREPARE seems to suggest that a way of parsing a
 sequence of SQL statements from a string is to call PREPARE recursively on
 PREPARE's `rest` return, until `rest` returns `""`. Thus:
 {{{
 (define (execute-statements* sql-string)
   (let-values (((stmt rest) (prepare db sql-string)))
     (if (string-null? rest)
         (finalize! stmt)
         (begin
           (dynamic-wind
               values
               (lambda ()
                 (update stmt))
               (lambda ()
                 (finalize! stmt)))
           (execute-statements* rest)))))
 }}}
 This will work //if and only if// the SQL string ends in whitespace, but
 will not work if the input string has no trailing whitespace or if it ends
 in a comment.  Spotting when `sql-string` is all whitespace, and special-
 casing this, helps in many cases, but doesn't help in the case where `sql-
 string` contains, or has through this process ended up containing, only a
 comment.

 There //might// be a way of wrapping this up which solves the problem, and
 there might be a way of deducing that a statement is a 'zombie' by
 (mis)using other procedures, but more straightforward would be one of the
 following:

 * Create a STATEMENT-ZOMBIE? predicate for the case where (in the
 implementation) `statement-ptr` is `#f`, and a statement would display as
 `zombie`.  Advantages: straightforward to implement; quite specific.
 Disadvantages: introduces an extra concept which isn't really present in
 the underlying SQLite library, and which appears to be meaningful only for
 this case.
 * Have STATEMENT? return `#f` for 'zombie' statements.  Advantages:
 matches the real semantics of the situation; so is probably the least
 surprising thing.  Disadvantages: might in principle confuse some future
 type reasoning, which might assume that if something is a statement, then
 it can be passed to UPDATE without error.
 * Have PREPARE return `#f` for the statement when no statement is parsed.
 Advantages: also unsurprising, and easy to check for without changing the
 definition of STATEMENT?.  Disadvantates: some complication to the type
 signature of PREPARE.

 Of the three, I think the first is unattractive, and the second slightly
 more attractive than the third.

 I've marked this as an enhancement request, though I think it's on the
 border of being a bug.  I don't know what the criteria are for major vs
 minor priority.

--
Ticket URL: <https://bugs.call-cc.org/ticket/1553>
CHICKEN Scheme <https://www.call-cc.org/>
CHICKEN Scheme is a compiler for the Scheme programming language.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]