panic: sql: Register called twice for driver postgresのエラーが出た時の解決方法


# 概要
SQLBoilerを使っていて、以下のようなエラーに遭遇しました。

```shell-session
panic: sql: Register called twice for driver postgres

goroutine 1 [running]:
database/sql.Register(0x18c7cd9, 0x8, 0x1d3b420, 0x1da74c8)
        /usr/local/opt/go/libexec/src/database/sql/sql.go:50 +0x1ad
github.com/volatiletech/sqlboiler/vendor/github.com/lib/pq.init.0()
        /Users/teppei/src/github.com/volatiletech/sqlboiler/vendor/github.com/lib/pq/conn.go:49 +0x5c
github.com/volatiletech/sqlboiler/vendor/github.com/lib/pq.init()
        <autogenerated>:1 +0x782
github.com/volatiletech/sqlboiler/bdb/drivers.init()
        <autogenerated>:1 +0x7b
github.com/knqyf263/db-test/models.init()
        <autogenerated>:1 +0xe4
main.init()
        <autogenerated>:1 +0x4e
```

2回Registerが呼ばれてるよってことですが、特に何も変えてないのに何で急にエラーが出たんだ？！と少しハマったので書いておきます。

# 結論
あとで経緯を書きますが、先に結論を書いておきます。
結論としては、`volatiletech/sqlboiler` をimportした先でvendoringされていた `lib/pq` がimportされていたせいでした。
なのでimportする先のディレクトリ先にvendorディレクトリがあれば、それを削除すれば動くようになります（意図せず置かれているものであれば、ですが）。
今回のケースでは以下のようにすることでエラーは解消されました。

```
$ rm -rf $GOPATH/src/github.com/volatiletech/sqlboiler/vendor
```

この問題はSQLBoilerに関わらず、`lib/pq`を使っていると起こりうるケースかなと思います。

例えば、 `knqyf263/db-test` で以下の2つのパッケージをimportしていたとします。
1. `lib/pq`
2. `volatiletech/sqlboiler`

この時、1の `lib/pq` はvendoringしていなかったので、 `$GOPATH/src/github.com/lib/pq` を参照していました。
また、 `lib/pq` は`init()`で`sql.Register`しているため、importした段階で`Register`されます。
同様に、2についても `$GOPATH/src/github.com/volatiletech/sqlboiler` を参照していました。
この `volatiletech/sqlboiler` は中で `lib/pq` をimportしています。
その際、もし`$GOPATH/src/github.com/volatiletech/sqlboiler/vendor`が存在すると、そちらを見に行くようです（当たり前といえば当たり前ですが、普段あまり意識してなかった）。
その結果、 `$GOPATH/src/github.com/volatiletech/sqlboiler/vendor/github.com/lib/pq` がimportされることになります。
結果として、

- `$GOPATH/src/github.com/lib/pq`
- `$GOPATH/src/github.com/volatiletech/sqlboiler/vendor/github.com/lib/pq`

この2種類のpqがimportされることになります。
そうなるとそれぞれで`Register`が呼ばれてしまい、上記のエラーになっていました。

# 詳細
経緯を少し書いておきます。
`knqyf263/db-test` という適当なリポジトリでSQLBoilerで生成したmodelを管理していました。
その際に、急に以下のエラーが出ました。

```shell-session
panic: sql: Register called twice for driver postgres
```

しばらく [volatiletech/sqlboiler](https://github.com/volatiletech/sqlboiler) や[lib/pq](https://github.com/lib/pq) のソースコードを眺めましたが、あまり原因は分かりませんでした。

確実なこととしては、`lib/pq`は`init()`で`sql.Register()`を呼んでいるということです。
https://github.com/lib/pq/blob/b609790bd85edf8e9ab7e0f8912750a786177bcf/conn.go#L48-L50

ということはimportしただけで呼ばれるので、2回importしただけでエラーになる...？と疑いましたが、import先で再度`lib/pq` をimportしても特にエラーになりませんでした。

そこで、もしかして複数の `lib/pq` が読み込まれているのでは...？と急に閃いてfindで探したところ、以下のvendorディレクトリ内にもpqが存在することが分かりました。

- `$GOPATH/src/github.com/volatiletech/sqlboiler/vendor/github.com/lib/pq`

何でvendorあるんだろう？と思いましたが、前日にSQLBoilerのバグを直すために開発用にvendoringしていたことを思い出しました（[これ](https://github.com/volatiletech/sqlboiler/pull/219)）。
そこでこのvendorディレクトリを消してみたところ、エラーが出なくなりました。

つまり、 `volatiletech/sqlboiler` の中でも `lib/pq` がimportされており、その場合は `volatiletech/sqlboiler/vendor` の方が優先して使われるようです。
普段は気にしたことはなかったのですが、import先にvendorディレクトリがあると、その中のライブラリが優先して使われるということを初めて知りました。
考えてみたら当たり前な気もしますが、そういう発想がなかったので少しハマりました。

# まとめ
- `lib/pq` は異なるものがimportされると死ぬ
- importした先にvendorディレクトリがあるとGOPATHより優先して使われる
- `init()`があるとソースコードを追いにくくて辛い