gopy
gopy copied to clipboard
Panic when function returns a map of non-pointer structs
A function returning a map of struct values causes a panic:
panic: interface conversion: interface {} is batman.Foo, not *batman.Foo
type Foo struct {
S string
}
// crash
func Bar() map[string]Foo {
return map[string]Foo{"foo": Foo{"bar"}}
}
// no crash
func Baz() map[string]*Foo {
return map[string]*Foo{"foo": &Foo{"bar"}}
}
I believe I have this same problem. I'm studying trying to make a sql query builder for Python using gopy, but I'm having a similar problem:
panic: interface conversion: interface {} is map[string]interface {}, not *map[string]interface {}
Function causing the error:
func (qb *QueryBuilder) Exec() ([]map[string]interface{}, error) {
qb.Compiler.SetOptionsBuilder(qb.Statements, qb.Simple)
result, err := qb.Compiler.Exec()
qb.Reset()
return result, err
}
qb.Compiler.Exec() function:
func (qc *QueryCompiler) Exec() ([]map[string]interface{}, error) {
query := qc.Simple.Raw.Sql
if query == "" {
query = qc.ToSQL()
}
qc.Reset()
var result []map[string]interface{}
if qc.Simple.IsDQL {
rows, err := qc.Client.Query(query)
if err != nil {
return nil, err
}
defer rows.Close()
cols, err := rows.Columns()
if err != nil {
fmt.Println(err)
}
colTypes, err := rows.ColumnTypes()
if err != nil {
fmt.Println(err)
return nil, err
}
vals := make([]interface{}, len(cols))
for i, ct := range colTypes {
switch ct.DatabaseTypeName() {
case "VARCHAR", "TEXT":
vals[i] = new(string)
case "INT":
vals[i] = new(int)
default:
vals[i] = new(interface{})
}
}
for rows.Next() {
scanArgs := make([]interface{}, len(cols))
for i := range vals {
scanArgs[i] = &vals[i]
}
err = rows.Scan(scanArgs...)
if err != nil {
fmt.Println(err)
continue
}
rowMap := make(map[string]interface{})
for i, colName := range cols {
valPtr := vals[i]
var val interface{}
switch v := valPtr.(type) {
case *string:
if v != nil {
val = *v
}
case *int:
if v != nil {
val = *v
}
default:
val = v
}
rowMap[colName] = val
}
result = append(result, rowMap)
}
} else {
_, err := qc.Client.Exec(query)
if err != nil {
return nil, err
}
}
fmt.Println("result", result)
return result, nil
}
This is the complete code: https://github.com/richecr/pythonicsqlgo
Assuming fixed by #350 -- again would like a test if possible.