return nil, err
        }
 
+       // -1 means the driver doesn't know how to count the number of
+       // placeholders, so we won't sanity check input here and instead let the
+       // driver deal with errors.
+       if want := ds.si.NumInput(); want >= 0 && want != len(dargs) {
+               return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(dargs))
+       }
+
        resi, err := ctxDriverStmtExec(ctx, ds.si, dargs)
        if err != nil {
                return nil, err
        ds.Lock()
        defer ds.Unlock()
 
-       want := ds.si.NumInput()
+       dargs, err := driverArgsConnLocked(ci, ds, args)
+       if err != nil {
+               return nil, err
+       }
 
        // -1 means the driver doesn't know how to count the number of
        // placeholders, so we won't sanity check input here and instead let the
        // driver deal with errors.
-       if want != -1 && len(args) != want {
-               return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(args))
-       }
-
-       dargs, err := driverArgsConnLocked(ci, ds, args)
-       if err != nil {
-               return nil, err
+       if want := ds.si.NumInput(); want >= 0 && want != len(dargs) {
+               return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(dargs))
        }
 
        rowsi, err := ctxDriverStmtQuery(ctx, ds.si, dargs)