Package pq is a Go PostgreSQL driver for database/sql.
Most clients will use the database/sql package instead of using this package directly. For example:
import (
"database/sql"
_ "github.com/lib/pq"
)
func main() {
dsn := "user=pqgo dbname=pqgo sslmode=verify-full"
db, err := sql.Open("postgres", dsn)
if err != nil {
log.Fatal(err)
}
age := 21
rows, err := db.Query("select name from users where age = $1", age)
// …
}
You can also connect with an URL:
dsn := "postgres://pqgo:password@localhost/pqgo?sslmode=verify-full"
db, err := sql.Open("postgres", dsn)
Connection String Parameters ¶
See NewConfig.
Queries ¶
database/sql does not dictate any specific format for parameter placeholders, and pq uses the PostgreSQL-native ordinal markers ($1, $2, etc.). The same placeholder can be used more than once:
rows, err := db.Query( `select * from users where name = $1 or age between $2 and $2 + 3`, "Duck", 64)
pq does not support sql.Result.LastInsertId. Use the RETURNING clause with a Query or QueryRow call instead to return the identifier:
row := db.QueryRow(`insert into users(name, age) values('Scrooge McDuck', 93) returning id`)
var userid int
err := row.Scan(&userid)
Data Types ¶
Parameters pass through driver.DefaultParameterConverter before they are handled by this package. When the binary_parameters connection option is enabled, []byte values are sent directly to the backend as data in binary format.
This package returns the following types for values from the PostgreSQL backend:
- integer types smallint, integer, and bigint are returned as int64
- floating-point types real and double precision are returned as float64
- character types char, varchar, and text are returned as string
- temporal types date, time, timetz, timestamp, and timestamptz are returned as time.Time
- the boolean type is returned as bool
- the bytea type is returned as []byte
All other types are returned directly from the backend as []byte values in text format.
Errors ¶
pq may return errors of type *pq.Error which contain error details:
pqErr := new(pq.Error)
if errors.As(err, &pqErr) {
fmt.Println("pq error:", pqErr.Code.Name())
}
Bulk imports ¶
You can perform bulk imports by preparing a "COPY [..] FROM STDIN" statement in a transaction (sql.Tx). The returned sql.Stmt handle can then be repeatedly "executed" to copy data into the target table. After all data has been processed you should call Exec() once with no arguments to flush all buffered data. Any call to Exec() might return an error which should be handled appropriately, but because of the internal buffering an error returned by Exec() might not be related to the data passed in the call that failed.
It is not possible to COPY outside of an explicit transaction in pq.
Use nil for NULL, or explicitly add WITH NULL 'SOME STRING' (the default of \N doesn't work).
Notifications ¶
PostgreSQL supports a simple publish/subscribe model using PostgreSQL's NOTIFY mechanism.
To start listening for notifications, you first have to open a new connection to the database by calling NewListener. This connection can not be used for anything other than LISTEN / NOTIFY. Calling Listen will open a "notification channel"; once a notification channel is open, a notification generated on that channel will effect a send on the Listener.Notify channel. A notification channel will remain open until Unlisten is called, though connection loss might result in some notifications being lost. To solve this problem, Listener sends a nil pointer over the Notify channel any time the connection is re-established following a connection loss. The application can get information about the state of the underlying connection by setting an event callback in the call to NewListener.
A single Listener can safely be used from concurrent goroutines, which means that there is often no need to create more than one Listener in your application. However, a Listener is always connected to a single database, so you will need to create a new Listener instance for every database you want to receive notifications in.
The channel name in both Listen and Unlisten is case sensitive, and can contain any characters legal in an identifier. Note that the channel name will be truncated to 63 bytes by the PostgreSQL server.
Kerberos Support ¶
If you need support for Kerberos authentication, add the following to your main package:
import "github.com/lib/pq/auth/kerberos"
func init() {
pq.RegisterGSSProvider(func() (pq.Gss, error) { return kerberos.NewGSS() })
}
This package is in a separate module so that users who don't need Kerberos don't have to add unnecessary dependencies.
package main
import (
"database/sql"
"fmt"
"log"
)
func main() {
// Connect and create table.
db, err := sql.Open("postgres", "")
if err != nil {
log.Fatal(err)
}
defer db.Close()
_, err = db.Exec(`create temp table users (name text, age int)`)
if err != nil {
log.Fatal(err)
}
// Need to start transaction and prepare a statement.
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
defer tx.Rollback()
stmt, err := tx.Prepare(`copy users (name, age) from stdin`)
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
// Insert rows.
users := []struct {
Name string
Age int
}{
{"Donald Duck", 36},
{"Scrooge McDuck", 86},
}
for _, user := range users {
_, err = stmt.Exec(user.Name, user.Age)
if err != nil {
log.Fatal(err)
}
}
// Finalize copy and statement, and commit transaction.
if _, err := stmt.Exec(); err != nil {
log.Fatal(err)
}
if err := stmt.Close(); err != nil {
log.Fatal(err)
}
if err := tx.Commit(); err != nil {
log.Fatal(err)
}
// Query rows to verify.
rows, err := db.Query(`select * from users order by name`)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var (
name string
age int
)
err := rows.Scan(&name, &age)
if err != nil {
log.Fatal(err)
}
fmt.Println(name, age)
}
}
Output: Donald Duck 36 Scrooge McDuck 86
package main
import (
"database/sql"
"log"
)
func main() {
// Or as URL: postgresql://localhost/pqgo
db, err := sql.Open("postgres", "dbname=pqgo")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// db.Open() only creates a connection pool, and doesn't actually establish
// a connection to the database. To ensure the connection works you need to
// do *something* with a connection.
err = db.Ping()
if err != nil {
log.Fatal(err)
}
}
package main
import (
"database/sql"
"log"
"github.com/lib/pq"
)
func main() {
cfg := pq.Config{
Host: "localhost",
Port: 5432,
User: "pqgo",
}
// Or: create a new Config from the defaults, environment, and DSN.
// cfg, err := pq.NewConfig("host=postgres dbname=pqgo")
// if err != nil {
// log.Fatal(err)
// }
c, err := pq.NewConnectorConfig(cfg)
if err != nil {
log.Fatal(err)
}
// Create connection pool.
db := sql.OpenDB(c)
defer db.Close()
// Make sure it works.
err = db.Ping()
if err != nil {
log.Fatal(err)
}
}
package main
import (
"database/sql"
"fmt"
"log"
"time"
)
func main() {
dbUTC, err := sql.Open("postgres", "dbname=pqgo timezone=UTC")
if err != nil {
log.Fatal(err)
}
defer dbUTC.Close()
dbPL, err := sql.Open("postgres", "dbname=pqgo timezone=Asia/Gaza")
if err != nil {
log.Fatal(err)
}
defer dbPL.Close()
var tsUTC, tsPL time.Time
err = dbUTC.QueryRow(`select '2026-03-15 17:45:47Z'::timestamptz`).Scan(&tsUTC)
if err != nil {
log.Fatal(err)
}
err = dbPL.QueryRow(`select '2026-03-15 17:45:47Z'::timestamptz`).Scan(&tsPL)
if err != nil {
log.Fatal(err)
}
fmt.Println("timestamptz in UTC: ", tsUTC)
fmt.Println("timestamptz in Asia/Gaza:", tsPL)
fmt.Println("Equal(): ", tsUTC.Equal(tsPL))
}
Output: timestamptz in UTC: 2026-03-15 17:45:47 +0000 UTC timestamptz in Asia/Gaza: 2026-03-15 19:45:47 +0200 EET Equal(): true
package main
import (
"database/sql"
"fmt"
"log"
"time"
)
func main() {
db, err := sql.Open("postgres", "dbname=pqgo timezone=UTC")
if err != nil {
log.Fatal(err)
}
defer db.Close()
var ts time.Time
err = db.QueryRow(`select '2026-03-15 17:45:47'::timestamp`).Scan(&ts)
if err != nil {
log.Fatal(err)
}
z, o := ts.Zone()
fmt.Println("timestamp : ", ts)
fmt.Printf("Zone(): %q %v\n", z, o)
fmt.Println("Location() == time.UTC: ", ts.Location() == time.UTC)
fmt.Println("Location() == FixedZone: ", ts.Location() == time.FixedZone("", 0))
}
Output: timestamp : 2026-03-15 17:45:47 +0000 +0000 Zone(): "" 0 Location() == time.UTC: false Location() == FixedZone: true
- Constants
- Variables
- func Array(a any) interface{ ... }
- func BufferQuoteIdentifier(name string, buffer *bytes.Buffer)
- func ConnectorNoticeHandler(c driver.Connector) func(*Error)
- func ConnectorNotificationHandler(c driver.Connector) func(*Notification)
- func CopyIn(table string, columns ...string) stringdeprecated
- func CopyInSchema(schema, table string, columns ...string) stringdeprecated
- func DialOpen(d Dialer, dsn string) (_ driver.Conn, err error)
- func EnableInfinityTs(negative time.Time, positive time.Time)
- func FormatTimestamp(t time.Time) []byte
- func NoticeHandler(c driver.Conn) func(*Error)
- func Open(dsn string) (_ driver.Conn, err error)
- func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, error)
- func ParseURL(url string) (string, error)deprecated
- func QuoteIdentifier(name string) string
- func QuoteLiteral(literal string) string
- func RegisterGSSProvider(newGssArg NewGSSFunc)
- func RegisterTLSConfig(key string, config *tls.Config) error
- func SetNoticeHandler(c driver.Conn, handler func(*Error))
- func SetNotificationHandler(c driver.Conn, handler func(*Notification))
- type ArrayDelimiter
- type BoolArray
- type ByteaArray
- type Config
- type ConfigMultihost
- type Connector
- type Dialer
- type DialerContext
- type Driver
- type Error
- type ErrorClassdeprecated
- type ErrorCodedeprecated
- type EventCallbackType
- type Float32Array
- type Float64Array
- type GSS
- type GenericArray
- type Int32Array
- type Int64Array
- type Listener
- type ListenerConn
- func (l *ListenerConn) Close() error
- func (l *ListenerConn) Err() error
- func (l *ListenerConn) ExecSimpleQuery(q string) (executed bool, err error)
- func (l *ListenerConn) Listen(channel string) (bool, error)
- func (l *ListenerConn) Ping() error
- func (l *ListenerConn) Unlisten(channel string) (bool, error)
- func (l *ListenerConn) UnlistenAll() (bool, error)
- type ListenerEventType
- type LoadBalanceHosts
- type NewGSSFunc
- type NoticeHandlerConnector
- type Notification
- type NotificationHandlerConnector
- type NullTimedeprecated
- type PGErrordeprecated
- type ProtocolVersion
- type SSLMode
- type SSLNegotiation
- type SSLProtocolVersion
- type StringArray
- type TargetSessionAttrs
const ( SSLModeDisable = SSLMode("disable") SSLModeAllow = SSLMode("allow") SSLModePrefer = SSLMode("prefer") SSLModeRequire = SSLMode("require") SSLModeVerifyCA = SSLMode("verify-ca") SSLModeVerifyFull = SSLMode("verify-full") )
Values for SSLMode that pq supports.
const ( SSLNegotiationPostgres = SSLNegotiation("postgres") SSLNegotiationDirect = SSLNegotiation("direct") )
Values for SSLNegotiation that pq supports.
const ( TargetSessionAttrsAny = TargetSessionAttrs("any") TargetSessionAttrsReadWrite = TargetSessionAttrs("read-write") TargetSessionAttrsReadOnly = TargetSessionAttrs("read-only") TargetSessionAttrsPrimary = TargetSessionAttrs("primary") TargetSessionAttrsStandby = TargetSessionAttrs("standby") TargetSessionAttrsPreferStandby = TargetSessionAttrs("prefer-standby") )
Values for TargetSessionAttrs that pq supports.
const ( LoadBalanceHostsDisable = LoadBalanceHosts("disable") LoadBalanceHostsRandom = LoadBalanceHosts("random") )
Values for LoadBalanceHosts that pq supports.
const ( ProtocolVersion30 = ProtocolVersion("3.0") ProtocolVersion32 = ProtocolVersion("3.2") ProtocolVersionLatest = ProtocolVersion("latest") )
Values for ProtocolVersion that pq supports.
const ( SSLProtocolVersionTLS10 = SSLProtocolVersion("TLSv1.0") SSLProtocolVersionTLS11 = SSLProtocolVersion("TLSv1.1") SSLProtocolVersionTLS12 = SSLProtocolVersion("TLSv1.2") SSLProtocolVersionTLS13 = SSLProtocolVersion("TLSv1.3") )
Values for SSLProtocolVersion that pq supports.
pq.Error.Severity values.
Deprecated: use pqerror.Severity[..] values.
var ( ErrNotSupported = errors.New("pq: unsupported command") ErrInFailedTransaction = errors.New("pq: could not complete operation in a failed transaction") ErrCouldNotDetectUsername = errors.New("pq: could not detect default username; please provide one explicitly") )
Common error types
ErrChannelAlreadyOpen is returned from Listen when a channel is already open.
ErrChannelNotOpen is returned from Unlisten when a channel is not open.
Array returns the optimal driver.Valuer and sql.Scanner for an array or slice of any dimension.
For example:
db.Query(`SELECT * FROM t WHERE id = ANY($1)`, pq.Array([]int{235, 401}))
var x []sql.NullInt64
db.QueryRow(`SELECT ARRAY[235, 401]`).Scan(pq.Array(&x))
Scanning multi-dimensional arrays is not supported. Arrays where the lower bound is not one (such as `[0:0]={1}') are not supported.
BufferQuoteIdentifier satisfies the same purpose as QuoteIdentifier, but backed by a byte buffer.
func ConnectorNoticeHandler ¶ added in v1.4.0
ConnectorNoticeHandler returns the currently set notice handler, if any. If the given connector is not a result of ConnectorWithNoticeHandler, nil is returned.
func ConnectorNotificationHandler ¶ added in v1.5.1
ConnectorNotificationHandler returns the currently set notification handler, if any. If the given connector is not a result of ConnectorWithNotificationHandler, nil is returned.
CopyIn creates a COPY FROM statement which can be prepared with Tx.Prepare(). The target table should be visible in search_path.
It copies all columns if the list of columns is empty.
Deprecated: there is no need to use this query builder, you can use:
tx.Prepare("copy tbl (col1, col2) from stdin")
CopyInSchema creates a COPY FROM statement which can be prepared with Tx.Prepare().
Deprecated: there is no need to use this query builder, you can use:
tx.Prepare("copy schema.tbl (col1, col2) from stdin")
DialOpen opens a new connection to the database using a dialer.
EnableInfinityTs controls the handling of Postgres' "-infinity" and "infinity" "timestamp"s.
If EnableInfinityTs is not called, "-infinity" and "infinity" will return []byte("-infinity") and []byte("infinity") respectively, and potentially cause error "sql: Scan error on column index 0: unsupported driver -> Scan pair: []uint8 -> *time.Time", when scanning into a time.Time value.
Once EnableInfinityTs has been called, all connections created using this driver will decode Postgres' "-infinity" and "infinity" for "timestamp", "timestamp with time zone" and "date" types to the predefined minimum and maximum times, respectively. When encoding time.Time values, any time which equals or precedes the predefined minimum time will be encoded to "-infinity". Any values at or past the maximum time will similarly be encoded to "infinity".
If EnableInfinityTs is called with negative >= positive, it will panic. Calling EnableInfinityTs after a connection has been established results in undefined behavior. If EnableInfinityTs is called more than once, it will panic.
FormatTimestamp formats t into Postgres' text format for timestamps.
func NoticeHandler ¶ added in v1.4.0
NoticeHandler returns the notice handler on the given connection, if any. A runtime panic occurs if c is not a pq connection. This is rarely used directly, use ConnectorNoticeHandler and ConnectorWithNoticeHandler instead.
Open opens a new connection to the database. dsn is a connection string. Most users should only use it through database/sql package from the standard library.
ParseTimestamp parses Postgres' text format. It returns a time.Time in currentLocation iff that time's offset agrees with the offset sent from the Postgres server. Otherwise, ParseTimestamp returns a time.Time with the fixed offset offset provided by the Postgres server.
ParseURL converts a url to a connection string for driver.Open.
Deprecated: directly passing an URL to sql.Open("postgres", "postgres://...") now works, and calling this manually is no longer required.
QuoteIdentifier quotes an "identifier" (e.g. a table or a column name) to be used as part of an SQL statement. For example:
tblname := "my_table"
data := "my_data"
quoted := pq.QuoteIdentifier(tblname)
err := db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", quoted), data)
Any double quotes in name will be escaped. The quoted identifier will be case sensitive when used in a query. If the input string contains a zero byte, the result will be truncated immediately before it.
QuoteLiteral quotes a 'literal' (e.g. a parameter, often used to pass literal to DDL and other statements that do not accept parameters) to be used as part of an SQL statement. For example:
exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z")
err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date))
Any single quotes in name will be escaped. Any backslashes (i.e. "\") will be replaced by two backslashes (i.e. "\\") and the C-style escape identifier that PostgreSQL provides ('E') will be prepended to the string.
func RegisterGSSProvider(newGssArg NewGSSFunc)
RegisterGSSProvider registers a GSS authentication provider. For example, if you need to use Kerberos to authenticate with your server, add this to your main package:
import "github.com/lib/pq/auth/kerberos"
func init() {
pq.RegisterGSSProvider(func() (pq.GSS, error) { return kerberos.NewGSS() })
}
RegisterTLSConfig registers a custom tls.Config. They are used by using sslmode=pqgo-«key» in the connection string.
Set the config to nil to remove a configuration.
package main
import (
"crypto/tls"
"crypto/x509"
"database/sql"
"log"
"os"
"github.com/lib/pq"
)
func main() {
pem, err := os.ReadFile("testdata/ssl/root.crt")
if err != nil {
log.Fatal(err)
}
root := x509.NewCertPool()
root.AppendCertsFromPEM(pem)
certs, err := tls.LoadX509KeyPair("testdata/ssl/postgresql.crt", "testdata/ssl/postgresql.key")
if err != nil {
log.Fatal(err)
}
pq.RegisterTLSConfig("mytls", &tls.Config{
RootCAs: root,
Certificates: []tls.Certificate{certs},
ServerName: "postgres",
})
db, err := sql.Open("postgres", "host=postgres dbname=pqgo sslmode=pqgo-mytls")
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
}
func SetNoticeHandler ¶ added in v1.4.0
SetNoticeHandler sets the given notice handler on the given connection. A runtime panic occurs if c is not a pq connection. A nil handler may be used to unset it. This is rarely used directly, use ConnectorNoticeHandler and ConnectorWithNoticeHandler instead.
Note: Notice handlers are executed synchronously by pq meaning commands won't continue to be processed until the handler returns.
func SetNotificationHandler ¶ added in v1.5.0
func SetNotificationHandler(c driver.Conn, handler func(*Notification))
SetNotificationHandler sets the given notification handler on the given connection. A runtime panic occurs if c is not a pq connection. A nil handler may be used to unset it.
Note: Notification handlers are executed synchronously by pq meaning commands won't continue to be processed until the handler returns.
type ArrayDelimiter interface {
ArrayDelimiter() string
}
ArrayDelimiter may be optionally implemented by driver.Valuer or sql.Scanner to override the array delimiter used by GenericArray.
BoolArray represents a one-dimensional array of the PostgreSQL boolean type.
Scan implements the sql.Scanner interface.
Value implements the driver.Valuer interface.
ByteaArray represents a one-dimensional array of the PostgreSQL bytea type.
Scan implements the sql.Scanner interface.
Value implements the driver.Valuer interface. It uses the "hex" format which is only supported on PostgreSQL 9.0 or newer.
type Config struct {
Host string `postgres:"host" env:"PGHOST"`
Hostaddr netip.Addr `postgres:"hostaddr" env:"PGHOSTADDR"`
Port uint16 `postgres:"port" env:"PGPORT"`
Database string `postgres:"dbname" env:"PGDATABASE"`
User string `postgres:"user" env:"PGUSER"`
Password string `postgres:"password" env:"PGPASSWORD"`
Passfile string `postgres:"passfile" env:"PGPASSFILE"`
Options string `postgres:"options" env:"PGOPTIONS"`
ApplicationName string `postgres:"application_name" env:"PGAPPNAME"`
FallbackApplicationName string `postgres:"fallback_application_name" env:"-"`
SSLMode SSLMode `postgres:"sslmode" env:"PGSSLMODE"`
SSLNegotiation SSLNegotiation `postgres:"sslnegotiation" env:"PGSSLNEGOTIATION"`
SSLCert string `postgres:"sslcert" env:"PGSSLCERT"`
SSLKey string `postgres:"sslkey" env:"PGSSLKEY"`
SSLRootCert string `postgres:"sslrootcert" env:"PGSSLROOTCERT"`
SSLSNI bool `postgres:"sslsni" env:"PGSSLSNI"`
SSLMinProtocolVersion SSLProtocolVersion `postgres:"ssl_min_protocol_version" env:"SSLPGMINPROTOCOLVERSION"`
SSLMaxProtocolVersion SSLProtocolVersion `postgres:"ssl_max_protocol_version" env:"SSLPGMAXPROTOCOLVERSION"`
SSLInline bool `postgres:"sslinline" env:"-"`
KrbSrvname string `postgres:"krbsrvname" env:"PGKRBSRVNAME"`
KrbSpn string `postgres:"krbspn" env:"-"`
ConnectTimeout time.Duration `postgres:"connect_timeout" env:"PGCONNECT_TIMEOUT"`
BinaryParameters bool `postgres:"binary_parameters" env:"-"`
DisablePreparedBinaryResult bool `postgres:"disable_prepared_binary_result" env:"-"`
ClientEncoding string `postgres:"client_encoding" env:"PGCLIENTENCODING"`
Datestyle string `postgres:"datestyle" env:"PGDATESTYLE"`
TZ string `postgres:"tz" env:"PGTZ"`
Geqo string `postgres:"geqo" env:"PGGEQO"`
TargetSessionAttrs TargetSessionAttrs `postgres:"target_session_attrs" env:"PGTARGETSESSIONATTRS"`
LoadBalanceHosts LoadBalanceHosts `postgres:"load_balance_hosts" env:"PGLOADBALANCEHOSTS"`
MinProtocolVersion ProtocolVersion `postgres:"min_protocol_version" env:"PGMINPROTOCOLVERSION"`
MaxProtocolVersion ProtocolVersion `postgres:"max_protocol_version" env:"PGMAXPROTOCOLVERSION"`
Service string `postgres:"service" env:"PGSERVICE"`
ServiceFile string `postgres:"-" env:"PGSERVICEFILE"`
Runtime map[string]string `postgres:"-" env:"-"`
Multi []ConfigMultihost
}
Config holds options pq supports when connecting to PostgreSQL.
The postgres struct tag is used for the value from the DSN (e.g. "dbname=abc"), and the env struct tag is used for the environment variable (e.g. "PGDATABASE=abc")
NewConfig creates a new Config from the defaults, environment, service file, and DSN, in that order. That is: a service overrides any value from the environment, which in turn gets overridden by the same parameter in the connection string.
Most connection parameters supported by PostgreSQL are supported; see the Config struct for supported parameters. pq also lets you specify any run-time parameter such as search_path or work_mem in the connection string. This is different from libpq, which uses the "options" parameter for this (which also works in pq).
key=value connection strings ¶
For key=value strings, use single quotes for values that contain whitespace or empty values. A backslash will escape the next character:
"user=pqgo password='with spaces'" "user=''" "user=space\ man password='it\'s valid'"
URL connection strings ¶
pq supports URL-style postgres:// or postgresql:// connection strings in the form:
postgres[ql]://[user[:pwd]@][net-location][:port][/dbname][?param1=value1&...]
Go's net/url.Parse is more strict than PostgreSQL's URL parser and will (correctly) reject %2F in the host part. This means that unix-socket URLs:
postgres://[user[:pwd]@][unix-socket][:port[/dbname]][?param1=value1&...] postgres://%2Ftmp%2Fpostgres/db
will not work. You will need to use "host=/tmp/postgres dbname=db".
Similarly, multiple ports also won't work, but ?port= will:
postgres://host1,host2:5432,6543/dbname Doesn't work postgres://host1,host2/dbname?port=5432,6543 Works
Environment ¶
Most PostgreSQL environment variables are supported by pq. Environment variables have a lower precedence than explicitly provided connection parameters. pq will return an error if environment variables it does not support are set. Environment variables have a lower precedence than explicitly provided connection parameters.
ConfigMultihost specifies an additional server to try to connect to.
type Connector struct {
}
Connector represents a fixed configuration for the pq driver with a given dsn. Connector satisfies the database/sql/driver.Connector interface and can be used to create any number of DB Conn's via sql.OpenDB.
NewConnector returns a connector for the pq driver in a fixed configuration with the given dsn. The returned connector can be used to create any number of equivalent Conn's. The returned connector is intended to be used with sql.OpenDB.
package main
import (
"database/sql"
"log"
"github.com/lib/pq"
)
func main() {
c, err := pq.NewConnector("host=postgres dbname=pqgo")
if err != nil {
log.Fatal(err)
}
db := sql.OpenDB(c)
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
}
NewConnectorConfig returns a connector for the pq driver in a fixed configuration with the given Config. The returned connector can be used to create any number of equivalent Conn's. The returned connector is intended to be used with sql.OpenDB.
Connect returns a connection to the database using the fixed configuration of this Connector. Context is not used.
Driver returns the underlying driver of this Connector.
Dialer is the dialer interface. It can be used to obtain more control over how pq creates network connections.
DialerContext is the context-aware dialer interface.
type Driver struct{}
Driver is the Postgres database driver.
Open opens a new connection to the database. name is a connection string. Most users should only use it through database/sql package from the standard library.
Error returned by the PostgreSQL server.
The Error method returns the error message and error code:
pq: invalid input syntax for type json (22P02)
The [ErrorWithDetail] method also includes the error Detail, Hint, and location context (if any):
ERROR: invalid input syntax for type json (22P02)
DETAIL: Token "asd" is invalid.
CONTEXT: line 5, column 8:
3 | 'def',
4 | 123,
5 | 'foo', 'asd'::jsonb
^
As asserts that the given error is pq.Error and returns it, returning nil if it's not a pq.Error.
It will return nil if the pq.Error is not one of the given error codes. If no codes are given it will always return the Error.
This is safe to call with a nil error.
package main
import (
"database/sql"
"log"
"github.com/lib/pq"
"github.com/lib/pq/pqerror"
)
func main() {
db, err := sql.Open("postgres", "")
if err != nil {
log.Fatal(err)
}
email := "hello@example.com"
_, err = db.Exec("insert into t (email) values ($1)", email)
if pqErr := pq.As(err, pqerror.UniqueViolation); pqErr != nil {
log.Fatalf("email %q already exsts", email)
}
if err != nil {
log.Fatalf("unknown error: %s", err)
}
}
ErrorWithDetail returns the error message with detailed information and location context (if any).
See the documentation on Error.
Get implements the legacy PGError interface.
Deprecated: new code should use the fields of the Error struct directly.
SQLState returns the SQLState of the error.
ErrorClass is only the class part of an error code.
Deprecated: use pqerror.Class
ErrorCode is a five-character error code.
Deprecated: use pqerror.Code
type EventCallbackType func(event ListenerEventType, err error)
EventCallbackType is the event callback type. See also ListenerEventType constants' documentation.
Float32Array represents a one-dimensional array of the PostgreSQL double precision type.
Scan implements the sql.Scanner interface.
Value implements the driver.Valuer interface.
Float64Array represents a one-dimensional array of the PostgreSQL double precision type.
Scan implements the sql.Scanner interface.
Value implements the driver.Valuer interface.
GSS provides GSSAPI authentication (e.g., Kerberos).
type GenericArray struct{ A any }
GenericArray implements the driver.Valuer and sql.Scanner interfaces for an array or slice of any dimension.
Scan implements the sql.Scanner interface.
Value implements the driver.Valuer interface.
Int32Array represents a one-dimensional array of the PostgreSQL integer types.
Scan implements the sql.Scanner interface.
Value implements the driver.Valuer interface.
Int64Array represents a one-dimensional array of the PostgreSQL integer types.
Scan implements the sql.Scanner interface.
Value implements the driver.Valuer interface.
type Listener struct {
Notify chan *Notification
}
Listener provides an interface for listening to notifications from a PostgreSQL database. For general usage information, see section "Notifications".
Listener can safely be used from concurrently running goroutines.
package main
import (
"database/sql"
"fmt"
"log"
"time"
"github.com/lib/pq"
)
func main() {
// Connect with Listener.
var (
dsn = "dbname=pqgo "
minReconnect = 10 * time.Second
maxReconnect = time.Minute
)
l := pq.NewListener(dsn, minReconnect, maxReconnect, func(ev pq.ListenerEventType, err error) {
fmt.Printf("callback: %s: %v\n", ev, err)
})
defer l.Close()
// Can listen on as many channels as you want.
err := l.Listen("coconut")
if err != nil {
log.Fatal(err)
}
err = l.Listen("banana")
if err != nil {
log.Fatal(err)
}
// Send notifications for our test.
go func() {
db, err := sql.Open("postgres", dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
_, err = db.Exec(`notify coconut, 'got a lovely bunch'`)
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(`notify banana, 'yellow and curvy'`)
if err != nil {
log.Fatal(err)
}
}()
// Keep listening on Notify channel.
var i int
for {
select {
case <-time.After(1 * time.Second):
l.Close()
case n := <-l.Notify:
i++
if n == nil {
fmt.Println("nil notify: closing Listener")
return
}
fmt.Printf("notification on %q with data %q\n", n.Channel, n.Extra)
// Quickly exit after second notification in this example, so tests
// run faster.
if i == 2 {
l.Close()
}
}
}
}
Output: callback: connected: <nil> notification on "coconut" with data "got a lovely bunch" notification on "banana" with data "yellow and curvy" nil notify: closing Listener
NewDialListener is like NewListener but it takes a Dialer.
NewListener creates a new database connection dedicated to LISTEN / NOTIFY.
name should be set to a connection string to be used to establish the database connection (see section "Connection String Parameters" above).
minReconnect controls the duration to wait before trying to re-establish the database connection after connection loss. After each consecutive failure this interval is doubled, until maxReconnect is reached. Successfully completing the connection establishment procedure resets the interval back to minReconnect.
The last parameter cb can be set to a function which will be called by the Listener when the state of the underlying database connection changes. This callback will be called by the goroutine which dispatches the notifications over the Notify channel, so you should try to avoid doing potentially time-consuming operations from the callback.
Close disconnects the Listener from the database and shuts it down. Subsequent calls to its methods will return an error. Close returns an error if the connection has already been closed.
Listen starts listening for notifications on a channel. Calls to this function will block until an acknowledgement has been received from the server. Note that Listener automatically re-establishes the connection after connection loss, so this function may block indefinitely if the connection can not be re-established.
Listen will only fail in three conditions:
- The channel is already open. The returned error will be ErrChannelAlreadyOpen.
- The query was executed on the remote server, but PostgreSQL returned an error message in response to the query. The returned error will be a pq.Error containing the information the server supplied.
- Close is called on the Listener before the request could be completed.
The channel name is case-sensitive.
func (l *Listener) NotificationChannel() <-chan *Notification
NotificationChannel returns the notification channel for this listener. This is the same channel as Notify, and will not be recreated during the life time of the Listener.
Ping the remote server to make sure it's alive. Non-nil return value means that there is no active connection.
Unlisten removes a channel from the Listener's channel list. Returns ErrChannelNotOpen if the Listener is not listening on the specified channel. Returns immediately with no error if there is no connection. Note that you might still get notifications for this channel even after Unlisten has returned.
The channel name is case-sensitive.
type ListenerConn struct {
}
ListenerConn is a low-level interface for waiting for notifications. You should use Listener instead.
func NewListenerConn(name string, notificationChan chan<- *Notification) (*ListenerConn, error)
NewListenerConn creates a new ListenerConn. Use NewListener instead.
Close closes the connection.
Err returns the reason the connection was closed. It is not safe to call this function until l.Notify has been closed.
ExecSimpleQuery executes a "simple query" (i.e. one with no bindable parameters) on the connection. The possible return values are:
- "executed" is true; the query was executed to completion on the database server. If the query failed, err will be set to the error returned by the database, otherwise err will be nil.
- If "executed" is false, the query could not be executed on the remote server. err will be non-nil.
After a call to ExecSimpleQuery has returned an executed=false value, the connection has either been closed or will be closed shortly thereafter, and all subsequently executed queries will return an error.
Listen sends a LISTEN query to the server. See ExecSimpleQuery.
Ping the remote server to make sure it's alive. Non-nil error means the connection has failed and should be abandoned.
Unlisten sends an UNLISTEN query to the server. See ExecSimpleQuery.
UnlistenAll sends an `UNLISTEN *` query to the server. See ExecSimpleQuery.
type ListenerEventType int
ListenerEventType is an enumeration of listener event types.
const ( ListenerEventConnected ListenerEventType = iota ListenerEventDisconnected ListenerEventReconnected ListenerEventConnectionAttemptFailed )
LoadBalanceHosts is a load_balance_hosts setting.
NewGSSFunc creates a GSS authentication provider, for use with RegisterGSSProvider.
type NoticeHandlerConnector ¶ added in v1.4.0
NoticeHandlerConnector wraps a regular connector and sets a notice handler on it.
func ConnectorWithNoticeHandler ¶ added in v1.4.0
ConnectorWithNoticeHandler creates or sets the given handler for the given connector. If the given connector is a result of calling this function previously, it is simply set on the given connector and returned. Otherwise, this returns a new connector wrapping the given one and setting the notice handler. A nil notice handler may be used to unset it.
The returned connector is intended to be used with database/sql.OpenDB.
Note: Notice handlers are executed synchronously by pq meaning commands won't continue to be processed until the handler returns.
package main
import (
"database/sql"
"fmt"
"log"
"github.com/lib/pq"
)
func main() {
// Base connector to wrap
base, err := pq.NewConnector("dbname=pqgo")
if err != nil {
log.Fatal(err)
}
// Wrap the connector to simply print out the message
connector := pq.ConnectorWithNoticeHandler(base, func(notice *pq.Error) {
fmt.Printf("NOTICE: %s\n", notice.Message)
})
db := sql.OpenDB(connector)
defer db.Close()
// Raise a notice
_, err = db.Exec(`drop table if exists doesntexist`)
if err != nil {
log.Fatal(err)
}
// And via PL/pgSQL.
_, err = db.Exec(`
do language plpgsql $$ begin
raise notice 'test notice';
end $$
`)
if err != nil {
log.Fatal(err)
}
}
Output: NOTICE: table "doesntexist" does not exist, skipping NOTICE: test notice
Notification represents a single notification from the database.
type NotificationHandlerConnector ¶ added in v1.5.1
NotificationHandlerConnector wraps a regular connector and sets a notification handler on it.
func ConnectorWithNotificationHandler ¶ added in v1.5.1
ConnectorWithNotificationHandler creates or sets the given handler for the given connector. If the given connector is a result of calling this function previously, it is simply set on the given connector and returned. Otherwise, this returns a new connector wrapping the given one and setting the notification handler. A nil notification handler may be used to unset it.
The returned connector is intended to be used with database/sql.OpenDB.
Note: Notification handlers are executed synchronously by pq meaning commands won't continue to be processed until the handler returns.
PGError is an interface used by previous versions of pq.
Deprecated: use the Error type. This is never used.
ProtocolVersion is a min_protocol_version or max_protocol_version setting.
SSLMode is a sslmode setting.
SSLNegotiation is a sslnegotiation setting.
type SSLProtocolVersion string
SSLProtocolVersion is a ssl_min_protocol_version or ssl_max_protocol_version setting.
StringArray represents a one-dimensional array of the PostgreSQL character types.
Scan implements the sql.Scanner interface.
Value implements the driver.Valuer interface.
type TargetSessionAttrs string
TargetSessionAttrs is a target_session_attrs setting.