diff --git a/src/database/sql/convert.go b/src/database/sql/convert.go index 26b139ababd..8a0457f9f49 100644 --- a/src/database/sql/convert.go +++ b/src/database/sql/convert.go @@ -55,7 +55,7 @@ func (c ccChecker) CheckNamedValue(nv *driver.NamedValue) error { // it isn't expecting. The final error will be thrown // in the argument converter loop. index := nv.Ordinal - 1 - if c.want <= index { + if c.want >= 0 && c.want <= index { return nil } diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go index c3f228ef0ba..6ee85058558 100644 --- a/src/database/sql/sql_test.go +++ b/src/database/sql/sql_test.go @@ -5135,3 +5135,50 @@ func TestIssue69728(t *testing.T) { t.Errorf("not equal; v1 = %v, v2 = %v", v1, v2) } } + +func TestColumnConverterWithUnknownInputCount(t *testing.T) { + db := OpenDB(&unknownInputsConnector{}) + stmt, err := db.Prepare("SELECT ?") + if err != nil { + t.Fatal(err) + } + _, err = stmt.Exec(1) + if err != nil { + t.Fatal(err) + } +} + +type unknownInputsConnector struct{} + +func (unknownInputsConnector) Connect(context.Context) (driver.Conn, error) { + return unknownInputsConn{}, nil +} + +func (unknownInputsConnector) Driver() driver.Driver { return nil } + +type unknownInputsConn struct{} + +func (unknownInputsConn) Prepare(string) (driver.Stmt, error) { return unknownInputsStmt{}, nil } +func (unknownInputsConn) Close() error { return nil } +func (unknownInputsConn) Begin() (driver.Tx, error) { return nil, nil } + +type unknownInputsStmt struct{} + +func (unknownInputsStmt) Close() error { return nil } +func (unknownInputsStmt) NumInput() int { return -1 } +func (unknownInputsStmt) Exec(args []driver.Value) (driver.Result, error) { + if _, ok := args[0].(string); !ok { + return nil, fmt.Errorf("Expected string, got %T", args[0]) + } + return nil, nil +} +func (unknownInputsStmt) Query([]driver.Value) (driver.Rows, error) { return nil, nil } +func (unknownInputsStmt) ColumnConverter(idx int) driver.ValueConverter { + return unknownInputsValueConverter{} +} + +type unknownInputsValueConverter struct{} + +func (unknownInputsValueConverter) ConvertValue(v any) (driver.Value, error) { + return "string", nil +}