github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/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 "time" 16 "unicode" 17 "unicode/utf8" 18 ) 19 20 var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error 21 22 func describeNamedValue(nv *driver.NamedValue) string { 23 if len(nv.Name) == 0 { 24 return fmt.Sprintf("$%d", nv.Ordinal) 25 } 26 return fmt.Sprintf("with name %q", nv.Name) 27 } 28 29 func validateNamedValueName(name string) error { 30 if len(name) == 0 { 31 return nil 32 } 33 r, _ := utf8.DecodeRuneInString(name) 34 if unicode.IsLetter(r) { 35 return nil 36 } 37 return fmt.Errorf("name %q does not begin with a letter", name) 38 } 39 40 // driverArgs converts arguments from callers of Stmt.Exec and 41 // Stmt.Query into driver Values. 42 // 43 // The statement ds may be nil, if no statement is available. 44 func driverArgs(ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) { 45 nvargs := make([]driver.NamedValue, len(args)) 46 var si driver.Stmt 47 if ds != nil { 48 si = ds.si 49 } 50 cc, ok := si.(driver.ColumnConverter) 51 52 // Normal path, for a driver.Stmt that is not a ColumnConverter. 53 if !ok { 54 for n, arg := range args { 55 var err error 56 nv := &nvargs[n] 57 nv.Ordinal = n + 1 58 if np, ok := arg.(NamedArg); ok { 59 if err := validateNamedValueName(np.Name); err != nil { 60 return nil, err 61 } 62 arg = np.Value 63 nvargs[n].Name = np.Name 64 } 65 nv.Value, err = driver.DefaultParameterConverter.ConvertValue(arg) 66 67 if err != nil { 68 return nil, fmt.Errorf("sql: converting Exec argument %s type: %v", describeNamedValue(nv), err) 69 } 70 } 71 return nvargs, nil 72 } 73 74 // Let the Stmt convert its own arguments. 75 for n, arg := range args { 76 nv := &nvargs[n] 77 nv.Ordinal = n + 1 78 if np, ok := arg.(NamedArg); ok { 79 if err := validateNamedValueName(np.Name); err != nil { 80 return nil, err 81 } 82 arg = np.Value 83 nv.Name = np.Name 84 } 85 // First, see if the value itself knows how to convert 86 // itself to a driver type. For example, a NullString 87 // struct changing into a string or nil. 88 if vr, ok := arg.(driver.Valuer); ok { 89 sv, err := callValuerValue(vr) 90 if err != nil { 91 return nil, fmt.Errorf("sql: argument %s from Value: %v", describeNamedValue(nv), err) 92 } 93 if !driver.IsValue(sv) { 94 return nil, fmt.Errorf("sql: argument %s: non-subset type %T returned from Value", describeNamedValue(nv), sv) 95 } 96 arg = sv 97 } 98 99 // Second, ask the column to sanity check itself. For 100 // example, drivers might use this to make sure that 101 // an int64 values being inserted into a 16-bit 102 // integer field is in range (before getting 103 // truncated), or that a nil can't go into a NOT NULL 104 // column before going across the network to get the 105 // same error. 106 var err error 107 ds.Lock() 108 nv.Value, err = cc.ColumnConverter(n).ConvertValue(arg) 109 ds.Unlock() 110 if err != nil { 111 return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err) 112 } 113 if !driver.IsValue(nv.Value) { 114 return nil, fmt.Errorf("sql: for argument %s, driver ColumnConverter error converted %T to unsupported type %T", 115 describeNamedValue(nv), arg, nv.Value) 116 } 117 } 118 119 return nvargs, nil 120 } 121 122 // convertAssign copies to dest the value in src, converting it if possible. 123 // An error is returned if the copy would result in loss of information. 124 // dest should be a pointer type. 125 func convertAssign(dest, src interface{}) error { 126 // Common cases, without reflect. 127 switch s := src.(type) { 128 case string: 129 switch d := dest.(type) { 130 case *string: 131 if d == nil { 132 return errNilPtr 133 } 134 *d = s 135 return nil 136 case *[]byte: 137 if d == nil { 138 return errNilPtr 139 } 140 *d = []byte(s) 141 return nil 142 } 143 case []byte: 144 switch d := dest.(type) { 145 case *string: 146 if d == nil { 147 return errNilPtr 148 } 149 *d = string(s) 150 return nil 151 case *interface{}: 152 if d == nil { 153 return errNilPtr 154 } 155 *d = cloneBytes(s) 156 return nil 157 case *[]byte: 158 if d == nil { 159 return errNilPtr 160 } 161 *d = cloneBytes(s) 162 return nil 163 case *RawBytes: 164 if d == nil { 165 return errNilPtr 166 } 167 *d = s 168 return nil 169 } 170 case time.Time: 171 switch d := dest.(type) { 172 case *string: 173 *d = s.Format(time.RFC3339Nano) 174 return nil 175 case *[]byte: 176 if d == nil { 177 return errNilPtr 178 } 179 *d = []byte(s.Format(time.RFC3339Nano)) 180 return nil 181 } 182 case nil: 183 switch d := dest.(type) { 184 case *interface{}: 185 if d == nil { 186 return errNilPtr 187 } 188 *d = nil 189 return nil 190 case *[]byte: 191 if d == nil { 192 return errNilPtr 193 } 194 *d = nil 195 return nil 196 case *RawBytes: 197 if d == nil { 198 return errNilPtr 199 } 200 *d = nil 201 return nil 202 } 203 } 204 205 var sv reflect.Value 206 207 switch d := dest.(type) { 208 case *string: 209 sv = reflect.ValueOf(src) 210 switch sv.Kind() { 211 case reflect.Bool, 212 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 213 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 214 reflect.Float32, reflect.Float64: 215 *d = asString(src) 216 return nil 217 } 218 case *[]byte: 219 sv = reflect.ValueOf(src) 220 if b, ok := asBytes(nil, sv); ok { 221 *d = b 222 return nil 223 } 224 case *RawBytes: 225 sv = reflect.ValueOf(src) 226 if b, ok := asBytes([]byte(*d)[:0], sv); ok { 227 *d = RawBytes(b) 228 return nil 229 } 230 case *bool: 231 bv, err := driver.Bool.ConvertValue(src) 232 if err == nil { 233 *d = bv.(bool) 234 } 235 return err 236 case *interface{}: 237 *d = src 238 return nil 239 } 240 241 if scanner, ok := dest.(Scanner); ok { 242 return scanner.Scan(src) 243 } 244 245 dpv := reflect.ValueOf(dest) 246 if dpv.Kind() != reflect.Ptr { 247 return errors.New("destination not a pointer") 248 } 249 if dpv.IsNil() { 250 return errNilPtr 251 } 252 253 if !sv.IsValid() { 254 sv = reflect.ValueOf(src) 255 } 256 257 dv := reflect.Indirect(dpv) 258 if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) { 259 switch b := src.(type) { 260 case []byte: 261 dv.Set(reflect.ValueOf(cloneBytes(b))) 262 default: 263 dv.Set(sv) 264 } 265 return nil 266 } 267 268 if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) { 269 dv.Set(sv.Convert(dv.Type())) 270 return nil 271 } 272 273 // The following conversions use a string value as an intermediate representation 274 // to convert between various numeric types. 275 // 276 // This also allows scanning into user defined types such as "type Int int64". 277 // For symmetry, also check for string destination types. 278 switch dv.Kind() { 279 case reflect.Ptr: 280 if src == nil { 281 dv.Set(reflect.Zero(dv.Type())) 282 return nil 283 } else { 284 dv.Set(reflect.New(dv.Type().Elem())) 285 return convertAssign(dv.Interface(), src) 286 } 287 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 288 s := asString(src) 289 i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) 290 if err != nil { 291 err = strconvErr(err) 292 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 293 } 294 dv.SetInt(i64) 295 return nil 296 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 297 s := asString(src) 298 u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) 299 if err != nil { 300 err = strconvErr(err) 301 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 302 } 303 dv.SetUint(u64) 304 return nil 305 case reflect.Float32, reflect.Float64: 306 s := asString(src) 307 f64, err := strconv.ParseFloat(s, dv.Type().Bits()) 308 if err != nil { 309 err = strconvErr(err) 310 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) 311 } 312 dv.SetFloat(f64) 313 return nil 314 case reflect.String: 315 switch v := src.(type) { 316 case string: 317 dv.SetString(v) 318 return nil 319 case []byte: 320 dv.SetString(string(v)) 321 return nil 322 } 323 } 324 325 return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) 326 } 327 328 func strconvErr(err error) error { 329 if ne, ok := err.(*strconv.NumError); ok { 330 return ne.Err 331 } 332 return err 333 } 334 335 func cloneBytes(b []byte) []byte { 336 if b == nil { 337 return nil 338 } else { 339 c := make([]byte, len(b)) 340 copy(c, b) 341 return c 342 } 343 } 344 345 func asString(src interface{}) string { 346 switch v := src.(type) { 347 case string: 348 return v 349 case []byte: 350 return string(v) 351 } 352 rv := reflect.ValueOf(src) 353 switch rv.Kind() { 354 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 355 return strconv.FormatInt(rv.Int(), 10) 356 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 357 return strconv.FormatUint(rv.Uint(), 10) 358 case reflect.Float64: 359 return strconv.FormatFloat(rv.Float(), 'g', -1, 64) 360 case reflect.Float32: 361 return strconv.FormatFloat(rv.Float(), 'g', -1, 32) 362 case reflect.Bool: 363 return strconv.FormatBool(rv.Bool()) 364 } 365 return fmt.Sprintf("%v", src) 366 } 367 368 func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) { 369 switch rv.Kind() { 370 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 371 return strconv.AppendInt(buf, rv.Int(), 10), true 372 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 373 return strconv.AppendUint(buf, rv.Uint(), 10), true 374 case reflect.Float32: 375 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true 376 case reflect.Float64: 377 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true 378 case reflect.Bool: 379 return strconv.AppendBool(buf, rv.Bool()), true 380 case reflect.String: 381 s := rv.String() 382 return append(buf, s...), true 383 } 384 return 385 } 386 387 var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() 388 389 // callValuerValue returns vr.Value(), with one exception: 390 // If vr.Value is an auto-generated method on a pointer type and the 391 // pointer is nil, it would panic at runtime in the panicwrap 392 // method. Treat it like nil instead. 393 // Issue 8415. 394 // 395 // This is so people can implement driver.Value on value types and 396 // still use nil pointers to those types to mean nil/NULL, just like 397 // string/*string. 398 // 399 // This function is mirrored in the database/sql/driver package. 400 func callValuerValue(vr driver.Valuer) (v driver.Value, err error) { 401 if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr && 402 rv.IsNil() && 403 rv.Type().Elem().Implements(valuerReflectType) { 404 return nil, nil 405 } 406 return vr.Value() 407 }