github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/database/sql/convert.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Type conversions for Scan. 6 7 package sql 8 9 import ( 10 "database/sql/driver" 11 "errors" 12 "fmt" 13 "reflect" 14 "strconv" 15 "sync" 16 "time" 17 "unicode" 18 "unicode/utf8" 19 ) 20 21 var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error 22 23 func describeNamedValue(nv *driver.NamedValue) string { 24 if len(nv.Name) == 0 { 25 return fmt.Sprintf("$%d", nv.Ordinal) 26 } 27 return fmt.Sprintf("with name %q", nv.Name) 28 } 29 30 func validateNamedValueName(name string) error { 31 if len(name) == 0 { 32 return nil 33 } 34 r, _ := utf8.DecodeRuneInString(name) 35 if unicode.IsLetter(r) { 36 return nil 37 } 38 return fmt.Errorf("name %q does not begin with a letter", name) 39 } 40 41 func driverNumInput(ds *driverStmt) int { 42 ds.Lock() 43 defer ds.Unlock() // in case NumInput panics 44 return ds.si.NumInput() 45 } 46 47 // ccChecker wraps the driver.ColumnConverter and allows it to be used 48 // as if it were a NamedValueChecker. If the driver ColumnConverter 49 // is not present then the NamedValueChecker will return driver.ErrSkip. 50 type ccChecker struct { 51 sync.Locker 52 cci driver.ColumnConverter 53 want int 54 } 55 56 func (c ccChecker) CheckNamedValue(nv *driver.NamedValue) error { 57 if c.cci == nil { 58 return driver.ErrSkip 59 } 60 // The column converter shouldn't be called on any index 61 // it isn't expecting. The final error will be thrown 62 // in the argument converter loop. 63 index := nv.Ordinal - 1 64 if c.want <= index { 65 return nil 66 } 67 68 // First, see if the value itself knows how to convert 69 // itself to a driver type. For example, a NullString 70 // struct changing into a string or nil. 71 if vr, ok := nv.Value.(driver.Valuer); ok { 72 sv, err := callValuerValue(vr) 73 if err != nil { 74 return err 75 } 76 if !driver.IsValue(sv) { 77 return fmt.Errorf("non-subset type %T returned from Value", sv) 78 } 79 nv.Value = sv 80 } 81 82 // Second, ask the column to sanity check itself. For 83 // example, drivers might use this to make sure that 84 // an int64 values being inserted into a 16-bit 85 // integer field is in range (before getting 86 // truncated), or that a nil can't go into a NOT NULL 87 // column before going across the network to get the 88 // same error. 89 var err error 90 arg := nv.Value 91 c.Lock() 92 nv.Value, err = c.cci.ColumnConverter(index).ConvertValue(arg) 93 c.Unlock() 94 if err != nil { 95 return err 96 } 97 if !driver.IsValue(nv.Value) { 98 return fmt.Errorf("driver ColumnConverter error converted %T to unsupported type %T", arg, nv.Value) 99 } 100 return nil 101 } 102 103 // defaultCheckNamedValue wraps the default ColumnConverter to have the same 104 // function signature as the CheckNamedValue in the driver.NamedValueChecker 105 // interface. 106 func defaultCheckNamedValue(nv *driver.NamedValue) (err error) { 107 nv.Value, err = driver.DefaultParameterConverter.ConvertValue(nv.Value) 108 return err 109 } 110 111 // driverArgs converts arguments from callers of Stmt.Exec and 112 // Stmt.Query into driver Values. 113 // 114 // The statement ds may be nil, if no statement is available. 115 func driverArgs(ci driver.Conn, ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) { 116 nvargs := make([]driver.NamedValue, len(args)) 117 118 // -1 means the driver doesn't know how to count the number of 119 // placeholders, so we won't sanity check input here and instead let the 120 // driver deal with errors. 121 want := -1 122 123 var si driver.Stmt 124 var cc ccChecker 125 if ds != nil { 126 si = ds.si 127 want = driverNumInput(ds) 128 cc.Locker = ds.Locker 129 cc.want = want 130 } 131 132 // Check all types of interfaces from the start. 133 // Drivers may opt to use the NamedValueChecker for special 134 // argument types, then return driver.ErrSkip to pass it along 135 // to the column converter. 136 nvc, ok := si.(driver.NamedValueChecker) 137 if !ok { 138 nvc, ok = ci.(driver.NamedValueChecker) 139 } 140 cci, ok := si.(driver.ColumnConverter) 141 if ok { 142 cc.cci = cci 143 } 144 145 // Loop through all the arguments, checking each one. 146 // If no error is returned simply increment the index 147 // and continue. However if driver.ErrRemoveArgument 148 // is returned the argument is not included in the query 149 // argument list. 150 var err error 151 var n int 152 for _, arg := range args { 153 nv := &nvargs[n] 154 if np, ok := arg.(NamedArg); ok { 155 if err = validateNamedValueName(np.Name); err != nil { 156 return nil, err 157 } 158 arg = np.Value 159 nv.Name = np.Name 160 } 161 nv.Ordinal = n + 1 162 nv.Value = arg 163 164 // Checking sequence has four routes: 165 // A: 1. Default 166 // B: 1. NamedValueChecker 2. Column Converter 3. Default 167 // C: 1. NamedValueChecker 3. Default 168 // D: 1. Column Converter 2. Default 169 // 170 // The only time a Column Converter is called is first 171 // or after NamedValueConverter. If first it is handled before 172 // the nextCheck label. Thus for repeats tries only when the 173 // NamedValueConverter is selected should the Column Converter 174 // be used in the retry. 175 checker := defaultCheckNamedValue 176 nextCC := false 177 switch { 178 case nvc != nil: 179 nextCC = cci != nil 180 checker = nvc.CheckNamedValue 181 case cci != nil: 182 checker = cc.CheckNamedValue 183 } 184 185 nextCheck: 186 err = checker(nv) 187 switch err { 188 case nil: 189 n++ 190 continue 191 case driver.ErrRemoveArgument: 192 nvargs = nvargs[:len(nvargs)-1] 193 continue 194 case driver.ErrSkip: 195 if nextCC { 196 nextCC = false 197 checker = cc.CheckNamedValue 198 } else { 199 checker = defaultCheckNamedValue 200 } 201 goto nextCheck 202 default: 203 return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err) 204 } 205 } 206 207 // Check the length of arguments after convertion to allow for omitted 208 // arguments. 209 if want != -1 && len(nvargs) != want { 210 return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(nvargs)) 211 } 212 213 return nvargs, nil 214 215 } 216 217 // convertAssign copies to dest the value in src, converting it if possible. 218 // An error is returned if the copy would result in loss of information. 219 // dest should be a pointer type. 220 func convertAssign(dest, src interface{}) error { 221 // Common cases, without reflect. 222 switch s := src.(type) { 223 case string: 224 switch d := dest.(type) { 225 case *string: 226 if d == nil { 227 return errNilPtr 228 } 229 *d = s 230 return nil 231 case *[]byte: 232 if d == nil { 233 return errNilPtr 234 } 235 *d = []byte(s) 236 return nil 237 } 238 case []byte: 239 switch d := dest.(type) { 240 case *string: 241 if d == nil { 242 return errNilPtr 243 } 244 *d = string(s) 245 return nil 246 case *interface{}: 247 if d == nil { 248 return errNilPtr 249 } 250 *d = cloneBytes(s) 251 return nil 252 case *[]byte: 253 if d == nil { 254 return errNilPtr 255 } 256 *d = cloneBytes(s) 257 return nil 258 case *RawBytes: 259 if d == nil { 260 return errNilPtr 261 } 262 *d = s 263 return nil 264 } 265 case time.Time: 266 switch d := dest.(type) { 267 case *string: 268 *d = s.Format(time.RFC3339Nano) 269 return nil 270 case *[]byte: 271 if d == nil { 272 return errNilPtr 273 } 274 *d = []byte(s.Format(time.RFC3339Nano)) 275 return nil 276 } 277 case nil: 278 switch d := dest.(type) { 279 case *interface{}: 280 if d == nil { 281 return errNilPtr 282 } 283 *d = nil 284 return nil 285 case *[]byte: 286 if d == nil { 287 return errNilPtr 288 } 289 *d = nil 290 return nil 291 case *RawBytes: 292 if d == nil { 293 return errNilPtr 294 } 295 *d = nil 296 return nil 297 } 298 } 299 300 var sv reflect.Value 301 302 switch d := dest.(type) { 303 case *string: 304 sv = reflect.ValueOf(src) 305 switch sv.Kind() { 306 case reflect.Bool, 307 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 308 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 309 reflect.Float32, reflect.Float64: 310 *d = asString(src) 311 return nil 312 } 313 case *[]byte: 314 sv = reflect.ValueOf(src) 315 if b, ok := asBytes(nil, sv); ok { 316 *d = b 317 return nil 318 } 319 case *RawBytes: 320 sv = reflect.ValueOf(src) 321 if b, ok := asBytes([]byte(*d)[:0], sv); ok { 322 *d = RawBytes(b) 323 return nil 324 } 325 case *bool: 326 bv, err := driver.Bool.ConvertValue(src) 327 if err == nil { 328 *d = bv.(bool) 329 } 330 return err 331 case *interface{}: 332 *d = src 333 return nil 334 } 335 336 if scanner, ok := dest.(Scanner); ok { 337 return scanner.Scan(src) 338 } 339 340 dpv := reflect.ValueOf(dest) 341 if dpv.Kind() != reflect.Ptr { 342 return errors.New("destination not a pointer") 343 } 344 if dpv.IsNil() { 345 return errNilPtr 346 } 347 348 if !sv.IsValid() { 349 sv = reflect.ValueOf(src) 350 } 351 352 dv := reflect.Indirect(dpv) 353 if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) { 354 switch b := src.(type) { 355 case []byte: 356 dv.Set(reflect.ValueOf(cloneBytes(b))) 357 default: 358 dv.Set(sv) 359 } 360 return nil 361 } 362 363 if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) { 364 dv.Set(sv.Convert(dv.Type())) 365 return nil 366 } 367 368 // The following conversions use a string value as an intermediate representation 369 // to convert between various numeric types. 370 // 371 // This also allows scanning into user defined types such as "type Int int64". 372 // For symmetry, also check for string destination types. 373 switch dv.Kind() { 374 case reflect.Ptr: 375 if src == nil { 376 dv.Set(reflect.Zero(dv.Type())) 377 return nil 378 } else { 379 dv.Set(reflect.New(dv.Type().Elem())) 380 return convertAssign(dv.Interface(), src) 381 } 382 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 383 s := asString(src) 384 i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) 385 if err != nil { 386 err = strconvErr(err) 387 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 388 } 389 dv.SetInt(i64) 390 return nil 391 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 392 s := asString(src) 393 u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) 394 if err != nil { 395 err = strconvErr(err) 396 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 397 } 398 dv.SetUint(u64) 399 return nil 400 case reflect.Float32, reflect.Float64: 401 s := asString(src) 402 f64, err := strconv.ParseFloat(s, dv.Type().Bits()) 403 if err != nil { 404 err = strconvErr(err) 405 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 406 } 407 dv.SetFloat(f64) 408 return nil 409 case reflect.String: 410 switch v := src.(type) { 411 case string: 412 dv.SetString(v) 413 return nil 414 case []byte: 415 dv.SetString(string(v)) 416 return nil 417 } 418 } 419 420 return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) 421 } 422 423 func strconvErr(err error) error { 424 if ne, ok := err.(*strconv.NumError); ok { 425 return ne.Err 426 } 427 return err 428 } 429 430 func cloneBytes(b []byte) []byte { 431 if b == nil { 432 return nil 433 } else { 434 c := make([]byte, len(b)) 435 copy(c, b) 436 return c 437 } 438 } 439 440 func asString(src interface{}) string { 441 switch v := src.(type) { 442 case string: 443 return v 444 case []byte: 445 return string(v) 446 } 447 rv := reflect.ValueOf(src) 448 switch rv.Kind() { 449 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 450 return strconv.FormatInt(rv.Int(), 10) 451 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 452 return strconv.FormatUint(rv.Uint(), 10) 453 case reflect.Float64: 454 return strconv.FormatFloat(rv.Float(), 'g', -1, 64) 455 case reflect.Float32: 456 return strconv.FormatFloat(rv.Float(), 'g', -1, 32) 457 case reflect.Bool: 458 return strconv.FormatBool(rv.Bool()) 459 } 460 return fmt.Sprintf("%v", src) 461 } 462 463 func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) { 464 switch rv.Kind() { 465 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 466 return strconv.AppendInt(buf, rv.Int(), 10), true 467 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 468 return strconv.AppendUint(buf, rv.Uint(), 10), true 469 case reflect.Float32: 470 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true 471 case reflect.Float64: 472 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true 473 case reflect.Bool: 474 return strconv.AppendBool(buf, rv.Bool()), true 475 case reflect.String: 476 s := rv.String() 477 return append(buf, s...), true 478 } 479 return 480 } 481 482 var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() 483 484 // callValuerValue returns vr.Value(), with one exception: 485 // If vr.Value is an auto-generated method on a pointer type and the 486 // pointer is nil, it would panic at runtime in the panicwrap 487 // method. Treat it like nil instead. 488 // Issue 8415. 489 // 490 // This is so people can implement driver.Value on value types and 491 // still use nil pointers to those types to mean nil/NULL, just like 492 // string/*string. 493 // 494 // This function is mirrored in the database/sql/driver package. 495 func callValuerValue(vr driver.Valuer) (v driver.Value, err error) { 496 if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr && 497 rv.IsNil() && 498 rv.Type().Elem().Implements(valuerReflectType) { 499 return nil, nil 500 } 501 return vr.Value() 502 }