Binding Values to Prepared Statement Returns "row value misused"
source-transformer opened this issue · 4 comments
If I bind more than one value to a prepared statement - I get "row value misused".
This works:
"SELECT * FROM `table1` WHERE `table1`.`column1` = ?"
The following doesn't work:
"SELECT * FROM `table1` WHERE `table1`.`column1` = ? AND `table1`.`column2` = ?"
It doesn't work in the sense that I get the following error returned:
"row value misused"
same result if you remove the backticks.
I cloned this repository and found this bit of code (but that's as far as I've looked into this):
SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
#ifndef SQLITE_OMIT_SUBQUERY
if( ExprUseXSelect(pExpr) ){
sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
}else
#endif
{
sqlite3ErrorMsg(pParse, "row value misused");
If I just manually inject the values into the SQL statement it works without issue.
I'm using go-sqlite3 thru GORM - my code looks like this:
func runQuery(ctx context.Context, query *models.FooRecord, values ...interface{}) (string, error) {
db := s.GetDB(ctx)
var fooRecords []*models.FooRecord
stmt := db.Session(&gorm.Session{DryRun: true}).Model(&models.FooRecord{}).Where(query).Find(&fooRecords).Statement
stmtStr := stmt.SQL.String()
var results map[string]interface{}
rawRes := db.Raw(stmtStr, values)
if rawRes.Error != nil {
return "", errors.New("runQuery: explain query failed: " + rawRes.Error.Error())
}
res := rawRes.Scan(&results)
if res.Error != nil {
return "", errors.New("runQuery: explain query failed: " + res.Error.Error())
}
// SNIPPED rest of code - but at this point you can just return nil, nil
return nil, nil
}
Not sure if it is useful - but here is how this is being called:
fooQuery := &models.FooRecord{
}
oneID := "asdf"
twoID := "qwer"
result, err = runQuery(ctx, fooQuery, oneID, twoID)
@source-transformer What version of this library are you using? What are the database schema and contents? Please provide a reproducer that only uses this library (via database/sql), not gorm.
Right - sorry forgot those details.
I was originally on version
v1.14.12
then I tried upgrading to latest
v1.14.16
with same result.
The db schema is just
table1
with column1 + column2 both being primary keys (together forming composite key).
I'm walking thru the build/install instructions (https://github.com/mattn/go-sqlite3#mac-osx) now to see if I can create a unit test. Any tips/pointers on where/how to create a unit test that creates a table along with my other specifics?
Thanks!
I think I can just clone this function and alter it to my needs:
func testManyQueryRow(t *testing.T) {
if testing.Short() {
t.Log("skipping in short mode")
return
}
db.tearDown()
db.mustExec("create table foo (id integer primary key, name varchar(50))")
db.mustExec(db.q("insert into foo (id, name) values(?,?)"), 1, "bob")
var name string
for i := 0; i < 10000; i++ {
err := db.QueryRow(db.q("select name from foo where id = ?"), 1).Scan(&name)
if err != nil || name != "bob" {
t.Fatalf("on query %d: err=%v, name=%q", i, err, name)
}
}
}
I added a couple of tests that have reassured me that sqlite3 is not the culprit - I can create a PR with those two new tests if you'd like them.
I found the bug in gorm - somehow it is appending a second question mark to my prepared statement:
"SELECT * FROM table1
WHERE table1
.column1
= (?,?) AND table1
.column2
= ?"
I'm going to see if I can create a git issue for gorm.