database/sql: don't ignore ColumnConverter for unknown input count

In the case a sql driver implements the ColumnConverter interface and also
returns -1 for NumInputs, indicating an unknown number of input arguments to
a query, the previous implementation would ignore the column converter would
not be called, leading to unexpected or invalid arguments passed to the driver.

Fixes #68342

Change-Id: Ib2ddaf040fa9be669d593eacdaa1e88ba66d7bc2
Reviewed-on: https://go-review.googlesource.com/c/go/+/597115
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Jonathan Hall 2024-07-08 18:14:43 +02:00 committed by t hepudds
parent 121bc3e464
commit 6f16669e34
2 changed files with 48 additions and 1 deletions

View file

@ -55,7 +55,7 @@ func (c ccChecker) CheckNamedValue(nv *driver.NamedValue) error {
// it isn't expecting. The final error will be thrown // it isn't expecting. The final error will be thrown
// in the argument converter loop. // in the argument converter loop.
index := nv.Ordinal - 1 index := nv.Ordinal - 1
if c.want <= index { if c.want >= 0 && c.want <= index {
return nil return nil
} }

View file

@ -5135,3 +5135,50 @@ func TestIssue69728(t *testing.T) {
t.Errorf("not equal; v1 = %v, v2 = %v", v1, v2) 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
}