pgx is a pure Go driver and toolkit for PostgreSQL providing a native high-performance interface with PostgreSQL-specific features plus a database/sql compatibility adapter.
PostgreSQL array support through generic types.
import "github.com/jackc/pgx/v5/pgtype"type Array[T any] struct {
Elements []T
Dims []ArrayDimension
Valid bool
}
func (a Array[T]) Dimensions() []ArrayDimension
func (a Array[T]) Index(i int) any
func (a Array[T]) IndexType() any
func (a Array[T]) ScanIndex(i int) any
func (a Array[T]) ScanIndexType() any
func (a *Array[T]) SetDimensions(dimensions []ArrayDimension) error
type ArrayDimension struct {
Length int32
LowerBound int32
}
type FlatArray[T any] []T // 1D array convenience typeFor 1D arrays, use FlatArray[T] for simplicity:
var tags pgtype.FlatArray[string]
conn.QueryRow(ctx, "SELECT tags FROM articles WHERE id = $1", id).Scan(&tags)
// tags is []string
// Insert
newTags := pgtype.FlatArray[string]{"golang", "postgresql", "database"}
_, err = conn.Exec(ctx, "UPDATE articles SET tags = $1 WHERE id = $2", newTags, id)For multi-dimensional arrays, use Array[T]:
var matrix pgtype.Array[int32]
err := conn.QueryRow(ctx, "SELECT matrix FROM data WHERE id = $1", id).Scan(&matrix)
// Access dimensions
for _, dim := range matrix.Dimensions() {
fmt.Printf("Dim length: %d, lower bound: %d
", dim.Length, dim.LowerBound)
}
// Access elements
for _, elem := range matrix.Elements {
fmt.Println(elem)
}// Integer arrays
var intArray pgtype.FlatArray[int32]
var bigIntArray pgtype.FlatArray[int64]
// Text arrays
var textArray pgtype.FlatArray[string]
// UUID arrays
var uuidArray pgtype.FlatArray[[16]byte]
// Float arrays
var floatArray pgtype.FlatArray[float64]type ArrayGetter interface {
Dimensions() []ArrayDimension
Index(i int) any
IndexType() any
}
type ArraySetter interface {
SetDimensions(dimensions []ArrayDimension) error
ScanIndex(i int) any
ScanIndexType() any
}Implement these for custom array types.
type ArrayCodec struct {
ElementType *Type
}Codec for any array type. Used internally by pgx but can be used for custom array codecs.
var ids pgtype.FlatArray[int64]
err := conn.QueryRow(ctx, "SELECT user_ids FROM groups WHERE id = $1", groupID).Scan(&ids)
for _, id := range ids {
fmt.Println("User ID:", id)
}tags := pgtype.FlatArray[string]{"important", "urgent", "review"}
_, err := conn.Exec(ctx,
"INSERT INTO tasks (title, tags) VALUES ($1, $2)",
"Complete project", tags)var tags pgtype.Array[string]
err := conn.QueryRow(ctx, "SELECT tags FROM articles WHERE id = $1", id).Scan(&tags)
if !tags.Valid {
fmt.Println("Tags is NULL")
} else {
fmt.Println("Tags:", tags.Elements)
}// Create 2x3 matrix
matrix := pgtype.Array[int32]{
Elements: []int32{1, 2, 3, 4, 5, 6},
Dims: []pgtype.ArrayDimension{
{Length: 2, LowerBound: 1},
{Length: 3, LowerBound: 1},
},
Valid: true,
}
_, err := conn.Exec(ctx, "INSERT INTO matrices (data) VALUES ($1)", matrix)Use pgtype.Map.SQLScanner for arrays with database/sql:
m := pgtype.NewMap()
var tags []string
err := db.QueryRow("SELECT tags FROM articles WHERE id = $1", id).Scan(m.SQLScanner(&tags))FlatArray[T] has less overhead than Array[T] for 1D arraysInstall with Tessl CLI
npx tessl i tessl/golang-github-com-jackc-pgx-v5@5.8.0