Search code examples
postgresqlgoprepared-statementpgbouncer

pq driver: prepared statement does not exist


I'm trying to connect to a postresql database with the pq driver in Go. When I do it on a local copy of the database, with a connection string like

DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable")

it all works well.

However, when I switch to a production server where the connection goes through pgbouncer:

DB, err = sql.Open("postgres", "user=user password=pwd host=/var/run/pgbouncer port=port dbname=mydb sslmode=disable")

I keep getting the same error for all queries, however simple:

Database error: pq: S:"ERROR" M:"prepared statement \"1\" does not exist" C:"26000" F:"prepare.c" L:"519" R:"FetchPreparedStatement"

(it's always "prepared statement \"1\"", independent of the query I'm trying to pass)

The query in both cases is run simply as follows:

res_rows, err := DB.Query(query)
if err != nil {
    log.Printf("Database error: %s\n", err)
}
for res_rows.Next() {
    ...
}

Googling suggests to turn off prepared statements, but I don't know how to do that in Go and I'm not sure it is supported at all. Any help (even a suggestion to use something else entirely) would be greatly appreciated.


Solution

  • Package driver

    type Queryer

    type Queryer interface {
        Query(query string, args []Value) (Rows, error)
    }
    

    Queryer is an optional interface that may be implemented by a Conn.

    If a Conn does not implement Queryer, the sql package's DB.Query will first prepare a query, execute the statement, and then close the statement.

    I don't see where the lib/pq PostgreSQL driver implements Queryer. Therefore, the DB.Query query is prepared before execution.

    PgBouncer doesn't support the PREPARE feature for all pooling methods: Feature matrix for pooling modes.