Skip to content
New issue

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

contrib/database/sql: panic: sqltrace.OpenDB: driver is not registered via sqltrace.Register #1634

Closed
tsbkw opened this issue Dec 22, 2022 · 1 comment
Labels
apm:ecosystem contrib/* related feature requests or bugs bug unintended behavior that has to be fixed

Comments

@tsbkw
Copy link
Contributor

tsbkw commented Dec 22, 2022

TL;DR

If we use some driver which implement driver.DriverContext interface, and call Register with driver struct(not a pointer to driver struct), it panic with panic: sqltrace.OpenDB: driver is not registered via sqltrace.Register.

It may be better to prevent error even if struct is passed when calling Register, but at least document should be fixed.

Details

In the example below, driver.Driver is passed as struct, and reflect.TypeOf(driver) is added to map.

// sqltrace.Register("pq", pq.Driver{})
// db, err := sqltrace.Open("pq", "postgres://pqgotest:password@localhost...")

Later when user call OpenDB, reflect.TypeOf(driver) is looked up in d.keys, therefore driver added and looked up must have same type. For example, if added type is struct, looked up by struct. And if added type is pointer of struct, looked up by pointer of struct.

name, ok := d.keys[reflect.TypeOf(driver)]

This behavior is not a problem when driver doesn't implement driver.DriverContext interface, because in this case driver get from map driver is used when lookup and type of these always same.

return OpenDB(&dsnConnector{dsn: dataSourceName, driver: d}, opts...), nil

However when driver implement driver.DriverContext, user must care whether type is pointer or not when calling Register.

Driver in lib/pq currently not implement driver.DriverContext but soon it will implement. see: lib/pq#900

The problem can be reproduced by code below with github.com/go-sql-driver/mysql. (You can see full code at https://go.dev/play/p/4g6-qwh9TqF but you have to run it locally.)

	sqltrace.Register("mysql", mysql.MySQLDriver{})
	_, err := sqltrace.Open("mysql", "user:password@tcp(localhost:3306)/db")
	fmt.Printf("err with mysql.MySQLDriver{} %v\n", err)

This print panic: sqltrace.OpenDB: driver is not registered via sqltrace.Register with stacktrace.

The error can be avoided by passing by pointer like below.

	sqltrace.Register("mysql", &mysql.MySQLDriver{})
	_, err2 := sqltrace.Open("mysql", "user:password@tcp(localhost:3306)/dbe")
	fmt.Printf("err with &mysql.MySQLDriver{} %v\n", err2)

This print err with &mysql.MySQLDriver{} <nil>.

@katiehockman katiehockman added enhancement quick change/addition that does not need full team approval apm:ecosystem contrib/* related feature requests or bugs and removed enhancement quick change/addition that does not need full team approval labels Jan 11, 2023
@knusbaum knusbaum added the bug unintended behavior that has to be fixed label Jan 11, 2023
@zarirhamza
Copy link
Contributor

PR was merged and issue should be fixed. Your contribution is much appreciated and if there are any ongoing problems, please open another issue. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apm:ecosystem contrib/* related feature requests or bugs bug unintended behavior that has to be fixed
Projects
None yet
Development

No branches or pull requests

4 participants