]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/database/sql/convert.go
libgo: update to Go1.14beta1
[thirdparty/gcc.git] / libgo / go / database / sql / convert.go
CommitLineData
d8f41257
ILT
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
7package sql
8
9import (
af92e385 10 "database/sql/driver"
2fd401c8 11 "errors"
d8f41257 12 "fmt"
d8f41257
ILT
13 "reflect"
14 "strconv"
f98dd1a3 15 "time"
c2047754
ILT
16 "unicode"
17 "unicode/utf8"
d8f41257
ILT
18)
19
be47d6ec
ILT
20var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
21
c2047754
ILT
22func 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
29func 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
bc998d03
ILT
40// ccChecker wraps the driver.ColumnConverter and allows it to be used
41// as if it were a NamedValueChecker. If the driver ColumnConverter
42// is not present then the NamedValueChecker will return driver.ErrSkip.
43type ccChecker struct {
bc998d03
ILT
44 cci driver.ColumnConverter
45 want int
46}
47
48func (c ccChecker) CheckNamedValue(nv *driver.NamedValue) error {
49 if c.cci == nil {
50 return driver.ErrSkip
51 }
52 // The column converter shouldn't be called on any index
53 // it isn't expecting. The final error will be thrown
54 // in the argument converter loop.
55 index := nv.Ordinal - 1
56 if c.want <= index {
57 return nil
58 }
59
60 // First, see if the value itself knows how to convert
61 // itself to a driver type. For example, a NullString
62 // struct changing into a string or nil.
63 if vr, ok := nv.Value.(driver.Valuer); ok {
64 sv, err := callValuerValue(vr)
65 if err != nil {
66 return err
67 }
68 if !driver.IsValue(sv) {
69 return fmt.Errorf("non-subset type %T returned from Value", sv)
70 }
71 nv.Value = sv
72 }
73
74 // Second, ask the column to sanity check itself. For
75 // example, drivers might use this to make sure that
76 // an int64 values being inserted into a 16-bit
77 // integer field is in range (before getting
78 // truncated), or that a nil can't go into a NOT NULL
79 // column before going across the network to get the
80 // same error.
81 var err error
82 arg := nv.Value
bc998d03 83 nv.Value, err = c.cci.ColumnConverter(index).ConvertValue(arg)
bc998d03
ILT
84 if err != nil {
85 return err
86 }
87 if !driver.IsValue(nv.Value) {
88 return fmt.Errorf("driver ColumnConverter error converted %T to unsupported type %T", arg, nv.Value)
89 }
90 return nil
91}
92
93// defaultCheckNamedValue wraps the default ColumnConverter to have the same
94// function signature as the CheckNamedValue in the driver.NamedValueChecker
95// interface.
96func defaultCheckNamedValue(nv *driver.NamedValue) (err error) {
97 nv.Value, err = driver.DefaultParameterConverter.ConvertValue(nv.Value)
98 return err
99}
100
aa8901e9 101// driverArgsConnLocked converts arguments from callers of Stmt.Exec and
4ccad563
ILT
102// Stmt.Query into driver Values.
103//
be47d6ec 104// The statement ds may be nil, if no statement is available.
aa8901e9
ILT
105//
106// ci must be locked.
1a2f01ef 107func driverArgsConnLocked(ci driver.Conn, ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) {
c2047754 108 nvargs := make([]driver.NamedValue, len(args))
bc998d03
ILT
109
110 // -1 means the driver doesn't know how to count the number of
111 // placeholders, so we won't sanity check input here and instead let the
112 // driver deal with errors.
113 want := -1
114
be47d6ec 115 var si driver.Stmt
bc998d03 116 var cc ccChecker
be47d6ec
ILT
117 if ds != nil {
118 si = ds.si
1a2f01ef 119 want = ds.si.NumInput()
bc998d03 120 cc.want = want
be47d6ec 121 }
4ccad563 122
bc998d03
ILT
123 // Check all types of interfaces from the start.
124 // Drivers may opt to use the NamedValueChecker for special
125 // argument types, then return driver.ErrSkip to pass it along
126 // to the column converter.
127 nvc, ok := si.(driver.NamedValueChecker)
4ccad563 128 if !ok {
bc998d03
ILT
129 nvc, ok = ci.(driver.NamedValueChecker)
130 }
131 cci, ok := si.(driver.ColumnConverter)
132 if ok {
133 cc.cci = cci
4ccad563
ILT
134 }
135
bc998d03
ILT
136 // Loop through all the arguments, checking each one.
137 // If no error is returned simply increment the index
138 // and continue. However if driver.ErrRemoveArgument
139 // is returned the argument is not included in the query
140 // argument list.
141 var err error
142 var n int
143 for _, arg := range args {
c2047754 144 nv := &nvargs[n]
c2047754 145 if np, ok := arg.(NamedArg); ok {
bc998d03 146 if err = validateNamedValueName(np.Name); err != nil {
c2047754
ILT
147 return nil, err
148 }
149 arg = np.Value
150 nv.Name = np.Name
151 }
bc998d03
ILT
152 nv.Ordinal = n + 1
153 nv.Value = arg
154
155 // Checking sequence has four routes:
156 // A: 1. Default
157 // B: 1. NamedValueChecker 2. Column Converter 3. Default
158 // C: 1. NamedValueChecker 3. Default
159 // D: 1. Column Converter 2. Default
160 //
161 // The only time a Column Converter is called is first
162 // or after NamedValueConverter. If first it is handled before
163 // the nextCheck label. Thus for repeats tries only when the
164 // NamedValueConverter is selected should the Column Converter
165 // be used in the retry.
166 checker := defaultCheckNamedValue
167 nextCC := false
168 switch {
169 case nvc != nil:
170 nextCC = cci != nil
171 checker = nvc.CheckNamedValue
172 case cci != nil:
173 checker = cc.CheckNamedValue
4ccad563
ILT
174 }
175
bc998d03
ILT
176 nextCheck:
177 err = checker(nv)
178 switch err {
179 case nil:
180 n++
181 continue
182 case driver.ErrRemoveArgument:
183 nvargs = nvargs[:len(nvargs)-1]
184 continue
185 case driver.ErrSkip:
186 if nextCC {
187 nextCC = false
188 checker = cc.CheckNamedValue
189 } else {
190 checker = defaultCheckNamedValue
191 }
192 goto nextCheck
193 default:
c2047754 194 return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err)
4ccad563 195 }
bc998d03
ILT
196 }
197
1a2f01ef 198 // Check the length of arguments after conversion to allow for omitted
bc998d03
ILT
199 // arguments.
200 if want != -1 && len(nvargs) != want {
201 return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(nvargs))
ab61e9c4 202 }
4ccad563 203
c2047754 204 return nvargs, nil
bc998d03 205
ab61e9c4
ILT
206}
207
4f4a855d
ILT
208// convertAssign is the same as convertAssignRows, but without the optional
209// rows argument.
2fd401c8 210func convertAssign(dest, src interface{}) error {
4f4a855d
ILT
211 return convertAssignRows(dest, src, nil)
212}
213
214// convertAssignRows copies to dest the value in src, converting it if possible.
215// An error is returned if the copy would result in loss of information.
216// dest should be a pointer type. If rows is passed in, the rows will
217// be used as the parent for any cursor values converted from a
218// driver.Rows to a *Rows.
219func convertAssignRows(dest, src interface{}, rows *Rows) error {
be47d6ec 220 // Common cases, without reflect.
d8f41257
ILT
221 switch s := src.(type) {
222 case string:
223 switch d := dest.(type) {
224 case *string:
be47d6ec
ILT
225 if d == nil {
226 return errNilPtr
227 }
d8f41257
ILT
228 *d = s
229 return nil
9af4cb95 230 case *[]byte:
be47d6ec
ILT
231 if d == nil {
232 return errNilPtr
233 }
9af4cb95
ILT
234 *d = []byte(s)
235 return nil
1a2f01ef
ILT
236 case *RawBytes:
237 if d == nil {
238 return errNilPtr
239 }
240 *d = append((*d)[:0], s...)
241 return nil
d8f41257
ILT
242 }
243 case []byte:
244 switch d := dest.(type) {
245 case *string:
be47d6ec
ILT
246 if d == nil {
247 return errNilPtr
248 }
d8f41257
ILT
249 *d = string(s)
250 return nil
94252f4b 251 case *interface{}:
be47d6ec
ILT
252 if d == nil {
253 return errNilPtr
254 }
255 *d = cloneBytes(s)
94252f4b 256 return nil
d8f41257 257 case *[]byte:
be47d6ec
ILT
258 if d == nil {
259 return errNilPtr
260 }
261 *d = cloneBytes(s)
262 return nil
263 case *RawBytes:
264 if d == nil {
265 return errNilPtr
266 }
d8f41257
ILT
267 *d = s
268 return nil
269 }
f98dd1a3
ILT
270 case time.Time:
271 switch d := dest.(type) {
1a2f01ef
ILT
272 case *time.Time:
273 *d = s
274 return nil
f98dd1a3
ILT
275 case *string:
276 *d = s.Format(time.RFC3339Nano)
277 return nil
278 case *[]byte:
279 if d == nil {
280 return errNilPtr
281 }
282 *d = []byte(s.Format(time.RFC3339Nano))
283 return nil
1a2f01ef
ILT
284 case *RawBytes:
285 if d == nil {
286 return errNilPtr
287 }
288 *d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
289 return nil
f98dd1a3 290 }
aa8901e9
ILT
291 case decimalDecompose:
292 switch d := dest.(type) {
293 case decimalCompose:
294 return d.Compose(s.Decompose(nil))
295 }
9af4cb95
ILT
296 case nil:
297 switch d := dest.(type) {
be47d6ec
ILT
298 case *interface{}:
299 if d == nil {
300 return errNilPtr
301 }
302 *d = nil
303 return nil
9af4cb95 304 case *[]byte:
be47d6ec
ILT
305 if d == nil {
306 return errNilPtr
307 }
308 *d = nil
309 return nil
310 case *RawBytes:
311 if d == nil {
312 return errNilPtr
313 }
9af4cb95
ILT
314 *d = nil
315 return nil
316 }
4f4a855d
ILT
317 // The driver is returning a cursor the client may iterate over.
318 case driver.Rows:
319 switch d := dest.(type) {
320 case *Rows:
321 if d == nil {
322 return errNilPtr
323 }
324 if rows == nil {
325 return errors.New("invalid context to convert cursor rows, missing parent *Rows")
326 }
327 rows.closemu.Lock()
328 *d = Rows{
329 dc: rows.dc,
330 releaseConn: func(error) {},
331 rowsi: s,
332 }
333 // Chain the cancel function.
334 parentCancel := rows.cancel
335 rows.cancel = func() {
336 // When Rows.cancel is called, the closemu will be locked as well.
337 // So we can access rs.lasterr.
338 d.close(rows.lasterr)
339 if parentCancel != nil {
340 parentCancel()
341 }
342 }
343 rows.closemu.Unlock()
344 return nil
345 }
d8f41257
ILT
346 }
347
9c63abc9 348 var sv reflect.Value
d8f41257
ILT
349
350 switch d := dest.(type) {
351 case *string:
9c63abc9 352 sv = reflect.ValueOf(src)
d8f41257
ILT
353 switch sv.Kind() {
354 case reflect.Bool,
355 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
356 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
357 reflect.Float32, reflect.Float64:
6736ef96 358 *d = asString(src)
d8f41257
ILT
359 return nil
360 }
be47d6ec
ILT
361 case *[]byte:
362 sv = reflect.ValueOf(src)
6736ef96
ILT
363 if b, ok := asBytes(nil, sv); ok {
364 *d = b
be47d6ec
ILT
365 return nil
366 }
367 case *RawBytes:
368 sv = reflect.ValueOf(src)
6736ef96
ILT
369 if b, ok := asBytes([]byte(*d)[:0], sv); ok {
370 *d = RawBytes(b)
be47d6ec
ILT
371 return nil
372 }
9c63abc9
ILT
373 case *bool:
374 bv, err := driver.Bool.ConvertValue(src)
375 if err == nil {
376 *d = bv.(bool)
377 }
378 return err
94252f4b
ILT
379 case *interface{}:
380 *d = src
381 return nil
d8f41257
ILT
382 }
383
cbb6491d
ILT
384 if scanner, ok := dest.(Scanner); ok {
385 return scanner.Scan(src)
d8f41257
ILT
386 }
387
388 dpv := reflect.ValueOf(dest)
389 if dpv.Kind() != reflect.Ptr {
2fd401c8 390 return errors.New("destination not a pointer")
d8f41257 391 }
be47d6ec
ILT
392 if dpv.IsNil() {
393 return errNilPtr
394 }
d8f41257 395
9c63abc9
ILT
396 if !sv.IsValid() {
397 sv = reflect.ValueOf(src)
398 }
399
d8f41257 400 dv := reflect.Indirect(dpv)
f98dd1a3 401 if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
22b955cc
ILT
402 switch b := src.(type) {
403 case []byte:
404 dv.Set(reflect.ValueOf(cloneBytes(b)))
405 default:
406 dv.Set(sv)
407 }
d8f41257
ILT
408 return nil
409 }
410
f98dd1a3
ILT
411 if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
412 dv.Set(sv.Convert(dv.Type()))
413 return nil
414 }
415
bc998d03
ILT
416 // The following conversions use a string value as an intermediate representation
417 // to convert between various numeric types.
418 //
419 // This also allows scanning into user defined types such as "type Int int64".
420 // For symmetry, also check for string destination types.
d8f41257 421 switch dv.Kind() {
cbb6491d
ILT
422 case reflect.Ptr:
423 if src == nil {
424 dv.Set(reflect.Zero(dv.Type()))
425 return nil
cbb6491d 426 }
dd931d9b 427 dv.Set(reflect.New(dv.Type().Elem()))
4f4a855d 428 return convertAssignRows(dv.Interface(), src, rows)
d8f41257 429 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
aa8901e9
ILT
430 if src == nil {
431 return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
432 }
9c63abc9 433 s := asString(src)
9a0e3259 434 i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
9c63abc9 435 if err != nil {
f98dd1a3
ILT
436 err = strconvErr(err)
437 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
9c63abc9 438 }
9c63abc9
ILT
439 dv.SetInt(i64)
440 return nil
d8f41257 441 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
aa8901e9
ILT
442 if src == nil {
443 return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
444 }
9c63abc9 445 s := asString(src)
9a0e3259 446 u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
9c63abc9 447 if err != nil {
f98dd1a3
ILT
448 err = strconvErr(err)
449 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
9c63abc9 450 }
9c63abc9
ILT
451 dv.SetUint(u64)
452 return nil
453 case reflect.Float32, reflect.Float64:
aa8901e9
ILT
454 if src == nil {
455 return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
456 }
9c63abc9 457 s := asString(src)
9a0e3259 458 f64, err := strconv.ParseFloat(s, dv.Type().Bits())
9c63abc9 459 if err != nil {
f98dd1a3
ILT
460 err = strconvErr(err)
461 return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
9c63abc9 462 }
9c63abc9
ILT
463 dv.SetFloat(f64)
464 return nil
bc998d03 465 case reflect.String:
aa8901e9
ILT
466 if src == nil {
467 return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
468 }
bc998d03
ILT
469 switch v := src.(type) {
470 case string:
471 dv.SetString(v)
472 return nil
473 case []byte:
474 dv.SetString(string(v))
475 return nil
476 }
d8f41257
ILT
477 }
478
f98dd1a3
ILT
479 return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
480}
481
482func strconvErr(err error) error {
483 if ne, ok := err.(*strconv.NumError); ok {
484 return ne.Err
485 }
486 return err
d8f41257
ILT
487}
488
be47d6ec
ILT
489func cloneBytes(b []byte) []byte {
490 if b == nil {
491 return nil
be47d6ec 492 }
dd931d9b
ILT
493 c := make([]byte, len(b))
494 copy(c, b)
495 return c
be47d6ec
ILT
496}
497
9c63abc9 498func asString(src interface{}) string {
d8f41257
ILT
499 switch v := src.(type) {
500 case string:
9c63abc9 501 return v
d8f41257 502 case []byte:
9c63abc9 503 return string(v)
d8f41257 504 }
6736ef96
ILT
505 rv := reflect.ValueOf(src)
506 switch rv.Kind() {
507 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
508 return strconv.FormatInt(rv.Int(), 10)
509 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
510 return strconv.FormatUint(rv.Uint(), 10)
511 case reflect.Float64:
512 return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
513 case reflect.Float32:
514 return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
515 case reflect.Bool:
516 return strconv.FormatBool(rv.Bool())
517 }
9c63abc9 518 return fmt.Sprintf("%v", src)
d8f41257 519}
6736ef96
ILT
520
521func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
522 switch rv.Kind() {
523 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
524 return strconv.AppendInt(buf, rv.Int(), 10), true
525 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
526 return strconv.AppendUint(buf, rv.Uint(), 10), true
527 case reflect.Float32:
528 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
529 case reflect.Float64:
530 return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
531 case reflect.Bool:
532 return strconv.AppendBool(buf, rv.Bool()), true
533 case reflect.String:
534 s := rv.String()
535 return append(buf, s...), true
536 }
537 return
538}
c2047754
ILT
539
540var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
541
542// callValuerValue returns vr.Value(), with one exception:
543// If vr.Value is an auto-generated method on a pointer type and the
544// pointer is nil, it would panic at runtime in the panicwrap
545// method. Treat it like nil instead.
546// Issue 8415.
547//
548// This is so people can implement driver.Value on value types and
549// still use nil pointers to those types to mean nil/NULL, just like
550// string/*string.
551//
552// This function is mirrored in the database/sql/driver package.
553func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
554 if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr &&
555 rv.IsNil() &&
556 rv.Type().Elem().Implements(valuerReflectType) {
557 return nil, nil
558 }
559 return vr.Value()
560}
aa8901e9
ILT
561
562// decimal composes or decomposes a decimal value to and from individual parts.
563// There are four parts: a boolean negative flag, a form byte with three possible states
564// (finite=0, infinite=1, NaN=2), a base-2 big-endian integer
565// coefficient (also known as a significand) as a []byte, and an int32 exponent.
566// These are composed into a final value as "decimal = (neg) (form=finite) coefficient * 10 ^ exponent".
567// A zero length coefficient is a zero value.
5a8ea165 568// The big-endian integer coefficient stores the most significant byte first (at coefficient[0]).
aa8901e9
ILT
569// If the form is not finite the coefficient and exponent should be ignored.
570// The negative parameter may be set to true for any form, although implementations are not required
571// to respect the negative parameter in the non-finite form.
572//
573// Implementations may choose to set the negative parameter to true on a zero or NaN value,
574// but implementations that do not differentiate between negative and positive
575// zero or NaN values should ignore the negative parameter without error.
576// If an implementation does not support Infinity it may be converted into a NaN without error.
577// If a value is set that is larger than what is supported by an implementation,
578// an error must be returned.
579// Implementations must return an error if a NaN or Infinity is attempted to be set while neither
580// are supported.
581//
582// NOTE(kardianos): This is an experimental interface. See https://golang.org/issue/30870
583type decimal interface {
584 decimalDecompose
585 decimalCompose
586}
587
588type decimalDecompose interface {
589 // Decompose returns the internal decimal state in parts.
590 // If the provided buf has sufficient capacity, buf may be returned as the coefficient with
591 // the value set and length set as appropriate.
592 Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
593}
594
595type decimalCompose interface {
596 // Compose sets the internal decimal value from parts. If the value cannot be
597 // represented then an error should be returned.
598 Compose(form byte, negative bool, coefficient []byte, exponent int32) error
599}