in sources/oracle/data.go [215:341]
func convArray(spannerType ddl.Type, srcTypeName string, v string) (interface{}, error) {
v = strings.TrimSpace(v)
// Handle empty array. Note that we use an empty NullString array
// for all Spanner array types since this will be converted to the
// appropriate type by the Spanner client.
if v == "" {
return []spanner.NullString{}, nil
}
// The Spanner client for go does not accept []interface{} for arrays.
// Instead it only accepts slices of a specific type eg: []string
// Hence we have to do the following case analysis.
switch spannerType.Name {
case ddl.String:
var a []string
var r []spanner.NullString
err := json.Unmarshal([]byte(v), &a)
if err != nil {
return []spanner.NullString{}, err
}
for _, s := range a {
if s == "NULL" {
r = append(r, spanner.NullString{Valid: false})
continue
}
r = append(r, spanner.NullString{StringVal: s, Valid: true})
}
return r, nil
case ddl.Numeric:
var a []interface{}
var r []spanner.NullNumeric
err := json.Unmarshal([]byte(v), &a)
if err != nil {
return []spanner.NullNumeric{}, err
}
for _, s := range a {
if s == "NULL" {
r = append(r, spanner.NullNumeric{Valid: false})
continue
}
val := new(big.Rat)
if _, ok := val.SetString(fmt.Sprint(s)); !ok {
return []spanner.NullNumeric{}, fmt.Errorf("can't convert %q to big.Rat", s)
}
r = append(r, spanner.NullNumeric{Numeric: *val, Valid: true})
}
return r, nil
case ddl.Int64:
var a []interface{}
var r []spanner.NullInt64
err := json.Unmarshal([]byte(v), &a)
if err != nil {
return []spanner.NullInt64{}, err
}
for _, s := range a {
if s == "NULL" {
r = append(r, spanner.NullInt64{Valid: false})
continue
}
val, err := convInt64(fmt.Sprint(s))
if err != nil {
return []spanner.NullInt64{}, err
}
r = append(r, spanner.NullInt64{Int64: val, Valid: true})
}
return r, nil
case ddl.Float32:
var a []interface{}
var r []spanner.NullFloat32
err := json.Unmarshal([]byte(v), &a)
if err != nil {
return []spanner.NullFloat32{}, err
}
for _, s := range a {
if s == "NULL" {
r = append(r, spanner.NullFloat32{Valid: false})
continue
}
val, err := convFloat32(fmt.Sprint(s))
if err != nil {
return []spanner.NullFloat32{}, err
}
r = append(r, spanner.NullFloat32{Float32: val, Valid: true})
}
return r, nil
case ddl.Float64:
var a []interface{}
var r []spanner.NullFloat64
err := json.Unmarshal([]byte(v), &a)
if err != nil {
return []spanner.NullFloat64{}, err
}
for _, s := range a {
if s == "NULL" {
r = append(r, spanner.NullFloat64{Valid: false})
continue
}
val, err := convFloat64(fmt.Sprint(s))
if err != nil {
return []spanner.NullFloat64{}, err
}
r = append(r, spanner.NullFloat64{Float64: val, Valid: true})
}
return r, nil
case ddl.Date:
var a []interface{}
err := json.Unmarshal([]byte(v), &a)
if err != nil {
return []spanner.NullDate{}, err
}
var r []spanner.NullDate
for _, s := range a {
if s == "NULL" {
r = append(r, spanner.NullDate{Valid: false})
continue
}
val, err := convDate(fmt.Sprint(s))
if err != nil {
return []spanner.NullDate{}, err
}
r = append(r, spanner.NullDate{Date: val, Valid: true})
}
return r, nil
}
return []interface{}{}, fmt.Errorf("array type conversion not implemented for type %v", spannerType.Name)
}