in dbconn/dbconn.go [190:249]
func (dbconn *DBConn) Connect(numConns int, utilityMode ...bool) error {
if numConns < 1 {
return errors.Errorf("Must specify a connection pool size that is a positive integer")
}
if dbconn.ConnPool != nil {
return errors.Errorf("The database connection must be closed before reusing the connection")
}
// This string takes in the literal user/database names. They do not need
// to be escaped or quoted.
// By default pgx/v4 turns on automatic prepared statement caching. This
// causes an issue in GPDB4 where creating an object, deleting it, creating
// the same object again, then querying for the object in the same
// connection will generate a cache lookup failure. To disable pgx's
// automatic prepared statement cache we set statement_cache_capacity to 0.
connStr := fmt.Sprintf("postgres://%s@%s:%d/%s?sslmode=disable&statement_cache_capacity=0", dbconn.User, dbconn.Host, dbconn.Port, dbconn.DBName)
dbconn.ConnPool = make([]*sqlx.DB, numConns)
if len(utilityMode) > 1 {
return errors.Errorf("The utility mode parameter accepts exactly one boolean value")
} else if len(utilityMode) == 1 && utilityMode[0] {
// The utility mode GUC differs between GPDB 7 and later (gp_role)
// and GPDB 6 and earlier (gp_session_role), and we don't get the
// database version until after the connection is established, so
// we need to just try one first and see whether it works.
roleConnStr := connStr + "&gp_role=utility"
sessionRoleConnStr := connStr + "&gp_session_role=utility"
utilConn, err := dbconn.Driver.Connect("pgx", sessionRoleConnStr)
if utilConn != nil {
utilConn.Close()
}
if err != nil {
if strings.Contains(err.Error(), `unrecognized configuration parameter "gp_session_role"`) {
connStr = roleConnStr
} else {
return dbconn.handleConnectionError(err)
}
} else {
connStr = sessionRoleConnStr
}
}
for i := 0; i < numConns; i++ {
conn, err := dbconn.Driver.Connect("pgx", connStr)
err = dbconn.handleConnectionError(err)
if err != nil {
return err
}
conn.SetMaxOpenConns(1)
conn.SetMaxIdleConns(1)
dbconn.ConnPool[i] = conn
}
dbconn.Tx = make([]*sqlx.Tx, numConns)
dbconn.NumConns = numConns
version, err := InitializeVersion(dbconn)
if err != nil {
return errors.Wrap(err, "Failed to determine database version")
}
dbconn.Version = version
return nil
}