From 1569116e3e926315895200adce60eccf858690a8 Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Sat, 16 May 2026 08:18:23 -0400 Subject: [PATCH] Fix wrong arg count in Exec's "not enough args" error The Exec and Query paths share the same multi-statement loop and the same `len(args)-start < na` check, but the Exec error message was printing `len(args)` instead of `len(args)-start`. With one arg passed to a two-statement query like `SELECT ?; SELECT ?`, the first statement consumes the arg and the second one trips the check, so the "got" count should be 0 (args remaining), not 1 (total args originally passed). The Query path was already correct. This just brings Exec in line. Closes #1395 Signed-off-by: Charlie Tonneslan --- sqlite3.go | 2 +- sqlite3_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/sqlite3.go b/sqlite3.go index b9deb72a..d44ae15f 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -962,7 +962,7 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []driver.Named na := s.NumInput() if len(args)-start < na { s.Close() - return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)) + return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)-start) } stmtArgs := stmtArgs(args, start, na) res, err = s.(*SQLiteStmt).exec(ctx, stmtArgs) diff --git a/sqlite3_test.go b/sqlite3_test.go index ac81458c..c1874225 100644 --- a/sqlite3_test.go +++ b/sqlite3_test.go @@ -1090,6 +1090,38 @@ func TestExecer(t *testing.T) { } } +func TestExecNotEnoughArgsErrorMessage(t *testing.T) { + tempFilename := TempFilename(t) + defer os.Remove(tempFilename) + db, err := sql.Open("sqlite3", tempFilename) + if err != nil { + t.Fatal("Failed to open database:", err) + } + defer db.Close() + + // Second statement is missing its arg. The "got" count should reflect + // the args remaining after the first statement consumed one, not the + // total number of args originally passed in. + _, err = db.Exec("SELECT ?; SELECT ?", "hello") + if err == nil { + t.Fatal("expected error for missing arg") + } + want := "not enough args to execute query: want 1 got 0" + if err.Error() != want { + t.Errorf("Exec error message:\n got: %q\nwant: %q", err.Error(), want) + } + + // Query already reports the right number; check it stays that way so + // the two paths don't drift again. + _, err = db.Query("SELECT ?; SELECT ?", "hello") + if err == nil { + t.Fatal("expected error for missing arg") + } + if err.Error() != want { + t.Errorf("Query error message:\n got: %q\nwant: %q", err.Error(), want) + } +} + func TestQueryer(t *testing.T) { tempFilename := TempFilename(t) defer os.Remove(tempFilename)