`in-query` broken with `#:group` option
LiberalArtist opened this issue · comments
Philip McGrath commented
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...