This eliminates an edge case that can cause a deadlock and is a prerequisite to cheaply testing connection liveness and to recoving a connection after a timeout. https://github.com/jackc/pgconn/issues/27 Squashed commit of the following: commit 0d7b0dddea1575e9fd72592665badb8cbdd581cc Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 25 13:15:05 2022 -0500 Add test for non-blocking IO preventing deadlock commit 79d68d23d38bb03ddb8bf13cb45792430eaf959a Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 18 18:23:24 2022 -0500 Release CopyFrom buf when done commit 95a43139c7b0b7557898c4480e5b3e42417ee3c0 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 18 18:22:32 2022 -0500 Avoid allocations with non-blocking write commit 6b63ceee076794bc4380495a55dd414dbbd08a43 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 18 17:46:49 2022 -0500 Simplify iobufpool usage commit 60ecdda02e5a24c894df4f58d31c485b90de5d5b Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 18 11:51:59 2022 -0500 Add true non-blocking IO commit 7dd26a34a182d4aacaed3bf8c09f9cc48a7b6156 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 20:28:23 2022 -0500 Fix block when reading more than buffered commit afa702213f1b6d24c976406448301b2be53b7f70 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 20:10:23 2022 -0500 More TLS support commit 51655bf8f40321d5f89bc3c02dd55fba0ac6aa49 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 17:46:00 2022 -0500 Steps toward TLS commit 2b80beb1ed75f0f58db8188b87753dbc26b62098 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 13:06:29 2022 -0500 Litle more TLS support commit 765b2c6e7b034ff6ffab3974579fd6ee7add593b Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 12:29:30 2022 -0500 Add testing of TLS commit 5b64432afbed9224f9512cc46624c88e7ebec625 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 09:48:19 2022 -0500 Introduce testVariants in prep for TLS commit ecebd7b103d4a9125c61e83f3651b950658b0b84 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 09:32:14 2022 -0500 Handle and test read of previously buffered data commit 09c64d8cf3ca5be1a31bef46bf78fa5cb9fae831 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 09:04:48 2022 -0500 Rename nbbconn to nbconn commit 73398bc67a7b7bd1aa044fb9b0546f4198ef92d2 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 08:59:53 2022 -0500 Remove backup files commit f1df39a29d23ae4e5175b92c69697f2bf9b4e112 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 08:58:05 2022 -0500 Initial passing tests commit ea3cdab234343fc9761d9b7966c5346179cd1b01 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat Jun 4 08:38:57 2022 -0500 Fix connect timeout commit ca22396789d120ff556f9704f4470268fbc8c0d8 Author: Jack Christensen <jack@jackchristensen.com> Date: Thu Jun 2 19:32:55 2022 -0500 wip commit 2e7b46d5d7454daf0859dd48f8a8e190995164c5 Author: Jack Christensen <jack@jackchristensen.com> Date: Mon May 30 08:32:43 2022 -0500 Update comments commit 7d04dc5caa80cb147929b6f65bab60a27baaff89 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat May 28 19:43:23 2022 -0500 Fix broken test commit bf1edc77d70465b4097a59c08c581033d2033ac6 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat May 28 19:40:33 2022 -0500 fixed putting wrong size bufs commit 1f7a855b2e4d1e14f85ac5f5683e2b93db0a4bd9 Author: Jack Christensen <jack@jackchristensen.com> Date: Sat May 28 18:13:47 2022 -0500 initial not quite working non-blocking conn
pgx - PostgreSQL Driver and Toolkit
This is the v5 development branch. It is still in active development and testing.
pgx is a pure Go driver and toolkit for PostgreSQL.
pgx aims to be low-level, fast, and performant, while also enabling PostgreSQL-specific features that the standard database/sql
package does not allow for.
The driver component of pgx can be used alongside the standard database/sql
package.
The toolkit component is a related set of packages that implement PostgreSQL functionality such as parsing the wire protocol and type mapping between PostgreSQL and Go. These underlying packages can be used to implement alternative drivers, proxies, load balancers, logical replication clients, etc.
Example Usage
package main
import (
"context"
"fmt"
"os"
"github.com/jackc/pgx/v5"
)
func main() {
// urlExample := "postgres://username:password@localhost:5432/database_name"
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
os.Exit(1)
}
defer conn.Close(context.Background())
var name string
var weight int64
err = conn.QueryRow(context.Background(), "select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
if err != nil {
fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
os.Exit(1)
}
fmt.Println(name, weight)
}
See the getting started guide for more information.
Choosing Between the pgx and database/sql Interfaces
It is recommended to use the pgx interface if:
- The application only targets PostgreSQL.
- No other libraries that require
database/sql
are in use.
The pgx interface is faster and exposes more features.
The database/sql
interface only allows the underlying driver to return or receive the following types: int64
,
float64
, bool
, []byte
, string
, time.Time
, or nil
. Handling other types requires implementing the
database/sql.Scanner
and the database/sql/driver/driver.Valuer
interfaces which require transmission of values in text format. The binary format can be substantially faster, which is what the pgx interface uses.
Features
pgx supports many features beyond what is available through database/sql
:
- Support for approximately 70 different PostgreSQL types
- Automatic statement preparation and caching
- Batch queries
- Single-round trip query mode
- Full TLS connection control
- Binary format support for custom types (allows for much quicker encoding/decoding)
- COPY protocol support for faster bulk data loads
- Extendable logging support
- Connection pool with after-connect hook for arbitrary connection setup
- Listen / notify
- Conversion of PostgreSQL arrays to Go slice mappings for integers, floats, and strings
- Hstore support
- JSON and JSONB support
- Maps
inet
andcidr
PostgreSQL types tonet.IPNet
andnet.IP
- Large object support
- NULL mapping to Null* struct or pointer to pointer
- Supports
database/sql.Scanner
anddatabase/sql/driver.Valuer
interfaces for custom types - Notice response handling
- Simulated nested transactions with savepoints
Performance
There are three areas in particular where pgx can provide a significant performance advantage over the standard
database/sql
interface and other drivers:
- PostgreSQL specific types - Types such as arrays can be parsed much quicker because pgx uses the binary format.
- Automatic statement preparation and caching - pgx will prepare and cache statements by default. This can provide an significant free improvement to code that does not explicitly use prepared statements. Under certain workloads, it can perform nearly 3x the number of queries per second.
- Batched queries - Multiple queries can be batched together to minimize network round trips.
Testing
pgx tests naturally require a PostgreSQL database. It will connect to the database specified in the PGX_TEST_DATABASE
environment
variable. The PGX_TEST_DATABASE
environment variable can either be a URL or DSN. In addition, the standard PG*
environment
variables will be respected. Consider using direnv to simplify environment variable
handling.
Example Test Environment
Connect to your PostgreSQL server and run:
create database pgx_test;
Connect to the newly-created database and run:
create domain uint64 as numeric(20,0);
Now, you can run the tests:
PGX_TEST_DATABASE="host=/var/run/postgresql database=pgx_test" go test ./...
In addition, there are tests specific for PgBouncer that will be executed if PGX_TEST_PGBOUNCER_CONN_STRING
is set.
Supported Go and PostgreSQL Versions
pgx supports the same versions of Go and PostgreSQL that are supported by their respective teams. For Go that is the two most recent major releases and for PostgreSQL the major releases in the last 5 years. This means pgx supports Go 1.17 and higher and PostgreSQL 10 and higher. pgx also is tested against the latest version of CockroachDB.
v5
is targeted at Go 1.18+. The general release of v5
is not planned until second half of 2022 so it is expected that the policy of supporting the two most recent versions of Go will be maintained or restored soon after its release.
Version Policy
pgx follows semantic versioning for the documented public API on stable releases. v4
is the latest stable major version.
PGX Family Libraries
github.com/jackc/pglogrepl
pglogrepl provides functionality to act as a client for PostgreSQL logical replication.
github.com/jackc/pgmock
pgmock offers the ability to create a server that mocks the PostgreSQL wire protocol. This is used internally to test pgx by purposely inducing unusual errors. pgproto3 and pgmock together provide most of the foundational tooling required to implement a PostgreSQL proxy or MitM (such as for a custom connection pooler).
github.com/jackc/tern
tern is a stand-alone SQL migration system.
github.com/jackc/pgerrcode
pgerrcode contains constants for the PostgreSQL error codes.
Adapters for 3rd Party Types
- github.com/jackc/pgx-gofrs-uuid
- github.com/jackc/pgx-shopspring-decimal
- github.com/vgarvardt/pgx-google-uuid
Adapters for 3rd Party Loggers
- github.com/jackc/pgx-go-kit-log
- github.com/jackc/pgx-log15
- github.com/jackc/pgx-logrus
- github.com/jackc/pgx-zap
- github.com/jackc/pgx-zerolog
3rd Party Libraries with PGX Support
github.com/georgysavva/scany
Library for scanning data from a database into Go structs and more.
https://github.com/otan/gopgkrb5
Adds GSSAPI / Kerberos authentication support.