racket / db

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`in-query` broken with `#:group` option

LiberalArtist opened this issue · comments

When using in-query with a #:group option, there are mutually contradictory result arity mismatch and wrong number of columns errors.

Here is a (relatively) short program to illustrate:

#lang at-exp racket

(require db
         )

(define db
  (let ([db (sqlite3-connect #:database 'memory)])
    (query-exec db
                @~a{
CREATE TABLE tUsers (
userUUID TEXT NOT NULL PRIMARY KEY,
userName TEXT NOT NULL,
userEmailAddress TEXT NOT NULL
)
})
    (query-exec db
                @~a{
 CREATE TABLE tLogEntries (
 userUUID TEXT NOT NULL,
 userAccessSeconds INTEGER NOT NULL,
 userAccessIP TEXT NOT NULL,
 PRIMARY KEY (userUUID,userAccessSeconds),
 FOREIGN KEY (userUUID) REFERENCES tUsers
 ON DELETE CASCADE ON UPDATE CASCADE
 )
 })
    (query-exec db
                @~a{
INSERT INTO tUsers (userUUID,userName,userEmailAddress)
VALUES (?,?,?)
}
                "1a2b3c"
                "Jane Doe"
                "jdoe@example.org")
    (let ([stmnt @~a{
INSERT INTO tLogEntries (userUUID,userAccessSeconds,userAccessIP)
VALUES (?,?,?)
           }])
      (query-exec db stmnt "1a2b3c" 555 "192.168.1.1")
      (query-exec db stmnt "1a2b3c" 77777 "10.0.1.10"))        
    db))

(define select-statement
  @~a{
 SELECT
 userUUID,
 userName,
 userEmailAddress,
 userAccessSeconds,
 userAccessIP
 FROM tUsers
 NATURAL LEFT OUTER JOIN tLogEntries
 WHERE userUUID = ?
})

Given the above, group-rows demonstrates the correct grouping behavior, so

(rows-result-rows
 (group-rows
  (query db select-statement "1a2b3c")
  #:group #("userUUID"
            "userName"
            "userEmailAddress")))

evaluates to

'(#("1a2b3c"
    "Jane Doe"
    "jdoe@example.org"
    (#(555 "192.168.1.1") #(77777 "10.0.1.10"))))

However, in-query does not work correctly. If you write what you would expect, e.g.

(for/list ([(uuid name email grouped)
            (in-query db
                      select-statement
                      "1a2b3c"
                      #:group #("userUUID"
                                "userName"
                                "userEmailAddress"))])
  (vector uuid name email grouped))

you get the following error from in-query:

in-query: query returned wrong number of columns
  statement: "SELECT\nuserUUID,\nuserName,\nuserEmailAddress,\nuserAccessSeconds,\nuserAccessIP\nFROM tUsers\nNATURAL LEFT OUTER JOIN tLogEntries\nWHERE userUUID = ?"
  expected: 4
  got: 5

This error message is incorrect, however. If you instead write:

(for/list ([(uuid name email four five)
            (in-query db
                      select-statement
                      "1a2b3c"
                      #:group #("userUUID"
                                "userName"
                                "userEmailAddress"))])
  (vector uuid name email four five))

you get this error instead:

result arity mismatch;
 expected number of values not received
  expected: 5
  received: 4
  from: 
  in: local-binding form
  values...