We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
any
interface{}
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hey, I'm trying to write some aggregator functions that work on any data type. Here's a minimal example:
package main import ( "database/sql" "fmt" "log" sqlite "github.com/mattn/go-sqlite3" ) type mode struct { counts map[any]int top any topCount int } func newMode() *mode { return &mode{ counts: map[any]int{}, } } func (m *mode) Step(x any) { m.counts[x]++ c := m.counts[x] if c > m.topCount { m.top = x m.topCount = c } } func (m *mode) Done() any { return m.top } func main() { sql.Register("sqlite3_custom", &sqlite.SQLiteDriver{ ConnectHook: func(conn *sqlite.SQLiteConn) error { if err := conn.RegisterAggregator("mode", newMode, true); err != nil { return err } return nil }, }) db, err := sql.Open("sqlite3_custom", ":memory:") if err != nil { log.Fatal("Failed to open database:", err) } defer db.Close() _, err = db.Exec("create table foo (department integer, profits integer)") if err != nil { log.Fatal("Failed to create table:", err) } _, err = db.Exec("insert into foo values (1, 10), (1, 20), (1, 45), (2, 42), (2, 115), (2, 20)") if err != nil { log.Fatal("Failed to insert records:", err) } rows, err := db.Query("select mode(profits) from foo") if err != nil { log.Fatal("MODE query error:", err) } defer rows.Close() for rows.Next() { //var dept int64 var dev string if err := rows.Scan( &dev); err != nil { log.Fatal(err) } fmt.Printf("mode=%s\n", dev) } if err := rows.Err(); err != nil { log.Fatal(err) } }
When I run this though I get a panic:
panic: reflect: Elem of invalid type interface {} goroutine 1 [running]: reflect.(*rtype).Elem(0x64b2a0?) /usr/local/go/src/reflect/type.go:965 +0x134 github.com/mattn/go-sqlite3.callbackRet({0x64bd60, 0x5fdfe0}) /home/phil/tmp/sqlite3-test/vendor/github.com/mattn/go-sqlite3/callback.go:366 +0x17c github.com/mattn/go-sqlite3.(*SQLiteConn).RegisterAggregator(0xc000076180, {0x61a96a, 0x4}, {0x5f6fa0, 0x625d60}, 0x1) /home/phil/tmp/sqlite3-test/vendor/github.com/mattn/go-sqlite3/sqlite3.go:776 +0xbaf main.main.func1(0xc0000161a0?) /home/phil/tmp/sqlite3-test/main2.go:40 +0x39 github.com/mattn/go-sqlite3.(*SQLiteDriver).Open(0xc00006a040, {0x61b08b, 0x8}) /home/phil/tmp/sqlite3-test/vendor/github.com/mattn/go-sqlite3/sqlite3.go:1765 +0x3c79 database/sql.dsnConnector.Connect(...) /usr/local/go/src/database/sql/sql.go:761 database/sql.(*DB).conn(0xc00010ea90, {0x64b7a0, 0xc00001e0e0}, 0x1) /usr/local/go/src/database/sql/sql.go:1395 +0x782 database/sql.(*DB).exec(0x4d770e?, {0x64b7a0, 0xc00001e0e0}, {0x6244c3, 0x36}, {0x0, 0x0, 0x0}, 0x40?) /usr/local/go/src/database/sql/sql.go:1657 +0x5d database/sql.(*DB).ExecContext(0x61c4c1?, {0x64b7a0, 0xc00001e0e0}, {0x6244c3, 0x36}, {0x0, 0x0, 0x0}) /usr/local/go/src/database/sql/sql.go:1635 +0xe5 database/sql.(*DB).Exec(...) /usr/local/go/src/database/sql/sql.go:1653 main.main() /home/phil/tmp/sqlite3-test/main2.go:53 +0x172
I changed Done() to return a string here and did:
Done()
func (m *mode) Done() string { return fmt.Sprintf("%v", m.top) }
And that works. But I don't want to force every result to a string here.
Are you open to patching the callbackRet function to support returning any from Done()? Or is that just not possible?
callbackRet
The text was updated successfully, but these errors were encountered:
I proposed a change that fixes the problem for me, in #1046.
Sorry, something went wrong.
Resolved in commit 3ccccfb.
Successfully merging a pull request may close this issue.
Uh oh!
There was an error while loading. Please reload this page.
Hey, I'm trying to write some aggregator functions that work on any data type. Here's a minimal example:
When I run this though I get a panic:
I changed
Done()
to return a string here and did:And that works. But I don't want to force every result to a string here.
Are you open to patching the
callbackRet
function to support returningany
fromDone()
? Or is that just not possible?The text was updated successfully, but these errors were encountered: