Showing preview only (2,220K chars total). Download the full file or copy to clipboard to get everything.
Repository: jackc/pgx
Branch: master
Commit: 274f2706d0be
Files: 341
Total size: 2.1 MB
Directory structure:
gitextract_9td1e4zc/
├── .devcontainer/
│ ├── Dockerfile
│ ├── devcontainer.json
│ ├── docker-compose.yml
│ └── post-create.bash
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ └── other-issues.md
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .golangci.yml
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── Rakefile
├── batch.go
├── batch_test.go
├── bench_test.go
├── ci/
│ └── setup_test.bash
├── conn.go
├── conn_internal_test.go
├── conn_test.go
├── copy_from.go
├── copy_from_test.go
├── derived_types.go
├── derived_types_test.go
├── doc.go
├── examples/
│ ├── README.md
│ ├── chat/
│ │ ├── README.md
│ │ └── main.go
│ ├── todo/
│ │ ├── README.md
│ │ ├── main.go
│ │ └── structure.sql
│ └── url_shortener/
│ ├── README.md
│ ├── main.go
│ └── structure.sql
├── extended_query_builder.go
├── go.mod
├── go.sum
├── helper_test.go
├── internal/
│ ├── faultyconn/
│ │ └── faultyconn.go
│ ├── iobufpool/
│ │ ├── iobufpool.go
│ │ ├── iobufpool_internal_test.go
│ │ └── iobufpool_test.go
│ ├── pgio/
│ │ ├── README.md
│ │ ├── doc.go
│ │ ├── write.go
│ │ └── write_test.go
│ ├── pgmock/
│ │ ├── pgmock.go
│ │ └── pgmock_test.go
│ ├── sanitize/
│ │ ├── benchmark.sh
│ │ ├── sanitize.go
│ │ ├── sanitize_bench_test.go
│ │ ├── sanitize_fuzz_test.go
│ │ └── sanitize_test.go
│ └── stmtcache/
│ ├── lru_cache.go
│ └── stmtcache.go
├── large_objects.go
├── large_objects_private_test.go
├── large_objects_test.go
├── log/
│ └── testingadapter/
│ └── adapter.go
├── multitracer/
│ ├── tracer.go
│ └── tracer_test.go
├── named_args.go
├── named_args_test.go
├── pgbouncer_test.go
├── pgconn/
│ ├── README.md
│ ├── auth_oauth.go
│ ├── auth_scram.go
│ ├── auth_scram_test.go
│ ├── benchmark_private_test.go
│ ├── benchmark_test.go
│ ├── config.go
│ ├── config_test.go
│ ├── ctxwatch/
│ │ ├── context_watcher.go
│ │ ├── context_watcher_test.go
│ │ └── synctest_test.go
│ ├── defaults.go
│ ├── defaults_windows.go
│ ├── doc.go
│ ├── errors.go
│ ├── errors_test.go
│ ├── export_test.go
│ ├── helper_test.go
│ ├── internal/
│ │ └── bgreader/
│ │ ├── bgreader.go
│ │ └── bgreader_test.go
│ ├── krb5.go
│ ├── pgconn.go
│ ├── pgconn_private_test.go
│ ├── pgconn_stress_test.go
│ └── pgconn_test.go
├── pgproto3/
│ ├── README.md
│ ├── authentication_cleartext_password.go
│ ├── authentication_gss.go
│ ├── authentication_gss_continue.go
│ ├── authentication_md5_password.go
│ ├── authentication_ok.go
│ ├── authentication_sasl.go
│ ├── authentication_sasl_continue.go
│ ├── authentication_sasl_final.go
│ ├── backend.go
│ ├── backend_key_data.go
│ ├── backend_key_data_test.go
│ ├── backend_test.go
│ ├── big_endian.go
│ ├── bind.go
│ ├── bind_complete.go
│ ├── bind_test.go
│ ├── cancel_request.go
│ ├── cancel_request_test.go
│ ├── chunkreader.go
│ ├── chunkreader_test.go
│ ├── close.go
│ ├── close_complete.go
│ ├── command_complete.go
│ ├── copy_both_response.go
│ ├── copy_both_response_test.go
│ ├── copy_data.go
│ ├── copy_done.go
│ ├── copy_fail.go
│ ├── copy_in_response.go
│ ├── copy_out_response.go
│ ├── data_row.go
│ ├── describe.go
│ ├── doc.go
│ ├── empty_query_response.go
│ ├── error_response.go
│ ├── example/
│ │ └── pgfortune/
│ │ ├── README.md
│ │ ├── main.go
│ │ └── server.go
│ ├── execute.go
│ ├── flush.go
│ ├── frontend.go
│ ├── frontend_test.go
│ ├── function_call.go
│ ├── function_call_decode_test.go
│ ├── function_call_response.go
│ ├── function_call_response_test.go
│ ├── function_call_test.go
│ ├── fuzz_test.go
│ ├── gss_enc_request.go
│ ├── gss_response.go
│ ├── json_test.go
│ ├── negotiate_protocol_version.go
│ ├── negotiate_protocol_version_test.go
│ ├── no_data.go
│ ├── notice_response.go
│ ├── notification_response.go
│ ├── parameter_description.go
│ ├── parameter_status.go
│ ├── parse.go
│ ├── parse_complete.go
│ ├── password_message.go
│ ├── pgproto3.go
│ ├── pgproto3_private_test.go
│ ├── portal_suspended.go
│ ├── query.go
│ ├── query_test.go
│ ├── ready_for_query.go
│ ├── row_description.go
│ ├── sasl_initial_response.go
│ ├── sasl_response.go
│ ├── ssl_request.go
│ ├── startup_message.go
│ ├── sync.go
│ ├── terminate.go
│ ├── testdata/
│ │ └── fuzz/
│ │ └── FuzzFrontend/
│ │ ├── 39c5e864da4707fc15fea48f7062d6a07796fdc43b33e0ba9dbd7074a0211fa6
│ │ ├── 9b06792b1aaac8a907dbfa04d526ae14326c8573b7409032caac8461e83065f7
│ │ ├── a661fb98e802839f0a7361160fbc6e28794612a411d00bde104364ee281c4214
│ │ └── fc98dcd487a5173b38763a5f7dd023933f3a86ab566e3f2b091eb36248107eb4
│ ├── trace.go
│ └── trace_test.go
├── pgtype/
│ ├── array.go
│ ├── array_codec.go
│ ├── array_codec_test.go
│ ├── array_test.go
│ ├── bits.go
│ ├── bits_test.go
│ ├── bool.go
│ ├── bool_test.go
│ ├── box.go
│ ├── box_test.go
│ ├── builtin_wrappers.go
│ ├── bytea.go
│ ├── bytea_test.go
│ ├── circle.go
│ ├── circle_test.go
│ ├── composite.go
│ ├── composite_test.go
│ ├── convert.go
│ ├── date.go
│ ├── date_test.go
│ ├── derived_types_test.go
│ ├── doc.go
│ ├── enum_codec.go
│ ├── enum_codec_test.go
│ ├── example_child_records_test.go
│ ├── example_custom_type_test.go
│ ├── example_json_test.go
│ ├── float4.go
│ ├── float4_test.go
│ ├── float8.go
│ ├── float8_test.go
│ ├── hstore.go
│ ├── hstore_test.go
│ ├── inet.go
│ ├── inet_test.go
│ ├── int.go
│ ├── int.go.erb
│ ├── int_test.go
│ ├── int_test.go.erb
│ ├── integration_benchmark_test.go
│ ├── integration_benchmark_test.go.erb
│ ├── integration_benchmark_test_gen.sh
│ ├── interval.go
│ ├── interval_test.go
│ ├── json.go
│ ├── json_test.go
│ ├── jsonb.go
│ ├── jsonb_test.go
│ ├── line.go
│ ├── line_test.go
│ ├── lseg.go
│ ├── lseg_test.go
│ ├── ltree.go
│ ├── ltree_test.go
│ ├── macaddr.go
│ ├── macaddr_test.go
│ ├── multirange.go
│ ├── multirange_test.go
│ ├── numeric.go
│ ├── numeric_test.go
│ ├── path.go
│ ├── path_test.go
│ ├── pgtype.go
│ ├── pgtype_default.go
│ ├── pgtype_test.go
│ ├── point.go
│ ├── point_test.go
│ ├── polygon.go
│ ├── polygon_test.go
│ ├── qchar.go
│ ├── qchar_test.go
│ ├── range.go
│ ├── range_codec.go
│ ├── range_codec_test.go
│ ├── range_test.go
│ ├── record_codec.go
│ ├── record_codec_test.go
│ ├── register_default_pg_types.go
│ ├── register_default_pg_types_disabled.go
│ ├── text.go
│ ├── text_format_only_codec.go
│ ├── text_test.go
│ ├── tid.go
│ ├── tid_test.go
│ ├── time.go
│ ├── time_test.go
│ ├── timestamp.go
│ ├── timestamp_test.go
│ ├── timestamptz.go
│ ├── timestamptz_test.go
│ ├── tsvector.go
│ ├── tsvector_test.go
│ ├── uint32.go
│ ├── uint32_test.go
│ ├── uint64.go
│ ├── uint64_test.go
│ ├── uuid.go
│ ├── uuid_test.go
│ ├── xml.go
│ ├── xml_test.go
│ └── zeronull/
│ ├── doc.go
│ ├── float8.go
│ ├── float8_test.go
│ ├── int.go
│ ├── int.go.erb
│ ├── int_test.go
│ ├── int_test.go.erb
│ ├── text.go
│ ├── text_test.go
│ ├── timestamp.go
│ ├── timestamp_test.go
│ ├── timestamptz.go
│ ├── timestamptz_test.go
│ ├── uuid.go
│ ├── uuid_test.go
│ ├── zeronull.go
│ └── zeronull_test.go
├── pgx_test.go
├── pgxpool/
│ ├── batch_results.go
│ ├── bench_test.go
│ ├── common_test.go
│ ├── conn.go
│ ├── conn_test.go
│ ├── doc.go
│ ├── helper_test.go
│ ├── pool.go
│ ├── pool_test.go
│ ├── rows.go
│ ├── stat.go
│ ├── tracer.go
│ ├── tracer_test.go
│ ├── tx.go
│ └── tx_test.go
├── pgxtest/
│ └── pgxtest.go
├── pipeline_test.go
├── query_test.go
├── rows.go
├── rows_test.go
├── stdlib/
│ ├── bench_test.go
│ ├── sql.go
│ └── sql_test.go
├── test.sh
├── testsetup/
│ ├── README.md
│ ├── certs/
│ │ ├── ca.key.b64
│ │ ├── ca.pem.b64
│ │ ├── localhost.crt.b64
│ │ ├── localhost.key.b64
│ │ ├── pgx_sslcert.crt.b64
│ │ └── pgx_sslcert.key.b64
│ ├── generate_certs.go
│ ├── oauth_validator_module/
│ │ ├── Makefile
│ │ ├── dummy_validator.c
│ │ ├── pg_hba.conf
│ │ └── postgresql.conf
│ ├── pg_hba.conf
│ ├── pg_hba_devcontainer.conf
│ ├── pg_ssl_init.sh
│ ├── postgresql_setup.sql
│ └── postgresql_ssl.conf
├── tracelog/
│ ├── tracelog.go
│ └── tracelog_test.go
├── tracer.go
├── tracer_test.go
├── tx.go
├── tx_test.go
├── values.go
└── values_test.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .devcontainer/Dockerfile
================================================
FROM mcr.microsoft.com/devcontainers/go:2-1.25-trixie
RUN apt-get update && apt-get install -y postgresql-common \
&& yes | /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh \
&& apt-get install -y postgresql-client-18 \
&& rm -rf /var/lib/apt/lists/*
USER vscode
RUN go install golang.org/x/tools/cmd/goimports@latest
================================================
FILE: .devcontainer/devcontainer.json
================================================
{
"name": "pgx",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"postStartCommand": "base64 -d testsetup/certs/ca.pem.b64 > /tmp/ca.pem && base64 -d testsetup/certs/pgx_sslcert.crt.b64 > /tmp/pgx_sslcert.crt && base64 -d testsetup/certs/pgx_sslcert.key.b64 > /tmp/pgx_sslcert.key && chmod 600 /tmp/pgx_sslcert.key",
"postCreateCommand": ".devcontainer/post-create.bash"
}
================================================
FILE: .devcontainer/docker-compose.yml
================================================
volumes:
postgres-14-data:
postgres-15-data:
postgres-16-data:
postgres-17-data:
postgres-18-data:
pg-sockets:
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ../..:/workspaces:cached
- pg-sockets:/var/run/postgresql
environment:
PGUSER: postgres
PGPASSWORD: postgres
PGDATABASE: pgx_test
PGHOST: localhost
PGCLIENTENCODING: utf8
# PGX test env vars target PG18 (port 5432) by default.
# test.sh overrides these per-target.
PGX_TEST_DATABASE: "host=localhost port=5432 user=postgres password=postgres dbname=pgx_test"
PGX_TEST_UNIX_SOCKET_CONN_STRING: "host=/var/run/postgresql port=5432 user=postgres dbname=pgx_test"
PGX_TEST_TCP_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_md5 password=secret dbname=pgx_test"
PGX_TEST_MD5_PASSWORD_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_md5 password=secret dbname=pgx_test"
PGX_TEST_SCRAM_PASSWORD_CONN_STRING: "host=localhost port=5432 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
PGX_TEST_SCRAM_PLUS_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
PGX_TEST_PLAIN_PASSWORD_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_pw password=secret dbname=pgx_test"
PGX_TEST_TLS_CONN_STRING: "host=localhost port=5432 user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
PGX_TEST_TLS_CLIENT_CONN_STRING: "host=localhost port=5432 user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
PGX_SSL_PASSWORD: certpw
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
postgres-14:
image: postgres:14
restart: unless-stopped
volumes:
- postgres-14-data:/var/lib/postgresql
- ../testsetup/postgresql_setup.sql:/docker-entrypoint-initdb.d/01-setup.sql:ro
- ../testsetup/pg_ssl_init.sh:/docker-entrypoint-initdb.d/02-ssl-init.sh:ro
- ../testsetup/pg_hba_devcontainer.conf:/etc/postgresql/pg_hba.conf:ro
- ../testsetup/certs:/etc/postgresql/ssl:ro
- ../testsetup/postgresql_ssl.conf:/etc/postgresql/postgresql_ssl.conf:ro
- pg-sockets:/var/run/postgresql
network_mode: service:app
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: pgx_test
POSTGRES_HOSTNAME: localhost
PGPORT: 5414
command: postgres -c port=5414 -c hba_file=/etc/postgresql/pg_hba.conf -c unix_socket_directories=/var/run/postgresql
postgres-15:
image: postgres:15
restart: unless-stopped
volumes:
- postgres-15-data:/var/lib/postgresql
- ../testsetup/postgresql_setup.sql:/docker-entrypoint-initdb.d/01-setup.sql:ro
- ../testsetup/pg_ssl_init.sh:/docker-entrypoint-initdb.d/02-ssl-init.sh:ro
- ../testsetup/pg_hba_devcontainer.conf:/etc/postgresql/pg_hba.conf:ro
- ../testsetup/certs:/etc/postgresql/ssl:ro
- ../testsetup/postgresql_ssl.conf:/etc/postgresql/postgresql_ssl.conf:ro
- pg-sockets:/var/run/postgresql
network_mode: service:app
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: pgx_test
POSTGRES_HOSTNAME: localhost
PGPORT: 5415
command: postgres -c port=5415 -c hba_file=/etc/postgresql/pg_hba.conf -c unix_socket_directories=/var/run/postgresql
postgres-16:
image: postgres:16
restart: unless-stopped
volumes:
- postgres-16-data:/var/lib/postgresql
- ../testsetup/postgresql_setup.sql:/docker-entrypoint-initdb.d/01-setup.sql:ro
- ../testsetup/pg_ssl_init.sh:/docker-entrypoint-initdb.d/02-ssl-init.sh:ro
- ../testsetup/pg_hba_devcontainer.conf:/etc/postgresql/pg_hba.conf:ro
- ../testsetup/certs:/etc/postgresql/ssl:ro
- ../testsetup/postgresql_ssl.conf:/etc/postgresql/postgresql_ssl.conf:ro
- pg-sockets:/var/run/postgresql
network_mode: service:app
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: pgx_test
POSTGRES_HOSTNAME: localhost
PGPORT: 5416
command: postgres -c port=5416 -c hba_file=/etc/postgresql/pg_hba.conf -c unix_socket_directories=/var/run/postgresql
postgres-17:
image: postgres:17
restart: unless-stopped
volumes:
- postgres-17-data:/var/lib/postgresql
- ../testsetup/postgresql_setup.sql:/docker-entrypoint-initdb.d/01-setup.sql:ro
- ../testsetup/pg_ssl_init.sh:/docker-entrypoint-initdb.d/02-ssl-init.sh:ro
- ../testsetup/pg_hba_devcontainer.conf:/etc/postgresql/pg_hba.conf:ro
- ../testsetup/certs:/etc/postgresql/ssl:ro
- ../testsetup/postgresql_ssl.conf:/etc/postgresql/postgresql_ssl.conf:ro
- pg-sockets:/var/run/postgresql
network_mode: service:app
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: pgx_test
POSTGRES_HOSTNAME: localhost
PGPORT: 5417
command: postgres -c port=5417 -c hba_file=/etc/postgresql/pg_hba.conf -c unix_socket_directories=/var/run/postgresql
postgres-18:
image: postgres:18
restart: unless-stopped
volumes:
- postgres-18-data:/var/lib/postgresql
- ../testsetup/postgresql_setup.sql:/docker-entrypoint-initdb.d/01-setup.sql:ro
- ../testsetup/pg_ssl_init.sh:/docker-entrypoint-initdb.d/02-ssl-init.sh:ro
- ../testsetup/pg_hba_devcontainer.conf:/etc/postgresql/pg_hba.conf:ro
- ../testsetup/certs:/etc/postgresql/ssl:ro
- ../testsetup/postgresql_ssl.conf:/etc/postgresql/postgresql_ssl.conf:ro
- pg-sockets:/var/run/postgresql
network_mode: service:app
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: pgx_test
POSTGRES_HOSTNAME: localhost
command: postgres -c hba_file=/etc/postgresql/pg_hba.conf -c unix_socket_directories=/var/run/postgresql
cockroachdb:
image: cockroachdb/cockroach:v25.4.4
restart: unless-stopped
network_mode: service:app
command: start-single-node --insecure --listen-addr=127.0.0.1:26257 --store=type=mem,size=1024MiB
================================================
FILE: .devcontainer/post-create.bash
================================================
#!/bin/bash
set -e
# Run any additional setup scripts included in the shared/devcontainer directory. This is to allow for per developer or
# per-environment customizations. These scripts are not checked into source control.
if [ -x "../shared/devcontainer/install" ]; then
../shared/devcontainer/install
fi
# Create a symlink to the shared .scratch directory for temporary files if it exists.
if [ -x "../shared/.scratch" ]; then
if [ ! -e .scratch ] && [ ! -L .scratch ]; then
ln -s ../shared/.scratch
fi
fi
================================================
FILE: .github/FUNDING.yml
================================================
github: jackc
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
If possible, please provide runnable example such as:
```go
package main
import (
"context"
"log"
"os"
"github.com/jackc/pgx/v5"
)
func main() {
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer conn.Close(context.Background())
// Your code here...
}
```
Please run your example with the race detector enabled. For example, `go run -race main.go` or `go test -race`.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Actual behavior**
A clear and concise description of what actually happened.
**Version**
- Go: `$ go version` -> [e.g. go version go1.18.3 darwin/amd64]
- PostgreSQL: `$ psql --no-psqlrc --tuples-only -c 'select version()'` -> [e.g. PostgreSQL 14.4 on x86_64-apple-darwin21.5.0, compiled by Apple clang version 13.1.6 (clang-1316.0.21.2.5), 64-bit]
- pgx: `$ grep 'github.com/jackc/pgx/v[0-9]' go.mod` -> [e.g. v4.16.1]
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/ISSUE_TEMPLATE/other-issues.md
================================================
---
name: Other issues
about: Any issue that is not a bug or a feature request
title: ''
labels: ''
assignees: ''
---
Please describe the issue in detail. If this is a question about how to use pgx please use discussions instead.
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
test:
name: Test
runs-on: ubuntu-22.04
strategy:
matrix:
go-version: ["1.24", "1.25"]
pg-version: [14, 15, 16, 17, 18, cockroachdb]
include:
- pg-version: 14
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
pgx-ssl-password: certpw
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
- pg-version: 15
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
pgx-ssl-password: certpw
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
- pg-version: 16
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
pgx-ssl-password: certpw
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
- pg-version: 17
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
pgx-ssl-password: certpw
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
- pg-version: 18
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
pgx-test-oauth: "true"
pgx-ssl-password: certpw
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
- pg-version: cockroachdb
pgx-test-database: "postgresql://root@127.0.0.1:26257/pgx_test?sslmode=disable&experimental_enable_temp_tables=on"
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v5
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go-version }}
- name: Setup database server for testing
run: ci/setup_test.bash
env:
PGVERSION: ${{ matrix.pg-version }}
# - name: Setup upterm session
# uses: lhotari/action-upterm@v1
# with:
# ## limits ssh access and adds the ssh public key for the user which triggered the workflow
# limit-access-to-actor: true
# env:
# PGX_TEST_DATABASE: ${{ matrix.pgx-test-database }}
# PGX_TEST_UNIX_SOCKET_CONN_STRING: ${{ matrix.pgx-test-unix-socket-conn-string }}
# PGX_TEST_TCP_CONN_STRING: ${{ matrix.pgx-test-tcp-conn-string }}
# PGX_TEST_SCRAM_PASSWORD_CONN_STRING: ${{ matrix.pgx-test-scram-password-conn-string }}
# PGX_TEST_MD5_PASSWORD_CONN_STRING: ${{ matrix.pgx-test-md5-password-conn-string }}
# PGX_TEST_PLAIN_PASSWORD_CONN_STRING: ${{ matrix.pgx-test-plain-password-conn-string }}
# PGX_TEST_TLS_CONN_STRING: ${{ matrix.pgx-test-tls-conn-string }}
# PGX_SSL_PASSWORD: ${{ matrix.pgx-ssl-password }}
# PGX_TEST_TLS_CLIENT_CONN_STRING: ${{ matrix.pgx-test-tls-client-conn-string }}
- name: Check formatting
run: |
gofmt -l -s -w .
git status
git diff --exit-code
- name: Test
# parallel testing is disabled because somehow parallel testing causes Github Actions to kill the runner.
run: go test -parallel=1 -race ./...
env:
PGX_TEST_DATABASE: ${{ matrix.pgx-test-database }}
PGX_TEST_UNIX_SOCKET_CONN_STRING: ${{ matrix.pgx-test-unix-socket-conn-string }}
PGX_TEST_TCP_CONN_STRING: ${{ matrix.pgx-test-tcp-conn-string }}
PGX_TEST_SCRAM_PASSWORD_CONN_STRING: ${{ matrix.pgx-test-scram-password-conn-string }}
PGX_TEST_MD5_PASSWORD_CONN_STRING: ${{ matrix.pgx-test-md5-password-conn-string }}
PGX_TEST_PLAIN_PASSWORD_CONN_STRING: ${{ matrix.pgx-test-plain-password-conn-string }}
PGX_TEST_OAUTH: ${{ matrix.pgx-test-oauth }}
# TestConnectTLS fails. However, it succeeds if I connect to the CI server with upterm and run it. Give up on that test for now.
# PGX_TEST_TLS_CONN_STRING: ${{ matrix.pgx-test-tls-conn-string }}
# PGX_TEST_SCRAM_PLUS_CONN_STRING: ${{ matrix.pgx-test-scram-plus-conn-string }}
PGX_SSL_PASSWORD: ${{ matrix.pgx-ssl-password }}
PGX_TEST_TLS_CLIENT_CONN_STRING: ${{ matrix.pgx-test-tls-client-conn-string }}
test-windows:
name: Test Windows
runs-on: windows-latest
strategy:
matrix:
go-version: ["1.24", "1.25"]
steps:
- name: Setup PostgreSQL
id: postgres
uses: ikalnytskyi/action-setup-postgres@v4
with:
database: pgx_test
- name: Check out code into the Go module directory
uses: actions/checkout@v5
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go-version }}
- name: Initialize test database
run: |
psql -f testsetup/postgresql_setup.sql pgx_test
env:
PGSERVICE: ${{ steps.postgres.outputs.service-name }}
shell: bash
- name: Test
# Parallel testing is disabled because somehow parallel testing causes Github Actions to kill the runner.
# Disabling CGO because that is not working on the Windows runner. Apparently, we could install MingW and set up
# CGO to work, but disabling CGO takes less CI time. Without CGO, we also must not use the race detector.
run: go test -parallel=1 ./...
env:
CGO_ENABLED: 0
PGX_TEST_DATABASE: ${{ steps.postgres.outputs.connection-uri }}
================================================
FILE: .gitignore
================================================
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
.envrc
/.testdb
.DS_Store
================================================
FILE: .golangci.yml
================================================
# See for configurations: https://golangci-lint.run/usage/configuration/
version: "2"
linters:
default: none
enable:
- govet
- ineffassign
# See: https://golangci-lint.run/usage/formatters/
formatters:
enable:
- gofmt # https://pkg.go.dev/cmd/gofmt
- gofumpt # https://github.com/mvdan/gofumpt
settings:
gofmt:
simplify: true # Simplify code: gofmt with `-s` option.
gofumpt:
# Module path which contains the source code being formatted.
# Default: ""
module-path: github.com/jackc/pgx/v5 # Should match with module in go.mod
# Choose whether to use the extra rules.
# Default: false
extra-rules: true
================================================
FILE: CHANGELOG.md
================================================
# 5.8.0 (December 26, 2025)
* Require Go 1.24+
* Remove golang.org/x/crypto dependency
* Add OptionShouldPing to control ResetSession ping behavior (ilyam8)
* Fix: Avoid overflow when MaxConns is set to MaxInt32
* Fix: Close batch pipeline after a query error (Anthonin Bonnefoy)
* Faster shutdown of pgxpool.Pool background goroutines (Blake Gentry)
* Add pgxpool ping timeout (Amirsalar Safaei)
* Fix: Rows.FieldDescriptions for empty query
* Scan unknown types into *any as string or []byte based on format code
* Optimize pgtype.Numeric (Philip Dubé)
* Add AfterNetConnect hook to pgconn.Config
* Fix: Handle for preparing statements that fail during the Describe phase
* Fix overflow in numeric scanning (Ilia Demianenko)
* Fix: json/jsonb sql.Scanner source type is []byte
* Migrate from math/rand to math/rand/v2 (Mathias Bogaert)
* Optimize internal iobufpool (Mathias Bogaert)
* Optimize stmtcache invalidation (Mathias Bogaert)
* Fix: missing error case in interval parsing (Maxime Soulé)
* Fix: invalidate statement/description cache in Exec (James Hartig)
* ColumnTypeLength method return the type length for varbit type (DengChan)
* Array and Composite codecs handle typed nils
# 5.7.6 (September 8, 2025)
* Use ParseConfigError in pgx.ParseConfig and pgxpool.ParseConfig (Yurasov Ilia)
* Add PrepareConn hook to pgxpool (Jonathan Hall)
* Reduce allocations in QueryContext (Dominique Lefevre)
* Add MarshalJSON and UnmarshalJSON for pgtype.Uint32 (Panos Koutsovasilis)
* Configure ping behavior on pgxpool with ShouldPing (Christian Kiely)
* zeronull int types implement Int64Valuer and Int64Scanner (Li Zeghong)
* Fix panic when receiving terminate connection message during CopyFrom (Michal Drausowski)
* Fix statement cache not being invalidated on error during batch (Muhammadali Nazarov)
# 5.7.5 (May 17, 2025)
* Support sslnegotiation connection option (divyam234)
* Update golang.org/x/crypto to v0.37.0. This placates security scanners that were unable to see that pgx did not use the behavior affected by https://pkg.go.dev/vuln/GO-2025-3487.
* TraceLog now logs Acquire and Release at the debug level (dave sinclair)
* Add support for PGTZ environment variable
* Add support for PGOPTIONS environment variable
* Unpin memory used by Rows quicker
* Remove PlanScan memoization. This resolves a rare issue where scanning could be broken for one type by first scanning another. The problem was in the memoization system and benchmarking revealed that memoization was not providing any meaningful benefit.
# 5.7.4 (March 24, 2025)
* Fix / revert change to scanning JSON `null` (Felix Röhrich)
# 5.7.3 (March 21, 2025)
* Expose EmptyAcquireWaitTime in pgxpool.Stat (vamshiaruru32)
* Improve SQL sanitizer performance (ninedraft)
* Fix Scan confusion with json(b), sql.Scanner, and automatic dereferencing (moukoublen, felix-roehrich)
* Fix Values() for xml type always returning nil instead of []byte
* Add ability to send Flush message in pipeline mode (zenkovev)
* Fix pgtype.Timestamp's JSON behavior to match PostgreSQL (pconstantinou)
* Better error messages when scanning structs (logicbomb)
* Fix handling of error on batch write (bonnefoa)
* Match libpq's connection fallback behavior more closely (felix-roehrich)
* Add MinIdleConns to pgxpool (djahandarie)
# 5.7.2 (December 21, 2024)
* Fix prepared statement already exists on batch prepare failure
* Add commit query to tx options (Lucas Hild)
* Fix pgtype.Timestamp json unmarshal (Shean de Montigny-Desautels)
* Add message body size limits in frontend and backend (zene)
* Add xid8 type
* Ensure planning encodes and scans cannot infinitely recurse
* Implement pgtype.UUID.String() (Konstantin Grachev)
* Switch from ExecParams to Exec in ValidateConnectTargetSessionAttrs functions (Alexander Rumyantsev)
* Update golang.org/x/crypto
* Fix json(b) columns prefer sql.Scanner interface like database/sql (Ludovico Russo)
# 5.7.1 (September 10, 2024)
* Fix data race in tracelog.TraceLog
* Update puddle to v2.2.2. This removes the import of nanotime via linkname.
* Update golang.org/x/crypto and golang.org/x/text
# 5.7.0 (September 7, 2024)
* Add support for sslrootcert=system (Yann Soubeyrand)
* Add LoadTypes to load multiple types in a single SQL query (Nick Farrell)
* Add XMLCodec supports encoding + scanning XML column type like json (nickcruess-soda)
* Add MultiTrace (Stepan Rabotkin)
* Add TraceLogConfig with customizable TimeKey (stringintech)
* pgx.ErrNoRows wraps sql.ErrNoRows to aid in database/sql compatibility with native pgx functions (merlin)
* Support scanning binary formatted uint32 into string / TextScanner (jennifersp)
* Fix interval encoding to allow 0s and avoid extra spaces (Carlos Pérez-Aradros Herce)
* Update pgservicefile - fixes panic when parsing invalid file
* Better error message when reading past end of batch
* Don't print url when url.Parse returns an error (Kevin Biju)
* Fix snake case name normalization collision in RowToStructByName with db tag (nolandseigler)
* Fix: Scan and encode types with underlying types of arrays
# 5.6.0 (May 25, 2024)
* Add StrictNamedArgs (Tomas Zahradnicek)
* Add support for macaddr8 type (Carlos Pérez-Aradros Herce)
* Add SeverityUnlocalized field to PgError / Notice
* Performance optimization of RowToStructByPos/Name (Zach Olstein)
* Allow customizing context canceled behavior for pgconn
* Add ScanLocation to pgtype.Timestamp[tz]Codec
* Add custom data to pgconn.PgConn
* Fix ResultReader.Read() to handle nil values
* Do not encode interval microseconds when they are 0 (Carlos Pérez-Aradros Herce)
* pgconn.SafeToRetry checks for wrapped errors (tjasko)
* Failed connection attempts include all errors
* Optimize LargeObject.Read (Mitar)
* Add tracing for connection acquire and release from pool (ngavinsir)
* Fix encode driver.Valuer not called when nil
* Add support for custom JSON marshal and unmarshal (Mitar)
* Use Go default keepalive for TCP connections (Hans-Joachim Kliemeck)
# 5.5.5 (March 9, 2024)
Use spaces instead of parentheses for SQL sanitization.
This still solves the problem of negative numbers creating a line comment, but this avoids breaking edge cases such as
`set foo to $1` where the substitution is taking place in a location where an arbitrary expression is not allowed.
# 5.5.4 (March 4, 2024)
Fix CVE-2024-27304
SQL injection can occur if an attacker can cause a single query or bind message to exceed 4 GB in size. An integer
overflow in the calculated message size can cause the one large message to be sent as multiple messages under the
attacker's control.
Thanks to Paul Gerste for reporting this issue.
* Fix behavior of CollectRows to return empty slice if Rows are empty (Felix)
* Fix simple protocol encoding of json.RawMessage
* Fix *Pipeline.getResults should close pipeline on error
* Fix panic in TryFindUnderlyingTypeScanPlan (David Kurman)
* Fix deallocation of invalidated cached statements in a transaction
* Handle invalid sslkey file
* Fix scan float4 into sql.Scanner
* Fix pgtype.Bits not making copy of data from read buffer. This would cause the data to be corrupted by future reads.
# 5.5.3 (February 3, 2024)
* Fix: prepared statement already exists
* Improve CopyFrom auto-conversion of text-ish values
* Add ltree type support (Florent Viel)
* Make some properties of Batch and QueuedQuery public (Pavlo Golub)
* Add AppendRows function (Edoardo Spadolini)
* Optimize convert UUID [16]byte to string (Kirill Malikov)
* Fix: LargeObject Read and Write of more than ~1GB at a time (Mitar)
# 5.5.2 (January 13, 2024)
* Allow NamedArgs to start with underscore
* pgproto3: Maximum message body length support (jeremy.spriet)
* Upgrade golang.org/x/crypto to v0.17.0
* Add snake_case support to RowToStructByName (Tikhon Fedulov)
* Fix: update description cache after exec prepare (James Hartig)
* Fix: pipeline checks if it is closed (James Hartig and Ryan Fowler)
* Fix: normalize timeout / context errors during TLS startup (Samuel Stauffer)
* Add OnPgError for easier centralized error handling (James Hartig)
# 5.5.1 (December 9, 2023)
* Add CopyFromFunc helper function. (robford)
* Add PgConn.Deallocate method that uses PostgreSQL protocol Close message.
* pgx uses new PgConn.Deallocate method. This allows deallocating statements to work in a failed transaction. This fixes a case where the prepared statement map could become invalid.
* Fix: Prefer driver.Valuer over json.Marshaler for json fields. (Jacopo)
* Fix: simple protocol SQL sanitizer previously panicked if an invalid $0 placeholder was used. This now returns an error instead. (maksymnevajdev)
* Add pgtype.Numeric.ScanScientific (Eshton Robateau)
# 5.5.0 (November 4, 2023)
* Add CollectExactlyOneRow. (Julien GOTTELAND)
* Add OpenDBFromPool to create *database/sql.DB from *pgxpool.Pool. (Lev Zakharov)
* Prepare can automatically choose statement name based on sql. This makes it easier to explicitly manage prepared statements.
* Statement cache now uses deterministic, stable statement names.
* database/sql prepared statement names are deterministically generated.
* Fix: SendBatch wasn't respecting context cancellation.
* Fix: Timeout error from pipeline is now normalized.
* Fix: database/sql encoding json.RawMessage to []byte.
* CancelRequest: Wait for the cancel request to be acknowledged by the server. This should improve PgBouncer compatibility. (Anton Levakin)
* stdlib: Use Ping instead of CheckConn in ResetSession
* Add json.Marshaler and json.Unmarshaler for Float4, Float8 (Kirill Mironov)
# 5.4.3 (August 5, 2023)
* Fix: QCharArrayOID was defined with the wrong OID (Christoph Engelbert)
* Fix: connect_timeout for sslmode=allow|prefer (smaher-edb)
* Fix: pgxpool: background health check cannot overflow pool
* Fix: Check for nil in defer when sending batch (recover properly from panic)
* Fix: json scan of non-string pointer to pointer
* Fix: zeronull.Timestamptz should use pgtype.Timestamptz
* Fix: NewConnsCount was not correctly counting connections created by Acquire directly. (James Hartig)
* RowTo(AddrOf)StructByPos ignores fields with "-" db tag
* Optimization: improve text format numeric parsing (horpto)
# 5.4.2 (July 11, 2023)
* Fix: RowScanner errors are fatal to Rows
* Fix: Enable failover efforts when pg_hba.conf disallows non-ssl connections (Brandon Kauffman)
* Hstore text codec internal improvements (Evan Jones)
* Fix: Stop timers for background reader when not in use. Fixes memory leak when closing connections (Adrian-Stefan Mares)
* Fix: Stop background reader as soon as possible.
* Add PgConn.SyncConn(). This combined with the above fix makes it safe to directly use the underlying net.Conn.
# 5.4.1 (June 18, 2023)
* Fix: concurrency bug with pgtypeDefaultMap and simple protocol (Lev Zakharov)
* Add TxOptions.BeginQuery to allow overriding the default BEGIN query
# 5.4.0 (June 14, 2023)
* Replace platform specific syscalls for non-blocking IO with more traditional goroutines and deadlines. This returns to the v4 approach with some additional improvements and fixes. This restores the ability to use a pgx.Conn over an ssh.Conn as well as other non-TCP or Unix socket connections. In addition, it is a significantly simpler implementation that is less likely to have cross platform issues.
* Optimization: The default type registrations are now shared among all connections. This saves about 100KB of memory per connection. `pgtype.Type` and `pgtype.Codec` values are now required to be immutable after registration. This was already necessary in most cases but wasn't documented until now. (Lev Zakharov)
* Fix: Ensure pgxpool.Pool.QueryRow.Scan releases connection on panic
* CancelRequest: don't try to read the reply (Nicola Murino)
* Fix: correctly handle bool type aliases (Wichert Akkerman)
* Fix: pgconn.CancelRequest: Fix unix sockets: don't use RemoteAddr()
* Fix: pgx.Conn memory leak with prepared statement caching (Evan Jones)
* Add BeforeClose to pgxpool.Pool (Evan Cordell)
* Fix: various hstore fixes and optimizations (Evan Jones)
* Fix: RowToStructByPos with embedded unexported struct
* Support different bool string representations (Lev Zakharov)
* Fix: error when using BatchResults.Exec on a select that returns an error after some rows.
* Fix: pipelineBatchResults.Exec() not returning error from ResultReader
* Fix: pipeline batch results not closing pipeline when error occurs while reading directly from results instead of using
a callback.
* Fix: scanning a table type into a struct
* Fix: scan array of record to pointer to slice of struct
* Fix: handle null for json (Cemre Mengu)
* Batch Query callback is called even when there is an error
* Add RowTo(AddrOf)StructByNameLax (Audi P. Risa P)
# 5.3.1 (February 27, 2023)
* Fix: Support v4 and v5 stdlib in same program (Tomáš Procházka)
* Fix: sql.Scanner not being used in certain cases
* Add text format jsonpath support
* Fix: fake non-blocking read adaptive wait time
# 5.3.0 (February 11, 2023)
* Fix: json values work with sql.Scanner
* Fixed / improved error messages (Mark Chambers and Yevgeny Pats)
* Fix: support scan into single dimensional arrays
* Fix: MaxConnLifetimeJitter setting actually jitter (Ben Weintraub)
* Fix: driver.Value representation of bytea should be []byte not string
* Fix: better handling of unregistered OIDs
* CopyFrom can use query cache to avoid extra round trip to get OIDs (Alejandro Do Nascimento Mora)
* Fix: encode to json ignoring driver.Valuer
* Support sql.Scanner on renamed base type
* Fix: pgtype.Numeric text encoding of negative numbers (Mark Chambers)
* Fix: connect with multiple hostnames when one can't be resolved
* Upgrade puddle to remove dependency on uber/atomic and fix alignment issue on 32-bit platform
* Fix: scanning json column into **string
* Multiple reductions in memory allocations
* Fake non-blocking read adapts its max wait time
* Improve CopyFrom performance and reduce memory usage
* Fix: encode []any to array
* Fix: LoadType for composite with dropped attributes (Felix Röhrich)
* Support v4 and v5 stdlib in same program
* Fix: text format array decoding with string of "NULL"
* Prefer binary format for arrays
# 5.2.0 (December 5, 2022)
* `tracelog.TraceLog` implements the pgx.PrepareTracer interface. (Vitalii Solodilov)
* Optimize creating begin transaction SQL string (Petr Evdokimov and ksco)
* `Conn.LoadType` supports range and multirange types (Vitalii Solodilov)
* Fix scan `uint` and `uint64` `ScanNumeric`. This resolves a PostgreSQL `numeric` being incorrectly scanned into `uint` and `uint64`.
# 5.1.1 (November 17, 2022)
* Fix simple query sanitizer where query text contains a Unicode replacement character.
* Remove erroneous `name` argument from `DeallocateAll()`. Technically, this is a breaking change, but given that method was only added 5 days ago this change was accepted. (Bodo Kaiser)
# 5.1.0 (November 12, 2022)
* Update puddle to v2.1.2. This resolves a race condition and a deadlock in pgxpool.
* `QueryRewriter.RewriteQuery` now returns an error. Technically, this is a breaking change for any external implementers, but given the minimal likelihood that there are actually any external implementers this change was accepted.
* Expose `GetSSLPassword` support to pgx.
* Fix encode `ErrorResponse` unknown field handling. This would only affect pgproto3 being used directly as a proxy with a non-PostgreSQL server that included additional error fields.
* Fix date text format encoding with 5 digit years.
* Fix date values passed to a `sql.Scanner` as `string` instead of `time.Time`.
* DateCodec.DecodeValue can return `pgtype.InfinityModifier` instead of `string` for infinite values. This now matches the behavior of the timestamp types.
* Add domain type support to `Conn.LoadType()`.
* Add `RowToStructByName` and `RowToAddrOfStructByName`. (Pavlo Golub)
* Add `Conn.DeallocateAll()` to clear all prepared statements including the statement cache. (Bodo Kaiser)
# 5.0.4 (October 24, 2022)
* Fix: CollectOneRow prefers PostgreSQL error over pgx.ErrorNoRows
* Fix: some reflect Kind checks to first check for nil
* Bump golang.org/x/text dependency to placate snyk
* Fix: RowToStructByPos on structs with multiple anonymous sub-structs (Baptiste Fontaine)
* Fix: Exec checks if tx is closed
# 5.0.3 (October 14, 2022)
* Fix `driver.Valuer` handling edge cases that could cause infinite loop or crash
# v5.0.2 (October 8, 2022)
* Fix date encoding in text format to always use 2 digits for month and day
* Prefer driver.Valuer over wrap plans when encoding
* Fix scan to pointer to pointer to renamed type
* Allow scanning NULL even if PG and Go types are incompatible
# v5.0.1 (September 24, 2022)
* Fix 32-bit atomic usage
* Add MarshalJSON for Float8 (yogipristiawan)
* Add `[` and `]` to text encoding of `Lseg`
* Fix sqlScannerWrapper NULL handling
# v5.0.0 (September 17, 2022)
## Merged Packages
`github.com/jackc/pgtype`, `github.com/jackc/pgconn`, and `github.com/jackc/pgproto3` are now included in the main
`github.com/jackc/pgx` repository. Previously there was confusion as to where issues should be reported, additional
release work due to releasing multiple packages, and less clear changelogs.
## pgconn
`CommandTag` is now an opaque type instead of directly exposing an underlying `[]byte`.
The return value `ResultReader.Values()` is no longer safe to retain a reference to after a subsequent call to `NextRow()` or `Close()`.
`Trace()` method adds low level message tracing similar to the `PQtrace` function in `libpq`.
pgconn now uses non-blocking IO. This is a significant internal restructuring, but it should not cause any visible changes on its own. However, it is important in implementing other new features.
`CheckConn()` checks a connection's liveness by doing a non-blocking read. This can be used to detect database restarts or network interruptions without executing a query or a ping.
pgconn now supports pipeline mode.
`*PgConn.ReceiveResults` removed. Use pipeline mode instead.
`Timeout()` no longer considers `context.Canceled` as a timeout error. `context.DeadlineExceeded` still is considered a timeout error.
## pgxpool
`Connect` and `ConnectConfig` have been renamed to `New` and `NewWithConfig` respectively. The `LazyConnect` option has been removed. Pools always lazily connect.
## pgtype
The `pgtype` package has been significantly changed.
### NULL Representation
Previously, types had a `Status` field that could be `Undefined`, `Null`, or `Present`. This has been changed to a
`Valid` `bool` field to harmonize with how `database/sql` represents `NULL` and to make the zero value useable.
Previously, a type that implemented `driver.Valuer` would have the `Value` method called even on a nil pointer. All nils
whether typed or untyped now represent `NULL`.
### Codec and Value Split
Previously, the type system combined decoding and encoding values with the value types. e.g. Type `Int8` both handled
encoding and decoding the PostgreSQL representation and acted as a value object. This caused some difficulties when
there was not an exact 1 to 1 relationship between the Go types and the PostgreSQL types For example, scanning a
PostgreSQL binary `numeric` into a Go `float64` was awkward (see https://github.com/jackc/pgtype/issues/147). This
concepts have been separated. A `Codec` only has responsibility for encoding and decoding values. Value types are
generally defined by implementing an interface that a particular `Codec` understands (e.g. `PointScanner` and
`PointValuer` for the PostgreSQL `point` type).
### Array Types
All array types are now handled by `ArrayCodec` instead of using code generation for each new array type. This also
means that less common array types such as `point[]` are now supported. `Array[T]` supports PostgreSQL multi-dimensional
arrays.
### Composite Types
Composite types must be registered before use. `CompositeFields` may still be used to construct and destruct composite
values, but any type may now implement `CompositeIndexGetter` and `CompositeIndexScanner` to be used as a composite.
### Range Types
Range types are now handled with types `RangeCodec` and `Range[T]`. This allows additional user defined range types to
easily be handled. Multirange types are handled similarly with `MultirangeCodec` and `Multirange[T]`.
### pgxtype
`LoadDataType` moved to `*Conn` as `LoadType`.
### Bytea
The `Bytea` and `GenericBinary` types have been replaced. Use the following instead:
* `[]byte` - For normal usage directly use `[]byte`.
* `DriverBytes` - Uses driver memory only available until next database method call. Avoids a copy and an allocation.
* `PreallocBytes` - Uses preallocated byte slice to avoid an allocation.
* `UndecodedBytes` - Avoids any decoding. Allows working with raw bytes.
### Dropped lib/pq Support
`pgtype` previously supported and was tested against [lib/pq](https://github.com/lib/pq). While it will continue to work
in most cases this is no longer supported.
### database/sql Scan
Previously, most `Scan` implementations would convert `[]byte` to `string` automatically to decode a text value. Now
only `string` is handled. This is to allow the possibility of future binary support in `database/sql` mode by
considering `[]byte` to be binary format and `string` text format. This change should have no effect for any use with
`pgx`. The previous behavior was only necessary for `lib/pq` compatibility.
Added `*Map.SQLScanner` to create a `sql.Scanner` for types such as `[]int32` and `Range[T]` that do not implement
`sql.Scanner` directly.
### Number Type Fields Include Bit size
`Int2`, `Int4`, `Int8`, `Float4`, `Float8`, and `Uint32` fields now include bit size. e.g. `Int` is renamed to `Int64`.
This matches the convention set by `database/sql`. In addition, for comparable types like `pgtype.Int8` and
`sql.NullInt64` the structures are identical. This means they can be directly converted one to another.
### 3rd Party Type Integrations
* Extracted integrations with https://github.com/shopspring/decimal and https://github.com/gofrs/uuid to
https://github.com/jackc/pgx-shopspring-decimal and https://github.com/jackc/pgx-gofrs-uuid respectively. This trims
the pgx dependency tree.
### Other Changes
* `Bit` and `Varbit` are both replaced by the `Bits` type.
* `CID`, `OID`, `OIDValue`, and `XID` are replaced by the `Uint32` type.
* `Hstore` is now defined as `map[string]*string`.
* `JSON` and `JSONB` types removed. Use `[]byte` or `string` directly.
* `QChar` type removed. Use `rune` or `byte` directly.
* `Inet` and `Cidr` types removed. Use `netip.Addr` and `netip.Prefix` directly. These types are more memory efficient than the previous `net.IPNet`.
* `Macaddr` type removed. Use `net.HardwareAddr` directly.
* Renamed `pgtype.ConnInfo` to `pgtype.Map`.
* Renamed `pgtype.DataType` to `pgtype.Type`.
* Renamed `pgtype.None` to `pgtype.Finite`.
* `RegisterType` now accepts a `*Type` instead of `Type`.
* Assorted array helper methods and types made private.
## stdlib
* Removed `AcquireConn` and `ReleaseConn` as that functionality has been built in since Go 1.13.
## Reduced Memory Usage by Reusing Read Buffers
Previously, the connection read buffer would allocate large chunks of memory and never reuse them. This allowed
transferring ownership to anything such as scanned values without incurring an additional allocation and memory copy.
However, this came at the cost of overall increased memory allocation size. But worse it was also possible to pin large
chunks of memory by retaining a reference to a small value that originally came directly from the read buffer. Now
ownership remains with the read buffer and anything needing to retain a value must make a copy.
## Query Execution Modes
Control over automatic prepared statement caching and simple protocol use are now combined into query execution mode.
See documentation for `QueryExecMode`.
## QueryRewriter Interface and NamedArgs
pgx now supports named arguments with the `NamedArgs` type. This is implemented via the new `QueryRewriter` interface which
allows arbitrary rewriting of query SQL and arguments.
## RowScanner Interface
The `RowScanner` interface allows a single argument to Rows.Scan to scan the entire row.
## Rows Result Helpers
* `CollectRows` and `RowTo*` functions simplify collecting results into a slice.
* `CollectOneRow` collects one row using `RowTo*` functions.
* `ForEachRow` simplifies scanning each row and executing code using the scanned values. `ForEachRow` replaces `QueryFunc`.
## Tx Helpers
Rather than every type that implemented `Begin` or `BeginTx` methods also needing to implement `BeginFunc` and
`BeginTxFunc` these methods have been converted to functions that take a db that implements `Begin` or `BeginTx`.
## Improved Batch Query Ergonomics
Previously, the code for building a batch went in one place before the call to `SendBatch`, and the code for reading the
results went in one place after the call to `SendBatch`. This could make it difficult to match up the query and the code
to handle the results. Now `Queue` returns a `QueuedQuery` which has methods `Query`, `QueryRow`, and `Exec` which can
be used to register a callback function that will handle the result. Callback functions are called automatically when
`BatchResults.Close` is called.
## SendBatch Uses Pipeline Mode When Appropriate
Previously, a batch with 10 unique parameterized statements executed 100 times would entail 11 network round trips. 1
for each prepare / describe and 1 for executing them all. Now pipeline mode is used to prepare / describe all statements
in a single network round trip. So it would only take 2 round trips.
## Tracing and Logging
Internal logging support has been replaced with tracing hooks. This allows custom tracing integration with tools like OpenTelemetry. Package tracelog provides an adapter for pgx v4 loggers to act as a tracer.
All integrations with 3rd party loggers have been extracted to separate repositories. This trims the pgx dependency
tree.
================================================
FILE: CLAUDE.md
================================================
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
pgx is a PostgreSQL driver and toolkit for Go (`github.com/jackc/pgx/v5`). It provides both a native PostgreSQL interface and a `database/sql` compatible driver. Requires Go 1.24+ and supports PostgreSQL 14+ and CockroachDB.
## Build & Test Commands
```bash
# Run all tests (requires PGX_TEST_DATABASE to be set)
go test ./...
# Run a specific test
go test -run TestFunctionName ./...
# Run tests for a specific package
go test ./pgconn/...
# Run tests with race detector
go test -race ./...
# DevContainer: run tests against specific PostgreSQL versions
./test.sh pg18 # Default: PostgreSQL 18
./test.sh pg16 -run TestConnect # Specific test against PG16
./test.sh crdb # CockroachDB
./test.sh all # All targets (pg14-18 + crdb)
# Format (always run after making changes)
goimports -w .
# Lint
golangci-lint run ./...
```
## Test Database Setup
Tests require `PGX_TEST_DATABASE` environment variable. In the devcontainer, `test.sh` handles this. For local development:
```bash
export PGX_TEST_DATABASE="host=localhost user=postgres password=postgres dbname=pgx_test"
```
The test database needs extensions: `hstore`, `ltree`, and a `uint64` domain. See `testsetup/postgresql_setup.sql` for full setup. Many tests are skipped unless additional `PGX_TEST_*` env vars are set (for TLS, SCRAM, MD5, unix socket, PgBouncer testing).
## Architecture
The codebase is a layered architecture, bottom-up:
- **pgproto3/** — PostgreSQL wire protocol v3 encoder/decoder. Defines `FrontendMessage` and `BackendMessage` types for every protocol message.
- **pgconn/** — Low-level connection layer (roughly libpq-equivalent). Handles authentication, TLS, query execution, COPY protocol, and notifications. `PgConn` is the core type.
- **pgx** (root package) — High-level query interface built on `pgconn`. Provides `Conn`, `Rows`, `Tx`, `Batch`, `CopyFrom`, and generic helpers like `CollectRows`/`ForEachRow`. Includes automatic statement caching (LRU).
- **pgtype/** — Type system mapping between Go and PostgreSQL types (70+ types). Key interfaces: `Codec`, `Type`, `TypeMap`. Custom types (enums, composites, domains) are registered through `TypeMap`.
- **pgxpool/** — Concurrency-safe connection pool built on `puddle/v2`. `Pool` is the main type; wraps `pgx.Conn`.
- **stdlib/** — `database/sql` compatibility adapter.
Supporting packages:
- **internal/stmtcache/** — Prepared statement cache with LRU eviction
- **internal/sanitize/** — SQL query sanitization
- **tracelog/** — Logging adapter that implements tracer interfaces
- **multitracer/** — Composes multiple tracers into one
- **pgxtest/** — Test helpers for running tests across connection types
## Key Design Conventions
- **Semantic versioning** — strictly followed. Do not break the public API (no removing or renaming exported types, functions, methods, or fields; no changing function signatures).
- **Minimal dependencies** — adding new dependencies is strongly discouraged (see CONTRIBUTING.md).
- **Context-based** — all blocking operations take `context.Context`.
- **Tracer interfaces** — observability via `QueryTracer`, `BatchTracer`, `CopyFromTracer`, `PrepareTracer` on `ConnConfig.Tracer`.
- **Formatting** — always run `goimports -w .` after making changes to ensure code is properly formatted. CI checks formatting via `gofmt -l -s -w . && git diff --exit-code`. `gofumpt` with extra rules is also enforced via `golangci-lint`.
- **Linters** — `govet` and `ineffassign` only (configured in `.golangci.yml`).
- **CI matrix** — tests run against Go 1.24/1.25 × PostgreSQL 14-18 + CockroachDB, on Linux and Windows. Race detector enabled on Linux only.
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
## Discuss Significant Changes
Before you invest a significant amount of time on a change, please create a discussion or issue describing your
proposal. This will help to ensure your proposed change has a reasonable chance of being merged.
## Avoid Dependencies
Adding a dependency is a big deal. While on occasion a new dependency may be accepted, the default answer to any change
that adds a dependency is no.
## AI
Using AI is acceptable (not that it can really be stopped) under one the following conditions.
* AI was used, but you deeply understand the code and you can answer questions regarding your change. You are not going
to answer questions with "I don't know", AI did it. You are not going to "answer" questions by relaying them to your
agent. This is wasteful of the code reviewer's time.
* AI was used to solve a problem without your deep understanding. This can still be a good starting point for a fix or
feature. But you need to clearly state that this is an AI proposal. You should include additional information such as
the AI used and what prompts were used. You should also be aware that large, complicated, or subtle changes may be
rejected simply because the reviewer is not confident in a change that no human understands.
## Development Environment Setup
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 key-value pairs. In addition,
the standard `PG*` environment variables will be respected. Consider using [direnv](https://github.com/direnv/direnv) to
simplify environment variable handling.
### Devcontainer
The easiest way to start development is with the included devcontainer. It includes containers for each supported
PostgreSQL version as well as CockroachDB. `./test.sh all` will run the tests against all database types.
### Using an Existing PostgreSQL Cluster Outside of a Devcontainer
If you already have a PostgreSQL development server this is the quickest way to start and run the majority of the pgx
test suite. Some tests will be skipped that require server configuration changes (e.g. those testing different
authentication methods).
Create and setup a test database:
```
export PGDATABASE=pgx_test
createdb
psql -c 'create extension hstore;'
psql -c 'create extension ltree;'
psql -c 'create domain uint64 as numeric(20,0);'
```
Ensure a `postgres` user exists. This happens by default in normal PostgreSQL installs, but some installation methods
such as Homebrew do not.
```
createuser -s postgres
```
Ensure your `PGX_TEST_DATABASE` environment variable points to the database you just created and run the tests.
```
export PGX_TEST_DATABASE="host=/private/tmp database=pgx_test"
go test ./...
```
This will run the vast majority of the tests, but some tests will be skipped (e.g. those testing different connection methods).
### Creating a New PostgreSQL Cluster Exclusively for Testing Outside of a Devcontainer
The following environment variables need to be set both for initial setup and whenever the tests are run. (direnv is
highly recommended). Depending on your platform, you may need to change the host for `PGX_TEST_UNIX_SOCKET_CONN_STRING`.
```
export PGPORT=5015
export PGUSER=postgres
export PGDATABASE=pgx_test
export POSTGRESQL_DATA_DIR=postgresql
export PGX_TEST_DATABASE="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret"
export PGX_TEST_UNIX_SOCKET_CONN_STRING="host=/private/tmp database=pgx_test"
export PGX_TEST_TCP_CONN_STRING="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret"
export PGX_TEST_SCRAM_PASSWORD_CONN_STRING="host=127.0.0.1 user=pgx_scram password=secret database=pgx_test channel_binding=disable"
export PGX_TEST_SCRAM_PLUS_CONN_STRING="host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem database=pgx_test channel_binding=require"
export PGX_TEST_MD5_PASSWORD_CONN_STRING="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret"
export PGX_TEST_PLAIN_PASSWORD_CONN_STRING="host=127.0.0.1 user=pgx_pw password=secret"
export PGX_TEST_TLS_CONN_STRING="host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem channel_binding=disable"
export PGX_SSL_PASSWORD=certpw
export PGX_TEST_TLS_CLIENT_CONN_STRING="host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem database=pgx_test sslcert=`pwd`/.testdb/pgx_sslcert.crt sslkey=`pwd`/.testdb/pgx_sslcert.key"
```
Create a new database cluster.
```
initdb --locale=en_US -E UTF-8 --username=postgres .testdb/$POSTGRESQL_DATA_DIR
echo "listen_addresses = '127.0.0.1'" >> .testdb/$POSTGRESQL_DATA_DIR/postgresql.conf
echo "port = $PGPORT" >> .testdb/$POSTGRESQL_DATA_DIR/postgresql.conf
cat testsetup/postgresql_ssl.conf >> .testdb/$POSTGRESQL_DATA_DIR/postgresql.conf
cp testsetup/pg_hba.conf .testdb/$POSTGRESQL_DATA_DIR/pg_hba.conf
cd .testdb
# Generate CA, server, and encrypted client certificates.
go run ../testsetup/generate_certs.go
# Copy certificates to server directory and set permissions.
cp ca.pem $POSTGRESQL_DATA_DIR/root.crt
cp localhost.key $POSTGRESQL_DATA_DIR/server.key
chmod 600 $POSTGRESQL_DATA_DIR/server.key
cp localhost.crt $POSTGRESQL_DATA_DIR/server.crt
cd ..
```
Start the new cluster. This will be necessary whenever you are running pgx tests.
```
postgres -D .testdb/$POSTGRESQL_DATA_DIR
```
Setup the test database in the new cluster.
```
createdb
psql --no-psqlrc -f testsetup/postgresql_setup.sql
```
### PgBouncer
There are tests specific for PgBouncer that will be executed if `PGX_TEST_PGBOUNCER_CONN_STRING` is set.
### Optional Tests
pgx supports multiple connection types and means of authentication. These tests are optional. They will only run if the
appropriate environment variables are set. In addition, there may be tests specific to particular PostgreSQL versions,
non-PostgreSQL servers (e.g. CockroachDB), or connection poolers (e.g. PgBouncer). `go test ./... -v | grep SKIP` to see
if any tests are being skipped.
================================================
FILE: LICENSE
================================================
Copyright (c) 2013-2021 Jack Christensen
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
[](https://pkg.go.dev/github.com/jackc/pgx/v5)
[](https://github.com/jackc/pgx/actions/workflows/ci.yml)
# pgx - PostgreSQL Driver and Toolkit
pgx is a pure Go driver and toolkit for PostgreSQL.
The pgx driver is a low-level, high performance interface that exposes PostgreSQL-specific features such as `LISTEN` /
`NOTIFY` and `COPY`. It also includes an adapter for the standard `database/sql` interface.
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
```go
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](https://github.com/jackc/pgx/wiki/Getting-started-with-pgx) for more information.
## Features
* 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
* Tracing and 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` and `cidr` PostgreSQL types to `netip.Addr` and `netip.Prefix`
* Large object support
* NULL mapping to pointer to pointer
* Supports `database/sql.Scanner` and `database/sql/driver.Valuer` interfaces for custom types
* Notice response handling
* Simulated nested transactions with savepoints
## Choosing Between the pgx and database/sql Interfaces
The pgx interface is faster. Many PostgreSQL specific features such as `LISTEN` / `NOTIFY` and `COPY` are not available
through the `database/sql` interface.
The pgx interface is recommended when:
1. The application only targets PostgreSQL.
2. No other libraries that require `database/sql` are in use.
It is also possible to use the `database/sql` interface and convert a connection to the lower-level pgx interface as needed.
## Testing
See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions.
## Architecture
See the presentation at Golang Estonia, [PGX Top to Bottom](https://www.youtube.com/watch?v=sXMSWhcHCf8) for a description of pgx architecture.
## Supported Go and PostgreSQL Versions
pgx supports the same versions of Go and PostgreSQL that are supported by their respective teams. For [Go](https://golang.org/doc/devel/release.html#policy) that is the two most recent major releases and for [PostgreSQL](https://www.postgresql.org/support/versioning/) the major releases in the last 5 years. This means pgx supports Go 1.24 and higher and PostgreSQL 14 and higher. pgx also is tested against the latest version of [CockroachDB](https://www.cockroachlabs.com/product/).
## Version Policy
pgx follows semantic versioning for the documented public API on stable releases. `v5` is the latest stable major version.
## PGX Family Libraries
### [github.com/jackc/pglogrepl](https://github.com/jackc/pglogrepl)
pglogrepl provides functionality to act as a client for PostgreSQL logical replication.
### [github.com/jackc/pgmock](https://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](https://github.com/jackc/tern)
tern is a stand-alone SQL migration system.
### [github.com/jackc/pgerrcode](https://github.com/jackc/pgerrcode)
pgerrcode contains constants for the PostgreSQL error codes.
## Adapters for 3rd Party Types
* [github.com/jackc/pgx-gofrs-uuid](https://github.com/jackc/pgx-gofrs-uuid)
* [github.com/jackc/pgx-shopspring-decimal](https://github.com/jackc/pgx-shopspring-decimal)
* [github.com/ColeBurch/pgx-govalues-decimal](https://github.com/ColeBurch/pgx-govalues-decimal)
* [github.com/twpayne/pgx-geos](https://github.com/twpayne/pgx-geos) ([PostGIS](https://postgis.net/) and [GEOS](https://libgeos.org/) via [go-geos](https://github.com/twpayne/go-geos))
* [github.com/vgarvardt/pgx-google-uuid](https://github.com/vgarvardt/pgx-google-uuid)
## Adapters for 3rd Party Tracers
* [github.com/jackhopner/pgx-xray-tracer](https://github.com/jackhopner/pgx-xray-tracer)
* [github.com/exaring/otelpgx](https://github.com/exaring/otelpgx)
## Adapters for 3rd Party Loggers
These adapters can be used with the tracelog package.
* [github.com/jackc/pgx-go-kit-log](https://github.com/jackc/pgx-go-kit-log)
* [github.com/jackc/pgx-log15](https://github.com/jackc/pgx-log15)
* [github.com/jackc/pgx-logrus](https://github.com/jackc/pgx-logrus)
* [github.com/jackc/pgx-zap](https://github.com/jackc/pgx-zap)
* [github.com/jackc/pgx-zerolog](https://github.com/jackc/pgx-zerolog)
* [github.com/mcosta74/pgx-slog](https://github.com/mcosta74/pgx-slog)
* [github.com/kataras/pgx-golog](https://github.com/kataras/pgx-golog)
## 3rd Party Libraries with PGX Support
### [github.com/pashagolub/pgxmock](https://github.com/pashagolub/pgxmock)
pgxmock is a mock library implementing pgx interfaces.
pgxmock has one and only purpose - to simulate pgx behavior in tests, without needing a real database connection.
### [github.com/georgysavva/scany](https://github.com/georgysavva/scany)
Library for scanning data from a database into Go structs and more.
### [github.com/vingarcia/ksql](https://github.com/vingarcia/ksql)
A carefully designed SQL client for making using SQL easier,
more productive, and less error-prone on Golang.
### [github.com/otan/gopgkrb5](https://github.com/otan/gopgkrb5)
Adds GSSAPI / Kerberos authentication support.
### [github.com/wcamarao/pmx](https://github.com/wcamarao/pmx)
Explicit data mapping and scanning library for Go structs and slices.
### [github.com/stephenafamo/scan](https://github.com/stephenafamo/scan)
Type safe and flexible package for scanning database data into Go types.
Supports, structs, maps, slices and custom mapping functions.
### [github.com/z0ne-dev/mgx](https://github.com/z0ne-dev/mgx)
Code first migration library for native pgx (no database/sql abstraction).
### [github.com/amirsalarsafaei/sqlc-pgx-monitoring](https://github.com/amirsalarsafaei/sqlc-pgx-monitoring)
A database monitoring/metrics library for pgx and sqlc. Trace, log and monitor your sqlc query performance using OpenTelemetry.
### [https://github.com/nikolayk812/pgx-outbox](https://github.com/nikolayk812/pgx-outbox)
Simple Golang implementation for transactional outbox pattern for PostgreSQL using jackc/pgx driver.
### [https://github.com/Arlandaren/pgxWrappy](https://github.com/Arlandaren/pgxWrappy)
Simplifies working with the pgx library, providing convenient scanning of nested structures.
### [https://github.com/KoNekoD/pgx-colon-query-rewriter](https://github.com/KoNekoD/pgx-colon-query-rewriter)
Implementation of the pgx query rewriter to use ':' instead of '@' in named query parameters.
================================================
FILE: Rakefile
================================================
require "erb"
rule '.go' => '.go.erb' do |task|
erb = ERB.new(File.read(task.source))
File.write(task.name, "// Code generated from #{task.source}. DO NOT EDIT.\n\n" + erb.result(binding))
sh "goimports", "-w", task.name
end
generated_code_files = [
"pgtype/int.go",
"pgtype/int_test.go",
"pgtype/integration_benchmark_test.go",
"pgtype/zeronull/int.go",
"pgtype/zeronull/int_test.go"
]
desc "Generate code"
task generate: generated_code_files
================================================
FILE: batch.go
================================================
package pgx
import (
"context"
"errors"
"fmt"
"github.com/jackc/pgx/v5/pgconn"
)
// QueuedQuery is a query that has been queued for execution via a Batch.
type QueuedQuery struct {
SQL string
Arguments []any
Fn batchItemFunc
sd *pgconn.StatementDescription
}
type batchItemFunc func(br BatchResults) error
// Query sets fn to be called when the response to qq is received.
func (qq *QueuedQuery) Query(fn func(rows Rows) error) {
qq.Fn = func(br BatchResults) error {
rows, _ := br.Query()
defer rows.Close()
err := fn(rows)
if err != nil {
return err
}
rows.Close()
return rows.Err()
}
}
// Query sets fn to be called when the response to qq is received.
func (qq *QueuedQuery) QueryRow(fn func(row Row) error) {
qq.Fn = func(br BatchResults) error {
row := br.QueryRow()
return fn(row)
}
}
// Exec sets fn to be called when the response to qq is received.
//
// Note: for simple batch insert uses where it is not required to handle
// each potential error individually, it's sufficient to not set any callbacks,
// and just handle the return value of BatchResults.Close.
func (qq *QueuedQuery) Exec(fn func(ct pgconn.CommandTag) error) {
qq.Fn = func(br BatchResults) error {
ct, err := br.Exec()
if err != nil {
return err
}
return fn(ct)
}
}
// Batch queries are a way of bundling multiple queries together to avoid
// unnecessary network round trips. A Batch must only be sent once.
type Batch struct {
QueuedQueries []*QueuedQuery
}
// Queue queues a query to batch b. query can be an SQL query or the name of a prepared statement. The only pgx option
// argument that is supported is QueryRewriter. Queries are executed using the connection's DefaultQueryExecMode.
//
// While query can contain multiple statements if the connection's DefaultQueryExecMode is QueryModeSimple, this should
// be avoided. QueuedQuery.Fn must not be set as it will only be called for the first query. That is, QueuedQuery.Query,
// QueuedQuery.QueryRow, and QueuedQuery.Exec must not be called. In addition, any error messages or tracing that
// include the current query may reference the wrong query.
func (b *Batch) Queue(query string, arguments ...any) *QueuedQuery {
qq := &QueuedQuery{
SQL: query,
Arguments: arguments,
}
b.QueuedQueries = append(b.QueuedQueries, qq)
return qq
}
// Len returns number of queries that have been queued so far.
func (b *Batch) Len() int {
return len(b.QueuedQueries)
}
type BatchResults interface {
// Exec reads the results from the next query in the batch as if the query has been sent with Conn.Exec. Prefer
// calling Exec on the QueuedQuery, or just calling Close.
Exec() (pgconn.CommandTag, error)
// Query reads the results from the next query in the batch as if the query has been sent with Conn.Query. Prefer
// calling Query on the QueuedQuery.
Query() (Rows, error)
// QueryRow reads the results from the next query in the batch as if the query has been sent with Conn.QueryRow.
// Prefer calling QueryRow on the QueuedQuery.
QueryRow() Row
// Close closes the batch operation. All unread results are read and any callback functions registered with
// QueuedQuery.Query, QueuedQuery.QueryRow, or QueuedQuery.Exec will be called. If a callback function returns an
// error or the batch encounters an error subsequent callback functions will not be called.
//
// For simple batch inserts inside a transaction or similar queries, it's sufficient to not set any callbacks,
// and just handle the return value of Close.
//
// Close must be called before the underlying connection can be used again. Any error that occurred during a batch
// operation may have made it impossible to resyncronize the connection with the server. In this case the underlying
// connection will have been closed.
//
// Close is safe to call multiple times. If it returns an error subsequent calls will return the same error. Callback
// functions will not be rerun.
Close() error
}
type batchResults struct {
ctx context.Context
conn *Conn
mrr *pgconn.MultiResultReader
err error
b *Batch
qqIdx int
closed bool
endTraced bool
}
// Exec reads the results from the next query in the batch as if the query has been sent with Exec.
func (br *batchResults) Exec() (pgconn.CommandTag, error) {
if br.err != nil {
return pgconn.CommandTag{}, br.err
}
if br.closed {
return pgconn.CommandTag{}, fmt.Errorf("batch already closed")
}
query, arguments, _ := br.nextQueryAndArgs()
if !br.mrr.NextResult() {
err := br.mrr.Close()
if err == nil {
err = errors.New("no more results in batch")
}
if br.conn.batchTracer != nil {
br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{
SQL: query,
Args: arguments,
Err: err,
})
}
return pgconn.CommandTag{}, err
}
commandTag, err := br.mrr.ResultReader().Close()
if err != nil {
br.err = err
br.mrr.Close()
}
if br.conn.batchTracer != nil {
br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{
SQL: query,
Args: arguments,
CommandTag: commandTag,
Err: br.err,
})
}
return commandTag, br.err
}
// Query reads the results from the next query in the batch as if the query has been sent with Query.
func (br *batchResults) Query() (Rows, error) {
query, arguments, ok := br.nextQueryAndArgs()
if !ok {
query = "batch query"
}
if br.err != nil {
return &baseRows{err: br.err, closed: true}, br.err
}
if br.closed {
alreadyClosedErr := fmt.Errorf("batch already closed")
return &baseRows{err: alreadyClosedErr, closed: true}, alreadyClosedErr
}
rows := br.conn.getRows(br.ctx, query, arguments)
rows.batchTracer = br.conn.batchTracer
if !br.mrr.NextResult() {
rows.err = br.mrr.Close()
if rows.err == nil {
rows.err = errors.New("no more results in batch")
}
rows.closed = true
if br.conn.batchTracer != nil {
br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{
SQL: query,
Args: arguments,
Err: rows.err,
})
}
return rows, rows.err
}
rows.resultReader = br.mrr.ResultReader()
return rows, nil
}
// QueryRow reads the results from the next query in the batch as if the query has been sent with QueryRow.
func (br *batchResults) QueryRow() Row {
rows, _ := br.Query()
return (*connRow)(rows.(*baseRows))
}
// Close closes the batch operation. Any error that occurred during a batch operation may have made it impossible to
// resyncronize the connection with the server. In this case the underlying connection will have been closed.
func (br *batchResults) Close() error {
defer func() {
if !br.endTraced {
if br.conn != nil && br.conn.batchTracer != nil {
br.conn.batchTracer.TraceBatchEnd(br.ctx, br.conn, TraceBatchEndData{Err: br.err})
}
br.endTraced = true
}
invalidateCachesOnBatchResultsError(br.conn, br.b, br.err)
}()
if br.err != nil {
return br.err
}
if br.closed {
return nil
}
// Read and run fn for all remaining items
for br.err == nil && !br.closed && br.b != nil && br.qqIdx < len(br.b.QueuedQueries) {
if br.b.QueuedQueries[br.qqIdx].Fn != nil {
err := br.b.QueuedQueries[br.qqIdx].Fn(br)
if err != nil {
br.err = err
}
} else {
br.Exec()
}
}
br.closed = true
err := br.mrr.Close()
if br.err == nil {
br.err = err
}
return br.err
}
func (br *batchResults) earlyError() error {
return br.err
}
func (br *batchResults) nextQueryAndArgs() (query string, args []any, ok bool) {
if br.b != nil && br.qqIdx < len(br.b.QueuedQueries) {
bi := br.b.QueuedQueries[br.qqIdx]
query = bi.SQL
args = bi.Arguments
ok = true
br.qqIdx++
}
return query, args, ok
}
type pipelineBatchResults struct {
ctx context.Context
conn *Conn
pipeline *pgconn.Pipeline
lastRows *baseRows
err error
b *Batch
qqIdx int
closed bool
endTraced bool
}
// Exec reads the results from the next query in the batch as if the query has been sent with Exec.
func (br *pipelineBatchResults) Exec() (pgconn.CommandTag, error) {
if br.err != nil {
return pgconn.CommandTag{}, br.err
}
if br.closed {
return pgconn.CommandTag{}, fmt.Errorf("batch already closed")
}
if br.lastRows != nil && br.lastRows.err != nil {
return pgconn.CommandTag{}, br.err
}
query, arguments, err := br.nextQueryAndArgs()
if err != nil {
return pgconn.CommandTag{}, err
}
results, err := br.pipeline.GetResults()
if err != nil {
br.err = err
return pgconn.CommandTag{}, br.err
}
var commandTag pgconn.CommandTag
switch results := results.(type) {
case *pgconn.ResultReader:
commandTag, br.err = results.Close()
default:
return pgconn.CommandTag{}, fmt.Errorf("unexpected pipeline result: %T", results)
}
if br.conn.batchTracer != nil {
br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{
SQL: query,
Args: arguments,
CommandTag: commandTag,
Err: br.err,
})
}
return commandTag, br.err
}
// Query reads the results from the next query in the batch as if the query has been sent with Query.
func (br *pipelineBatchResults) Query() (Rows, error) {
if br.err != nil {
return &baseRows{err: br.err, closed: true}, br.err
}
if br.closed {
alreadyClosedErr := fmt.Errorf("batch already closed")
return &baseRows{err: alreadyClosedErr, closed: true}, alreadyClosedErr
}
if br.lastRows != nil && br.lastRows.err != nil {
br.err = br.lastRows.err
return &baseRows{err: br.err, closed: true}, br.err
}
query, arguments, err := br.nextQueryAndArgs()
if err != nil {
return &baseRows{err: err, closed: true}, err
}
rows := br.conn.getRows(br.ctx, query, arguments)
rows.batchTracer = br.conn.batchTracer
br.lastRows = rows
results, err := br.pipeline.GetResults()
if err != nil {
br.err = err
rows.err = err
rows.closed = true
if br.conn.batchTracer != nil {
br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{
SQL: query,
Args: arguments,
Err: err,
})
}
} else {
switch results := results.(type) {
case *pgconn.ResultReader:
rows.resultReader = results
default:
err = fmt.Errorf("unexpected pipeline result: %T", results)
br.err = err
rows.err = err
rows.closed = true
}
}
return rows, rows.err
}
// QueryRow reads the results from the next query in the batch as if the query has been sent with QueryRow.
func (br *pipelineBatchResults) QueryRow() Row {
rows, _ := br.Query()
return (*connRow)(rows.(*baseRows))
}
// Close closes the batch operation. Any error that occurred during a batch operation may have made it impossible to
// resyncronize the connection with the server. In this case the underlying connection will have been closed.
func (br *pipelineBatchResults) Close() error {
defer func() {
if !br.endTraced {
if br.conn.batchTracer != nil {
br.conn.batchTracer.TraceBatchEnd(br.ctx, br.conn, TraceBatchEndData{Err: br.err})
}
br.endTraced = true
}
invalidateCachesOnBatchResultsError(br.conn, br.b, br.err)
}()
if br.err == nil && br.lastRows != nil && br.lastRows.err != nil {
br.err = br.lastRows.err
}
if br.closed {
return br.err
}
// Read and run fn for all remaining items
for br.err == nil && !br.closed && br.b != nil && br.qqIdx < len(br.b.QueuedQueries) {
if br.b.QueuedQueries[br.qqIdx].Fn != nil {
err := br.b.QueuedQueries[br.qqIdx].Fn(br)
if err != nil {
br.err = err
}
} else {
br.Exec()
}
}
br.closed = true
err := br.pipeline.Close()
if br.err == nil {
br.err = err
}
return br.err
}
func (br *pipelineBatchResults) earlyError() error {
return br.err
}
func (br *pipelineBatchResults) nextQueryAndArgs() (query string, args []any, err error) {
if br.b == nil {
return "", nil, errors.New("no reference to batch")
}
if br.qqIdx >= len(br.b.QueuedQueries) {
return "", nil, errors.New("no more results in batch")
}
bi := br.b.QueuedQueries[br.qqIdx]
br.qqIdx++
return bi.SQL, bi.Arguments, nil
}
type emptyBatchResults struct {
conn *Conn
closed bool
}
// Exec reads the results from the next query in the batch as if the query has been sent with Exec.
func (br *emptyBatchResults) Exec() (pgconn.CommandTag, error) {
if br.closed {
return pgconn.CommandTag{}, fmt.Errorf("batch already closed")
}
return pgconn.CommandTag{}, errors.New("no more results in batch")
}
// Query reads the results from the next query in the batch as if the query has been sent with Query.
func (br *emptyBatchResults) Query() (Rows, error) {
if br.closed {
alreadyClosedErr := fmt.Errorf("batch already closed")
return &baseRows{err: alreadyClosedErr, closed: true}, alreadyClosedErr
}
rows := br.conn.getRows(context.Background(), "", nil)
rows.err = errors.New("no more results in batch")
rows.closed = true
return rows, rows.err
}
// QueryRow reads the results from the next query in the batch as if the query has been sent with QueryRow.
func (br *emptyBatchResults) QueryRow() Row {
rows, _ := br.Query()
return (*connRow)(rows.(*baseRows))
}
// Close closes the batch operation. Any error that occurred during a batch operation may have made it impossible to
// resyncronize the connection with the server. In this case the underlying connection will have been closed.
func (br *emptyBatchResults) Close() error {
br.closed = true
return nil
}
// invalidates statement and description caches on batch results error
func invalidateCachesOnBatchResultsError(conn *Conn, b *Batch, err error) {
if err != nil && conn != nil && b != nil {
if sc := conn.statementCache; sc != nil {
for _, bi := range b.QueuedQueries {
sc.Invalidate(bi.SQL)
}
}
if sc := conn.descriptionCache; sc != nil {
for _, bi := range b.QueuedQueries {
sc.Invalidate(bi.SQL)
}
}
}
}
// ErrPreprocessingBatch occurs when an error is encountered while preprocessing a batch.
// The two preprocessing steps are "prepare" (server-side SQL parse/plan) and
// "build" (client-side argument encoding).
type ErrPreprocessingBatch struct {
step string // "prepare" or "build"
sql string
err error
}
func newErrPreprocessingBatch(step, sql string, err error) ErrPreprocessingBatch {
return ErrPreprocessingBatch{step: step, sql: sql, err: err}
}
func (e ErrPreprocessingBatch) Error() string {
// intentionally not including the SQL query in the error message
// to avoid leaking potentially sensitive information into logs.
// If the user wants the SQL, they can call SQL().
return fmt.Sprintf("error preprocessing batch (%s): %v", e.step, e.err)
}
func (e ErrPreprocessingBatch) Unwrap() error {
return e.err
}
func (e ErrPreprocessingBatch) SQL() string {
return e.sql
}
================================================
FILE: batch_test.go
================================================
package pgx_test
import (
"context"
"errors"
"fmt"
"io"
"net"
"os"
"testing"
"time"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/internal/faultyconn"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgproto3"
"github.com/jackc/pgx/v5/pgxtest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestConnSendBatch(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
pgxtest.SkipCockroachDB(t, conn, "Server serial type is incompatible with test")
sql := `create temporary table ledger(
id serial primary key,
description varchar not null,
amount int not null
);`
mustExec(t, conn, sql)
batch := &pgx.Batch{}
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q1", 1)
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q2", 2)
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q3", 3)
batch.Queue("select id, description, amount from ledger order by id")
batch.Queue("select id, description, amount from ledger order by id")
batch.Queue("select * from ledger where false")
batch.Queue("select sum(amount) from ledger")
br := conn.SendBatch(ctx, batch)
ct, err := br.Exec()
if err != nil {
t.Error(err)
}
if ct.RowsAffected() != 1 {
t.Errorf("ct.RowsAffected() => %v, want %v", ct.RowsAffected(), 1)
}
ct, err = br.Exec()
if err != nil {
t.Error(err)
}
if ct.RowsAffected() != 1 {
t.Errorf("ct.RowsAffected() => %v, want %v", ct.RowsAffected(), 1)
}
ct, err = br.Exec()
if err != nil {
t.Error(err)
}
if ct.RowsAffected() != 1 {
t.Errorf("ct.RowsAffected() => %v, want %v", ct.RowsAffected(), 1)
}
selectFromLedgerExpectedRows := []struct {
id int32
description string
amount int32
}{
{1, "q1", 1},
{2, "q2", 2},
{3, "q3", 3},
}
rows, err := br.Query()
if err != nil {
t.Error(err)
}
var id int32
var description string
var amount int32
rowCount := 0
for rows.Next() {
if rowCount >= len(selectFromLedgerExpectedRows) {
t.Fatalf("got too many rows: %d", rowCount)
}
if err := rows.Scan(&id, &description, &amount); err != nil {
t.Fatalf("row %d: %v", rowCount, err)
}
if id != selectFromLedgerExpectedRows[rowCount].id {
t.Errorf("id => %v, want %v", id, selectFromLedgerExpectedRows[rowCount].id)
}
if description != selectFromLedgerExpectedRows[rowCount].description {
t.Errorf("description => %v, want %v", description, selectFromLedgerExpectedRows[rowCount].description)
}
if amount != selectFromLedgerExpectedRows[rowCount].amount {
t.Errorf("amount => %v, want %v", amount, selectFromLedgerExpectedRows[rowCount].amount)
}
rowCount++
}
if rows.Err() != nil {
t.Fatal(rows.Err())
}
rowCount = 0
rows, _ = br.Query()
_, err = pgx.ForEachRow(rows, []any{&id, &description, &amount}, func() error {
if id != selectFromLedgerExpectedRows[rowCount].id {
t.Errorf("id => %v, want %v", id, selectFromLedgerExpectedRows[rowCount].id)
}
if description != selectFromLedgerExpectedRows[rowCount].description {
t.Errorf("description => %v, want %v", description, selectFromLedgerExpectedRows[rowCount].description)
}
if amount != selectFromLedgerExpectedRows[rowCount].amount {
t.Errorf("amount => %v, want %v", amount, selectFromLedgerExpectedRows[rowCount].amount)
}
rowCount++
return nil
})
if err != nil {
t.Error(err)
}
err = br.QueryRow().Scan(&id, &description, &amount)
if !errors.Is(err, pgx.ErrNoRows) {
t.Errorf("expected pgx.ErrNoRows but got: %v", err)
}
err = br.QueryRow().Scan(&amount)
if err != nil {
t.Error(err)
}
if amount != 6 {
t.Errorf("amount => %v, want %v", amount, 6)
}
err = br.Close()
if err != nil {
t.Fatal(err)
}
})
}
func TestConnSendBatchQueuedQuery(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
pgxtest.SkipCockroachDB(t, conn, "Server serial type is incompatible with test")
sql := `create temporary table ledger(
id serial primary key,
description varchar not null,
amount int not null
);`
mustExec(t, conn, sql)
batch := &pgx.Batch{}
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q1", 1).Exec(func(ct pgconn.CommandTag) error {
assert.EqualValues(t, 1, ct.RowsAffected())
return nil
})
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q2", 2).Exec(func(ct pgconn.CommandTag) error {
assert.EqualValues(t, 1, ct.RowsAffected())
return nil
})
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q3", 3).Exec(func(ct pgconn.CommandTag) error {
assert.EqualValues(t, 1, ct.RowsAffected())
return nil
})
selectFromLedgerExpectedRows := []struct {
id int32
description string
amount int32
}{
{1, "q1", 1},
{2, "q2", 2},
{3, "q3", 3},
}
batch.Queue("select id, description, amount from ledger order by id").Query(func(rows pgx.Rows) error {
rowCount := 0
var id int32
var description string
var amount int32
_, err := pgx.ForEachRow(rows, []any{&id, &description, &amount}, func() error {
assert.Equal(t, selectFromLedgerExpectedRows[rowCount].id, id)
assert.Equal(t, selectFromLedgerExpectedRows[rowCount].description, description)
assert.Equal(t, selectFromLedgerExpectedRows[rowCount].amount, amount)
rowCount++
return nil
})
assert.NoError(t, err)
return nil
})
batch.Queue("select id, description, amount from ledger order by id").Query(func(rows pgx.Rows) error {
rowCount := 0
var id int32
var description string
var amount int32
_, err := pgx.ForEachRow(rows, []any{&id, &description, &amount}, func() error {
assert.Equal(t, selectFromLedgerExpectedRows[rowCount].id, id)
assert.Equal(t, selectFromLedgerExpectedRows[rowCount].description, description)
assert.Equal(t, selectFromLedgerExpectedRows[rowCount].amount, amount)
rowCount++
return nil
})
assert.NoError(t, err)
return nil
})
batch.Queue("select * from ledger where false").QueryRow(func(row pgx.Row) error {
err := row.Scan(nil, nil, nil)
assert.ErrorIs(t, err, pgx.ErrNoRows)
return nil
})
batch.Queue("select sum(amount) from ledger").QueryRow(func(row pgx.Row) error {
var sumAmount int32
err := row.Scan(&sumAmount)
assert.NoError(t, err)
assert.EqualValues(t, 6, sumAmount)
return nil
})
err := conn.SendBatch(ctx, batch).Close()
assert.NoError(t, err)
})
}
func TestConnSendBatchMany(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
sql := `create temporary table ledger(
id serial primary key,
description varchar not null,
amount int not null
);`
mustExec(t, conn, sql)
batch := &pgx.Batch{}
numInserts := 1000
for range numInserts {
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q1", 1)
}
batch.Queue("select count(*) from ledger")
br := conn.SendBatch(ctx, batch)
for range numInserts {
ct, err := br.Exec()
assert.NoError(t, err)
assert.EqualValues(t, 1, ct.RowsAffected())
}
var actualInserts int
err := br.QueryRow().Scan(&actualInserts)
assert.NoError(t, err)
assert.EqualValues(t, numInserts, actualInserts)
err = br.Close()
require.NoError(t, err)
})
}
// https://github.com/jackc/pgx/issues/1801#issuecomment-2203784178
func TestConnSendBatchReadResultsWhenNothingQueued(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
batch := &pgx.Batch{}
br := conn.SendBatch(ctx, batch)
commandTag, err := br.Exec()
require.Equal(t, "", commandTag.String())
require.EqualError(t, err, "no more results in batch")
err = br.Close()
require.NoError(t, err)
})
}
func TestConnSendBatchReadMoreResultsThanQueriesSent(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
batch := &pgx.Batch{}
batch.Queue("select 1")
br := conn.SendBatch(ctx, batch)
commandTag, err := br.Exec()
require.Equal(t, "SELECT 1", commandTag.String())
require.NoError(t, err)
commandTag, err = br.Exec()
require.Equal(t, "", commandTag.String())
require.EqualError(t, err, "no more results in batch")
err = br.Close()
require.NoError(t, err)
})
}
func TestConnSendBatchWithPreparedStatement(t *testing.T) {
t.Parallel()
modes := []pgx.QueryExecMode{
pgx.QueryExecModeCacheStatement,
pgx.QueryExecModeCacheDescribe,
pgx.QueryExecModeDescribeExec,
pgx.QueryExecModeExec,
// Don't test simple mode with prepared statements.
}
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, modes, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
pgxtest.SkipCockroachDB(t, conn, "Server issues incorrect ParameterDescription (https://github.com/cockroachdb/cockroach/issues/60907)")
_, err := conn.Prepare(ctx, "ps1", "select n from generate_series(0,$1::int) n")
if err != nil {
t.Fatal(err)
}
batch := &pgx.Batch{}
queryCount := 3
for range queryCount {
batch.Queue("ps1", 5)
}
br := conn.SendBatch(ctx, batch)
for range queryCount {
rows, err := br.Query()
if err != nil {
t.Fatal(err)
}
for k := 0; rows.Next(); k++ {
var n int
if err := rows.Scan(&n); err != nil {
t.Fatal(err)
}
if n != k {
t.Fatalf("n => %v, want %v", n, k)
}
}
if rows.Err() != nil {
t.Fatal(rows.Err())
}
}
err = br.Close()
if err != nil {
t.Fatal(err)
}
})
}
func TestConnSendBatchWithQueryRewriter(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
batch := &pgx.Batch{}
batch.Queue("something to be replaced", &testQueryRewriter{sql: "select $1::int", args: []any{1}})
batch.Queue("something else to be replaced", &testQueryRewriter{sql: "select $1::text", args: []any{"hello"}})
batch.Queue("more to be replaced", &testQueryRewriter{sql: "select $1::int", args: []any{3}})
br := conn.SendBatch(ctx, batch)
var n int32
err := br.QueryRow().Scan(&n)
require.NoError(t, err)
require.EqualValues(t, 1, n)
var s string
err = br.QueryRow().Scan(&s)
require.NoError(t, err)
require.Equal(t, "hello", s)
err = br.QueryRow().Scan(&n)
require.NoError(t, err)
require.EqualValues(t, 3, n)
err = br.Close()
require.NoError(t, err)
})
}
// https://github.com/jackc/pgx/issues/856
func TestConnSendBatchWithPreparedStatementAndStatementCacheDisabled(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
require.NoError(t, err)
config.DefaultQueryExecMode = pgx.QueryExecModeDescribeExec
config.StatementCacheCapacity = 0
config.DescriptionCacheCapacity = 0
conn := mustConnect(t, config)
defer closeConn(t, conn)
pgxtest.SkipCockroachDB(t, conn, "Server issues incorrect ParameterDescription (https://github.com/cockroachdb/cockroach/issues/60907)")
_, err = conn.Prepare(ctx, "ps1", "select n from generate_series(0,$1::int) n")
if err != nil {
t.Fatal(err)
}
batch := &pgx.Batch{}
queryCount := 3
for range queryCount {
batch.Queue("ps1", 5)
}
br := conn.SendBatch(ctx, batch)
for range queryCount {
rows, err := br.Query()
if err != nil {
t.Fatal(err)
}
for k := 0; rows.Next(); k++ {
var n int
if err := rows.Scan(&n); err != nil {
t.Fatal(err)
}
if n != k {
t.Fatalf("n => %v, want %v", n, k)
}
}
if rows.Err() != nil {
t.Fatal(rows.Err())
}
}
err = br.Close()
if err != nil {
t.Fatal(err)
}
ensureConnValid(t, conn)
}
func TestConnSendBatchCloseRowsPartiallyRead(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
batch := &pgx.Batch{}
batch.Queue("select n from generate_series(0,5) n")
batch.Queue("select n from generate_series(0,5) n")
br := conn.SendBatch(ctx, batch)
rows, err := br.Query()
if err != nil {
t.Error(err)
}
for i := range 3 {
if !rows.Next() {
t.Error("expected a row to be available")
}
var n int
if err := rows.Scan(&n); err != nil {
t.Error(err)
}
if n != i {
t.Errorf("n => %v, want %v", n, i)
}
}
rows.Close()
rows, err = br.Query()
if err != nil {
t.Error(err)
}
for i := 0; rows.Next(); i++ {
var n int
if err := rows.Scan(&n); err != nil {
t.Error(err)
}
if n != i {
t.Errorf("n => %v, want %v", n, i)
}
}
if rows.Err() != nil {
t.Error(rows.Err())
}
err = br.Close()
if err != nil {
t.Fatal(err)
}
})
}
func TestConnSendBatchQueryError(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
batch := &pgx.Batch{}
batch.Queue("select n from generate_series(0,5) n where 100/(5-n) > 0")
batch.Queue("select n from generate_series(0,5) n")
br := conn.SendBatch(ctx, batch)
rows, err := br.Query()
if err != nil {
t.Error(err)
}
for i := 0; rows.Next(); i++ {
var n int
if err := rows.Scan(&n); err != nil {
t.Error(err)
}
if n != i {
t.Errorf("n => %v, want %v", n, i)
}
}
if pgErr, ok := rows.Err().(*pgconn.PgError); !(ok && pgErr.Code == "22012") {
t.Errorf("rows.Err() => %v, want error code %v", rows.Err(), 22012)
}
err = br.Close()
if pgErr, ok := err.(*pgconn.PgError); !(ok && pgErr.Code == "22012") {
t.Errorf("br.Close() => %v, want error code %v", err, 22012)
}
})
}
func TestConnSendBatchQuerySyntaxError(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
batch := &pgx.Batch{}
batch.Queue("select 1 1")
br := conn.SendBatch(ctx, batch)
var n int32
err := br.QueryRow().Scan(&n)
var pgErr *pgconn.PgError
if !(errors.As(err, &pgErr) && pgErr.Code == "42601") {
t.Errorf("rows.Err() => %v, want error code %v", err, 42601)
}
err = br.Close()
if err == nil {
t.Error("Expected error")
}
})
}
func TestConnSendBatchErrorReturnsErrPreprocessingBatch(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
// Only test exec modes that go through sendBatchExtendedWithDescription which wraps errors with ErrPreprocessingBatch.
modes := []pgx.QueryExecMode{
pgx.QueryExecModeCacheStatement,
pgx.QueryExecModeCacheDescribe,
pgx.QueryExecModeDescribeExec,
}
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, modes, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
var preprocessingErr pgx.ErrPreprocessingBatch
// Test prepare step failure: syntax error in a non-first statement.
batch := &pgx.Batch{}
batch.Queue("select 1")
batch.Queue("select 1 1") // syntax error triggers prepare failure
err := conn.SendBatch(ctx, batch).Close()
require.Error(t, err)
require.ErrorAs(t, err, &preprocessingErr)
assert.Equal(t, "select 1 1", preprocessingErr.SQL())
assert.NotContains(t, preprocessingErr.Error(), "select 1 1") // we don't want to leak the SQL query in the error message
assert.Contains(t, preprocessingErr.Error(), "error preprocessing batch (prepare)")
// Test build step failure: wrong number of arguments in a statement.
batch = &pgx.Batch{}
batch.Queue("select 1")
batch.Queue("select $1::int", 1, 2) // mismatched argument count triggers build failure
err = conn.SendBatch(ctx, batch).Close()
require.Error(t, err)
require.ErrorAs(t, err, &preprocessingErr)
assert.Equal(t, "select $1::int", preprocessingErr.SQL())
assert.NotContains(t, preprocessingErr.Error(), "select $1::int") // we don't want to leak the SQL query in the error message
assert.Contains(t, preprocessingErr.Error(), "error preprocessing batch (build)")
})
}
func TestConnSendBatchQueryRowInsert(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
sql := `create temporary table ledger(
id serial primary key,
description varchar not null,
amount int not null
);`
mustExec(t, conn, sql)
batch := &pgx.Batch{}
batch.Queue("select 1")
batch.Queue("insert into ledger(description, amount) values($1, $2),($1, $2)", "q1", 1)
br := conn.SendBatch(ctx, batch)
var value int
err := br.QueryRow().Scan(&value)
if err != nil {
t.Error(err)
}
ct, err := br.Exec()
if err != nil {
t.Error(err)
}
if ct.RowsAffected() != 2 {
t.Errorf("ct.RowsAffected() => %v, want %v", ct.RowsAffected(), 2)
}
br.Close()
})
}
func TestConnSendBatchQueryPartialReadInsert(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
sql := `create temporary table ledger(
id serial primary key,
description varchar not null,
amount int not null
);`
mustExec(t, conn, sql)
batch := &pgx.Batch{}
batch.Queue("select 1 union all select 2 union all select 3")
batch.Queue("insert into ledger(description, amount) values($1, $2),($1, $2)", "q1", 1)
br := conn.SendBatch(ctx, batch)
rows, err := br.Query()
if err != nil {
t.Error(err)
}
rows.Close()
ct, err := br.Exec()
if err != nil {
t.Error(err)
}
if ct.RowsAffected() != 2 {
t.Errorf("ct.RowsAffected() => %v, want %v", ct.RowsAffected(), 2)
}
br.Close()
})
}
func TestTxSendBatch(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
sql := `create temporary table ledger1(
id serial primary key,
description varchar not null
);`
mustExec(t, conn, sql)
sql = `create temporary table ledger2(
id int primary key,
amount int not null
);`
mustExec(t, conn, sql)
tx, _ := conn.Begin(ctx)
batch := &pgx.Batch{}
batch.Queue("insert into ledger1(description) values($1) returning id", "q1")
br := tx.SendBatch(context.Background(), batch)
var id int
err := br.QueryRow().Scan(&id)
if err != nil {
t.Error(err)
}
br.Close()
batch = &pgx.Batch{}
batch.Queue("insert into ledger2(id,amount) values($1, $2)", id, 2)
batch.Queue("select amount from ledger2 where id = $1", id)
br = tx.SendBatch(ctx, batch)
ct, err := br.Exec()
if err != nil {
t.Error(err)
}
if ct.RowsAffected() != 1 {
t.Errorf("ct.RowsAffected() => %v, want %v", ct.RowsAffected(), 1)
}
var amount int
err = br.QueryRow().Scan(&amount)
if err != nil {
t.Error(err)
}
br.Close()
tx.Commit(ctx)
var count int
conn.QueryRow(ctx, "select count(1) from ledger1 where id = $1", id).Scan(&count)
if count != 1 {
t.Errorf("count => %v, want %v", count, 1)
}
err = br.Close()
if err != nil {
t.Fatal(err)
}
})
}
func TestTxSendBatchRollback(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
sql := `create temporary table ledger1(
id serial primary key,
description varchar not null
);`
mustExec(t, conn, sql)
tx, _ := conn.Begin(ctx)
batch := &pgx.Batch{}
batch.Queue("insert into ledger1(description) values($1) returning id", "q1")
br := tx.SendBatch(ctx, batch)
var id int
err := br.QueryRow().Scan(&id)
if err != nil {
t.Error(err)
}
br.Close()
tx.Rollback(ctx)
row := conn.QueryRow(ctx, "select count(1) from ledger1 where id = $1", id)
var count int
row.Scan(&count)
if count != 0 {
t.Errorf("count => %v, want %v", count, 0)
}
})
}
// https://github.com/jackc/pgx/issues/1578
func TestSendBatchErrorWhileReadingResultsWithoutCallback(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
batch := &pgx.Batch{}
batch.Queue("select 4 / $1::int", 0)
batchResult := conn.SendBatch(ctx, batch)
_, execErr := batchResult.Exec()
require.Error(t, execErr)
closeErr := batchResult.Close()
require.Equal(t, execErr, closeErr)
// Try to use the connection.
_, err := conn.Exec(ctx, "select 1")
require.NoError(t, err)
})
}
func TestSendBatchErrorWhileReadingResultsWithExecWhereSomeRowsAreReturned(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
batch := &pgx.Batch{}
batch.Queue("select 4 / n from generate_series(-2, 2) n")
batchResult := conn.SendBatch(ctx, batch)
_, execErr := batchResult.Exec()
require.Error(t, execErr)
closeErr := batchResult.Close()
require.Equal(t, execErr, closeErr)
// Try to use the connection.
_, err := conn.Exec(ctx, "select 1")
require.NoError(t, err)
})
}
func TestConnBeginBatchDeferredError(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
pgxtest.SkipCockroachDB(t, conn, "Server does not support deferred constraint (https://github.com/cockroachdb/cockroach/issues/31632)")
mustExec(t, conn, `create temporary table t (
id text primary key,
n int not null,
unique (n) deferrable initially deferred
);
insert into t (id, n) values ('a', 1), ('b', 2), ('c', 3);`)
batch := &pgx.Batch{}
batch.Queue(`update t set n=n+1 where id='b' returning *`)
br := conn.SendBatch(ctx, batch)
rows, err := br.Query()
if err != nil {
t.Error(err)
}
for rows.Next() {
var id string
var n int32
err = rows.Scan(&id, &n)
if err != nil {
t.Fatal(err)
}
}
err = br.Close()
if err == nil {
t.Fatal("expected error 23505 but got none")
}
if err, ok := err.(*pgconn.PgError); !ok || err.Code != "23505" {
t.Fatalf("expected error 23505, got %v", err)
}
})
}
func TestConnSendBatchNoStatementCache(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
config := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeDescribeExec
config.StatementCacheCapacity = 0
config.DescriptionCacheCapacity = 0
conn := mustConnect(t, config)
defer closeConn(t, conn)
testConnSendBatch(t, ctx, conn, 3)
}
func TestConnSendBatchPrepareStatementCache(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
config := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement
config.StatementCacheCapacity = 32
conn := mustConnect(t, config)
defer closeConn(t, conn)
testConnSendBatch(t, ctx, conn, 3)
}
func TestConnSendBatchDescribeStatementCache(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
config := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheDescribe
config.DescriptionCacheCapacity = 32
conn := mustConnect(t, config)
defer closeConn(t, conn)
testConnSendBatch(t, ctx, conn, 3)
}
func testConnSendBatch(t *testing.T, ctx context.Context, conn *pgx.Conn, queryCount int) {
batch := &pgx.Batch{}
for range queryCount {
batch.Queue("select n from generate_series(0,5) n")
}
br := conn.SendBatch(ctx, batch)
for range queryCount {
rows, err := br.Query()
require.NoError(t, err)
for k := 0; rows.Next(); k++ {
var n int
err := rows.Scan(&n)
require.NoError(t, err)
require.Equal(t, k, n)
}
require.NoError(t, rows.Err())
}
err := br.Close()
require.NoError(t, err)
}
func TestSendBatchSimpleProtocol(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
config := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
conn := mustConnect(t, config)
defer closeConn(t, conn)
var batch pgx.Batch
batch.Queue("SELECT 1::int")
batch.Queue("SELECT 2::int; SELECT $1::int", 3)
results := conn.SendBatch(ctx, &batch)
rows, err := results.Query()
assert.NoError(t, err)
assert.True(t, rows.Next())
values, err := rows.Values()
assert.NoError(t, err)
assert.EqualValues(t, 1, values[0])
assert.False(t, rows.Next())
rows, err = results.Query()
assert.NoError(t, err)
assert.True(t, rows.Next())
values, err = rows.Values()
assert.NoError(t, err)
assert.EqualValues(t, 2, values[0])
assert.False(t, rows.Next())
rows, err = results.Query()
assert.NoError(t, err)
assert.True(t, rows.Next())
values, err = rows.Values()
assert.NoError(t, err)
assert.EqualValues(t, 3, values[0])
assert.False(t, rows.Next())
}
// https://github.com/jackc/pgx/issues/1847#issuecomment-2347858887
func TestConnSendBatchErrorDoesNotLeaveOrphanedPreparedStatement(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
pgxtest.SkipCockroachDB(t, conn, "Server serial type is incompatible with test")
mustExec(t, conn, `create temporary table foo(col1 text primary key);`)
batch := &pgx.Batch{}
batch.Queue("select col1 from foo")
batch.Queue("select col1 from baz")
err := conn.SendBatch(ctx, batch).Close()
require.ErrorContains(t, err, `relation "baz" does not exist (SQLSTATE 42P01)`)
mustExec(t, conn, `create temporary table baz(col1 text primary key);`)
// Since table baz now exists, the batch should succeed.
batch = &pgx.Batch{}
batch.Queue("select col1 from foo")
batch.Queue("select col1 from baz")
err = conn.SendBatch(ctx, batch).Close()
require.NoError(t, err)
})
}
func TestSendBatchStatementTimeout(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
pgxtest.RunWithQueryExecModes(ctx, t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
pgxtest.SkipCockroachDB(t, conn, "CockroachDB does not recover connection after batch statement timeout")
batch := &pgx.Batch{}
batch.Queue("SET statement_timeout='1ms'")
batch.Queue("SELECT pg_sleep(10)")
br := conn.SendBatch(context.Background(), batch)
// set statement_timeout
_, err := br.Exec()
assert.NoError(t, err)
// get pg_sleep results
rows, _ := br.Query()
// Consume rows and check error
rows.Close()
err = rows.Err()
assert.ErrorContains(t, err, "(SQLSTATE 57014)")
// The last error should be repeated when closing the batch
err = br.Close()
assert.ErrorContains(t, err, "(SQLSTATE 57014)")
// Connection should be usable after the statement timeout in pipeline
_, err = conn.Exec(context.Background(), "Select 1")
assert.NoError(t, err)
})
}
func TestSendBatchHandlesTimeoutBetweenParseAndDescribe(t *testing.T) {
// Not parallel because it is a timing sensitive test.
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
var faultyConn *faultyconn.Conn
faultyConnTestRunner := pgxtest.DefaultConnTestRunner()
faultyConnTestRunner.CreateConfig = func(ctx context.Context, t testing.TB) *pgx.ConnConfig {
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
require.NoError(t, err)
config.AfterNetConnect = func(ctx context.Context, config *pgconn.Config, conn net.Conn) (net.Conn, error) {
faultyConn = faultyconn.New(conn)
return faultyConn, nil
}
return config
}
// Only need to test modes that use Parse/Describe.
extendedQueryModes := []pgx.QueryExecMode{
pgx.QueryExecModeCacheStatement,
pgx.QueryExecModeCacheDescribe,
pgx.QueryExecModeDescribeExec,
pgx.QueryExecModeExec,
}
pgxtest.RunWithQueryExecModes(ctx, t, faultyConnTestRunner, extendedQueryModes, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
pgxtest.SkipCockroachDB(t, conn, "Induced error does not occur on CockroachDB")
_, err := conn.Exec(ctx, "set statement_timeout = '100ms'")
require.NoError(t, err)
batch := &pgx.Batch{}
batch.Queue("select 1")
batch.Queue("select 2")
faultyConn.HandleFrontendMessage = func(backendWriter io.Writer, msg pgproto3.FrontendMessage) error {
if _, ok := msg.(*pgproto3.Describe); ok {
time.Sleep(200 * time.Millisecond)
}
buf, err := msg.Encode(nil)
if err != nil {
return err
}
_, err = backendWriter.Write(buf)
return err
}
err = conn.SendBatch(ctx, batch).Close()
require.Error(t, err)
var pgErr *pgconn.PgError
require.True(t, errors.As(err, &pgErr))
require.Equal(t, "57014", pgErr.Code)
faultyConn.HandleFrontendMessage = nil
_, err = conn.Exec(ctx, "set statement_timeout = default")
require.NoError(t, err)
batch = &pgx.Batch{}
batch.Queue("select 1")
batch.Queue("select 2")
err = conn.SendBatch(ctx, batch).Close()
require.NoError(t, err)
})
}
func TestBatchNetworkUsage(t *testing.T) {
t.Parallel()
config := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement
var counterConn *byteCounterConn
config.AfterNetConnect = func(ctx context.Context, config *pgconn.Config, conn net.Conn) (net.Conn, error) {
counterConn = &byteCounterConn{conn: conn}
return counterConn, nil
}
conn := mustConnect(t, config)
defer closeConn(t, conn)
pgxtest.SkipCockroachDB(t, conn, "Server uses different number of bytes for same operations")
counterConn.bytesWritten = 0
counterConn.bytesRead = 0
batch := &pgx.Batch{}
for range 10 {
batch.Queue(
"select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n",
1,
)
}
err := conn.SendBatch(context.Background(), batch).Close()
require.NoError(t, err)
assert.Equal(t, 1736, counterConn.bytesRead)
assert.Equal(t, 1408, counterConn.bytesWritten)
ensureConnValid(t, conn)
}
func ExampleConn_SendBatch() {
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
conn, err := pgx.Connect(ctx, os.Getenv("PGX_TEST_DATABASE"))
if err != nil {
fmt.Printf("Unable to establish connection: %v", err)
return
}
batch := &pgx.Batch{}
batch.Queue("select 1 + 1").QueryRow(func(row pgx.Row) error {
var n int32
err := row.Scan(&n)
if err != nil {
return err
}
fmt.Println(n)
return err
})
batch.Queue("select 1 + 2").QueryRow(func(row pgx.Row) error {
var n int32
err := row.Scan(&n)
if err != nil {
return err
}
fmt.Println(n)
return err
})
batch.Queue("select 2 + 3").QueryRow(func(row pgx.Row) error {
var n int32
err := row.Scan(&n)
if err != nil {
return err
}
fmt.Println(n)
return err
})
err = conn.SendBatch(ctx, batch).Close()
if err != nil {
fmt.Printf("SendBatch error: %v", err)
return
}
// Output:
// 2
// 3
// 5
}
================================================
FILE: bench_test.go
================================================
package pgx_test
import (
"bytes"
"context"
"fmt"
"io"
"net"
"os"
"strconv"
"strings"
"testing"
"time"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgtype"
"github.com/stretchr/testify/require"
)
func BenchmarkConnectClose(b *testing.B) {
for b.Loop() {
conn, err := pgx.Connect(context.Background(), os.Getenv("PGX_TEST_DATABASE"))
if err != nil {
b.Fatal(err)
}
err = conn.Close(context.Background())
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkMinimalUnpreparedSelectWithoutStatementCache(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeDescribeExec
config.StatementCacheCapacity = 0
config.DescriptionCacheCapacity = 0
conn := mustConnect(b, config)
defer closeConn(b, conn)
var n int64
for i := 0; b.Loop(); i++ {
err := conn.QueryRow(context.Background(), "select $1::int8", i).Scan(&n)
if err != nil {
b.Fatal(err)
}
if n != int64(i) {
b.Fatalf("expected %d, got %d", i, n)
}
}
}
func BenchmarkMinimalUnpreparedSelectWithStatementCacheModeDescribe(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheDescribe
config.StatementCacheCapacity = 0
config.DescriptionCacheCapacity = 32
conn := mustConnect(b, config)
defer closeConn(b, conn)
var n int64
for i := 0; b.Loop(); i++ {
err := conn.QueryRow(context.Background(), "select $1::int8", i).Scan(&n)
if err != nil {
b.Fatal(err)
}
if n != int64(i) {
b.Fatalf("expected %d, got %d", i, n)
}
}
}
func BenchmarkMinimalUnpreparedSelectWithStatementCacheModePrepare(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement
config.StatementCacheCapacity = 32
config.DescriptionCacheCapacity = 0
conn := mustConnect(b, config)
defer closeConn(b, conn)
var n int64
for i := 0; b.Loop(); i++ {
err := conn.QueryRow(context.Background(), "select $1::int8", i).Scan(&n)
if err != nil {
b.Fatal(err)
}
if n != int64(i) {
b.Fatalf("expected %d, got %d", i, n)
}
}
}
func BenchmarkMinimalPreparedSelect(b *testing.B) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
_, err := conn.Prepare(context.Background(), "ps1", "select $1::int8")
if err != nil {
b.Fatal(err)
}
var n int64
for i := 0; b.Loop(); i++ {
err = conn.QueryRow(context.Background(), "ps1", i).Scan(&n)
if err != nil {
b.Fatal(err)
}
if n != int64(i) {
b.Fatalf("expected %d, got %d", i, n)
}
}
}
func BenchmarkMinimalPgConnPreparedSelect(b *testing.B) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
pgConn := conn.PgConn()
_, err := pgConn.Prepare(context.Background(), "ps1", "select $1::int8", nil)
if err != nil {
b.Fatal(err)
}
encodedBytes := make([]byte, 8)
for b.Loop() {
rr := pgConn.ExecPrepared(context.Background(), "ps1", [][]byte{encodedBytes}, []int16{1}, []int16{1})
if err != nil {
b.Fatal(err)
}
for rr.NextRow() {
for i := range rr.Values() {
if !bytes.Equal(rr.Values()[0], encodedBytes) {
b.Fatalf("unexpected values: %s %s", rr.Values()[i], encodedBytes)
}
}
}
_, err = rr.Close()
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkMinimalPgConnPreparedStatementDescriptionSelect(b *testing.B) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
pgConn := conn.PgConn()
psd, err := pgConn.Prepare(context.Background(), "ps1", "select $1::int8", nil)
if err != nil {
b.Fatal(err)
}
encodedBytes := make([]byte, 8)
b.ResetTimer()
for i := 0; i < b.N; i++ {
rr := pgConn.ExecStatement(context.Background(), psd, [][]byte{encodedBytes}, []int16{1}, []int16{1})
if err != nil {
b.Fatal(err)
}
for rr.NextRow() {
for i := range rr.Values() {
if !bytes.Equal(rr.Values()[0], encodedBytes) {
b.Fatalf("unexpected values: %s %s", rr.Values()[i], encodedBytes)
}
}
}
_, err = rr.Close()
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkPointerPointerWithNullValues(b *testing.B) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
_, err := conn.Prepare(context.Background(), "selectNulls", "select 1::int4, 'johnsmith', null::text, null::text, null::text, null::date, null::timestamptz")
if err != nil {
b.Fatal(err)
}
for b.Loop() {
var record struct {
id int32
userName string
email *string
name *string
sex *string
birthDate *time.Time
lastLoginTime *time.Time
}
err = conn.QueryRow(context.Background(), "selectNulls").Scan(
&record.id,
&record.userName,
&record.email,
&record.name,
&record.sex,
&record.birthDate,
&record.lastLoginTime,
)
if err != nil {
b.Fatal(err)
}
// These checks both ensure that the correct data was returned
// and provide a benchmark of accessing the returned values.
if record.id != 1 {
b.Fatalf("bad value for id: %v", record.id)
}
if record.userName != "johnsmith" {
b.Fatalf("bad value for userName: %v", record.userName)
}
if record.email != nil {
b.Fatalf("bad value for email: %v", record.email)
}
if record.name != nil {
b.Fatalf("bad value for name: %v", record.name)
}
if record.sex != nil {
b.Fatalf("bad value for sex: %v", record.sex)
}
if record.birthDate != nil {
b.Fatalf("bad value for birthDate: %v", record.birthDate)
}
if record.lastLoginTime != nil {
b.Fatalf("bad value for lastLoginTime: %v", record.lastLoginTime)
}
}
}
func BenchmarkPointerPointerWithPresentValues(b *testing.B) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
_, err := conn.Prepare(context.Background(), "selectNulls", "select 1::int4, 'johnsmith', 'johnsmith@example.com', 'John Smith', 'male', '1970-01-01'::date, '2015-01-01 00:00:00'::timestamptz")
if err != nil {
b.Fatal(err)
}
for b.Loop() {
var record struct {
id int32
userName string
email *string
name *string
sex *string
birthDate *time.Time
lastLoginTime *time.Time
}
err = conn.QueryRow(context.Background(), "selectNulls").Scan(
&record.id,
&record.userName,
&record.email,
&record.name,
&record.sex,
&record.birthDate,
&record.lastLoginTime,
)
if err != nil {
b.Fatal(err)
}
// These checks both ensure that the correct data was returned
// and provide a benchmark of accessing the returned values.
if record.id != 1 {
b.Fatalf("bad value for id: %v", record.id)
}
if record.userName != "johnsmith" {
b.Fatalf("bad value for userName: %v", record.userName)
}
if record.email == nil || *record.email != "johnsmith@example.com" {
b.Fatalf("bad value for email: %v", record.email)
}
if record.name == nil || *record.name != "John Smith" {
b.Fatalf("bad value for name: %v", record.name)
}
if record.sex == nil || *record.sex != "male" {
b.Fatalf("bad value for sex: %v", record.sex)
}
if record.birthDate == nil || *record.birthDate != time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC) {
b.Fatalf("bad value for birthDate: %v", record.birthDate)
}
if record.lastLoginTime == nil || *record.lastLoginTime != time.Date(2015, 1, 1, 0, 0, 0, 0, time.Local) {
b.Fatalf("bad value for lastLoginTime: %v", record.lastLoginTime)
}
}
}
const benchmarkWriteTableCreateSQL = `drop table if exists t;
create table t(
varchar_1 varchar not null,
varchar_2 varchar not null,
varchar_null_1 varchar,
date_1 date not null,
date_null_1 date,
int4_1 int4 not null,
int4_2 int4 not null,
int4_null_1 int4,
tstz_1 timestamptz not null,
tstz_2 timestamptz,
bool_1 bool not null,
bool_2 bool not null,
bool_3 bool not null
);
`
const benchmarkWriteTableInsertSQL = `insert into t(
varchar_1,
varchar_2,
varchar_null_1,
date_1,
date_null_1,
int4_1,
int4_2,
int4_null_1,
tstz_1,
tstz_2,
bool_1,
bool_2,
bool_3
) values (
$1::varchar,
$2::varchar,
$3::varchar,
$4::date,
$5::date,
$6::int4,
$7::int4,
$8::int4,
$9::timestamptz,
$10::timestamptz,
$11::bool,
$12::bool,
$13::bool
)`
type benchmarkWriteTableCopyFromSrc struct {
count int
idx int
row []any
}
func (s *benchmarkWriteTableCopyFromSrc) Next() bool {
next := s.idx < s.count
s.idx++
return next
}
func (s *benchmarkWriteTableCopyFromSrc) Values() ([]any, error) {
return s.row, nil
}
func (s *benchmarkWriteTableCopyFromSrc) Err() error {
return nil
}
func newBenchmarkWriteTableCopyFromSrc(count int) pgx.CopyFromSource {
return &benchmarkWriteTableCopyFromSrc{
count: count,
row: []any{
"varchar_1",
"varchar_2",
&pgtype.Text{},
time.Date(2000, 1, 1, 0, 0, 0, 0, time.Local),
&pgtype.Date{},
1,
2,
&pgtype.Int4{},
time.Date(2001, 1, 1, 0, 0, 0, 0, time.Local),
time.Date(2002, 1, 1, 0, 0, 0, 0, time.Local),
true,
false,
true,
},
}
}
func benchmarkWriteNRowsViaInsert(b *testing.B, n int) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
mustExec(b, conn, benchmarkWriteTableCreateSQL)
_, err := conn.Prepare(context.Background(), "insert_t", benchmarkWriteTableInsertSQL)
if err != nil {
b.Fatal(err)
}
for b.Loop() {
src := newBenchmarkWriteTableCopyFromSrc(n)
tx, err := conn.Begin(context.Background())
if err != nil {
b.Fatal(err)
}
for src.Next() {
values, _ := src.Values()
if _, err = tx.Exec(context.Background(), "insert_t", values...); err != nil {
b.Fatalf("Exec unexpectedly failed with: %v", err)
}
}
err = tx.Commit(context.Background())
if err != nil {
b.Fatal(err)
}
}
}
func benchmarkWriteNRowsViaBatchInsert(b *testing.B, n int) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
mustExec(b, conn, benchmarkWriteTableCreateSQL)
_, err := conn.Prepare(context.Background(), "insert_t", benchmarkWriteTableInsertSQL)
if err != nil {
b.Fatal(err)
}
for b.Loop() {
src := newBenchmarkWriteTableCopyFromSrc(n)
batch := &pgx.Batch{}
for src.Next() {
values, _ := src.Values()
batch.Queue("insert_t", values...)
}
err = conn.SendBatch(context.Background(), batch).Close()
if err != nil {
b.Fatal(err)
}
}
}
type queryArgs []any
func (qa *queryArgs) Append(v any) string {
*qa = append(*qa, v)
return "$" + strconv.Itoa(len(*qa))
}
// note this function is only used for benchmarks -- it doesn't escape tableName
// or columnNames
func multiInsert(conn *pgx.Conn, tableName string, columnNames []string, rowSrc pgx.CopyFromSource) (int, error) {
maxRowsPerInsert := 65535 / len(columnNames)
rowsThisInsert := 0
rowCount := 0
sqlBuf := &bytes.Buffer{}
args := make(queryArgs, 0)
resetQuery := func() {
sqlBuf.Reset()
fmt.Fprintf(sqlBuf, "insert into %s(%s) values", tableName, strings.Join(columnNames, ", "))
args = args[0:0]
rowsThisInsert = 0
}
resetQuery()
tx, err := conn.Begin(context.Background())
if err != nil {
return 0, err
}
defer tx.Rollback(context.Background())
for rowSrc.Next() {
if rowsThisInsert > 0 {
sqlBuf.WriteByte(',')
}
sqlBuf.WriteByte('(')
values, err := rowSrc.Values()
if err != nil {
return 0, err
}
for i, val := range values {
if i > 0 {
sqlBuf.WriteByte(',')
}
sqlBuf.WriteString(args.Append(val))
}
sqlBuf.WriteByte(')')
rowsThisInsert++
if rowsThisInsert == maxRowsPerInsert {
_, err := tx.Exec(context.Background(), sqlBuf.String(), args...)
if err != nil {
return 0, err
}
rowCount += rowsThisInsert
resetQuery()
}
}
if rowsThisInsert > 0 {
_, err := tx.Exec(context.Background(), sqlBuf.String(), args...)
if err != nil {
return 0, err
}
rowCount += rowsThisInsert
}
if err := tx.Commit(context.Background()); err != nil {
return 0, err
}
return rowCount, nil
}
func benchmarkWriteNRowsViaMultiInsert(b *testing.B, n int) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
mustExec(b, conn, benchmarkWriteTableCreateSQL)
_, err := conn.Prepare(context.Background(), "insert_t", benchmarkWriteTableInsertSQL)
if err != nil {
b.Fatal(err)
}
for b.Loop() {
src := newBenchmarkWriteTableCopyFromSrc(n)
_, err := multiInsert(conn, "t",
[]string{
"varchar_1",
"varchar_2",
"varchar_null_1",
"date_1",
"date_null_1",
"int4_1",
"int4_2",
"int4_null_1",
"tstz_1",
"tstz_2",
"bool_1",
"bool_2",
"bool_3",
},
src)
if err != nil {
b.Fatal(err)
}
}
}
func benchmarkWriteNRowsViaCopy(b *testing.B, n int) {
conn := mustConnect(b, mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE")))
defer closeConn(b, conn)
mustExec(b, conn, benchmarkWriteTableCreateSQL)
for b.Loop() {
src := newBenchmarkWriteTableCopyFromSrc(n)
_, err := conn.CopyFrom(context.Background(),
pgx.Identifier{"t"},
[]string{
"varchar_1",
"varchar_2",
"varchar_null_1",
"date_1",
"date_null_1",
"int4_1",
"int4_2",
"int4_null_1",
"tstz_1",
"tstz_2",
"bool_1",
"bool_2",
"bool_3",
},
src)
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkWrite2RowsViaInsert(b *testing.B) {
benchmarkWriteNRowsViaInsert(b, 2)
}
func BenchmarkWrite2RowsViaMultiInsert(b *testing.B) {
benchmarkWriteNRowsViaMultiInsert(b, 2)
}
func BenchmarkWrite2RowsViaBatchInsert(b *testing.B) {
benchmarkWriteNRowsViaBatchInsert(b, 2)
}
func BenchmarkWrite2RowsViaCopy(b *testing.B) {
benchmarkWriteNRowsViaCopy(b, 2)
}
func BenchmarkWrite5RowsViaInsert(b *testing.B) {
benchmarkWriteNRowsViaInsert(b, 5)
}
func BenchmarkWrite5RowsViaMultiInsert(b *testing.B) {
benchmarkWriteNRowsViaMultiInsert(b, 5)
}
func BenchmarkWrite5RowsViaBatchInsert(b *testing.B) {
benchmarkWriteNRowsViaBatchInsert(b, 5)
}
func BenchmarkWrite5RowsViaCopy(b *testing.B) {
benchmarkWriteNRowsViaCopy(b, 5)
}
func BenchmarkWrite10RowsViaInsert(b *testing.B) {
benchmarkWriteNRowsViaInsert(b, 10)
}
func BenchmarkWrite10RowsViaMultiInsert(b *testing.B) {
benchmarkWriteNRowsViaMultiInsert(b, 10)
}
func BenchmarkWrite10RowsViaBatchInsert(b *testing.B) {
benchmarkWriteNRowsViaBatchInsert(b, 10)
}
func BenchmarkWrite10RowsViaCopy(b *testing.B) {
benchmarkWriteNRowsViaCopy(b, 10)
}
func BenchmarkWrite100RowsViaInsert(b *testing.B) {
benchmarkWriteNRowsViaInsert(b, 100)
}
func BenchmarkWrite100RowsViaMultiInsert(b *testing.B) {
benchmarkWriteNRowsViaMultiInsert(b, 100)
}
func BenchmarkWrite100RowsViaBatchInsert(b *testing.B) {
benchmarkWriteNRowsViaBatchInsert(b, 100)
}
func BenchmarkWrite100RowsViaCopy(b *testing.B) {
benchmarkWriteNRowsViaCopy(b, 100)
}
func BenchmarkWrite1000RowsViaInsert(b *testing.B) {
benchmarkWriteNRowsViaInsert(b, 1_000)
}
func BenchmarkWrite1000RowsViaMultiInsert(b *testing.B) {
benchmarkWriteNRowsViaMultiInsert(b, 1_000)
}
func BenchmarkWrite1000RowsViaBatchInsert(b *testing.B) {
benchmarkWriteNRowsViaBatchInsert(b, 1_000)
}
func BenchmarkWrite1000RowsViaCopy(b *testing.B) {
benchmarkWriteNRowsViaCopy(b, 1_000)
}
func BenchmarkWrite10000RowsViaInsert(b *testing.B) {
benchmarkWriteNRowsViaInsert(b, 10_000)
}
func BenchmarkWrite10000RowsViaMultiInsert(b *testing.B) {
benchmarkWriteNRowsViaMultiInsert(b, 10_000)
}
func BenchmarkWrite10000RowsViaBatchInsert(b *testing.B) {
benchmarkWriteNRowsViaBatchInsert(b, 10_000)
}
func BenchmarkWrite10000RowsViaCopy(b *testing.B) {
benchmarkWriteNRowsViaCopy(b, 10_000)
}
func BenchmarkMultipleQueriesNonBatchNoStatementCache(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeDescribeExec
config.StatementCacheCapacity = 0
config.DescriptionCacheCapacity = 0
conn := mustConnect(b, config)
defer closeConn(b, conn)
benchmarkMultipleQueriesNonBatch(b, conn, 3)
}
func BenchmarkMultipleQueriesNonBatchPrepareStatementCache(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement
config.StatementCacheCapacity = 32
config.DescriptionCacheCapacity = 0
conn := mustConnect(b, config)
defer closeConn(b, conn)
benchmarkMultipleQueriesNonBatch(b, conn, 3)
}
func BenchmarkMultipleQueriesNonBatchDescribeStatementCache(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheDescribe
config.StatementCacheCapacity = 0
config.DescriptionCacheCapacity = 32
conn := mustConnect(b, config)
defer closeConn(b, conn)
benchmarkMultipleQueriesNonBatch(b, conn, 3)
}
func benchmarkMultipleQueriesNonBatch(b *testing.B, conn *pgx.Conn, queryCount int) {
for b.Loop() {
for range queryCount {
rows, err := conn.Query(context.Background(), "select n from generate_series(0, 5) n")
if err != nil {
b.Fatal(err)
}
for k := 0; rows.Next(); k++ {
var n int
if err := rows.Scan(&n); err != nil {
b.Fatal(err)
}
if n != k {
b.Fatalf("n => %v, want %v", n, k)
}
}
if rows.Err() != nil {
b.Fatal(rows.Err())
}
}
}
}
func BenchmarkMultipleQueriesBatchNoStatementCache(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeDescribeExec
config.StatementCacheCapacity = 0
config.DescriptionCacheCapacity = 0
conn := mustConnect(b, config)
defer closeConn(b, conn)
benchmarkMultipleQueriesBatch(b, conn, 3)
}
func BenchmarkMultipleQueriesBatchPrepareStatementCache(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement
config.StatementCacheCapacity = 32
config.DescriptionCacheCapacity = 0
conn := mustConnect(b, config)
defer closeConn(b, conn)
benchmarkMultipleQueriesBatch(b, conn, 3)
}
func BenchmarkMultipleQueriesBatchDescribeStatementCache(b *testing.B) {
config := mustParseConfig(b, os.Getenv("PGX_TEST_DATABASE"))
config.DefaultQueryExecMode = pgx.QueryExecModeCacheDescribe
config.StatementCacheCapacity = 0
config.DescriptionCacheCapacity = 32
conn := mustConnect(b, config)
defer closeConn(b, conn)
benchmarkMultipleQueriesBatch(b, conn, 3)
}
func benchmarkMultipleQueriesBatch(b *testing.B, conn *pgx.Conn, queryCount int) {
for b.Loop() {
batch := &pgx.Batch{}
for range queryCount {
batch.Queue("select n from generate_series(0,5) n")
}
br := conn.SendBatch(context.Background(), batch)
for range queryCount {
rows, err := br.Query()
if err != nil {
b.Fatal(err)
}
for k := 0; rows.Next(); k++ {
var n int
if err := rows.Scan(&n); err != nil {
b.Fatal(err)
}
if n != k {
b.Fatalf("n => %v, want %v", n, k)
}
}
if rows.Err() != nil {
b.Fatal(rows.Err())
}
}
err := br.Close()
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkSelectManyUnknownEnum(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
ctx := context.Background()
tx, err := conn.Begin(ctx)
require.NoError(b, err)
defer tx.Rollback(ctx)
_, err = tx.Exec(context.Background(), "drop type if exists color;")
require.NoError(b, err)
_, err = tx.Exec(ctx, `create type color as enum ('blue', 'green', 'orange')`)
require.NoError(b, err)
var x, y, z string
for b.Loop() {
rows, err := conn.Query(ctx, "select 'blue'::color, 'green'::color, 'orange'::color from generate_series(1,10)")
if err != nil {
b.Fatal(err)
}
for rows.Next() {
err = rows.Scan(&x, &y, &z)
if err != nil {
b.Fatal(err)
}
if x != "blue" {
b.Fatal("unexpected result")
}
if y != "green" {
b.Fatal("unexpected result")
}
if z != "orange" {
b.Fatal("unexpected result")
}
}
if rows.Err() != nil {
b.Fatal(rows.Err())
}
}
}
func BenchmarkSelectManyRegisteredEnum(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
ctx := context.Background()
tx, err := conn.Begin(ctx)
require.NoError(b, err)
defer tx.Rollback(ctx)
_, err = tx.Exec(context.Background(), "drop type if exists color;")
require.NoError(b, err)
_, err = tx.Exec(ctx, `create type color as enum ('blue', 'green', 'orange')`)
require.NoError(b, err)
var oid uint32
err = conn.QueryRow(context.Background(), "select oid from pg_type where typname=$1;", "color").Scan(&oid)
require.NoError(b, err)
conn.TypeMap().RegisterType(&pgtype.Type{Name: "color", OID: oid, Codec: &pgtype.EnumCodec{}})
var x, y, z string
for b.Loop() {
rows, err := conn.Query(ctx, "select 'blue'::color, 'green'::color, 'orange'::color from generate_series(1,10)")
if err != nil {
b.Fatal(err)
}
for rows.Next() {
err = rows.Scan(&x, &y, &z)
if err != nil {
b.Fatal(err)
}
if x != "blue" {
b.Fatal("unexpected result")
}
if y != "green" {
b.Fatal("unexpected result")
}
if z != "orange" {
b.Fatal("unexpected result")
}
}
if rows.Err() != nil {
b.Fatal(rows.Err())
}
}
}
func getSelectRowsCounts(b *testing.B) []int64 {
var rowCounts []int64
{
s := os.Getenv("PGX_BENCH_SELECT_ROWS_COUNTS")
if s != "" {
for p := range strings.SplitSeq(s, " ") {
n, err := strconv.ParseInt(p, 10, 64)
if err != nil {
b.Fatalf("Bad PGX_BENCH_SELECT_ROWS_COUNTS value: %v", err)
}
rowCounts = append(rowCounts, n)
}
}
}
if len(rowCounts) == 0 {
rowCounts = []int64{1, 10, 100, 1000}
}
return rowCounts
}
type BenchRowSimple struct {
ID int32
FirstName string
LastName string
Sex string
BirthDate time.Time
Weight int32
Height int32
Tags []string
UpdateTime time.Time
}
func BenchmarkSelectRowsScanSimple(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
br := &BenchRowSimple{}
for b.Loop() {
rows, err := conn.Query(context.Background(), "select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n", rowCount)
if err != nil {
b.Fatal(err)
}
for rows.Next() {
rows.Scan(&br.ID, &br.FirstName, &br.LastName, &br.Sex, &br.BirthDate, &br.Weight, &br.Height, &br.Tags, &br.UpdateTime)
}
if rows.Err() != nil {
b.Fatal(rows.Err())
}
}
})
}
}
type BenchRowStringBytes struct {
ID int32
FirstName []byte
LastName []byte
Sex []byte
BirthDate time.Time
Weight int32
Height int32
Tags []string
UpdateTime time.Time
}
func BenchmarkSelectRowsScanStringBytes(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
br := &BenchRowStringBytes{}
for b.Loop() {
rows, err := conn.Query(context.Background(), "select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n", rowCount)
if err != nil {
b.Fatal(err)
}
for rows.Next() {
rows.Scan(&br.ID, &br.FirstName, &br.LastName, &br.Sex, &br.BirthDate, &br.Weight, &br.Height, &br.Tags, &br.UpdateTime)
}
if rows.Err() != nil {
b.Fatal(rows.Err())
}
}
})
}
}
type BenchRowDecoder struct {
ID pgtype.Int4
FirstName pgtype.Text
LastName pgtype.Text
Sex pgtype.Text
BirthDate pgtype.Date
Weight pgtype.Int4
Height pgtype.Int4
Tags pgtype.FlatArray[string]
UpdateTime pgtype.Timestamptz
}
func BenchmarkSelectRowsScanDecoder(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
formats := []struct {
name string
code int16
}{
{"text", pgx.TextFormatCode},
{"binary", pgx.BinaryFormatCode},
}
for _, format := range formats {
b.Run(format.name, func(b *testing.B) {
br := &BenchRowDecoder{}
for b.Loop() {
rows, err := conn.Query(
context.Background(),
"select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n",
pgx.QueryResultFormats{format.code},
rowCount,
)
if err != nil {
b.Fatal(err)
}
for rows.Next() {
rows.Scan(&br.ID, &br.FirstName, &br.LastName, &br.Sex, &br.BirthDate, &br.Weight, &br.Height, &br.Tags, &br.UpdateTime)
}
if rows.Err() != nil {
b.Fatal(rows.Err())
}
}
})
}
})
}
}
func BenchmarkSelectRowsPgConnExecText(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
for b.Loop() {
mrr := conn.PgConn().Exec(context.Background(), fmt.Sprintf("select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + %d) n", rowCount))
for mrr.NextResult() {
rr := mrr.ResultReader()
for rr.NextRow() {
rr.Values()
}
}
err := mrr.Close()
if err != nil {
b.Fatal(err)
}
}
})
}
}
func BenchmarkSelectRowsPgConnExecParams(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
formats := []struct {
name string
code int16
}{
{"text", pgx.TextFormatCode},
{"binary - mostly", pgx.BinaryFormatCode},
}
for _, format := range formats {
b.Run(format.name, func(b *testing.B) {
for b.Loop() {
rr := conn.PgConn().ExecParams(
context.Background(),
"select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n",
[][]byte{[]byte(strconv.FormatInt(rowCount, 10))},
nil,
nil,
[]int16{format.code, pgx.TextFormatCode, pgx.TextFormatCode, pgx.TextFormatCode, format.code, format.code, format.code, format.code, format.code},
)
for rr.NextRow() {
rr.Values()
}
_, err := rr.Close()
if err != nil {
b.Fatal(err)
}
}
})
}
})
}
}
func BenchmarkSelectRowsSimpleCollectRowsRowToStructByPos(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
for b.Loop() {
rows, _ := conn.Query(context.Background(), "select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n", rowCount)
benchRows, err := pgx.CollectRows(rows, pgx.RowToStructByPos[BenchRowSimple])
if err != nil {
b.Fatal(err)
}
if len(benchRows) != int(rowCount) {
b.Fatalf("Expected %d rows, got %d", rowCount, len(benchRows))
}
}
})
}
}
func BenchmarkSelectRowsSimpleAppendRowsRowToStructByPos(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
benchRows := make([]BenchRowSimple, 0, rowCount)
for b.Loop() {
benchRows = benchRows[:0]
rows, _ := conn.Query(context.Background(), "select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n", rowCount)
var err error
benchRows, err = pgx.AppendRows(benchRows, rows, pgx.RowToStructByPos[BenchRowSimple])
if err != nil {
b.Fatal(err)
}
if len(benchRows) != int(rowCount) {
b.Fatalf("Expected %d rows, got %d", rowCount, len(benchRows))
}
}
})
}
}
func BenchmarkSelectRowsSimpleCollectRowsRowToStructByName(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
for b.Loop() {
rows, _ := conn.Query(context.Background(), "select n as id, 'Adam' as first_name, 'Smith ' || n as last_name, 'male' as sex, '1952-06-16'::date as birth_date, 258 as weight, 72 as height, '{foo,bar,baz}'::text[] as tags, '2001-01-28 01:02:03-05'::timestamptz as update_time from generate_series(100001, 100000 + $1) n", rowCount)
benchRows, err := pgx.CollectRows(rows, pgx.RowToStructByName[BenchRowSimple])
if err != nil {
b.Fatal(err)
}
if len(benchRows) != int(rowCount) {
b.Fatalf("Expected %d rows, got %d", rowCount, len(benchRows))
}
}
})
}
}
func BenchmarkSelectRowsSimpleAppendRowsRowToStructByName(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
benchRows := make([]BenchRowSimple, 0, rowCount)
for b.Loop() {
benchRows = benchRows[:0]
rows, _ := conn.Query(context.Background(), "select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n", rowCount)
var err error
benchRows, err = pgx.AppendRows(benchRows, rows, pgx.RowToStructByPos[BenchRowSimple])
if err != nil {
b.Fatal(err)
}
if len(benchRows) != int(rowCount) {
b.Fatalf("Expected %d rows, got %d", rowCount, len(benchRows))
}
}
})
}
}
func BenchmarkSelectRowsPgConnExecPrepared(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
_, err := conn.PgConn().Prepare(context.Background(), "ps1", "select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n", nil)
if err != nil {
b.Fatal(err)
}
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
formats := []struct {
name string
code int16
}{
{"text", pgx.TextFormatCode},
{"binary - mostly", pgx.BinaryFormatCode},
}
for _, format := range formats {
b.Run(format.name, func(b *testing.B) {
for b.Loop() {
rr := conn.PgConn().ExecPrepared(
context.Background(),
"ps1",
[][]byte{[]byte(strconv.FormatInt(rowCount, 10))},
nil,
[]int16{format.code, pgx.TextFormatCode, pgx.TextFormatCode, pgx.TextFormatCode, format.code, format.code, format.code, format.code, format.code},
)
for rr.NextRow() {
rr.Values()
}
_, err := rr.Close()
if err != nil {
b.Fatal(err)
}
}
})
}
})
}
}
func BenchmarkSelectRowsPgConnExecStatement(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE"))
defer closeConn(b, conn)
rowCounts := getSelectRowsCounts(b)
psd, err := conn.PgConn().Prepare(context.Background(), "ps1", "select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n", nil)
if err != nil {
b.Fatal(err)
}
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
formats := []struct {
name string
code int16
}{
{"text", pgx.TextFormatCode},
{"binary - mostly", pgx.BinaryFormatCode},
}
for _, format := range formats {
b.Run(format.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
rr := conn.PgConn().ExecStatement(
context.Background(),
psd,
[][]byte{[]byte(strconv.FormatInt(rowCount, 10))},
nil,
[]int16{format.code, pgx.TextFormatCode, pgx.TextFormatCode, pgx.TextFormatCode, format.code, format.code, format.code, format.code, format.code},
)
for rr.NextRow() {
rr.Values()
}
_, err := rr.Close()
if err != nil {
b.Fatal(err)
}
}
})
}
})
}
}
type queryRecorder struct {
conn net.Conn
writeBuf []byte
readCount int
}
func (qr *queryRecorder) Read(b []byte) (n int, err error) {
n, err = qr.conn.Read(b)
qr.readCount += n
return n, err
}
func (qr *queryRecorder) Write(b []byte) (n int, err error) {
qr.writeBuf = append(qr.writeBuf, b...)
return qr.conn.Write(b)
}
func (qr *queryRecorder) Close() error {
return qr.conn.Close()
}
func (qr *queryRecorder) LocalAddr() net.Addr {
return qr.conn.LocalAddr()
}
func (qr *queryRecorder) RemoteAddr() net.Addr {
return qr.conn.RemoteAddr()
}
func (qr *queryRecorder) SetDeadline(t time.Time) error {
return qr.conn.SetDeadline(t)
}
func (qr *queryRecorder) SetReadDeadline(t time.Time) error {
return qr.conn.SetReadDeadline(t)
}
func (qr *queryRecorder) SetWriteDeadline(t time.Time) error {
return qr.conn.SetWriteDeadline(t)
}
// BenchmarkSelectRowsRawPrepared hijacks a pgconn connection and inserts a queryRecorder. It then executes the query
// once. The benchmark is simply sending the exact query bytes over the wire to the server and reading the expected
// number of bytes back. It does nothing else. This should be the theoretical maximum performance a Go application
// could achieve.
func BenchmarkSelectRowsRawPrepared(b *testing.B) {
rowCounts := getSelectRowsCounts(b)
for _, rowCount := range rowCounts {
b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
formats := []struct {
name string
code int16
}{
{"text", pgx.TextFormatCode},
{"binary - mostly", pgx.BinaryFormatCode},
}
for _, format := range formats {
b.Run(format.name, func(b *testing.B) {
conn := mustConnectString(b, os.Getenv("PGX_TEST_DATABASE")).PgConn()
defer conn.Close(context.Background())
_, err := conn.Prepare(context.Background(), "ps1", "select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '{foo,bar,baz}'::text[], '2001-01-28 01:02:03-05'::timestamptz from generate_series(100001, 100000 + $1) n", nil)
if err != nil {
b.Fatal(err)
}
hijackedConn, err := conn.Hijack()
require.NoError(b, err)
qr := &queryRecorder{
conn: hijackedConn.Conn,
}
hijackedConn.Conn = qr
hijackedConn.Frontend = hijackedConn.Config.BuildFrontend(qr, qr)
conn, err = pgconn.Construct(hijackedConn)
require.NoError(b, err)
{
rr := conn.ExecPrepared(
context.Background(),
"ps1",
[][]byte{[]byte(strconv.FormatInt(rowCount, 10))},
nil,
[]int16{format.code, pgx.TextFormatCode, pgx.TextFormatCode, pgx.TextFormatCode, format.code, format.code, format.code, format.code, format.code},
)
_, err := rr.Close()
require.NoError(b, err)
}
buf := make([]byte, qr.readCount)
b.ResetTimer()
for b.Loop() {
_, err := qr.conn.Write(qr.writeBuf)
if err != nil {
b.Fatal(err)
}
_, err = io.ReadFull(qr.conn, buf)
if err != nil {
b.Fatal(err)
}
}
})
}
})
}
}
================================================
FILE: ci/setup_test.bash
================================================
#!/usr/bin/env bash
set -eux
if [[ "${PGVERSION-}" =~ ^[0-9.]+$ ]]
then
sudo apt-get remove -y --purge postgresql libpq-dev libpq5 postgresql-client-common postgresql-common
sudo rm -rf /var/lib/postgresql
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo sh -c "echo deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main $PGVERSION >> /etc/apt/sources.list.d/postgresql.list"
sudo apt-get update -qq
sudo apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::="--force-confnew" install postgresql-$PGVERSION postgresql-server-dev-$PGVERSION postgresql-contrib-$PGVERSION
sudo cp testsetup/pg_hba.conf /etc/postgresql/$PGVERSION/main/pg_hba.conf
sudo sh -c "echo \"listen_addresses = '127.0.0.1'\" >> /etc/postgresql/$PGVERSION/main/postgresql.conf"
sudo sh -c "cat testsetup/postgresql_ssl.conf >> /etc/postgresql/$PGVERSION/main/postgresql.conf"
if [ "$PGVERSION" -ge 18 ]; then
# Configure and Install OAuth validator for PostgreSQL 18+
sudo sh -c "cat testsetup/oauth_validator_module/postgresql.conf >> /etc/postgresql/$PGVERSION/main/postgresql.conf"
sudo sh -c "cat testsetup/oauth_validator_module/pg_hba.conf >> /etc/postgresql/$PGVERSION/main/pg_hba.conf"
(
cd testsetup/oauth_validator_module
sudo apt-get install -y gcc make libkrb5-dev
make && sudo make install
)
fi
cd testsetup
# Generate CA, server, and encrypted client certificates.
go run generate_certs.go
# Copy certificates to server directory and set permissions.
sudo cp ca.pem /var/lib/postgresql/$PGVERSION/main/root.crt
sudo chown postgres:postgres /var/lib/postgresql/$PGVERSION/main/root.crt
sudo cp localhost.key /var/lib/postgresql/$PGVERSION/main/server.key
sudo chown postgres:postgres /var/lib/postgresql/$PGVERSION/main/server.key
sudo chmod 600 /var/lib/postgresql/$PGVERSION/main/server.key
sudo cp localhost.crt /var/lib/postgresql/$PGVERSION/main/server.crt
sudo chown postgres:postgres /var/lib/postgresql/$PGVERSION/main/server.crt
cp ca.pem /tmp
cp pgx_sslcert.key /tmp
cp pgx_sslcert.crt /tmp
cd ..
sudo /etc/init.d/postgresql restart
createdb -U postgres pgx_test
psql -U postgres -f testsetup/postgresql_setup.sql pgx_test
fi
if [[ "${PGVERSION-}" =~ ^cockroach ]]
then
wget -qO- https://binaries.cockroachdb.com/cockroach-v25.4.4.linux-amd64.tgz | tar xvz
sudo mv cockroach-v25.4.4.linux-amd64/cockroach /usr/local/bin/
cockroach start-single-node --insecure --background --listen-addr=localhost
cockroach sql --insecure -e 'create database pgx_test'
fi
if [ "${CRATEVERSION-}" != "" ]
then
docker run \
-p "6543:5432" \
-d \
crate:"$CRATEVERSION" \
crate \
-Cnetwork.host=0.0.0.0 \
-Ctransport.host=localhost \
-Clicense.enterprise=false
fi
================================================
FILE: conn.go
================================================
package pgx
import (
"context"
"crypto/sha256"
"database/sql"
"encoding/hex"
"errors"
"fmt"
"strconv"
"strings"
"time"
"github.com/jackc/pgx/v5/internal/sanitize"
"github.com/jackc/pgx/v5/internal/stmtcache"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgtype"
)
// ConnConfig contains all the options used to establish a connection. It must be created by ParseConfig and
// then it can be modified. A manually initialized ConnConfig will cause ConnectConfig to panic.
type ConnConfig struct {
pgconn.Config
Tracer QueryTracer
// Original connection string that was parsed into config.
connString string
// StatementCacheCapacity is maximum size of the statement cache used when executing a query with "cache_statement"
// query exec mode.
StatementCacheCapacity int
// DescriptionCacheCapacity is the maximum size of the description cache used when executing a query with
// "cache_describe" query exec mode.
DescriptionCacheCapacity int
// DefaultQueryExecMode controls the default mode for executing queries. By default pgx uses the extended protocol
// and automatically prepares and caches prepared statements. However, this may be incompatible with proxies such as
// PGBouncer. In this case it may be preferable to use QueryExecModeExec or QueryExecModeSimpleProtocol. The same
// functionality can be controlled on a per query basis by passing a QueryExecMode as the first query argument.
DefaultQueryExecMode QueryExecMode
createdByParseConfig bool // Used to enforce created by ParseConfig rule.
}
// ParseConfigOptions contains options that control how a config is built such as getsslpassword.
type ParseConfigOptions struct {
pgconn.ParseConfigOptions
}
// Copy returns a deep copy of the config that is safe to use and modify.
// The only exception is the tls.Config:
// according to the tls.Config docs it must not be modified after creation.
func (cc *ConnConfig) Copy() *ConnConfig {
newConfig := new(ConnConfig)
*newConfig = *cc
newConfig.Config = *newConfig.Config.Copy()
return newConfig
}
// ConnString returns the connection string as parsed by pgx.ParseConfig into pgx.ConnConfig.
func (cc *ConnConfig) ConnString() string { return cc.connString }
// Conn is a PostgreSQL connection handle. It is not safe for concurrent usage. Use a connection pool to manage access
// to multiple database connections from multiple goroutines.
type Conn struct {
pgConn *pgconn.PgConn
config *ConnConfig // config used when establishing this connection
preparedStatements map[string]*pgconn.StatementDescription
failedDescribeStatement string
statementCache stmtcache.Cache
descriptionCache stmtcache.Cache
queryTracer QueryTracer
batchTracer BatchTracer
copyFromTracer CopyFromTracer
prepareTracer PrepareTracer
notifications []*pgconn.Notification
doneChan chan struct{}
closedChan chan error
typeMap *pgtype.Map
wbuf []byte
eqb ExtendedQueryBuilder
}
// Identifier a PostgreSQL identifier or name. Identifiers can be composed of
// multiple parts such as ["schema", "table"] or ["table", "column"].
type Identifier []string
// Sanitize returns a sanitized string safe for SQL interpolation.
func (ident Identifier) Sanitize() string {
parts := make([]string, len(ident))
for i := range ident {
s := strings.ReplaceAll(ident[i], string([]byte{0}), "")
parts[i] = `"` + strings.ReplaceAll(s, `"`, `""`) + `"`
}
return strings.Join(parts, ".")
}
var (
// ErrNoRows occurs when rows are expected but none are returned.
ErrNoRows = newProxyErr(sql.ErrNoRows, "no rows in result set")
// ErrTooManyRows occurs when more rows than expected are returned.
ErrTooManyRows = errors.New("too many rows in result set")
)
func newProxyErr(background error, msg string) error {
return &proxyError{
msg: msg,
background: background,
}
}
type proxyError struct {
msg string
background error
}
func (err *proxyError) Error() string { return err.msg }
func (err *proxyError) Unwrap() error { return err.background }
var (
errDisabledStatementCache = fmt.Errorf("cannot use QueryExecModeCacheStatement with disabled statement cache")
errDisabledDescriptionCache = fmt.Errorf("cannot use QueryExecModeCacheDescribe with disabled description cache")
)
// Connect establishes a connection with a PostgreSQL server with a connection string. See
// pgconn.Connect for details.
func Connect(ctx context.Context, connString string) (*Conn, error) {
connConfig, err := ParseConfig(connString)
if err != nil {
return nil, err
}
return connect(ctx, connConfig)
}
// ConnectWithOptions behaves exactly like Connect with the addition of options. At the present options is only used to
// provide a GetSSLPassword function.
func ConnectWithOptions(ctx context.Context, connString string, options ParseConfigOptions) (*Conn, error) {
connConfig, err := ParseConfigWithOptions(connString, options)
if err != nil {
return nil, err
}
return connect(ctx, connConfig)
}
// ConnectConfig establishes a connection with a PostgreSQL server with a configuration struct.
// connConfig must have been created by ParseConfig.
func ConnectConfig(ctx context.Context, connConfig *ConnConfig) (*Conn, error) {
// In general this improves safety. In particular avoid the config.Config.OnNotification mutation from affecting other
// connections with the same config. See https://github.com/jackc/pgx/issues/618.
connConfig = connConfig.Copy()
return connect(ctx, connConfig)
}
// ParseConfigWithOptions behaves exactly as ParseConfig does with the addition of options. At the present options is
// only used to provide a GetSSLPassword function.
func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*ConnConfig, error) {
config, err := pgconn.ParseConfigWithOptions(connString, options.ParseConfigOptions)
if err != nil {
return nil, err
}
statementCacheCapacity := 512
if s, ok := config.RuntimeParams["statement_cache_capacity"]; ok {
delete(config.RuntimeParams, "statement_cache_capacity")
n, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return nil, pgconn.NewParseConfigError(connString, "cannot parse statement_cache_capacity", err)
}
statementCacheCapacity = int(n)
}
descriptionCacheCapacity := 512
if s, ok := config.RuntimeParams["description_cache_capacity"]; ok {
delete(config.RuntimeParams, "description_cache_capacity")
n, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return nil, pgconn.NewParseConfigError(connString, "cannot parse description_cache_capacity", err)
}
descriptionCacheCapacity = int(n)
}
defaultQueryExecMode := QueryExecModeCacheStatement
if s, ok := config.RuntimeParams["default_query_exec_mode"]; ok {
delete(config.RuntimeParams, "default_query_exec_mode")
switch s {
case "cache_statement":
defaultQueryExecMode = QueryExecModeCacheStatement
case "cache_describe":
defaultQueryExecMode = QueryExecModeCacheDescribe
case "describe_exec":
defaultQueryExecMode = QueryExecModeDescribeExec
case "exec":
defaultQueryExecMode = QueryExecModeExec
case "simple_protocol":
defaultQueryExecMode = QueryExecModeSimpleProtocol
default:
return nil, pgconn.NewParseConfigError(
connString, "invalid default_query_exec_mode", fmt.Errorf("unknown value %q", s),
)
}
}
connConfig := &ConnConfig{
Config: *config,
createdByParseConfig: true,
StatementCacheCapacity: statementCacheCapacity,
DescriptionCacheCapacity: descriptionCacheCapacity,
DefaultQueryExecMode: defaultQueryExecMode,
connString: connString,
}
return connConfig, nil
}
// ParseConfig creates a ConnConfig from a connection string. ParseConfig handles all options that [pgconn.ParseConfig]
// does. In addition, it accepts the following options:
//
// - default_query_exec_mode.
// Possible values: "cache_statement", "cache_describe", "describe_exec", "exec", and "simple_protocol". See
// QueryExecMode constant documentation for the meaning of these values. Default: "cache_statement".
//
// - statement_cache_capacity.
// The maximum size of the statement cache used when executing a query with "cache_statement" query exec mode.
// Default: 512.
//
// - description_cache_capacity.
// The maximum size of the description cache used when executing a query with "cache_describe" query exec mode.
// Default: 512.
func ParseConfig(connString string) (*ConnConfig, error) {
return ParseConfigWithOptions(connString, ParseConfigOptions{})
}
// connect connects to a database. connect takes ownership of config. The caller must not use or access it again.
func connect(ctx context.Context, config *ConnConfig) (c *Conn, err error) {
if connectTracer, ok := config.Tracer.(ConnectTracer); ok {
ctx = connectTracer.TraceConnectStart(ctx, TraceConnectStartData{ConnConfig: config})
defer func() {
connectTracer.TraceConnectEnd(ctx, TraceConnectEndData{Conn: c, Err: err})
}()
}
// Default values are set in ParseConfig. Enforce initial creation by ParseConfig rather than setting defaults from
// zero values.
if !config.createdByParseConfig {
panic("config must be created by ParseConfig")
}
c = &Conn{
config: config,
typeMap: pgtype.NewMap(),
queryTracer: config.Tracer,
}
if t, ok := c.queryTracer.(BatchTracer); ok {
c.batchTracer = t
}
if t, ok := c.queryTracer.(CopyFromTracer); ok {
c.copyFromTracer = t
}
if t, ok := c.queryTracer.(PrepareTracer); ok {
c.prepareTracer = t
}
// Only install pgx notification system if no other callback handler is present.
if config.Config.OnNotification == nil {
config.Config.OnNotification = c.bufferNotifications
}
c.pgConn, err = pgconn.ConnectConfig(ctx, &config.Config)
if err != nil {
return nil, err
}
c.preparedStatements = make(map[string]*pgconn.StatementDescription)
c.doneChan = make(chan struct{})
c.closedChan = make(chan error)
c.wbuf = make([]byte, 0, 1024)
if c.config.StatementCacheCapacity > 0 {
c.statementCache = stmtcache.NewLRUCache(c.config.StatementCacheCapacity)
}
if c.config.DescriptionCacheCapacity > 0 {
c.descriptionCache = stmtcache.NewLRUCache(c.config.DescriptionCacheCapacity)
}
return c, nil
}
// Close closes a connection. It is safe to call Close on an already closed
// connection.
func (c *Conn) Close(ctx context.Context) error {
if c.IsClosed() {
return nil
}
err := c.pgConn.Close(ctx)
return err
}
// Prepare creates a prepared statement with name and sql. sql can contain placeholders for bound parameters. These
// placeholders are referenced positionally as $1, $2, etc. name can be used instead of sql with Query, QueryRow, and
// Exec to execute the statement. It can also be used with Batch.Queue.
//
// The underlying PostgreSQL identifier for the prepared statement will be name if name != sql or a digest of sql if
// name == sql.
//
// Prepare is idempotent; i.e. it is safe to call Prepare multiple times with the same name and sql arguments. This
// allows a code path to Prepare and Query/Exec without concern for if the statement has already been prepared.
func (c *Conn) Prepare(ctx context.Context, name, sql string) (sd *pgconn.StatementDescription, err error) {
if c.failedDescribeStatement != "" {
err = c.Deallocate(ctx, c.failedDescribeStatement)
if err != nil {
return nil, fmt.Errorf("failed to deallocate previously failed statement %q: %w", c.failedDescribeStatement, err)
}
c.failedDescribeStatement = ""
}
if c.prepareTracer != nil {
ctx = c.prepareTracer.TracePrepareStart(ctx, c, TracePrepareStartData{Name: name, SQL: sql})
}
if name != "" {
var ok bool
if sd, ok = c.preparedStatements[name]; ok && sd.SQL == sql {
if c.prepareTracer != nil {
c.prepareTracer.TracePrepareEnd(ctx, c, TracePrepareEndData{AlreadyPrepared: true})
}
return sd, nil
}
}
if c.prepareTracer != nil {
defer func() {
c.prepareTracer.TracePrepareEnd(ctx, c, TracePrepareEndData{Err: err})
}()
}
var psName, psKey string
if name == sql {
digest := sha256.Sum256([]byte(sql))
psName = "stmt_" + hex.EncodeToString(digest[0:24])
psKey = sql
} else {
psName = name
psKey = name
}
sd, err = c.pgConn.Prepare(ctx, psName, sql, nil)
if err != nil {
var pErr *pgconn.PrepareError
if errors.As(err, &pErr) {
c.failedDescribeStatement = psKey
}
return nil, err
}
if psKey != "" {
c.preparedStatements[psKey] = sd
}
return sd, nil
}
// Deallocate releases a prepared statement. Calling Deallocate on a non-existent prepared statement will succeed.
func (c *Conn) Deallocate(ctx context.Context, name string) error {
var psName string
sd := c.preparedStatements[name]
if sd != nil {
psName = sd.Name
} else {
psName = name
}
err := c.pgConn.Deallocate(ctx, psName)
if err != nil {
return err
}
if sd != nil {
delete(c.preparedStatements, name)
}
return nil
}
// DeallocateAll releases all previously prepared statements from the server and client, where it also resets the statement and description cache.
func (c *Conn) DeallocateAll(ctx context.Context) error {
c.preparedStatements = map[string]*pgconn.StatementDescription{}
if c.config.StatementCacheCapacity > 0 {
c.statementCache = stmtcache.NewLRUCache(c.config.StatementCacheCapacity)
}
if c.config.DescriptionCacheCapacity > 0 {
c.descriptionCache = stmtcache.NewLRUCache(c.config.DescriptionCacheCapacity)
}
_, err := c.pgConn.Exec(ctx, "deallocate all").ReadAll()
return err
}
func (c *Conn) bufferNotifications(_ *pgconn.PgConn, n *pgconn.Notification) {
c.notifications = append(c.notifications, n)
}
// WaitForNotification waits for a PostgreSQL notification. It wraps the underlying pgconn notification system in a
// slightly more convenient form.
func (c *Conn) WaitForNotification(ctx context.Context) (*pgconn.Notification, error) {
var n *pgconn.Notification
// Return already received notification immediately
if len(c.notifications) > 0 {
n = c.notifications[0]
c.notifications = c.notifications[1:]
return n, nil
}
err := c.pgConn.WaitForNotification(ctx)
if len(c.notifications) > 0 {
n = c.notifications[0]
c.notifications = c.notifications[1:]
}
return n, err
}
// IsClosed reports if the connection has been closed.
func (c *Conn) IsClosed() bool {
return c.pgConn.IsClosed()
}
func (c *Conn) die() {
if c.IsClosed() {
return
}
ctx, cancel := context.WithCancel(context.Background())
cancel() // force immediate hard cancel
c.pgConn.Close(ctx)
}
func quoteIdentifier(s string) string {
return `"` + strings.ReplaceAll(s, `"`, `""`) + `"`
}
// Ping delegates to the underlying *pgconn.PgConn.Ping.
func (c *Conn) Ping(ctx context.Context) error {
return c.pgConn.Ping(ctx)
}
// PgConn returns the underlying *pgconn.PgConn. This is an escape hatch method that allows lower level access to the
// PostgreSQL connection than pgx exposes.
//
// It is strongly recommended that the connection be idle (no in-progress queries) before the underlying *pgconn.PgConn
// is used and the connection must be returned to the same state before any *pgx.Conn methods are again used.
func (c *Conn) PgConn() *pgconn.PgConn { return c.pgConn }
// TypeMap returns the connection info used for this connection.
func (c *Conn) TypeMap() *pgtype.Map { return c.typeMap }
// Config returns a copy of config that was used to establish this connection.
func (c *Conn) Config() *ConnConfig { return c.config.Copy() }
// Exec executes sql. sql can be either a prepared statement name or an SQL string. arguments should be referenced
// positionally from the sql string as $1, $2, etc.
func (c *Conn) Exec(ctx context.Context, sql string, arguments ...any) (pgconn.CommandTag, error) {
if c.queryTracer != nil {
ctx = c.queryTracer.TraceQueryStart(ctx, c, TraceQueryStartData{SQL: sql, Args: arguments})
}
if err := c.deallocateInvalidatedCachedStatements(ctx); err != nil {
return pgconn.CommandTag{}, err
}
commandTag, err := c.exec(ctx, sql, arguments...)
if c.queryTracer != nil {
c.queryTracer.TraceQueryEnd(ctx, c, TraceQueryEndData{CommandTag: commandTag, Err: err})
}
return commandTag, err
}
func (c *Conn) exec(ctx context.Context, sql string, arguments ...any) (commandTag pgconn.CommandTag, err error) {
mode := c.config.DefaultQueryExecMode
var queryRewriter QueryRewriter
optionLoop:
for len(arguments) > 0 {
switch arg := arguments[0].(type) {
case QueryExecMode:
mode = arg
arguments = arguments[1:]
case QueryRewriter:
queryRewriter = arg
arguments = arguments[1:]
default:
break optionLoop
}
}
if queryRewriter != nil {
sql, arguments, err = queryRewriter.RewriteQuery(ctx, c, sql, arguments)
if err != nil {
return pgconn.CommandTag{}, fmt.Errorf("rewrite query failed: %w", err)
}
}
// Always use simple protocol when there are no arguments.
if len(arguments) == 0 {
mode = QueryExecModeSimpleProtocol
}
defer func() {
if err != nil {
if sc := c.statementCache; sc != nil {
sc.Invalidate(sql)
}
if sc := c.descriptionCache; sc != nil {
sc.Invalidate(sql)
}
}
}()
if sd, ok := c.preparedStatements[sql]; ok {
return c.execPrepared(ctx, sd, arguments)
}
switch mode {
case QueryExecModeCacheStatement:
if c.statementCache == nil {
return pgconn.CommandTag{}, errDisabledStatementCache
}
sd := c.statementCache.Get(sql)
if sd == nil {
sd, err = c.Prepare(ctx, stmtcache.StatementName(sql), sql)
if err != nil {
return pgconn.CommandTag{}, err
}
c.statementCache.Put(sd)
}
return c.execPrepared(ctx, sd, arguments)
case QueryExecModeCacheDescribe:
if c.descriptionCache == nil {
return pgconn.CommandTag{}, errDisabledDescriptionCache
}
sd := c.descriptionCache.Get(sql)
if sd == nil {
sd, err = c.Prepare(ctx, "", sql)
if err != nil {
return pgconn.CommandTag{}, err
}
c.descriptionCache.Put(sd)
}
return c.execParams(ctx, sd, arguments)
case QueryExecModeDescribeExec:
sd, err := c.Prepare(ctx, "", sql)
if err != nil {
return pgconn.CommandTag{}, err
}
return c.execPrepared(ctx, sd, arguments)
case QueryExecModeExec:
return c.execSQLParams(ctx, sql, arguments)
case QueryExecModeSimpleProtocol:
return c.execSimpleProtocol(ctx, sql, arguments)
default:
return pgconn.CommandTag{}, fmt.Errorf("unknown QueryExecMode: %v", mode)
}
}
func (c *Conn) execSimpleProtocol(ctx context.Context, sql string, arguments []any) (commandTag pgconn.CommandTag, err error) {
if len(arguments) > 0 {
sql, err = c.sanitizeForSimpleQuery(sql, arguments...)
if err != nil {
return pgconn.CommandTag{}, err
}
}
mrr := c.pgConn.Exec(ctx, sql)
for mrr.NextResult() {
commandTag, _ = mrr.ResultReader().Close()
}
err = mrr.Close()
return commandTag, err
}
func (c *Conn) execParams(ctx context.Context, sd *pgconn.StatementDescription, arguments []any) (pgconn.CommandTag, error) {
err := c.eqb.Build(c.typeMap, sd, arguments)
if err != nil {
return pgconn.CommandTag{}, err
}
result := c.pgConn.ExecParams(ctx, sd.SQL, c.eqb.ParamValues, sd.ParamOIDs, c.eqb.ParamFormats, c.eqb.ResultFormats).Read()
c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible.
return result.CommandTag, result.Err
}
func (c *Conn) execPrepared(ctx context.Context, sd *pgconn.StatementDescription, arguments []any) (pgconn.CommandTag, error) {
err := c.eqb.Build(c.typeMap, sd, arguments)
if err != nil {
return pgconn.CommandTag{}, err
}
result := c.pgConn.ExecStatement(ctx, sd, c.eqb.ParamValues, c.eqb.ParamFormats, c.eqb.ResultFormats).Read()
c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible.
return result.CommandTag, result.Err
}
func (c *Conn) execSQLParams(ctx context.Context, sql string, args []any) (pgconn.CommandTag, error) {
err := c.eqb.Build(c.typeMap, nil, args)
if err != nil {
return pgconn.CommandTag{}, err
}
result := c.pgConn.ExecParams(ctx, sql, c.eqb.ParamValues, nil, c.eqb.ParamFormats, c.eqb.ResultFormats).Read()
c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible.
return result.CommandTag, result.Err
}
func (c *Conn) getRows(ctx context.Context, sql string, args []any) *baseRows {
r := &baseRows{}
r.ctx = ctx
r.queryTracer = c.queryTracer
r.typeMap = c.typeMap
r.startTime = time.Now()
r.sql = sql
r.args = args
r.conn = c
return r
}
type QueryExecMode int32
const (
_ QueryExecMode = iota
// Automatically prepare and cache statements. This uses the extended protocol. Queries are executed in a single round
// trip after the statement is cached. This is the default. If the database schema is modified or the search_path is
// changed after a statement is cached then the first execution of a previously cached query may fail. e.g. If the
// number of columns returned by a "SELECT *" changes or the type of a column is changed.
QueryExecModeCacheStatement
// Cache statement descriptions (i.e. argument and result types) and assume they do not change. This uses the extended
// protocol. Queries are executed in a single round trip after the description is cached. If the database schema is
// modified or the search_path is changed after a statement is cached then the first execution of a previously cached
// query may fail. e.g. If the number of columns returned by a "SELECT *" changes or the type of a column is changed.
QueryExecModeCacheDescribe
// Get the statement description on every execution. This uses the extended protocol. Queries require two round trips
// to execute. It does not use named prepared statements. But it does use the unnamed prepared statement to get the
// statement description on the first round trip and then uses it to execute the query on the second round trip. This
// may cause problems with connection poolers that switch the underlying connection between round trips. It is safe
// even when the database schema is modified concurrently.
QueryExecModeDescribeExec
// Assume the PostgreSQL query parameter types based on the Go type of the arguments. This uses the extended protocol
// with text formatted parameters and results. Queries are executed in a single round trip. Type mappings can be
// registered with pgtype.Map.RegisterDefaultPgType. Queries will be rejected that have arguments that are
// unregistered or ambiguous. e.g. A map[string]string may have the PostgreSQL type json or hstore. Modes that know
// the PostgreSQL type can use a map[string]string directly as an argument. This mode cannot.
//
// On rare occasions user defined types may behave differently when encoded in the text format instead of the binary
// format. For example, this could happen if a "type RomanNumeral int32" implements fmt.Stringer to format integers as
// Roman numerals (e.g. 7 is VII). The binary format would properly encode the integer 7 as the binary value for 7.
// But the text format would encode the integer 7 as the string "VII". As QueryExecModeExec uses the text format, it
// is possible that changing query mode from another mode to QueryExecModeExec could change the behavior of the query.
// This should not occur with types pgx supports directly and can be avoided by registering the types with
// pgtype.Map.RegisterDefaultPgType and implementing the appropriate type interfaces. In the cas of RomanNumeral, it
// should implement pgtype.Int64Valuer.
QueryExecModeExec
// Use the simple protocol. Assume the PostgreSQL query parameter types based on the Go type of the arguments. This is
// especially significant for []byte values. []byte values are encoded as PostgreSQL bytea. string must be used
// instead for text type values including json and jsonb. Type mappings can be registered with
// pgtype.Map.RegisterDefaultPgType. Queries will be rejected that have arguments that are unregistered or ambiguous.
// e.g. A map[string]string may have the PostgreSQL type json or hstore. Modes that know the PostgreSQL type can use a
// map[string]string directly as an argument. This mode cannot. Queries are executed in a single round trip.
//
// QueryExecModeSimpleProtocol should have the user application visible behavior as QueryExecModeExec. This includes
// the warning regarding differences in text format and binary format encoding with user defined types. There may be
// other minor exceptions such as behavior when multiple result returning queries are erroneously sent in a single
// string.
//
// QueryExecModeSimpleProtocol uses client side parameter interpolation. All values are quoted and escaped. Prefer
// QueryExecModeExec over QueryExecModeSimpleProtocol whenever possible. In general QueryExecModeSimpleProtocol should
// only be used if connecting to a proxy server, connection pool server, or non-PostgreSQL server that does not
// support the extended protocol.
QueryExecModeSimpleProtocol
)
func (m QueryExecMode) String() string {
switch m {
case QueryExecModeCacheStatement:
return "cache statement"
case QueryExecModeCacheDescribe:
return "cache describe"
case QueryExecModeDescribeExec:
return "describe exec"
case QueryExecModeExec:
return "exec"
case QueryExecModeSimpleProtocol:
return "simple protocol"
default:
return "invalid"
}
}
// QueryResultFormats controls the result format (text=0, binary=1) of a query by result column position.
type QueryResultFormats []int16
// QueryResultFormatsByOID controls the result format (text=0, binary=1) of a query by the result column OID.
type QueryResultFormatsByOID map[uint32]int16
// QueryRewriter rewrites a query when used as the first arguments to a query method.
type QueryRewriter interface {
RewriteQuery(ctx context.Context, conn *Conn, sql string, args []any) (newSQL string, newArgs []any, err error)
}
// Query sends a query to the server and returns a Rows to read the results. Only errors encountered sending the query
// and initializing Rows will be returned. Err() on the returned Rows must be checked after the Rows is closed to
// determine if the query executed successfully.
//
// The returned Rows must be closed before the connection can be used again. It is safe to attempt to read from the
// returned Rows even if an error is returned. The error will be the available in rows.Err() after rows are closed. It
// is allowed to ignore the error returned from Query and handle it in Rows.
//
// It is possible for a call of FieldDescriptions on the returned Rows to return nil even if the Query call did not
// return an error.
//
// It is possible for a query to return one or more rows before encountering an error. In most cases the rows should be
// collected before processing rather than processed while receiving each row. This avoids the possibility of the
// application processing rows from a query that the server rejected. The CollectRows function is useful here.
//
// An implementor of QueryRewriter may be passed as the first element of args. It can rewrite the sql and change or
// replace args. For example, NamedArgs is QueryRewriter that implements named arguments.
//
// For extra control over how the query is executed, the types QueryExecMode, QueryResultFormats, and
// QueryResultFormatsByOID may be used as the first args to control exactly how the query is executed. This is rarely
// needed. See the documentation for those types for details.
func (c *Conn) Query(ctx context.Context, sql string, args ...any) (Rows, error) {
if c.queryTracer != nil {
ctx = c.queryTracer.TraceQueryStart(ctx, c, TraceQueryStartData{SQL: sql, Args: args})
}
if err := c.deallocateInvalidatedCachedStatements(ctx); err != nil {
if c.queryTracer != nil {
c.queryTracer.TraceQueryEnd(ctx, c, TraceQueryEndData{Err: err})
}
return &baseRows{err: err, closed: true}, err
}
var resultFormats QueryResultFormats
var resultFormatsByOID QueryResultFormatsByOID
mode := c.config.DefaultQueryExecMode
var queryRewriter QueryRewriter
optionLoop:
for len(args) > 0 {
switch arg := args[0].(type) {
case QueryResultFormats:
resultFormats = arg
args = args[1:]
case QueryResultFormatsByOID:
resultFormatsByOID = arg
args = args[1:]
case QueryExecMode:
mode = arg
args = args[1:]
case QueryRewriter:
queryRewriter = arg
args = args[1:]
default:
break optionLoop
}
}
if queryRewriter != nil {
var err error
originalSQL := sql
originalArgs := args
sql, args, err = queryRewriter.RewriteQuery(ctx, c, sql, args)
if err != nil {
rows := c.getRows(ctx, originalSQL, originalArgs)
err = fmt.Errorf("rewrite query failed: %w", err)
rows.fatal(err)
return rows, err
}
}
// Bypass any statement caching.
if sql == "" {
mode = QueryExecModeSimpleProtocol
}
c.eqb.reset()
rows := c.getRows(ctx, sql, args)
var err error
sd, explicitPreparedStatement := c.preparedStatements[sql]
if sd != nil || mode == QueryExecModeCacheStatement || mode == QueryExecModeCacheDescribe || mode == QueryExecModeDescribeExec {
if sd == nil {
sd, err = c.getStatementDescription(ctx, mode, sql)
if err != nil {
rows.fatal(err)
return rows, err
}
}
if len(sd.ParamOIDs) != len(args) {
rows.fatal(fmt.Errorf("expected %d arguments, got %d", len(sd.ParamOIDs), len(args)))
return rows, rows.err
}
rows.sql = sd.SQL
err = c.eqb.Build(c.typeMap, sd, args)
if err != nil {
rows.fatal(err)
return rows, rows.err
}
if resultFormatsByOID != nil {
resultFormats = make([]int16, len(sd.Fields))
for i := range resultFormats {
resultFormats[i] = resultFormatsByOID[uint32(sd.Fields[i].DataTypeOID)]
}
}
if resultFormats == nil {
resultFormats = c.eqb.ResultFormats
}
if !explicitPreparedStatement && mode == QueryExecModeCacheDescribe {
rows.resultReader = c.pgConn.ExecParams(ctx, sql, c.eqb.ParamValues, sd.ParamOIDs, c.eqb.ParamFormats, resultFormats)
} else {
rows.resultReader = c.pgConn.ExecStatement(ctx, sd, c.eqb.ParamValues, c.eqb.ParamFormats, resultFormats)
}
} else if mode == QueryExecModeExec {
err := c.eqb.Build(c.typeMap, nil, args)
if err != nil {
rows.fatal(err)
return rows, rows.err
}
rows.resultReader = c.pgConn.ExecParams(ctx, sql, c.eqb.ParamValues, nil, c.eqb.ParamFormats, c.eqb.ResultFormats)
} else if mode == QueryExecModeSimpleProtocol {
sql, err = c.sanitizeForSimpleQuery(sql, args...)
if err != nil {
rows.fatal(err)
return rows, err
}
mrr := c.pgConn.Exec(ctx, sql)
if mrr.NextResult() {
rows.resultReader = mrr.ResultReader()
rows.multiResultReader = mrr
} else {
err = mrr.Close()
rows.fatal(err)
return rows, err
}
return rows, nil
} else {
err = fmt.Errorf("unknown QueryExecMode: %v", mode)
rows.fatal(err)
return rows, rows.err
}
c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible.
return rows, rows.err
}
// getStatementDescription returns the statement description of the sql query
// according to the given mode.
//
// If the mode is one that doesn't require to know the param and result OIDs
// then nil is returned without error.
func (c *Conn) getStatementDescription(
ctx context.Context,
mode QueryExecMode,
sql string,
) (sd *pgconn.StatementDescription, err error) {
switch mode {
case QueryExecModeCacheStatement:
if c.statementCache == nil {
return nil, errDisabledStatementCache
}
sd = c.statementCache.Get(sql)
if sd == nil {
sd, err = c.Prepare(ctx, stmtcache.StatementName(sql), sql)
if err != nil {
return nil, err
}
c.statementCache.Put(sd)
}
case QueryExecModeCacheDescribe:
if c.descriptionCache == nil {
return nil, errDisabledDescriptionCache
}
sd = c.descriptionCache.Get(sql)
if sd == nil {
sd, err = c.Prepare(ctx, "", sql)
if err != nil {
return nil, err
}
c.descriptionCache.Put(sd)
}
case QueryExecModeDescribeExec:
return c.Prepare(ctx, "", sql)
}
return sd, err
}
// QueryRow is a convenience wrapper over Query. Any error that occurs while
// querying is deferred until calling Scan on the returned Row. That Row will
// error with ErrNoRows if no rows are returned.
func (c *Conn) QueryRow(ctx context.Context, sql string, args ...any) Row {
rows, _ := c.Query(ctx, sql, args...)
return (*connRow)(rows.(*baseRows))
}
// SendBatch sends all queued queries to the server at once. All queries are run in an implicit transaction unless
// explicit transaction control statements are executed. The returned BatchResults must be closed before the connection
// is used again.
//
// Depending on the QueryExecMode, all queries may be prepared before any are executed. This means that creating a table
// and using it in a subsequent query in the same batch can fail.
func (c *Conn) SendBatch(ctx context.Context, b *Batch) (br BatchResults) {
if len(b.QueuedQueries) == 0 {
return &emptyBatchResults{conn: c}
}
if c.batchTracer != nil {
ctx = c.batchTracer.TraceBatchStart(ctx, c, TraceBatchStartData{Batch: b})
defer func() {
err := br.(interface{ earlyError() error }).earlyError()
if err != nil {
c.batchTracer.TraceBatchEnd(ctx, c, TraceBatchEndData{Err: err})
}
}()
}
if err := c.deallocateInvalidatedCachedStatements(ctx); err != nil {
return &batchResults{ctx: ctx, conn: c, err: err}
}
for _, bi := range b.QueuedQueries {
var queryRewriter QueryRewriter
sql := bi.SQL
arguments := bi.Arguments
optionLoop:
for len(arguments) > 0 {
// Update Batch.Queue function comment when additional options are implemented
switch arg := arguments[0].(type) {
case QueryRewriter:
queryRewriter = arg
arguments = arguments[1:]
default:
break optionLoop
}
}
if queryRewriter != nil {
var err error
sql, arguments, err = queryRewriter.RewriteQuery(ctx, c, sql, arguments)
if err != nil {
return &batchResults{ctx: ctx, conn: c, err: fmt.Errorf("rewrite query failed: %w", err)}
}
}
bi.SQL = sql
bi.Arguments = arguments
}
// TODO: changing mode per batch? Update Batch.Queue function comment when implemented
mode := c.config.DefaultQueryExecMode
if mode == QueryExecModeSimpleProtocol {
return c.sendBatchQueryExecModeSimpleProtocol(ctx, b)
}
// All other modes use extended protocol and thus can use prepared statements.
for _, bi := range b.QueuedQueries {
if sd, ok := c.preparedStatements[bi.SQL]; ok {
bi.sd = sd
}
}
switch mode {
case QueryExecModeExec:
return c.sendBatchQueryExecModeExec(ctx, b)
case QueryExecModeCacheStatement:
return c.sendBatchQueryExecModeCacheStatement(ctx, b)
case QueryExecModeCacheDescribe:
return c.sendBatchQueryExecModeCacheDescribe(ctx, b)
case QueryExecModeDescribeExec:
return c.sendBatchQueryExecModeDescribeExec(ctx, b)
default:
panic("unknown QueryExecMode")
}
}
func (c *Conn) sendBatchQueryExecModeSimpleProtocol(ctx context.Context, b *Batch) *batchResults {
var sb strings.Builder
for i, bi := range b.QueuedQueries {
if i > 0 {
sb.WriteByte(';')
}
sql, err := c.sanitizeForSimpleQuery(bi.SQL, bi.Arguments...)
if err != nil {
return &batchResults{ctx: ctx, conn: c, err: err}
}
sb.WriteString(sql)
}
mrr := c.pgConn.Exec(ctx, sb.String())
return &batchResults{
ctx: ctx,
conn: c,
mrr: mrr,
b: b,
qqIdx: 0,
}
}
func (c *Conn) sendBatchQueryExecModeExec(ctx context.Context, b *Batch) *batchResults {
batch := &pgconn.Batch{}
for _, bi := range b.QueuedQueries {
sd := bi.sd
if sd != nil {
err := c.eqb.Build(c.typeMap, sd, bi.Arguments)
if err != nil {
return &batchResults{ctx: ctx, conn: c, err: err}
}
batch.ExecPrepared(sd.Name, c.eqb.ParamValues, c.eqb.ParamFormats, c.eqb.ResultFormats)
} else {
err := c.eqb.Build(c.typeMap, nil, bi.Arguments)
if err != nil {
return &batchResults{ctx: ctx, conn: c, err: err}
}
batch.ExecParams(bi.SQL, c.eqb.ParamValues, nil, c.eqb.ParamFormats, c.eqb.ResultFormats)
}
}
c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible.
mrr := c.pgConn.ExecBatch(ctx, batch)
return &batchResults{
ctx: ctx,
conn: c,
mrr: mrr,
b: b,
qqIdx: 0,
}
}
func (c *Conn) sendBatchQueryExecModeCacheStatement(ctx context.Context, b *Batch) (pbr *pipelineBatchResults) {
if c.statementCache == nil {
return &pipelineBatchResults{ctx: ctx, conn: c, err: errDisabledStatementCache, closed: true}
}
distinctNewQueries := []*pgconn.StatementDescription{}
distinctNewQueriesIdxMap := make(map[string]int)
for _, bi := range b.QueuedQueries {
if bi.sd == nil {
sd := c.statementCache.Get(bi.SQL)
if sd != nil {
bi.sd = sd
} else {
if idx, present := distinctNewQueriesIdxMap[bi.SQL]; present {
bi.sd = distinctNewQueries[idx]
} else {
sd = &pgconn.StatementDescription{
Name: stmtcache.StatementName(bi.SQL),
SQL: bi.SQL,
}
distinctNewQueriesIdxMap[sd.SQL] = len(distinctNewQueries)
distinctNewQueries = append(distinctNewQueries, sd)
bi.sd = sd
}
}
}
}
return c.sendBatchExtendedWithDescription(ctx, b, distinctNewQueries, c.statementCache)
}
func (c *Conn) sendBatchQueryExecModeCacheDescribe(ctx context.Context, b *Batch) (pbr *pipelineBatchResults) {
if c.descriptionCache == nil {
return &pipelineBatchResults{ctx: ctx, conn: c, err: errDisabledDescriptionCache, closed: true}
}
distinctNewQueries := []*pgconn.StatementDescription{}
distinctNewQueriesIdxMap := make(map[string]int)
for _, bi := range b.QueuedQueries {
if bi.sd == nil {
sd := c.descriptionCache.Get(bi.SQL)
if sd != nil {
bi.sd = sd
} else {
if idx, present := distinctNewQueriesIdxMap[bi.SQL]; present {
bi.sd = distinctNewQueries[idx]
} else {
sd = &pgconn.StatementDescription{
SQL: bi.SQL,
}
distinctNewQueriesIdxMap[sd.SQL] = len(distinctNewQueries)
distinctNewQueries = append(distinctNewQueries, sd)
bi.sd = sd
}
}
}
}
return c.sendBatchExtendedWithDescription(ctx, b, distinctNewQueries, c.descriptionCache)
}
func (c *Conn) sendBatchQueryExecModeDescribeExec(ctx context.Context, b *Batch) (pbr *pipelineBatchResults) {
distinctNewQueries := []*pgconn.StatementDescription{}
distinctNewQueriesIdxMap := make(map[string]int)
for _, bi := range b.QueuedQueries {
if bi.sd == nil {
if idx, present := distinctNewQueriesIdxMap[bi.SQL]; present {
bi.sd = distinctNewQueries[idx]
} else {
sd := &pgconn.StatementDescription{
SQL: bi.SQL,
}
distinctNewQueriesIdxMap[sd.SQL] = len(distinctNewQueries)
distinctNewQueries = append(distinctNewQueries, sd)
bi.sd = sd
}
}
}
return c.sendBatchExtendedWithDescription(ctx, b, distinctNewQueries, nil)
}
func (c *Conn) sendBatchExtendedWithDescription(ctx context.Context, b *Batch, distinctNewQueries []*pgconn.StatementDescription, sdCache stmtcache.Cache) (pbr *pipelineBatchResults) {
pipeline := c.pgConn.StartPipeline(ctx)
defer func() {
if pbr != nil && pbr.err != nil {
pipeline.Close()
}
}()
// Prepare any needed queries
if len(distinctNewQueries) > 0 {
err := func() (err error) {
for _, sd := range distinctNewQueries {
pipeline.SendPrepare(sd.Name, sd.SQL, nil)
}
// Store all statements we are preparing into the cache. It's fine if it overflows because HandleInvalidated will
// clean them up later.
if sdCache != nil {
for _, sd := range distinctNewQueries {
sdCache.Put(sd)
}
}
// If something goes wrong preparing the statements, we need to invalidate the cache entries we just added.
defer func() {
if err != nil && sdCache != nil {
for _, sd := range distinctNewQueries {
sdCache.Invalidate(sd.SQL)
}
}
}()
err = pipeline.Sync()
if err != nil {
return err
}
for _, sd := range distinctNewQueries {
results, err := pipeline.GetResults()
if err != nil {
return newErrPreprocessingBatch("prepare", sd.SQL, err)
}
resultSD, ok := results.(*pgconn.StatementDescription)
if !ok {
return fmt.Errorf("expected statement description, got %T", results)
}
// Fill in the previously empty / pending statement descriptions.
sd.ParamOIDs = resultSD.ParamOIDs
sd.Fields = resultSD.Fields
}
results, err := pipeline.GetResults()
if err != nil {
return err
}
_, ok := results.(*pgconn.PipelineSync)
if !ok {
return fmt.Errorf("expected sync, got %T", results)
}
return nil
}()
if err != nil {
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
}
}
// Queue the queries.
for _, bi := range b.QueuedQueries {
err := c.eqb.Build(c.typeMap, bi.sd, bi.Arguments)
if err != nil {
err = newErrPreprocessingBatch("build", bi.SQL, err)
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
}
if bi.sd.Name == "" {
pipeline.SendQueryParams(bi.sd.SQL, c.eqb.ParamValues, bi.sd.ParamOIDs, c.eqb.ParamFormats, c.eqb.ResultFormats)
} else {
pipeline.SendQueryStatement(bi.sd, c.eqb.ParamValues, c.eqb.ParamFormats, c.eqb.ResultFormats)
}
}
err := pipeline.Sync()
if err != nil {
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
}
return &pipelineBatchResults{
ctx: ctx,
conn: c,
pipeline: pipeline,
b: b,
}
}
func (c *Conn) sanitizeForSimpleQuery(sql string, args ...any) (string, error) {
if c.pgConn.ParameterStatus("standard_conforming_strings") != "on" {
return "", errors.New("simple protocol queries must be run with standard_conforming_strings=on")
}
if c.pgConn.ParameterStatus("client_encoding") != "UTF8" {
return "", errors.New("simple protocol queries must be run with client_encoding=UTF8")
}
var err error
valueArgs := make([]any, len(args))
for i, a := range args {
valueArgs[i], err = convertSimpleArgument(c.typeMap, a)
if err != nil {
return "", err
}
}
return sanitize.SanitizeSQL(sql, valueArgs...)
}
// LoadType inspects the database for typeName and produces a pgtype.Type suitable for r
gitextract_9td1e4zc/ ├── .devcontainer/ │ ├── Dockerfile │ ├── devcontainer.json │ ├── docker-compose.yml │ └── post-create.bash ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ ├── feature_request.md │ │ └── other-issues.md │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .golangci.yml ├── CHANGELOG.md ├── CLAUDE.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── Rakefile ├── batch.go ├── batch_test.go ├── bench_test.go ├── ci/ │ └── setup_test.bash ├── conn.go ├── conn_internal_test.go ├── conn_test.go ├── copy_from.go ├── copy_from_test.go ├── derived_types.go ├── derived_types_test.go ├── doc.go ├── examples/ │ ├── README.md │ ├── chat/ │ │ ├── README.md │ │ └── main.go │ ├── todo/ │ │ ├── README.md │ │ ├── main.go │ │ └── structure.sql │ └── url_shortener/ │ ├── README.md │ ├── main.go │ └── structure.sql ├── extended_query_builder.go ├── go.mod ├── go.sum ├── helper_test.go ├── internal/ │ ├── faultyconn/ │ │ └── faultyconn.go │ ├── iobufpool/ │ │ ├── iobufpool.go │ │ ├── iobufpool_internal_test.go │ │ └── iobufpool_test.go │ ├── pgio/ │ │ ├── README.md │ │ ├── doc.go │ │ ├── write.go │ │ └── write_test.go │ ├── pgmock/ │ │ ├── pgmock.go │ │ └── pgmock_test.go │ ├── sanitize/ │ │ ├── benchmark.sh │ │ ├── sanitize.go │ │ ├── sanitize_bench_test.go │ │ ├── sanitize_fuzz_test.go │ │ └── sanitize_test.go │ └── stmtcache/ │ ├── lru_cache.go │ └── stmtcache.go ├── large_objects.go ├── large_objects_private_test.go ├── large_objects_test.go ├── log/ │ └── testingadapter/ │ └── adapter.go ├── multitracer/ │ ├── tracer.go │ └── tracer_test.go ├── named_args.go ├── named_args_test.go ├── pgbouncer_test.go ├── pgconn/ │ ├── README.md │ ├── auth_oauth.go │ ├── auth_scram.go │ ├── auth_scram_test.go │ ├── benchmark_private_test.go │ ├── benchmark_test.go │ ├── config.go │ ├── config_test.go │ ├── ctxwatch/ │ │ ├── context_watcher.go │ │ ├── context_watcher_test.go │ │ └── synctest_test.go │ ├── defaults.go │ ├── defaults_windows.go │ ├── doc.go │ ├── errors.go │ ├── errors_test.go │ ├── export_test.go │ ├── helper_test.go │ ├── internal/ │ │ └── bgreader/ │ │ ├── bgreader.go │ │ └── bgreader_test.go │ ├── krb5.go │ ├── pgconn.go │ ├── pgconn_private_test.go │ ├── pgconn_stress_test.go │ └── pgconn_test.go ├── pgproto3/ │ ├── README.md │ ├── authentication_cleartext_password.go │ ├── authentication_gss.go │ ├── authentication_gss_continue.go │ ├── authentication_md5_password.go │ ├── authentication_ok.go │ ├── authentication_sasl.go │ ├── authentication_sasl_continue.go │ ├── authentication_sasl_final.go │ ├── backend.go │ ├── backend_key_data.go │ ├── backend_key_data_test.go │ ├── backend_test.go │ ├── big_endian.go │ ├── bind.go │ ├── bind_complete.go │ ├── bind_test.go │ ├── cancel_request.go │ ├── cancel_request_test.go │ ├── chunkreader.go │ ├── chunkreader_test.go │ ├── close.go │ ├── close_complete.go │ ├── command_complete.go │ ├── copy_both_response.go │ ├── copy_both_response_test.go │ ├── copy_data.go │ ├── copy_done.go │ ├── copy_fail.go │ ├── copy_in_response.go │ ├── copy_out_response.go │ ├── data_row.go │ ├── describe.go │ ├── doc.go │ ├── empty_query_response.go │ ├── error_response.go │ ├── example/ │ │ └── pgfortune/ │ │ ├── README.md │ │ ├── main.go │ │ └── server.go │ ├── execute.go │ ├── flush.go │ ├── frontend.go │ ├── frontend_test.go │ ├── function_call.go │ ├── function_call_decode_test.go │ ├── function_call_response.go │ ├── function_call_response_test.go │ ├── function_call_test.go │ ├── fuzz_test.go │ ├── gss_enc_request.go │ ├── gss_response.go │ ├── json_test.go │ ├── negotiate_protocol_version.go │ ├── negotiate_protocol_version_test.go │ ├── no_data.go │ ├── notice_response.go │ ├── notification_response.go │ ├── parameter_description.go │ ├── parameter_status.go │ ├── parse.go │ ├── parse_complete.go │ ├── password_message.go │ ├── pgproto3.go │ ├── pgproto3_private_test.go │ ├── portal_suspended.go │ ├── query.go │ ├── query_test.go │ ├── ready_for_query.go │ ├── row_description.go │ ├── sasl_initial_response.go │ ├── sasl_response.go │ ├── ssl_request.go │ ├── startup_message.go │ ├── sync.go │ ├── terminate.go │ ├── testdata/ │ │ └── fuzz/ │ │ └── FuzzFrontend/ │ │ ├── 39c5e864da4707fc15fea48f7062d6a07796fdc43b33e0ba9dbd7074a0211fa6 │ │ ├── 9b06792b1aaac8a907dbfa04d526ae14326c8573b7409032caac8461e83065f7 │ │ ├── a661fb98e802839f0a7361160fbc6e28794612a411d00bde104364ee281c4214 │ │ └── fc98dcd487a5173b38763a5f7dd023933f3a86ab566e3f2b091eb36248107eb4 │ ├── trace.go │ └── trace_test.go ├── pgtype/ │ ├── array.go │ ├── array_codec.go │ ├── array_codec_test.go │ ├── array_test.go │ ├── bits.go │ ├── bits_test.go │ ├── bool.go │ ├── bool_test.go │ ├── box.go │ ├── box_test.go │ ├── builtin_wrappers.go │ ├── bytea.go │ ├── bytea_test.go │ ├── circle.go │ ├── circle_test.go │ ├── composite.go │ ├── composite_test.go │ ├── convert.go │ ├── date.go │ ├── date_test.go │ ├── derived_types_test.go │ ├── doc.go │ ├── enum_codec.go │ ├── enum_codec_test.go │ ├── example_child_records_test.go │ ├── example_custom_type_test.go │ ├── example_json_test.go │ ├── float4.go │ ├── float4_test.go │ ├── float8.go │ ├── float8_test.go │ ├── hstore.go │ ├── hstore_test.go │ ├── inet.go │ ├── inet_test.go │ ├── int.go │ ├── int.go.erb │ ├── int_test.go │ ├── int_test.go.erb │ ├── integration_benchmark_test.go │ ├── integration_benchmark_test.go.erb │ ├── integration_benchmark_test_gen.sh │ ├── interval.go │ ├── interval_test.go │ ├── json.go │ ├── json_test.go │ ├── jsonb.go │ ├── jsonb_test.go │ ├── line.go │ ├── line_test.go │ ├── lseg.go │ ├── lseg_test.go │ ├── ltree.go │ ├── ltree_test.go │ ├── macaddr.go │ ├── macaddr_test.go │ ├── multirange.go │ ├── multirange_test.go │ ├── numeric.go │ ├── numeric_test.go │ ├── path.go │ ├── path_test.go │ ├── pgtype.go │ ├── pgtype_default.go │ ├── pgtype_test.go │ ├── point.go │ ├── point_test.go │ ├── polygon.go │ ├── polygon_test.go │ ├── qchar.go │ ├── qchar_test.go │ ├── range.go │ ├── range_codec.go │ ├── range_codec_test.go │ ├── range_test.go │ ├── record_codec.go │ ├── record_codec_test.go │ ├── register_default_pg_types.go │ ├── register_default_pg_types_disabled.go │ ├── text.go │ ├── text_format_only_codec.go │ ├── text_test.go │ ├── tid.go │ ├── tid_test.go │ ├── time.go │ ├── time_test.go │ ├── timestamp.go │ ├── timestamp_test.go │ ├── timestamptz.go │ ├── timestamptz_test.go │ ├── tsvector.go │ ├── tsvector_test.go │ ├── uint32.go │ ├── uint32_test.go │ ├── uint64.go │ ├── uint64_test.go │ ├── uuid.go │ ├── uuid_test.go │ ├── xml.go │ ├── xml_test.go │ └── zeronull/ │ ├── doc.go │ ├── float8.go │ ├── float8_test.go │ ├── int.go │ ├── int.go.erb │ ├── int_test.go │ ├── int_test.go.erb │ ├── text.go │ ├── text_test.go │ ├── timestamp.go │ ├── timestamp_test.go │ ├── timestamptz.go │ ├── timestamptz_test.go │ ├── uuid.go │ ├── uuid_test.go │ ├── zeronull.go │ └── zeronull_test.go ├── pgx_test.go ├── pgxpool/ │ ├── batch_results.go │ ├── bench_test.go │ ├── common_test.go │ ├── conn.go │ ├── conn_test.go │ ├── doc.go │ ├── helper_test.go │ ├── pool.go │ ├── pool_test.go │ ├── rows.go │ ├── stat.go │ ├── tracer.go │ ├── tracer_test.go │ ├── tx.go │ └── tx_test.go ├── pgxtest/ │ └── pgxtest.go ├── pipeline_test.go ├── query_test.go ├── rows.go ├── rows_test.go ├── stdlib/ │ ├── bench_test.go │ ├── sql.go │ └── sql_test.go ├── test.sh ├── testsetup/ │ ├── README.md │ ├── certs/ │ │ ├── ca.key.b64 │ │ ├── ca.pem.b64 │ │ ├── localhost.crt.b64 │ │ ├── localhost.key.b64 │ │ ├── pgx_sslcert.crt.b64 │ │ └── pgx_sslcert.key.b64 │ ├── generate_certs.go │ ├── oauth_validator_module/ │ │ ├── Makefile │ │ ├── dummy_validator.c │ │ ├── pg_hba.conf │ │ └── postgresql.conf │ ├── pg_hba.conf │ ├── pg_hba_devcontainer.conf │ ├── pg_ssl_init.sh │ ├── postgresql_setup.sql │ └── postgresql_ssl.conf ├── tracelog/ │ ├── tracelog.go │ └── tracelog_test.go ├── tracer.go ├── tracer_test.go ├── tx.go ├── tx_test.go ├── values.go └── values_test.go
Showing preview only (410K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4383 symbols across 278 files)
FILE: batch.go
type QueuedQuery (line 12) | type QueuedQuery struct
method Query (line 22) | func (qq *QueuedQuery) Query(fn func(rows Rows) error) {
method QueryRow (line 38) | func (qq *QueuedQuery) QueryRow(fn func(row Row) error) {
method Exec (line 50) | func (qq *QueuedQuery) Exec(fn func(ct pgconn.CommandTag) error) {
type batchItemFunc (line 19) | type batchItemFunc
type Batch (line 63) | type Batch struct
method Queue (line 74) | func (b *Batch) Queue(query string, arguments ...any) *QueuedQuery {
method Len (line 84) | func (b *Batch) Len() int {
type BatchResults (line 88) | type BatchResults interface
type batchResults (line 117) | type batchResults struct
method Exec (line 129) | func (br *batchResults) Exec() (pgconn.CommandTag, error) {
method Query (line 173) | func (br *batchResults) Query() (Rows, error) {
method QueryRow (line 214) | func (br *batchResults) QueryRow() Row {
method Close (line 221) | func (br *batchResults) Close() error {
method earlyError (line 263) | func (br *batchResults) earlyError() error {
method nextQueryAndArgs (line 267) | func (br *batchResults) nextQueryAndArgs() (query string, args []any, ...
type pipelineBatchResults (line 278) | type pipelineBatchResults struct
method Exec (line 291) | func (br *pipelineBatchResults) Exec() (pgconn.CommandTag, error) {
method Query (line 333) | func (br *pipelineBatchResults) Query() (Rows, error) {
method QueryRow (line 386) | func (br *pipelineBatchResults) QueryRow() Row {
method Close (line 393) | func (br *pipelineBatchResults) Close() error {
method earlyError (line 435) | func (br *pipelineBatchResults) earlyError() error {
method nextQueryAndArgs (line 439) | func (br *pipelineBatchResults) nextQueryAndArgs() (query string, args...
type emptyBatchResults (line 453) | type emptyBatchResults struct
method Exec (line 459) | func (br *emptyBatchResults) Exec() (pgconn.CommandTag, error) {
method Query (line 467) | func (br *emptyBatchResults) Query() (Rows, error) {
method QueryRow (line 480) | func (br *emptyBatchResults) QueryRow() Row {
method Close (line 487) | func (br *emptyBatchResults) Close() error {
function invalidateCachesOnBatchResultsError (line 493) | func invalidateCachesOnBatchResultsError(conn *Conn, b *Batch, err error) {
type ErrPreprocessingBatch (line 512) | type ErrPreprocessingBatch struct
method Error (line 522) | func (e ErrPreprocessingBatch) Error() string {
method Unwrap (line 529) | func (e ErrPreprocessingBatch) Unwrap() error {
method SQL (line 533) | func (e ErrPreprocessingBatch) SQL() string {
function newErrPreprocessingBatch (line 518) | func newErrPreprocessingBatch(step, sql string, err error) ErrPreprocess...
FILE: batch_test.go
function TestConnSendBatch (line 22) | func TestConnSendBatch(t *testing.T) {
function TestConnSendBatchQueuedQuery (line 160) | func TestConnSendBatchQueuedQuery(t *testing.T) {
function TestConnSendBatchMany (line 256) | func TestConnSendBatchMany(t *testing.T) {
function TestConnSendBatchReadResultsWhenNothingQueued (line 298) | func TestConnSendBatchReadResultsWhenNothingQueued(t *testing.T) {
function TestConnSendBatchReadMoreResultsThanQueriesSent (line 315) | func TestConnSendBatchReadMoreResultsThanQueriesSent(t *testing.T) {
function TestConnSendBatchWithPreparedStatement (line 336) | func TestConnSendBatchWithPreparedStatement(t *testing.T) {
function TestConnSendBatchWithQueryRewriter (line 393) | func TestConnSendBatchWithQueryRewriter(t *testing.T) {
function TestConnSendBatchWithPreparedStatementAndStatementCacheDisabled (line 427) | func TestConnSendBatchWithPreparedStatementAndStatementCacheDisabled(t *...
function TestConnSendBatchCloseRowsPartiallyRead (line 488) | func TestConnSendBatchCloseRowsPartiallyRead(t *testing.T) {
function TestConnSendBatchQueryError (line 548) | func TestConnSendBatchQueryError(t *testing.T) {
function TestConnSendBatchQuerySyntaxError (line 587) | func TestConnSendBatchQuerySyntaxError(t *testing.T) {
function TestConnSendBatchErrorReturnsErrPreprocessingBatch (line 613) | func TestConnSendBatchErrorReturnsErrPreprocessingBatch(t *testing.T) {
function TestConnSendBatchQueryRowInsert (line 655) | func TestConnSendBatchQueryRowInsert(t *testing.T) {
function TestConnSendBatchQueryPartialReadInsert (line 693) | func TestConnSendBatchQueryPartialReadInsert(t *testing.T) {
function TestTxSendBatch (line 731) | func TestTxSendBatch(t *testing.T) {
function TestTxSendBatchRollback (line 799) | func TestTxSendBatchRollback(t *testing.T) {
function TestSendBatchErrorWhileReadingResultsWithoutCallback (line 836) | func TestSendBatchErrorWhileReadingResultsWithoutCallback(t *testing.T) {
function TestSendBatchErrorWhileReadingResultsWithExecWhereSomeRowsAreReturned (line 860) | func TestSendBatchErrorWhileReadingResultsWithExecWhereSomeRowsAreReturn...
function TestConnBeginBatchDeferredError (line 884) | func TestConnBeginBatchDeferredError(t *testing.T) {
function TestConnSendBatchNoStatementCache (line 932) | func TestConnSendBatchNoStatementCache(t *testing.T) {
function TestConnSendBatchPrepareStatementCache (line 947) | func TestConnSendBatchPrepareStatementCache(t *testing.T) {
function TestConnSendBatchDescribeStatementCache (line 961) | func TestConnSendBatchDescribeStatementCache(t *testing.T) {
function testConnSendBatch (line 975) | func testConnSendBatch(t *testing.T, ctx context.Context, conn *pgx.Conn...
function TestSendBatchSimpleProtocol (line 1001) | func TestSendBatchSimpleProtocol(t *testing.T) {
function TestConnSendBatchErrorDoesNotLeaveOrphanedPreparedStatement (line 1043) | func TestConnSendBatchErrorDoesNotLeaveOrphanedPreparedStatement(t *test...
function TestSendBatchStatementTimeout (line 1072) | func TestSendBatchStatementTimeout(t *testing.T) {
function TestSendBatchHandlesTimeoutBetweenParseAndDescribe (line 1108) | func TestSendBatchHandlesTimeoutBetweenParseAndDescribe(t *testing.T) {
function TestBatchNetworkUsage (line 1175) | func TestBatchNetworkUsage(t *testing.T) {
function ExampleConn_SendBatch (line 1212) | func ExampleConn_SendBatch() {
FILE: bench_test.go
function BenchmarkConnectClose (line 21) | func BenchmarkConnectClose(b *testing.B) {
function BenchmarkMinimalUnpreparedSelectWithoutStatementCache (line 35) | func BenchmarkMinimalUnpreparedSelectWithoutStatementCache(b *testing.B) {
function BenchmarkMinimalUnpreparedSelectWithStatementCacheModeDescribe (line 58) | func BenchmarkMinimalUnpreparedSelectWithStatementCacheModeDescribe(b *t...
function BenchmarkMinimalUnpreparedSelectWithStatementCacheModePrepare (line 81) | func BenchmarkMinimalUnpreparedSelectWithStatementCacheModePrepare(b *te...
function BenchmarkMinimalPreparedSelect (line 104) | func BenchmarkMinimalPreparedSelect(b *testing.B) {
function BenchmarkMinimalPgConnPreparedSelect (line 127) | func BenchmarkMinimalPgConnPreparedSelect(b *testing.B) {
function BenchmarkMinimalPgConnPreparedStatementDescriptionSelect (line 161) | func BenchmarkMinimalPgConnPreparedStatementDescriptionSelect(b *testing...
function BenchmarkPointerPointerWithNullValues (line 196) | func BenchmarkPointerPointerWithNullValues(b *testing.B) {
function BenchmarkPointerPointerWithPresentValues (line 255) | func BenchmarkPointerPointerWithPresentValues(b *testing.B) {
constant benchmarkWriteTableCreateSQL (line 314) | benchmarkWriteTableCreateSQL = `drop table if exists t;
constant benchmarkWriteTableInsertSQL (line 333) | benchmarkWriteTableInsertSQL = `insert into t(
type benchmarkWriteTableCopyFromSrc (line 363) | type benchmarkWriteTableCopyFromSrc struct
method Next (line 369) | func (s *benchmarkWriteTableCopyFromSrc) Next() bool {
method Values (line 375) | func (s *benchmarkWriteTableCopyFromSrc) Values() ([]any, error) {
method Err (line 379) | func (s *benchmarkWriteTableCopyFromSrc) Err() error {
function newBenchmarkWriteTableCopyFromSrc (line 383) | func newBenchmarkWriteTableCopyFromSrc(count int) pgx.CopyFromSource {
function benchmarkWriteNRowsViaInsert (line 404) | func benchmarkWriteNRowsViaInsert(b *testing.B, n int) {
function benchmarkWriteNRowsViaBatchInsert (line 436) | func benchmarkWriteNRowsViaBatchInsert(b *testing.B, n int) {
type queryArgs (line 462) | type queryArgs
method Append (line 464) | func (qa *queryArgs) Append(v any) string {
function multiInsert (line 471) | func multiInsert(conn *pgx.Conn, tableName string, columnNames []string,...
function benchmarkWriteNRowsViaMultiInsert (line 545) | func benchmarkWriteNRowsViaMultiInsert(b *testing.B, n int) {
function benchmarkWriteNRowsViaCopy (line 581) | func benchmarkWriteNRowsViaCopy(b *testing.B, n int) {
function BenchmarkWrite2RowsViaInsert (line 614) | func BenchmarkWrite2RowsViaInsert(b *testing.B) {
function BenchmarkWrite2RowsViaMultiInsert (line 618) | func BenchmarkWrite2RowsViaMultiInsert(b *testing.B) {
function BenchmarkWrite2RowsViaBatchInsert (line 622) | func BenchmarkWrite2RowsViaBatchInsert(b *testing.B) {
function BenchmarkWrite2RowsViaCopy (line 626) | func BenchmarkWrite2RowsViaCopy(b *testing.B) {
function BenchmarkWrite5RowsViaInsert (line 630) | func BenchmarkWrite5RowsViaInsert(b *testing.B) {
function BenchmarkWrite5RowsViaMultiInsert (line 634) | func BenchmarkWrite5RowsViaMultiInsert(b *testing.B) {
function BenchmarkWrite5RowsViaBatchInsert (line 638) | func BenchmarkWrite5RowsViaBatchInsert(b *testing.B) {
function BenchmarkWrite5RowsViaCopy (line 642) | func BenchmarkWrite5RowsViaCopy(b *testing.B) {
function BenchmarkWrite10RowsViaInsert (line 646) | func BenchmarkWrite10RowsViaInsert(b *testing.B) {
function BenchmarkWrite10RowsViaMultiInsert (line 650) | func BenchmarkWrite10RowsViaMultiInsert(b *testing.B) {
function BenchmarkWrite10RowsViaBatchInsert (line 654) | func BenchmarkWrite10RowsViaBatchInsert(b *testing.B) {
function BenchmarkWrite10RowsViaCopy (line 658) | func BenchmarkWrite10RowsViaCopy(b *testing.B) {
function BenchmarkWrite100RowsViaInsert (line 662) | func BenchmarkWrite100RowsViaInsert(b *testing.B) {
function BenchmarkWrite100RowsViaMultiInsert (line 666) | func BenchmarkWrite100RowsViaMultiInsert(b *testing.B) {
function BenchmarkWrite100RowsViaBatchInsert (line 670) | func BenchmarkWrite100RowsViaBatchInsert(b *testing.B) {
function BenchmarkWrite100RowsViaCopy (line 674) | func BenchmarkWrite100RowsViaCopy(b *testing.B) {
function BenchmarkWrite1000RowsViaInsert (line 678) | func BenchmarkWrite1000RowsViaInsert(b *testing.B) {
function BenchmarkWrite1000RowsViaMultiInsert (line 682) | func BenchmarkWrite1000RowsViaMultiInsert(b *testing.B) {
function BenchmarkWrite1000RowsViaBatchInsert (line 686) | func BenchmarkWrite1000RowsViaBatchInsert(b *testing.B) {
function BenchmarkWrite1000RowsViaCopy (line 690) | func BenchmarkWrite1000RowsViaCopy(b *testing.B) {
function BenchmarkWrite10000RowsViaInsert (line 694) | func BenchmarkWrite10000RowsViaInsert(b *testing.B) {
function BenchmarkWrite10000RowsViaMultiInsert (line 698) | func BenchmarkWrite10000RowsViaMultiInsert(b *testing.B) {
function BenchmarkWrite10000RowsViaBatchInsert (line 702) | func BenchmarkWrite10000RowsViaBatchInsert(b *testing.B) {
function BenchmarkWrite10000RowsViaCopy (line 706) | func BenchmarkWrite10000RowsViaCopy(b *testing.B) {
function BenchmarkMultipleQueriesNonBatchNoStatementCache (line 710) | func BenchmarkMultipleQueriesNonBatchNoStatementCache(b *testing.B) {
function BenchmarkMultipleQueriesNonBatchPrepareStatementCache (line 722) | func BenchmarkMultipleQueriesNonBatchPrepareStatementCache(b *testing.B) {
function BenchmarkMultipleQueriesNonBatchDescribeStatementCache (line 734) | func BenchmarkMultipleQueriesNonBatchDescribeStatementCache(b *testing.B) {
function benchmarkMultipleQueriesNonBatch (line 746) | func benchmarkMultipleQueriesNonBatch(b *testing.B, conn *pgx.Conn, quer...
function BenchmarkMultipleQueriesBatchNoStatementCache (line 771) | func BenchmarkMultipleQueriesBatchNoStatementCache(b *testing.B) {
function BenchmarkMultipleQueriesBatchPrepareStatementCache (line 783) | func BenchmarkMultipleQueriesBatchPrepareStatementCache(b *testing.B) {
function BenchmarkMultipleQueriesBatchDescribeStatementCache (line 795) | func BenchmarkMultipleQueriesBatchDescribeStatementCache(b *testing.B) {
function benchmarkMultipleQueriesBatch (line 807) | func benchmarkMultipleQueriesBatch(b *testing.B, conn *pgx.Conn, queryCo...
function BenchmarkSelectManyUnknownEnum (line 844) | func BenchmarkSelectManyUnknownEnum(b *testing.B) {
function BenchmarkSelectManyRegisteredEnum (line 889) | func BenchmarkSelectManyRegisteredEnum(b *testing.B) {
function getSelectRowsCounts (line 940) | func getSelectRowsCounts(b *testing.B) []int64 {
type BenchRowSimple (line 962) | type BenchRowSimple struct
function BenchmarkSelectRowsScanSimple (line 974) | func BenchmarkSelectRowsScanSimple(b *testing.B) {
type BenchRowStringBytes (line 1001) | type BenchRowStringBytes struct
function BenchmarkSelectRowsScanStringBytes (line 1013) | func BenchmarkSelectRowsScanStringBytes(b *testing.B) {
type BenchRowDecoder (line 1040) | type BenchRowDecoder struct
function BenchmarkSelectRowsScanDecoder (line 1052) | func BenchmarkSelectRowsScanDecoder(b *testing.B) {
function BenchmarkSelectRowsPgConnExecText (line 1095) | func BenchmarkSelectRowsPgConnExecText(b *testing.B) {
function BenchmarkSelectRowsPgConnExecParams (line 1121) | func BenchmarkSelectRowsPgConnExecParams(b *testing.B) {
function BenchmarkSelectRowsSimpleCollectRowsRowToStructByPos (line 1162) | func BenchmarkSelectRowsSimpleCollectRowsRowToStructByPos(b *testing.B) {
function BenchmarkSelectRowsSimpleAppendRowsRowToStructByPos (line 1184) | func BenchmarkSelectRowsSimpleAppendRowsRowToStructByPos(b *testing.B) {
function BenchmarkSelectRowsSimpleCollectRowsRowToStructByName (line 1209) | func BenchmarkSelectRowsSimpleCollectRowsRowToStructByName(b *testing.B) {
function BenchmarkSelectRowsSimpleAppendRowsRowToStructByName (line 1231) | func BenchmarkSelectRowsSimpleAppendRowsRowToStructByName(b *testing.B) {
function BenchmarkSelectRowsPgConnExecPrepared (line 1256) | func BenchmarkSelectRowsPgConnExecPrepared(b *testing.B) {
function BenchmarkSelectRowsPgConnExecStatement (line 1301) | func BenchmarkSelectRowsPgConnExecStatement(b *testing.B) {
type queryRecorder (line 1346) | type queryRecorder struct
method Read (line 1352) | func (qr *queryRecorder) Read(b []byte) (n int, err error) {
method Write (line 1358) | func (qr *queryRecorder) Write(b []byte) (n int, err error) {
method Close (line 1363) | func (qr *queryRecorder) Close() error {
method LocalAddr (line 1367) | func (qr *queryRecorder) LocalAddr() net.Addr {
method RemoteAddr (line 1371) | func (qr *queryRecorder) RemoteAddr() net.Addr {
method SetDeadline (line 1375) | func (qr *queryRecorder) SetDeadline(t time.Time) error {
method SetReadDeadline (line 1379) | func (qr *queryRecorder) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 1383) | func (qr *queryRecorder) SetWriteDeadline(t time.Time) error {
function BenchmarkSelectRowsRawPrepared (line 1391) | func BenchmarkSelectRowsRawPrepared(b *testing.B) {
FILE: conn.go
type ConnConfig (line 22) | type ConnConfig struct
method Copy (line 55) | func (cc *ConnConfig) Copy() *ConnConfig {
method ConnString (line 63) | func (cc *ConnConfig) ConnString() string { return cc.connString }
type ParseConfigOptions (line 48) | type ParseConfigOptions struct
type Conn (line 67) | type Conn struct
method Close (line 301) | func (c *Conn) Close(ctx context.Context) error {
method Prepare (line 319) | func (c *Conn) Prepare(ctx context.Context, name, sql string) (sd *pgc...
method Deallocate (line 375) | func (c *Conn) Deallocate(ctx context.Context, name string) error {
method DeallocateAll (line 397) | func (c *Conn) DeallocateAll(ctx context.Context) error {
method bufferNotifications (line 409) | func (c *Conn) bufferNotifications(_ *pgconn.PgConn, n *pgconn.Notific...
method WaitForNotification (line 415) | func (c *Conn) WaitForNotification(ctx context.Context) (*pgconn.Notif...
method IsClosed (line 434) | func (c *Conn) IsClosed() bool {
method die (line 438) | func (c *Conn) die() {
method Ping (line 453) | func (c *Conn) Ping(ctx context.Context) error {
method PgConn (line 462) | func (c *Conn) PgConn() *pgconn.PgConn { return c.pgConn }
method TypeMap (line 465) | func (c *Conn) TypeMap() *pgtype.Map { return c.typeMap }
method Config (line 468) | func (c *Conn) Config() *ConnConfig { return c.config.Copy() }
method Exec (line 472) | func (c *Conn) Exec(ctx context.Context, sql string, arguments ...any)...
method exec (line 490) | func (c *Conn) exec(ctx context.Context, sql string, arguments ...any)...
method execSimpleProtocol (line 580) | func (c *Conn) execSimpleProtocol(ctx context.Context, sql string, arg...
method execParams (line 596) | func (c *Conn) execParams(ctx context.Context, sd *pgconn.StatementDes...
method execPrepared (line 607) | func (c *Conn) execPrepared(ctx context.Context, sd *pgconn.StatementD...
method execSQLParams (line 618) | func (c *Conn) execSQLParams(ctx context.Context, sql string, args []a...
method getRows (line 629) | func (c *Conn) getRows(ctx context.Context, sql string, args []any) *b...
method Query (line 751) | func (c *Conn) Query(ctx context.Context, sql string, args ...any) (Ro...
method getStatementDescription (line 891) | func (c *Conn) getStatementDescription(
method QueryRow (line 930) | func (c *Conn) QueryRow(ctx context.Context, sql string, args ...any) ...
method SendBatch (line 941) | func (c *Conn) SendBatch(ctx context.Context, b *Batch) (br BatchResul...
method sendBatchQueryExecModeSimpleProtocol (line 1016) | func (c *Conn) sendBatchQueryExecModeSimpleProtocol(ctx context.Contex...
method sendBatchQueryExecModeExec (line 1038) | func (c *Conn) sendBatchQueryExecModeExec(ctx context.Context, b *Batc...
method sendBatchQueryExecModeCacheStatement (line 1072) | func (c *Conn) sendBatchQueryExecModeCacheStatement(ctx context.Contex...
method sendBatchQueryExecModeCacheDescribe (line 1104) | func (c *Conn) sendBatchQueryExecModeCacheDescribe(ctx context.Context...
method sendBatchQueryExecModeDescribeExec (line 1135) | func (c *Conn) sendBatchQueryExecModeDescribeExec(ctx context.Context,...
method sendBatchExtendedWithDescription (line 1157) | func (c *Conn) sendBatchExtendedWithDescription(ctx context.Context, b...
method sanitizeForSimpleQuery (line 1255) | func (c *Conn) sanitizeForSimpleQuery(sql string, args ...any) (string...
method LoadType (line 1285) | func (c *Conn) LoadType(ctx context.Context, typeName string) (*pgtype...
method getArrayElementOID (line 1359) | func (c *Conn) getArrayElementOID(ctx context.Context, oid uint32) (ui...
method getRangeElementOID (line 1370) | func (c *Conn) getRangeElementOID(ctx context.Context, oid uint32) (ui...
method getMultiRangeElementOID (line 1381) | func (c *Conn) getMultiRangeElementOID(ctx context.Context, oid uint32...
method getCompositeFields (line 1392) | func (c *Conn) getCompositeFields(ctx context.Context, oid uint32) ([]...
method deallocateInvalidatedCachedStatements (line 1426) | func (c *Conn) deallocateInvalidatedCachedStatements(ctx context.Conte...
type Identifier (line 93) | type Identifier
method Sanitize (line 96) | func (ident Identifier) Sanitize() string {
function newProxyErr (line 112) | func newProxyErr(background error, msg string) error {
type proxyError (line 119) | type proxyError struct
method Error (line 124) | func (err *proxyError) Error() string { return err.msg }
method Unwrap (line 126) | func (err *proxyError) Unwrap() error { return err.background }
function Connect (line 135) | func Connect(ctx context.Context, connString string) (*Conn, error) {
function ConnectWithOptions (line 145) | func ConnectWithOptions(ctx context.Context, connString string, options ...
function ConnectConfig (line 155) | func ConnectConfig(ctx context.Context, connConfig *ConnConfig) (*Conn, ...
function ParseConfigWithOptions (line 165) | func ParseConfigWithOptions(connString string, options ParseConfigOption...
function ParseConfig (line 238) | func ParseConfig(connString string) (*ConnConfig, error) {
function connect (line 243) | func connect(ctx context.Context, config *ConnConfig) (c *Conn, err erro...
function quoteIdentifier (line 448) | func quoteIdentifier(s string) string {
type QueryExecMode (line 643) | type QueryExecMode
method String (line 702) | func (m QueryExecMode) String() string {
constant _ (line 646) | _ QueryExecMode = iota
constant QueryExecModeCacheStatement (line 652) | QueryExecModeCacheStatement
constant QueryExecModeCacheDescribe (line 658) | QueryExecModeCacheDescribe
constant QueryExecModeDescribeExec (line 665) | QueryExecModeDescribeExec
constant QueryExecModeExec (line 681) | QueryExecModeExec
constant QueryExecModeSimpleProtocol (line 699) | QueryExecModeSimpleProtocol
type QueryResultFormats (line 720) | type QueryResultFormats
type QueryResultFormatsByOID (line 723) | type QueryResultFormatsByOID
type QueryRewriter (line 726) | type QueryRewriter interface
FILE: conn_internal_test.go
function mustParseConfig (line 13) | func mustParseConfig(t testing.TB, connString string) *ConnConfig {
function mustConnect (line 19) | func mustConnect(t testing.TB, config *ConnConfig) *Conn {
function TestStmtCacheSizeLimit (line 29) | func TestStmtCacheSizeLimit(t *testing.T) {
FILE: conn_test.go
function TestCrateDBConnect (line 25) | func TestCrateDBConnect(t *testing.T) {
function TestConnect (line 49) | func TestConnect(t *testing.T) {
function TestConnectWithPreferSimpleProtocol (line 86) | func TestConnectWithPreferSimpleProtocol(t *testing.T) {
function TestConnectConfigRequiresConnConfigFromParseConfig (line 106) | func TestConnectConfigRequiresConnConfigFromParseConfig(t *testing.T) {
function TestConfigContainsConnStr (line 113) | func TestConfigContainsConnStr(t *testing.T) {
function TestConfigCopyReturnsEqualConfig (line 120) | func TestConfigCopyReturnsEqualConfig(t *testing.T) {
function TestConfigCopyCanBeUsedToConnect (line 129) | func TestConfigCopyCanBeUsedToConnect(t *testing.T) {
function TestParseConfigExtractsStatementCacheOptions (line 141) | func TestParseConfigExtractsStatementCacheOptions(t *testing.T) {
function TestParseConfigExtractsDefaultQueryExecMode (line 184) | func TestParseConfigExtractsDefaultQueryExecMode(t *testing.T) {
function TestParseConfigErrors (line 205) | func TestParseConfigErrors(t *testing.T) {
function TestExec (line 220) | func TestExec(t *testing.T) {
type testQueryRewriter (line 257) | type testQueryRewriter struct
method RewriteQuery (line 262) | func (qr *testQueryRewriter) RewriteQuery(ctx context.Context, conn *p...
function TestExecWithQueryRewriter (line 266) | func TestExecWithQueryRewriter(t *testing.T) {
function TestExecFailure (line 279) | func TestExecFailure(t *testing.T) {
function TestExecFailureWithArguments (line 298) | func TestExecFailureWithArguments(t *testing.T) {
function TestExecContextWithoutCancelation (line 316) | func TestExecContextWithoutCancelation(t *testing.T) {
function TestExecContextFailureWithoutCancelation (line 337) | func TestExecContextFailureWithoutCancelation(t *testing.T) {
function TestExecContextFailureWithoutCancelationWithArguments (line 362) | func TestExecContextFailureWithoutCancelationWithArguments(t *testing.T) {
function TestExecFailureCloseBefore (line 380) | func TestExecFailureCloseBefore(t *testing.T) {
function TestExecPerQuerySimpleProtocol (line 391) | func TestExecPerQuerySimpleProtocol(t *testing.T) {
function TestPrepare (line 420) | func TestPrepare(t *testing.T) {
function TestPrepareHandlesTimeoutBetweenParseAndDescribe (line 473) | func TestPrepareHandlesTimeoutBetweenParseAndDescribe(t *testing.T) {
function TestPrepareBadSQLFailure (line 535) | func TestPrepareBadSQLFailure(t *testing.T) {
function TestPrepareIdempotency (line 548) | func TestPrepareIdempotency(t *testing.T) {
function TestPrepareStatementCacheModes (line 580) | func TestPrepareStatementCacheModes(t *testing.T) {
function TestPrepareWithDigestedName (line 597) | func TestPrepareWithDigestedName(t *testing.T) {
function TestDeallocateInAbortedTransaction (line 620) | func TestDeallocateInAbortedTransaction(t *testing.T) {
function TestDeallocateMissingPreparedStatementStillClearsFromPreparedStatementMap (line 655) | func TestDeallocateMissingPreparedStatementStillClearsFromPreparedStatem...
function TestListenNotify (line 682) | func TestListenNotify(t *testing.T) {
function TestListenNotifyWhileBusyIsSafe (line 730) | func TestListenNotifyWhileBusyIsSafe(t *testing.T) {
function TestListenNotifySelfNotification (line 807) | func TestListenNotifySelfNotification(t *testing.T) {
function TestFatalRxError (line 842) | func TestFatalRxError(t *testing.T) {
function TestFatalTxError (line 878) | func TestFatalTxError(t *testing.T) {
function TestInsertBoolArray (line 909) | func TestInsertBoolArray(t *testing.T) {
function TestInsertTimestampArray (line 927) | func TestInsertTimestampArray(t *testing.T) {
function TestIdentifierSanitize (line 945) | func TestIdentifierSanitize(t *testing.T) {
function TestConnInitTypeMap (line 986) | func TestConnInitTypeMap(t *testing.T) {
function TestUnregisteredTypeUsableAsStringArgumentAndBaseResult (line 1014) | func TestUnregisteredTypeUsableAsStringArgumentAndBaseResult(t *testing....
function TestDomainType (line 1033) | func TestDomainType(t *testing.T) {
function TestLoadTypeSameNameInDifferentSchemas (line 1070) | func TestLoadTypeSameNameInDifferentSchemas(t *testing.T) {
function TestLoadCompositeType (line 1115) | func TestLoadCompositeType(t *testing.T) {
function TestLoadRangeType (line 1137) | func TestLoadRangeType(t *testing.T) {
function TestLoadMultiRangeType (line 1171) | func TestLoadMultiRangeType(t *testing.T) {
function TestStmtCacheInvalidationConn (line 1220) | func TestStmtCacheInvalidationConn(t *testing.T) {
function TestStmtCacheInvalidationTx (line 1282) | func TestStmtCacheInvalidationTx(t *testing.T) {
function TestStmtCacheInvalidationConnWithBatch (line 1361) | func TestStmtCacheInvalidationConnWithBatch(t *testing.T) {
function TestStmtCacheInvalidationTxWithBatch (line 1437) | func TestStmtCacheInvalidationTxWithBatch(t *testing.T) {
function TestStmtCacheInvalidationExec (line 1533) | func TestStmtCacheInvalidationExec(t *testing.T) {
function TestInsertDurationInterval (line 1578) | func TestInsertDurationInterval(t *testing.T) {
function TestRawValuesUnderlyingMemoryReused (line 1594) | func TestRawValuesUnderlyingMemoryReused(t *testing.T) {
function TestConnDeallocateInvalidatedCachedStatementsWhenCanceled (line 1626) | func TestConnDeallocateInvalidatedCachedStatementsWhenCanceled(t *testin...
function TestConnDeallocateInvalidatedCachedStatementsInTransactionWithBatch (line 1657) | func TestConnDeallocateInvalidatedCachedStatementsInTransactionWithBatch...
function TestErrNoRows (line 1695) | func TestErrNoRows(t *testing.T) {
FILE: copy_from.go
function CopyFromRows (line 15) | func CopyFromRows(rows [][]any) CopyFromSource {
type copyFromRows (line 19) | type copyFromRows struct
method Next (line 24) | func (ctr *copyFromRows) Next() bool {
method Values (line 29) | func (ctr *copyFromRows) Values() ([]any, error) {
method Err (line 33) | func (ctr *copyFromRows) Err() error {
function CopyFromSlice (line 39) | func CopyFromSlice(length int, next func(int) ([]any, error)) CopyFromSo...
type copyFromSlice (line 43) | type copyFromSlice struct
method Next (line 50) | func (cts *copyFromSlice) Next() bool {
method Values (line 55) | func (cts *copyFromSlice) Values() ([]any, error) {
method Err (line 63) | func (cts *copyFromSlice) Err() error {
function CopyFromFunc (line 70) | func CopyFromFunc(nxtf func() (row []any, err error)) CopyFromSource {
type copyFromFunc (line 74) | type copyFromFunc struct
method Next (line 80) | func (g *copyFromFunc) Next() bool {
method Values (line 86) | func (g *copyFromFunc) Values() ([]any, error) {
method Err (line 90) | func (g *copyFromFunc) Err() error {
type CopyFromSource (line 95) | type CopyFromSource interface
type copyFrom (line 109) | type copyFrom struct
method run (line 118) | func (ct *copyFrom) run(ctx context.Context) (int64, error) {
method buildCopyBuf (line 217) | func (ct *copyFrom) buildCopyBuf(buf []byte, sd *pgconn.StatementDescr...
method CopyFrom (line 265) | func (c *Conn) CopyFrom(ctx context.Context, tableName Identifier, colum...
FILE: copy_from_test.go
function TestConnCopyWithAllQueryExecModes (line 18) | func TestConnCopyWithAllQueryExecModes(t *testing.T) {
function TestConnCopyWithKnownOIDQueryExecModes (line 79) | func TestConnCopyWithKnownOIDQueryExecModes(t *testing.T) {
function TestConnCopyFromSmall (line 142) | func TestConnCopyFromSmall(t *testing.T) {
function TestConnCopyFromSliceSmall (line 201) | func TestConnCopyFromSliceSmall(t *testing.T) {
function TestConnCopyFromLarge (line 263) | func TestConnCopyFromLarge(t *testing.T) {
function TestConnCopyFromEnum (line 324) | func TestConnCopyFromEnum(t *testing.T) {
function TestConnCopyFromJSON (line 398) | func TestConnCopyFromJSON(t *testing.T) {
function TestConnCopyFromTSVector (line 456) | func TestConnCopyFromTSVector(t *testing.T) {
type clientFailSource (line 556) | type clientFailSource struct
method Next (line 561) | func (cfs *clientFailSource) Next() bool {
method Values (line 566) | func (cfs *clientFailSource) Values() ([]any, error) {
method Err (line 574) | func (cfs *clientFailSource) Err() error {
function TestConnCopyFromFailServerSideMidway (line 578) | func TestConnCopyFromFailServerSideMidway(t *testing.T) {
type failSource (line 636) | type failSource struct
method Next (line 640) | func (fs *failSource) Next() bool {
method Values (line 646) | func (fs *failSource) Values() ([]any, error) {
method Err (line 653) | func (fs *failSource) Err() error {
function TestConnCopyFromFailServerSideMidwayAbortsWithoutWaiting (line 657) | func TestConnCopyFromFailServerSideMidwayAbortsWithoutWaiting(t *testing...
type slowFailRaceSource (line 716) | type slowFailRaceSource struct
method Next (line 720) | func (fs *slowFailRaceSource) Next() bool {
method Values (line 726) | func (fs *slowFailRaceSource) Values() ([]any, error) {
method Err (line 733) | func (fs *slowFailRaceSource) Err() error {
function TestConnCopyFromSlowFailRace (line 737) | func TestConnCopyFromSlowFailRace(t *testing.T) {
function TestConnCopyFromCopyFromSourceErrorMidway (line 765) | func TestConnCopyFromCopyFromSourceErrorMidway(t *testing.T) {
type clientFinalErrSource (line 811) | type clientFinalErrSource struct
method Next (line 815) | func (cfs *clientFinalErrSource) Next() bool {
method Values (line 820) | func (cfs *clientFinalErrSource) Values() ([]any, error) {
method Err (line 824) | func (cfs *clientFinalErrSource) Err() error {
function TestConnCopyFromCopyFromSourceErrorEnd (line 828) | func TestConnCopyFromCopyFromSourceErrorEnd(t *testing.T) {
function TestConnCopyFromAutomaticStringConversion (line 874) | func TestConnCopyFromAutomaticStringConversion(t *testing.T) {
function TestConnCopyFromAutomaticStringConversionArray (line 907) | func TestConnCopyFromAutomaticStringConversionArray(t *testing.T) {
function TestCopyFromFunc (line 940) | func TestCopyFromFunc(t *testing.T) {
FILE: derived_types.go
function buildLoadDerivedTypesSQL (line 19) | func buildLoadDerivedTypesSQL(pgVersion int64, typeNames []string) string {
type derivedTypeInfo (line 151) | type derivedTypeInfo struct
method LoadTypes (line 162) | func (c *Conn) LoadTypes(ctx context.Context, typeNames []string) ([]*pg...
function serverVersion (line 243) | func serverVersion(c *Conn) (int64, error) {
FILE: derived_types_test.go
function TestCompositeCodecTranscodeWithLoadTypes (line 11) | func TestCompositeCodecTranscodeWithLoadTypes(t *testing.T) {
FILE: examples/chat/main.go
function main (line 14) | func main() {
function listen (line 50) | func listen() {
FILE: examples/todo/main.go
function main (line 14) | func main() {
function listTasks (line 73) | func listTasks() error {
function addTask (line 89) | func addTask(description string) error {
function updateTask (line 94) | func updateTask(itemNum int32, description string) error {
function removeTask (line 99) | func removeTask(itemNum int32) error {
function printHelp (line 104) | func printHelp() {
FILE: examples/todo/structure.sql
type tasks (line 1) | create table tasks (
FILE: examples/url_shortener/main.go
function getUrlHandler (line 16) | func getUrlHandler(w http.ResponseWriter, req *http.Request) {
function putUrlHandler (line 29) | func putUrlHandler(w http.ResponseWriter, req *http.Request) {
function deleteUrlHandler (line 47) | func deleteUrlHandler(w http.ResponseWriter, req *http.Request) {
function urlHandler (line 55) | func urlHandler(w http.ResponseWriter, req *http.Request) {
function main (line 72) | func main() {
FILE: examples/url_shortener/structure.sql
type shortened_urls (line 1) | create table shortened_urls (
FILE: extended_query_builder.go
type ExtendedQueryBuilder (line 12) | type ExtendedQueryBuilder struct
method Build (line 21) | func (eqb *ExtendedQueryBuilder) Build(m *pgtype.Map, sd *pgconn.State...
method appendParam (line 56) | func (eqb *ExtendedQueryBuilder) appendParam(m *pgtype.Map, oid uint32...
method appendResultFormat (line 91) | func (eqb *ExtendedQueryBuilder) appendResultFormat(format int16) {
method reset (line 96) | func (eqb *ExtendedQueryBuilder) reset() {
method encodeExtendedParamValue (line 118) | func (eqb *ExtendedQueryBuilder) encodeExtendedParamValue(m *pgtype.Ma...
method chooseParameterFormatCode (line 139) | func (eqb *ExtendedQueryBuilder) chooseParameterFormatCode(m *pgtype.M...
FILE: helper_test.go
function init (line 18) | func init() {
function mustConnectString (line 27) | func mustConnectString(t testing.TB, connString string) *pgx.Conn {
function mustParseConfig (line 35) | func mustParseConfig(t testing.TB, connString string) *pgx.ConnConfig {
function mustConnect (line 41) | func mustConnect(t testing.TB, config *pgx.ConnConfig) *pgx.Conn {
function closeConn (line 49) | func closeConn(t testing.TB, conn *pgx.Conn) {
function mustExec (line 56) | func mustExec(t testing.TB, conn *pgx.Conn, sql string, arguments ...any...
function ensureConnValid (line 65) | func ensureConnValid(t testing.TB, conn *pgx.Conn) {
function assertConfigsEqual (line 93) | func assertConfigsEqual(t *testing.T, expected, actual *pgx.ConnConfig, ...
FILE: internal/faultyconn/faultyconn.go
type Conn (line 18) | type Conn struct
method Read (line 48) | func (c *Conn) Read(b []byte) (n int, err error) {
method Write (line 52) | func (c *Conn) Write(b []byte) (n int, err error) {
method Close (line 77) | func (c *Conn) Close() error {
method LocalAddr (line 81) | func (c *Conn) LocalAddr() net.Addr {
method RemoteAddr (line 85) | func (c *Conn) RemoteAddr() net.Addr {
method SetDeadline (line 89) | func (c *Conn) SetDeadline(t time.Time) error {
method SetReadDeadline (line 93) | func (c *Conn) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 97) | func (c *Conn) SetWriteDeadline(t time.Time) error {
function New (line 35) | func New(c net.Conn) *Conn {
FILE: internal/iobufpool/iobufpool.go
constant minPoolExpOf2 (line 12) | minPoolExpOf2 = 8
function init (line 16) | func init() {
function Get (line 29) | func Get(size int) *[]byte {
function getPoolIdx (line 42) | func getPoolIdx(size int) int {
function Put (line 54) | func Put(buf *[]byte) {
function putPoolIdx (line 63) | func putPoolIdx(size int) int {
FILE: internal/iobufpool/iobufpool_internal_test.go
function TestPoolIdx (line 9) | func TestPoolIdx(t *testing.T) {
FILE: internal/iobufpool/iobufpool_test.go
function TestGetCap (line 10) | func TestGetCap(t *testing.T) {
function TestPutHandlesWrongSizedBuffers (line 38) | func TestPutHandlesWrongSizedBuffers(t *testing.T) {
function TestPutGetBufferReuse (line 71) | func TestPutGetBufferReuse(t *testing.T) {
FILE: internal/pgio/write.go
function AppendUint16 (line 3) | func AppendUint16(buf []byte, n uint16) []byte {
function AppendUint32 (line 7) | func AppendUint32(buf []byte, n uint32) []byte {
function AppendUint64 (line 11) | func AppendUint64(buf []byte, n uint64) []byte {
function AppendInt16 (line 18) | func AppendInt16(buf []byte, n int16) []byte {
function AppendInt32 (line 22) | func AppendInt32(buf []byte, n int32) []byte {
function AppendInt64 (line 26) | func AppendInt64(buf []byte, n int64) []byte {
function SetInt32 (line 30) | func SetInt32(buf []byte, n int32) {
FILE: internal/pgio/write_test.go
function TestAppendUint16NilBuf (line 8) | func TestAppendUint16NilBuf(t *testing.T) {
function TestAppendUint16EmptyBuf (line 15) | func TestAppendUint16EmptyBuf(t *testing.T) {
function TestAppendUint16BufWithCapacityDoesNotAllocate (line 23) | func TestAppendUint16BufWithCapacityDoesNotAllocate(t *testing.T) {
function TestAppendUint32NilBuf (line 32) | func TestAppendUint32NilBuf(t *testing.T) {
function TestAppendUint32EmptyBuf (line 39) | func TestAppendUint32EmptyBuf(t *testing.T) {
function TestAppendUint32BufWithCapacityDoesNotAllocate (line 47) | func TestAppendUint32BufWithCapacityDoesNotAllocate(t *testing.T) {
function TestAppendUint64NilBuf (line 56) | func TestAppendUint64NilBuf(t *testing.T) {
function TestAppendUint64EmptyBuf (line 63) | func TestAppendUint64EmptyBuf(t *testing.T) {
function TestAppendUint64BufWithCapacityDoesNotAllocate (line 71) | func TestAppendUint64BufWithCapacityDoesNotAllocate(t *testing.T) {
FILE: internal/pgmock/pgmock.go
type Step (line 12) | type Step interface
type Script (line 16) | type Script struct
method Run (line 20) | func (s *Script) Run(backend *pgproto3.Backend) error {
method Step (line 31) | func (s *Script) Step(backend *pgproto3.Backend) error {
type expectMessageStep (line 35) | type expectMessageStep struct
method Step (line 40) | func (e *expectMessageStep) Step(backend *pgproto3.Backend) error {
type expectStartupMessageStep (line 57) | type expectStartupMessageStep struct
method Step (line 62) | func (e *expectStartupMessageStep) Step(backend *pgproto3.Backend) err...
function ExpectMessage (line 79) | func ExpectMessage(want pgproto3.FrontendMessage) Step {
function ExpectAnyMessage (line 83) | func ExpectAnyMessage(want pgproto3.FrontendMessage) Step {
function expectMessage (line 87) | func expectMessage(want pgproto3.FrontendMessage, any bool) Step {
type sendMessageStep (line 95) | type sendMessageStep struct
method Step (line 99) | func (e *sendMessageStep) Step(backend *pgproto3.Backend) error {
function SendMessage (line 104) | func SendMessage(msg pgproto3.BackendMessage) Step {
type waitForCloseMessageStep (line 108) | type waitForCloseMessageStep struct
method Step (line 110) | func (e *waitForCloseMessageStep) Step(backend *pgproto3.Backend) error {
function WaitForClose (line 125) | func WaitForClose() Step {
function AcceptUnauthenticatedConnRequestSteps (line 129) | func AcceptUnauthenticatedConnRequestSteps() []Step {
FILE: internal/pgmock/pgmock_test.go
function TestScript (line 19) | func TestScript(t *testing.T) {
FILE: internal/sanitize/sanitize.go
type Part (line 17) | type Part
type Query (line 19) | type Query struct
method Sanitize (line 44) | func (q *Query) Sanitize(args ...any) (string, error) {
method init (line 125) | func (q *Query) init(sql string) {
constant replacementcharacterwidth (line 27) | replacementcharacterwidth = 3
constant maxBufSize (line 29) | maxBufSize = 16384
function NewQuery (line 108) | func NewQuery(sql string) (*Query, error) {
function QuoteString (line 147) | func QuoteString(dst []byte, str string) []byte {
function QuoteBytes (line 171) | func QuoteBytes(dst, buf []byte) []byte {
type sqlLexer (line 204) | type sqlLexer struct
type stateFn (line 213) | type stateFn
function rawState (line 215) | func rawState(l *sqlLexer) stateFn {
function singleQuoteState (line 264) | func singleQuoteState(l *sqlLexer) stateFn {
function doubleQuoteState (line 288) | func doubleQuoteState(l *sqlLexer) stateFn {
function placeholderState (line 314) | func placeholderState(l *sqlLexer) stateFn {
function escapeStringState (line 333) | func escapeStringState(l *sqlLexer) stateFn {
function oneLineCommentState (line 360) | func oneLineCommentState(l *sqlLexer) stateFn {
function multilineCommentState (line 383) | func multilineCommentState(l *sqlLexer) stateFn {
function SanitizeSQL (line 433) | func SanitizeSQL(sql string, args ...any) (string, error) {
type pool (line 441) | type pool struct
method get (line 447) | func (pool *pool[E]) get() E {
method put (line 456) | func (p *pool[E]) put(v E) {
FILE: internal/sanitize/sanitize_bench_test.go
constant benchmarkQuery (line 13) | benchmarkQuery = "" +
function BenchmarkSanitize (line 34) | func BenchmarkSanitize(b *testing.B) {
function BenchmarkSanitizeSQL (line 52) | func BenchmarkSanitizeSQL(b *testing.B) {
FILE: internal/sanitize/sanitize_fuzz_test.go
function FuzzQuoteString (line 10) | func FuzzQuoteString(f *testing.F) {
function FuzzQuoteBytes (line 33) | func FuzzQuoteBytes(f *testing.F) {
FILE: internal/sanitize/sanitize_test.go
function TestNewQuery (line 12) | func TestNewQuery(t *testing.T) {
function TestQuerySanitize (line 123) | func TestQuerySanitize(t *testing.T) {
function TestQuoteString (line 233) | func TestQuoteString(t *testing.T) {
function oldQuoteString (line 255) | func oldQuoteString(str string) string {
function TestQuoteBytes (line 259) | func TestQuoteBytes(t *testing.T) {
function oldQuoteBytes (line 281) | func oldQuoteBytes(buf []byte) string {
FILE: internal/stmtcache/lru_cache.go
type lruNode (line 8) | type lruNode struct
type LRUCache (line 15) | type LRUCache struct
method Get (line 45) | func (c *LRUCache) Get(key string) *pgconn.StatementDescription {
method Put (line 56) | func (c *LRUCache) Put(sd *pgconn.StatementDescription) {
method Invalidate (line 82) | func (c *LRUCache) Invalidate(sql string) {
method InvalidateAll (line 96) | func (c *LRUCache) InvalidateAll() {
method GetInvalidated (line 112) | func (c *LRUCache) GetInvalidated() []*pgconn.StatementDescription {
method RemoveInvalidated (line 119) | func (c *LRUCache) RemoveInvalidated() {
method Len (line 125) | func (c *LRUCache) Len() int {
method Cap (line 130) | func (c *LRUCache) Cap() int {
method invalidateOldest (line 134) | func (c *LRUCache) invalidateOldest() {
method insertAfter (line 149) | func (c *LRUCache) insertAfter(at, node *lruNode) {
method unlink (line 156) | func (c *LRUCache) unlink(node *lruNode) {
method moveToFront (line 161) | func (c *LRUCache) moveToFront(node *lruNode) {
method allocNode (line 171) | func (c *LRUCache) allocNode() *lruNode {
method freeNode (line 182) | func (c *LRUCache) freeNode(node *lruNode) {
function NewLRUCache (line 29) | func NewLRUCache(cap int) *LRUCache {
FILE: internal/stmtcache/stmtcache.go
function StatementName (line 13) | func StatementName(sql string) string {
type Cache (line 19) | type Cache interface
FILE: large_objects.go
type LargeObjects (line 20) | type LargeObjects struct
method Create (line 32) | func (o *LargeObjects) Create(ctx context.Context, oid uint32) (uint32...
method Open (line 39) | func (o *LargeObjects) Open(ctx context.Context, oid uint32, mode Larg...
method Unlink (line 49) | func (o *LargeObjects) Unlink(ctx context.Context, oid uint32) error {
type LargeObjectMode (line 24) | type LargeObjectMode
constant LargeObjectModeWrite (line 27) | LargeObjectModeWrite LargeObjectMode = 0x20000
constant LargeObjectModeRead (line 28) | LargeObjectModeRead LargeObjectMode = 0x40000
type LargeObject (line 70) | type LargeObject struct
method Write (line 77) | func (o *LargeObject) Write(p []byte) (int, error) {
method Read (line 110) | func (o *LargeObject) Read(p []byte) (int, error) {
method Seek (line 140) | func (o *LargeObject) Seek(offset int64, whence int) (n int64, err err...
method Tell (line 146) | func (o *LargeObject) Tell() (n int64, err error) {
method Truncate (line 152) | func (o *LargeObject) Truncate(size int64) (err error) {
method Close (line 158) | func (o *LargeObject) Close() error {
FILE: large_objects_private_test.go
function SetMaxLargeObjectMessageLength (line 11) | func SetMaxLargeObjectMessageLength(t *testing.T, length int) {
FILE: large_objects_test.go
function TestLargeObjects (line 15) | func TestLargeObjects(t *testing.T) {
function TestLargeObjectsSimpleProtocol (line 37) | func TestLargeObjectsSimpleProtocol(t *testing.T) {
function testLargeObjects (line 66) | func testLargeObjects(t *testing.T, ctx context.Context, tx pgx.Tx) {
function TestLargeObjectsMultipleTransactions (line 164) | func TestLargeObjectsMultipleTransactions(t *testing.T) {
FILE: log/testingadapter/adapter.go
type TestingLogger (line 14) | type TestingLogger interface
type Logger (line 18) | type Logger struct
method Log (line 26) | func (l *Logger) Log(ctx context.Context, level tracelog.LogLevel, msg...
function NewLogger (line 22) | func NewLogger(l TestingLogger) *Logger {
FILE: multitracer/tracer.go
type Tracer (line 13) | type Tracer struct
method TraceQueryStart (line 58) | func (t *Tracer) TraceQueryStart(ctx context.Context, conn *pgx.Conn, ...
method TraceQueryEnd (line 66) | func (t *Tracer) TraceQueryEnd(ctx context.Context, conn *pgx.Conn, da...
method TraceBatchStart (line 72) | func (t *Tracer) TraceBatchStart(ctx context.Context, conn *pgx.Conn, ...
method TraceBatchQuery (line 80) | func (t *Tracer) TraceBatchQuery(ctx context.Context, conn *pgx.Conn, ...
method TraceBatchEnd (line 86) | func (t *Tracer) TraceBatchEnd(ctx context.Context, conn *pgx.Conn, da...
method TraceCopyFromStart (line 92) | func (t *Tracer) TraceCopyFromStart(ctx context.Context, conn *pgx.Con...
method TraceCopyFromEnd (line 100) | func (t *Tracer) TraceCopyFromEnd(ctx context.Context, conn *pgx.Conn,...
method TracePrepareStart (line 106) | func (t *Tracer) TracePrepareStart(ctx context.Context, conn *pgx.Conn...
method TracePrepareEnd (line 114) | func (t *Tracer) TracePrepareEnd(ctx context.Context, conn *pgx.Conn, ...
method TraceConnectStart (line 120) | func (t *Tracer) TraceConnectStart(ctx context.Context, data pgx.Trace...
method TraceConnectEnd (line 128) | func (t *Tracer) TraceConnectEnd(ctx context.Context, data pgx.TraceCo...
method TraceAcquireStart (line 134) | func (t *Tracer) TraceAcquireStart(ctx context.Context, pool *pgxpool....
method TraceAcquireEnd (line 142) | func (t *Tracer) TraceAcquireEnd(ctx context.Context, pool *pgxpool.Po...
method TraceRelease (line 148) | func (t *Tracer) TraceRelease(pool *pgxpool.Pool, data pgxpool.TraceRe...
function New (line 24) | func New(tracers ...pgx.QueryTracer) *Tracer {
FILE: multitracer/tracer_test.go
type testFullTracer (line 13) | type testFullTracer struct
method TraceQueryStart (line 15) | func (tt *testFullTracer) TraceQueryStart(ctx context.Context, conn *p...
method TraceQueryEnd (line 19) | func (tt *testFullTracer) TraceQueryEnd(ctx context.Context, conn *pgx...
method TraceBatchStart (line 22) | func (tt *testFullTracer) TraceBatchStart(ctx context.Context, conn *p...
method TraceBatchQuery (line 26) | func (tt *testFullTracer) TraceBatchQuery(ctx context.Context, conn *p...
method TraceBatchEnd (line 29) | func (tt *testFullTracer) TraceBatchEnd(ctx context.Context, conn *pgx...
method TraceCopyFromStart (line 32) | func (tt *testFullTracer) TraceCopyFromStart(ctx context.Context, conn...
method TraceCopyFromEnd (line 36) | func (tt *testFullTracer) TraceCopyFromEnd(ctx context.Context, conn *...
method TracePrepareStart (line 39) | func (tt *testFullTracer) TracePrepareStart(ctx context.Context, conn ...
method TracePrepareEnd (line 43) | func (tt *testFullTracer) TracePrepareEnd(ctx context.Context, conn *p...
method TraceConnectStart (line 46) | func (tt *testFullTracer) TraceConnectStart(ctx context.Context, data ...
method TraceConnectEnd (line 50) | func (tt *testFullTracer) TraceConnectEnd(ctx context.Context, data pg...
method TraceAcquireStart (line 53) | func (tt *testFullTracer) TraceAcquireStart(ctx context.Context, pool ...
method TraceAcquireEnd (line 57) | func (tt *testFullTracer) TraceAcquireEnd(ctx context.Context, pool *p...
method TraceRelease (line 60) | func (tt *testFullTracer) TraceRelease(pool *pgxpool.Pool, data pgxpoo...
type testCopyTracer (line 63) | type testCopyTracer struct
method TraceQueryStart (line 65) | func (tt *testCopyTracer) TraceQueryStart(ctx context.Context, conn *p...
method TraceQueryEnd (line 69) | func (tt *testCopyTracer) TraceQueryEnd(ctx context.Context, conn *pgx...
method TraceCopyFromStart (line 72) | func (tt *testCopyTracer) TraceCopyFromStart(ctx context.Context, conn...
method TraceCopyFromEnd (line 76) | func (tt *testCopyTracer) TraceCopyFromEnd(ctx context.Context, conn *...
function TestNew (line 79) | func TestNew(t *testing.T) {
FILE: named_args.go
type NamedArgs (line 21) | type NamedArgs
method RewriteQuery (line 24) | func (na NamedArgs) RewriteQuery(ctx context.Context, conn *Conn, sql ...
type StrictNamedArgs (line 30) | type StrictNamedArgs
method RewriteQuery (line 33) | func (sna StrictNamedArgs) RewriteQuery(ctx context.Context, conn *Con...
type namedArg (line 37) | type namedArg
type sqlLexer (line 39) | type sqlLexer struct
type stateFn (line 50) | type stateFn
function rewriteQuery (line 52) | func rewriteQuery(na map[string]any, sql string, isStrict bool) (newSQL ...
function rawState (line 94) | func rawState(l *sqlLexer) stateFn {
function isLetter (line 141) | func isLetter(r rune) bool {
function namedArgState (line 145) | func namedArgState(l *sqlLexer) stateFn {
function singleQuoteState (line 173) | func singleQuoteState(l *sqlLexer) stateFn {
function doubleQuoteState (line 195) | func doubleQuoteState(l *sqlLexer) stateFn {
function escapeStringState (line 217) | func escapeStringState(l *sqlLexer) stateFn {
function oneLineCommentState (line 242) | func oneLineCommentState(l *sqlLexer) stateFn {
function multilineCommentState (line 263) | func multilineCommentState(l *sqlLexer) stateFn {
FILE: named_args_test.go
function TestNamedArgsRewriteQuery (line 12) | func TestNamedArgsRewriteQuery(t *testing.T) {
function TestStrictNamedArgsRewriteQuery (line 118) | func TestStrictNamedArgsRewriteQuery(t *testing.T) {
FILE: pgbouncer_test.go
function TestPgbouncerStatementCacheDescribe (line 13) | func TestPgbouncerStatementCacheDescribe(t *testing.T) {
function TestPgbouncerSimpleProtocol (line 26) | func TestPgbouncerSimpleProtocol(t *testing.T) {
function testPgbouncer (line 38) | func testPgbouncer(t *testing.T, config *pgx.ConnConfig, workers, iterat...
FILE: pgconn/auth_oauth.go
method oauthAuth (line 12) | func (c *PgConn) oauthAuth(ctx context.Context) error {
FILE: pgconn/auth_scram.go
constant clientNonceLen (line 37) | clientNonceLen = 18
constant scramSHA256Name (line 38) | scramSHA256Name = "SCRAM-SHA-256"
constant scramSHA256PlusName (line 39) | scramSHA256PlusName = "SCRAM-SHA-256-PLUS"
method scramAuth (line 43) | func (c *PgConn) scramAuth(serverAuthMechanisms []string) error {
method rxSASLContinue (line 114) | func (c *PgConn) rxSASLContinue() (*pgproto3.AuthenticationSASLContinue,...
method rxSASLFinal (line 129) | func (c *PgConn) rxSASLFinal() (*pgproto3.AuthenticationSASLFinal, error) {
type scramClient (line 144) | type scramClient struct
method clientFirstMessage (line 214) | func (sc *scramClient) clientFirstMessage() []byte {
method recvServerFirstMessage (line 243) | func (sc *scramClient) recvServerFirstMessage(serverFirstMessage []byt...
method clientFinalMessage (line 298) | func (sc *scramClient) clientFinalMessage() string {
method recvServerFinalMessage (line 325) | func (sc *scramClient) recvServerFinalMessage(serverFinalMessage []byt...
function newScramClient (line 181) | func newScramClient(serverAuthMechanisms []string, password string) (*sc...
function computeHMAC (line 339) | func computeHMAC(key, msg []byte) []byte {
function computeClientProof (line 345) | func computeClientProof(saltedPassword, authMessage []byte) []byte {
function computeServerSignature (line 360) | func computeServerSignature(saltedPassword, authMessage []byte) []byte {
function getTLSCertificateHash (line 370) | func getTLSCertificateHash(conn *tls.Conn) ([]byte, error) {
FILE: pgconn/auth_scram_test.go
function generateSelfSignedCert (line 23) | func generateSelfSignedCert(t *testing.T, sigAlg x509.SignatureAlgorithm...
function tlsConnWithCert (line 73) | func tlsConnWithCert(t *testing.T, cert tls.Certificate) *tls.Conn {
function TestGetTLSCertificateHash (line 100) | func TestGetTLSCertificateHash(t *testing.T) {
function TestScramClientFirstMessage (line 149) | func TestScramClientFirstMessage(t *testing.T) {
function TestScramClientFinalMessage (line 209) | func TestScramClientFinalMessage(t *testing.T) {
function TestScramClientMechanismValidation (line 280) | func TestScramClientMechanismValidation(t *testing.T) {
function TestScramClientRecvServerFirstMessage (line 296) | func TestScramClientRecvServerFirstMessage(t *testing.T) {
function TestScramClientRecvServerFinalMessage (line 381) | func TestScramClientRecvServerFinalMessage(t *testing.T) {
FILE: pgconn/benchmark_private_test.go
function BenchmarkCommandTagRowsAffected (line 8) | func BenchmarkCommandTagRowsAffected(b *testing.B) {
function BenchmarkCommandTagTypeFromString (line 33) | func BenchmarkCommandTagTypeFromString(b *testing.B) {
function BenchmarkCommandTagInsert (line 45) | func BenchmarkCommandTagInsert(b *testing.B) {
FILE: pgconn/benchmark_test.go
function BenchmarkConnect (line 13) | func BenchmarkConnect(b *testing.B) {
function BenchmarkExec (line 40) | func BenchmarkExec(b *testing.B) {
function BenchmarkExecPossibleToCancel (line 96) | func BenchmarkExecPossibleToCancel(b *testing.B) {
function BenchmarkExecPrepared (line 139) | func BenchmarkExecPrepared(b *testing.B) {
function BenchmarkExecPreparedPossibleToCancel (line 190) | func BenchmarkExecPreparedPossibleToCancel(b *testing.B) {
FILE: pgconn/config.go
type AfterConnectFunc (line 28) | type AfterConnectFunc
type ValidateConnectFunc (line 29) | type ValidateConnectFunc
type GetSSLPasswordFunc (line 30) | type GetSSLPasswordFunc
type Config (line 35) | type Config struct
method Copy (line 116) | func (c *Config) Copy() *Config {
type ParseConfigOptions (line 107) | type ParseConfigOptions struct
type FallbackConfig (line 142) | type FallbackConfig struct
type connectOneConfig (line 149) | type connectOneConfig struct
function isAbsolutePath (line 159) | func isAbsolutePath(path string) bool {
function NetworkAddress (line 177) | func NetworkAddress(host string, port uint16) (network, address string) {
function ParseConfig (line 266) | func ParseConfig(connString string) (*Config, error) {
function ParseConfigWithOptions (line 274) | func ParseConfigWithOptions(connString string, options ParseConfigOption...
function mergeSettings (line 490) | func mergeSettings(settingSets ...map[string]string) map[string]string {
function parseEnvSettings (line 500) | func parseEnvSettings() map[string]string {
function parseURLSettings (line 538) | func parseURLSettings(connString string) (map[string]string, error) {
function isIPOnly (line 607) | func isIPOnly(host string) bool {
function parseKeywordValueSettings (line 613) | func parseKeywordValueSettings(s string) (map[string]string, error) {
function parseServiceSettings (line 688) | func parseServiceSettings(servicefilePath, serviceName string) (map[stri...
function configTLS (line 717) | func configTLS(settings map[string]string, thisHost string, parseConfigO...
function parsePort (line 908) | func parsePort(s string) (uint16, error) {
function makeDefaultDialer (line 919) | func makeDefaultDialer() *net.Dialer {
function makeDefaultResolver (line 924) | func makeDefaultResolver() *net.Resolver {
function parseConnectTimeoutSetting (line 928) | func parseConnectTimeoutSetting(s string) (time.Duration, error) {
function makeConnectTimeoutDialFunc (line 939) | func makeConnectTimeoutDialFunc(timeout time.Duration) DialFunc {
function ValidateConnectTargetSessionAttrsReadWrite (line 947) | func ValidateConnectTargetSessionAttrsReadWrite(ctx context.Context, pgC...
function ValidateConnectTargetSessionAttrsReadOnly (line 962) | func ValidateConnectTargetSessionAttrsReadOnly(ctx context.Context, pgCo...
function ValidateConnectTargetSessionAttrsStandby (line 977) | func ValidateConnectTargetSessionAttrsStandby(ctx context.Context, pgCon...
function ValidateConnectTargetSessionAttrsPrimary (line 992) | func ValidateConnectTargetSessionAttrsPrimary(ctx context.Context, pgCon...
function ValidateConnectTargetSessionAttrsPreferStandby (line 1007) | func ValidateConnectTargetSessionAttrsPreferStandby(ctx context.Context,...
function parseProtocolVersion (line 1020) | func parseProtocolVersion(s string) (uint32, error) {
FILE: pgconn/config_test.go
function skipOnWindows (line 21) | func skipOnWindows(t *testing.T) {
function getDefaultPort (line 27) | func getDefaultPort(t *testing.T) uint16 {
function getDefaultUser (line 36) | func getDefaultUser(t *testing.T) string {
function clearPgEnvvars (line 58) | func clearPgEnvvars(t *testing.T) {
function TestParseConfig (line 64) | func TestParseConfig(t *testing.T) {
function TestParseConfigKVWithTrailingEmptyEqualDoesNotPanic (line 785) | func TestParseConfigKVWithTrailingEmptyEqualDoesNotPanic(t *testing.T) {
function TestParseConfigKVLeadingEqual (line 790) | func TestParseConfigKVLeadingEqual(t *testing.T) {
function TestParseConfigKVTrailingBackslash (line 796) | func TestParseConfigKVTrailingBackslash(t *testing.T) {
function TestConfigCopyReturnsEqualConfig (line 802) | func TestConfigCopyReturnsEqualConfig(t *testing.T) {
function TestConfigCopyOriginalConfigDidNotChange (line 811) | func TestConfigCopyOriginalConfigDidNotChange(t *testing.T) {
function TestConfigCopyCanBeUsedToConnect (line 828) | func TestConfigCopyCanBeUsedToConnect(t *testing.T) {
function TestNetworkAddress (line 840) | func TestNetworkAddress(t *testing.T) {
function assertConfigsEqual (line 889) | func assertConfigsEqual(t *testing.T, expected, actual *pgconn.Config, t...
function TestParseConfigEnvLibpq (line 931) | func TestParseConfigEnvLibpq(t *testing.T) {
function TestParseConfigReadsPgPassfile (line 1028) | func TestParseConfigReadsPgPassfile(t *testing.T) {
function TestParseConfigReadsPgServiceFile (line 1053) | func TestParseConfigReadsPgServiceFile(t *testing.T) {
function TestParseConfigExplicitEmptyUserDefaultsToOSUser (line 1149) | func TestParseConfigExplicitEmptyUserDefaultsToOSUser(t *testing.T) {
function TestParseConfigProtocolVersion (line 1202) | func TestParseConfigProtocolVersion(t *testing.T) {
function TestParseConfigChannelBinding (line 1318) | func TestParseConfigChannelBinding(t *testing.T) {
FILE: pgconn/ctxwatch/context_watcher.go
type ContextWatcher (line 10) | type ContextWatcher struct
method Watch (line 32) | func (cw *ContextWatcher) Watch(ctx context.Context) {
method Unwatch (line 51) | func (cw *ContextWatcher) Unwatch() {
function NewContextWatcher (line 23) | func NewContextWatcher(handler Handler) *ContextWatcher {
type Handler (line 65) | type Handler interface
FILE: pgconn/ctxwatch/context_watcher_test.go
type testHandler (line 13) | type testHandler struct
method HandleCancel (line 18) | func (h *testHandler) HandleCancel(ctx context.Context) {
method HandleUnwatchAfterCancel (line 22) | func (h *testHandler) HandleUnwatchAfterCancel() {
function TestContextWatcherContextCancelled (line 26) | func TestContextWatcherContextCancelled(t *testing.T) {
function TestContextWatcherUnwatchedBeforeContextCancelled (line 52) | func TestContextWatcherUnwatchedBeforeContextCancelled(t *testing.T) {
function TestContextWatcherMultipleWatchPanics (line 67) | func TestContextWatcherMultipleWatchPanics(t *testing.T) {
function TestContextWatcherUnwatchWhenNotWatchingIsSafe (line 80) | func TestContextWatcherUnwatchWhenNotWatchingIsSafe(t *testing.T) {
function TestContextWatcherUnwatchIsConcurrencySafe (line 90) | func TestContextWatcherUnwatchIsConcurrencySafe(t *testing.T) {
function TestContextWatcherStress (line 103) | func TestContextWatcherStress(t *testing.T) {
function BenchmarkContextWatcherUncancellable (line 155) | func BenchmarkContextWatcherUncancellable(b *testing.B) {
function BenchmarkContextWatcherCancelled (line 164) | func BenchmarkContextWatcherCancelled(b *testing.B) {
function BenchmarkContextWatcherCancellable (line 175) | func BenchmarkContextWatcherCancellable(b *testing.B) {
FILE: pgconn/ctxwatch/synctest_test.go
function TestContextWatchGoroutineBuildup (line 15) | func TestContextWatchGoroutineBuildup(t *testing.T) {
FILE: pgconn/defaults.go
function defaultSettings (line 12) | func defaultSettings() map[string]string {
function defaultHost (line 49) | func defaultHost() string {
FILE: pgconn/defaults_windows.go
function defaultSettings (line 10) | func defaultSettings() map[string]string {
function defaultHost (line 55) | func defaultHost() string {
FILE: pgconn/errors.go
function SafeToRetry (line 14) | func SafeToRetry(err error) bool {
function Timeout (line 24) | func Timeout(err error) bool {
type PgError (line 32) | type PgError struct
method Error (line 53) | func (pe *PgError) Error() string {
method SQLState (line 58) | func (pe *PgError) SQLState() string {
type ConnectError (line 63) | type ConnectError struct
method Error (line 68) | func (e *ConnectError) Error() string {
method Unwrap (line 78) | func (e *ConnectError) Unwrap() error {
type perDialConnectError (line 82) | type perDialConnectError struct
method Error (line 88) | func (e *perDialConnectError) Error() string {
method Unwrap (line 92) | func (e *perDialConnectError) Unwrap() error {
type connLockError (line 96) | type connLockError struct
method SafeToRetry (line 100) | func (e *connLockError) SafeToRetry() bool {
method Error (line 104) | func (e *connLockError) Error() string {
type ParseConfigError (line 109) | type ParseConfigError struct
method Error (line 123) | func (e *ParseConfigError) Error() string {
method Unwrap (line 134) | func (e *ParseConfigError) Unwrap() error {
function NewParseConfigError (line 115) | func NewParseConfigError(conn, msg string, err error) error {
function normalizeTimeoutError (line 138) | func normalizeTimeoutError(ctx context.Context, err error) error {
type pgconnError (line 153) | type pgconnError struct
method Error (line 159) | func (e *pgconnError) Error() string {
method SafeToRetry (line 169) | func (e *pgconnError) SafeToRetry() bool {
method Unwrap (line 173) | func (e *pgconnError) Unwrap() error {
type errTimeout (line 179) | type errTimeout struct
method Error (line 183) | func (e *errTimeout) Error() string {
method SafeToRetry (line 187) | func (e *errTimeout) SafeToRetry() bool {
method Unwrap (line 191) | func (e *errTimeout) Unwrap() error {
type contextAlreadyDoneError (line 195) | type contextAlreadyDoneError struct
method Error (line 199) | func (e *contextAlreadyDoneError) Error() string {
method SafeToRetry (line 203) | func (e *contextAlreadyDoneError) SafeToRetry() bool {
method Unwrap (line 207) | func (e *contextAlreadyDoneError) Unwrap() error {
function newContextAlreadyDoneError (line 212) | func newContextAlreadyDoneError(ctx context.Context) (err error) {
function redactPW (line 216) | func redactPW(connString string) string {
function redactURL (line 231) | func redactURL(u *url.URL) string {
type NotPreferredError (line 241) | type NotPreferredError struct
method Error (line 246) | func (e *NotPreferredError) Error() string {
method SafeToRetry (line 250) | func (e *NotPreferredError) SafeToRetry() bool {
method Unwrap (line 254) | func (e *NotPreferredError) Unwrap() error {
type PrepareError (line 258) | type PrepareError struct
method Error (line 264) | func (e *PrepareError) Error() string {
method Unwrap (line 271) | func (e *PrepareError) Unwrap() error {
FILE: pgconn/errors_test.go
function TestConfigError (line 10) | func TestConfigError(t *testing.T) {
FILE: pgconn/helper_test.go
function closeConn (line 14) | func closeConn(t testing.TB, conn *pgconn.PgConn) {
function ensureConnValid (line 26) | func ensureConnValid(t *testing.T, pgConn *pgconn.PgConn) {
FILE: pgconn/internal/bgreader/bgreader.go
constant StatusStopped (line 12) | StatusStopped = iota
constant StatusRunning (line 13) | StatusRunning
constant StatusStopping (line 14) | StatusStopping
type BGReader (line 18) | type BGReader struct
method Start (line 33) | func (r *BGReader) Start() {
method Stop (line 50) | func (r *BGReader) Stop() {
method Status (line 65) | func (r *BGReader) Status() int32 {
method bgRead (line 71) | func (r *BGReader) bgRead() {
method Read (line 90) | func (r *BGReader) Read(p []byte) (int, error) {
method readFromReadResults (line 111) | func (r *BGReader) readFromReadResults(p []byte) (int, error) {
type readResult (line 26) | type readResult struct
function New (line 132) | func New(r io.Reader) *BGReader {
FILE: pgconn/internal/bgreader/bgreader_test.go
function TestBGReaderReadWhenStopped (line 15) | func TestBGReaderReadWhenStopped(t *testing.T) {
function TestBGReaderReadWhenStarted (line 23) | func TestBGReaderReadWhenStarted(t *testing.T) {
type mockReadFunc (line 32) | type mockReadFunc
type mockReader (line 34) | type mockReader struct
method Read (line 38) | func (r *mockReader) Read(p []byte) (int, error) {
function TestBGReaderReadWaitsForBackgroundRead (line 49) | func TestBGReaderReadWaitsForBackgroundRead(t *testing.T) {
function TestBGReaderErrorWhenStarted (line 66) | func TestBGReaderErrorWhenStarted(t *testing.T) {
function TestBGReaderErrorWhenStopped (line 82) | func TestBGReaderErrorWhenStopped(t *testing.T) {
type numberReader (line 97) | type numberReader struct
method Read (line 102) | func (nr *numberReader) Read(p []byte) (int, error) {
function TestBGReaderStress (line 114) | func TestBGReaderStress(t *testing.T) {
FILE: pgconn/krb5.go
type NewGSSFunc (line 12) | type NewGSSFunc
function RegisterGSSProvider (line 25) | func RegisterGSSProvider(newGSSArg NewGSSFunc) {
type GSS (line 30) | type GSS interface
method gssAuth (line 36) | func (c *PgConn) gssAuth() error {
method rxGSSContinue (line 86) | func (c *PgConn) rxGSSContinue() (*pgproto3.AuthenticationGSSContinue, e...
FILE: pgconn/pgconn.go
constant connStatusUninitialized (line 30) | connStatusUninitialized = iota
constant connStatusConnecting (line 31) | connStatusConnecting
constant connStatusClosed (line 32) | connStatusClosed
constant connStatusIdle (line 33) | connStatusIdle
constant connStatusBusy (line 34) | connStatusBusy
type Notice (line 39) | type Notice
type Notification (line 42) | type Notification struct
type DialFunc (line 49) | type DialFunc
type LookupFunc (line 53) | type LookupFunc
type BuildFrontendFunc (line 56) | type BuildFrontendFunc
type PgErrorHandler (line 62) | type PgErrorHandler
type NoticeHandler (line 68) | type NoticeHandler
type NotificationHandler (line 74) | type NotificationHandler
type PgConn (line 77) | type PgConn struct
method txPasswordMessage (line 511) | func (pgConn *PgConn) txPasswordMessage(password string) (err error) {
method signalMessage (line 522) | func (pgConn *PgConn) signalMessage() chan struct{} {
method ReceiveMessage (line 547) | func (pgConn *PgConn) ReceiveMessage(ctx context.Context) (pgproto3.Ba...
method peekMessage (line 575) | func (pgConn *PgConn) peekMessage() (pgproto3.BackendMessage, error) {
method receiveMessage (line 614) | func (pgConn *PgConn) receiveMessage() (pgproto3.BackendMessage, error) {
method Conn (line 653) | func (pgConn *PgConn) Conn() net.Conn {
method PID (line 658) | func (pgConn *PgConn) PID() uint32 {
method TxStatus (line 671) | func (pgConn *PgConn) TxStatus() byte {
method SecretKey (line 676) | func (pgConn *PgConn) SecretKey() []byte {
method Frontend (line 681) | func (pgConn *PgConn) Frontend() *pgproto3.Frontend {
method Close (line 688) | func (pgConn *PgConn) Close(ctx context.Context) error {
method asyncClose (line 722) | func (pgConn *PgConn) asyncClose() {
method CleanupDone (line 754) | func (pgConn *PgConn) CleanupDone() chan (struct{}) {
method IsClosed (line 761) | func (pgConn *PgConn) IsClosed() bool {
method IsBusy (line 766) | func (pgConn *PgConn) IsBusy() bool {
method lock (line 771) | func (pgConn *PgConn) lock() error {
method unlock (line 784) | func (pgConn *PgConn) unlock() {
method ParameterStatus (line 796) | func (pgConn *PgConn) ParameterStatus(key string) string {
method getFieldDescriptionSlice (line 864) | func (pgConn *PgConn) getFieldDescriptionSlice(n int) []FieldDescripti...
method Prepare (line 900) | func (pgConn *PgConn) Prepare(ctx context.Context, name, sql string, p...
method Deallocate (line 966) | func (pgConn *PgConn) Deallocate(ctx context.Context, name string) err...
method CancelRequest (line 1039) | func (pgConn *PgConn) CancelRequest(ctx context.Context) error {
method WaitForNotification (line 1094) | func (pgConn *PgConn) WaitForNotification(ctx context.Context) error {
method Exec (line 1129) | func (pgConn *PgConn) Exec(ctx context.Context, sql string) *MultiResu...
method ExecParams (line 1187) | func (pgConn *PgConn) ExecParams(ctx context.Context, sql string, para...
method ExecPrepared (line 1213) | func (pgConn *PgConn) ExecPrepared(ctx context.Context, stmtName strin...
method ExecStatement (line 1242) | func (pgConn *PgConn) ExecStatement(ctx context.Context, statementDesc...
method execExtendedPrefix (line 1255) | func (pgConn *PgConn) execExtendedPrefix(ctx context.Context, paramVal...
method execExtendedSuffix (line 1290) | func (pgConn *PgConn) execExtendedSuffix(result *ResultReader, stateme...
method CopyTo (line 1311) | func (pgConn *PgConn) CopyTo(ctx context.Context, w io.Writer, sql str...
method CopyFrom (line 1370) | func (pgConn *PgConn) CopyFrom(ctx context.Context, r io.Reader, sql s...
method ExecBatch (line 1930) | func (pgConn *PgConn) ExecBatch(ctx context.Context, batch *Batch) *Mu...
method EscapeString (line 1995) | func (pgConn *PgConn) EscapeString(s string) (string, error) {
method CheckConn (line 2015) | func (pgConn *PgConn) CheckConn() error {
method Ping (line 2032) | func (pgConn *PgConn) Ping(ctx context.Context) error {
method makeCommandTag (line 2037) | func (pgConn *PgConn) makeCommandTag(buf []byte) CommandTag {
method enterPotentialWriteReadDeadlock (line 2043) | func (pgConn *PgConn) enterPotentialWriteReadDeadlock() {
method exitPotentialWriteReadDeadlock (line 2056) | func (pgConn *PgConn) exitPotentialWriteReadDeadlock() {
method flushWithPotentialWriteReadDeadlock (line 2069) | func (pgConn *PgConn) flushWithPotentialWriteReadDeadlock() error {
method SyncConn (line 2083) | func (pgConn *PgConn) SyncConn(ctx context.Context) error {
method CustomData (line 2101) | func (pgConn *PgConn) CustomData() map[string]any {
method Hijack (line 2126) | func (pgConn *PgConn) Hijack() (*HijackedConn, error) {
method StartPipeline (line 2359) | func (pgConn *PgConn) StartPipeline(ctx context.Context) *Pipeline {
function Connect (line 114) | func Connect(ctx context.Context, connString string) (*PgConn, error) {
function ConnectWithOptions (line 126) | func ConnectWithOptions(ctx context.Context, connString string, parseCon...
function ConnectConfig (line 141) | func ConnectConfig(ctx context.Context, config *Config) (*PgConn, error) {
function buildConnectOneConfigs (line 179) | func buildConnectOneConfigs(ctx context.Context, config *Config) ([]*con...
function connectPreferred (line 246) | func connectPreferred(ctx context.Context, config *Config, connectOneCon...
function connectOne (line 306) | func connectOne(ctx context.Context, config *Config, connectConfig *conn...
function startTLS (line 493) | func startTLS(conn net.Conn, tlsConfig *tls.Config) (net.Conn, error) {
function hexMD5 (line 516) | func hexMD5(s string) string {
type CommandTag (line 801) | type CommandTag struct
method RowsAffected (line 812) | func (ct CommandTag) RowsAffected() int64 {
method String (line 830) | func (ct CommandTag) String() string {
method Insert (line 835) | func (ct CommandTag) Insert() bool {
method Update (line 840) | func (ct CommandTag) Update() bool {
method Delete (line 845) | func (ct CommandTag) Delete() bool {
method Select (line 850) | func (ct CommandTag) Select() bool {
function NewCommandTag (line 806) | func NewCommandTag(s string) CommandTag {
type FieldDescription (line 854) | type FieldDescription struct
function convertRowDescription (line 872) | func convertRowDescription(dst []FieldDescription, rd *pgproto3.RowDescr...
type StatementDescription (line 884) | type StatementDescription struct
function ErrorResponseToPgError (line 1007) | func ErrorResponseToPgError(msg *pgproto3.ErrorResponse) *PgError {
function noticeResponseToNotice (line 1030) | func noticeResponseToNotice(msg *pgproto3.NoticeResponse) *Notice {
type MultiResultReader (line 1504) | type MultiResultReader struct
method ReadAll (line 1519) | func (mrr *MultiResultReader) ReadAll() ([]*Result, error) {
method receiveMessage (line 1530) | func (mrr *MultiResultReader) receiveMessage() (pgproto3.BackendMessag...
method NextResult (line 1553) | func (mrr *MultiResultReader) NextResult() bool {
method ResultReader (line 1627) | func (mrr *MultiResultReader) ResultReader() *ResultReader {
method Close (line 1632) | func (mrr *MultiResultReader) Close() error {
type ResultReader (line 1644) | type ResultReader struct
method Read (line 1668) | func (rr *ResultReader) Read() *Result {
method NextRow (line 1694) | func (rr *ResultReader) NextRow() bool {
method preloadRowValues (line 1716) | func (rr *ResultReader) preloadRowValues(values [][]byte) {
method FieldDescriptions (line 1724) | func (rr *ResultReader) FieldDescriptions() []FieldDescription {
method Values (line 1730) | func (rr *ResultReader) Values() [][]byte {
method Close (line 1736) | func (rr *ResultReader) Close() (CommandTag, error) {
method readUntilRowDescription (line 1773) | func (rr *ResultReader) readUntilRowDescription(statementDescription *...
method receiveMessage (line 1806) | func (rr *ResultReader) receiveMessage() (msg pgproto3.BackendMessage,...
method concludeCommand (line 1844) | func (rr *ResultReader) concludeCommand(commandTag CommandTag, err err...
type Result (line 1660) | type Result struct
type Batch (line 1861) | type Batch struct
method ExecParams (line 1869) | func (batch *Batch) ExecParams(sql string, paramValues [][]byte, param...
method ExecPrepared (line 1882) | func (batch *Batch) ExecPrepared(stmtName string, paramValues [][]byte...
method ExecStatement (line 1908) | func (batch *Batch) ExecStatement(statementDescription *StatementDescr...
type HijackedConn (line 2109) | type HijackedConn struct
function Construct (line 2151) | func Construct(hc *HijackedConn) (*PgConn, error) {
type Pipeline (line 2194) | type Pipeline struct
method SendPrepare (line 2396) | func (p *Pipeline) SendPrepare(name, sql string, paramOIDs []uint32) {
method SendDeallocate (line 2407) | func (p *Pipeline) SendDeallocate(name string) {
method SendQueryParams (line 2417) | func (p *Pipeline) SendQueryParams(sql string, paramValues [][]byte, p...
method SendQueryPrepared (line 2430) | func (p *Pipeline) SendQueryPrepared(stmtName string, paramValues [][]...
method SendQueryStatement (line 2442) | func (p *Pipeline) SendQueryStatement(statementDescription *StatementD...
method SendFlushRequest (line 2460) | func (p *Pipeline) SendFlushRequest() {
method SendPipelineSync (line 2475) | func (p *Pipeline) SendPipelineSync() {
method Flush (line 2485) | func (p *Pipeline) Flush() error {
method Sync (line 2511) | func (p *Pipeline) Sync() error {
method GetResults (line 2519) | func (p *Pipeline) GetResults() (results any, err error) {
method getResults (line 2530) | func (p *Pipeline) getResults() (results any, err error) {
method getResultsPrepare (line 2561) | func (p *Pipeline) getResultsPrepare() (*StatementDescription, error) {
method getResultsQueryParams (line 2611) | func (p *Pipeline) getResultsQueryParams() (*ResultReader, error) {
method getResultsQueryPrepared (line 2625) | func (p *Pipeline) getResultsQueryPrepared() (*ResultReader, error) {
method getResultsQueryStatement (line 2634) | func (p *Pipeline) getResultsQueryStatement() (*ResultReader, error) {
method getResultsDeallocate (line 2685) | func (p *Pipeline) getResultsDeallocate() (*CloseComplete, error) {
method getResultsSync (line 2704) | func (p *Pipeline) getResultsSync() (*PipelineSync, error) {
method receiveParseComplete (line 2727) | func (p *Pipeline) receiveParseComplete(errStr string) error {
method receiveBindComplete (line 2745) | func (p *Pipeline) receiveBindComplete(errStr string) error {
method receiveDescribedResultReader (line 2763) | func (p *Pipeline) receiveDescribedResultReader(errStr string) (*Resul...
method receiveMessage (line 2812) | func (p *Pipeline) receiveMessage() (pgproto3.BackendMessage, error) {
method handleUnexpectedMessage (line 2830) | func (p *Pipeline) handleUnexpectedMessage(errStr string, msg pgproto3...
method Close (line 2837) | func (p *Pipeline) Close() error {
type PipelineSync (line 2204) | type PipelineSync struct
type CloseComplete (line 2207) | type CloseComplete struct
type pipelineRequestType (line 2209) | type pipelineRequestType
constant pipelineNil (line 2212) | pipelineNil pipelineRequestType = iota
constant pipelinePrepare (line 2213) | pipelinePrepare
constant pipelineQueryParams (line 2214) | pipelineQueryParams
constant pipelineQueryPrepared (line 2215) | pipelineQueryPrepared
constant pipelineQueryStatement (line 2216) | pipelineQueryStatement
constant pipelineDeallocate (line 2217) | pipelineDeallocate
constant pipelineSyncRequest (line 2218) | pipelineSyncRequest
constant pipelineFlushRequest (line 2219) | pipelineFlushRequest
type pipelineRequestEvent (line 2222) | type pipelineRequestEvent struct
type pipelineState (line 2228) | type pipelineState struct
method Init (line 2237) | func (s *pipelineState) Init() {
method RegisterSendingToServer (line 2244) | func (s *pipelineState) RegisterSendingToServer() {
method registerFlushingBufferOnServer (line 2255) | func (s *pipelineState) registerFlushingBufferOnServer() {
method PushBackRequestType (line 2266) | func (s *pipelineState) PushBackRequestType(req pipelineRequestType) {
method ExtractFrontRequestType (line 2284) | func (s *pipelineState) ExtractFrontRequestType() pipelineRequestType {
method PushBackStatementData (line 2305) | func (s *pipelineState) PushBackStatementData(sd *StatementDescription...
method ExtractFrontStatementData (line 2310) | func (s *pipelineState) ExtractFrontStatementData() (*StatementDescrip...
method HandleError (line 2328) | func (s *pipelineState) HandleError(err *PgError) {
method HandleReadyForQuery (line 2332) | func (s *pipelineState) HandleReadyForQuery() {
method PendingSync (line 2336) | func (s *pipelineState) PendingSync() bool {
method ExpectedReadyForQuery (line 2349) | func (s *pipelineState) ExpectedReadyForQuery() int {
type DeadlineContextWatcherHandler (line 2881) | type DeadlineContextWatcherHandler struct
method HandleCancel (line 2888) | func (h *DeadlineContextWatcherHandler) HandleCancel(ctx context.Conte...
method HandleUnwatchAfterCancel (line 2892) | func (h *DeadlineContextWatcherHandler) HandleUnwatchAfterCancel() {
type CancelRequestContextWatcherHandler (line 2898) | type CancelRequestContextWatcherHandler struct
method HandleCancel (line 2911) | func (h *CancelRequestContextWatcherHandler) HandleCancel(context.Cont...
method HandleUnwatchAfterCancel (line 2941) | func (h *CancelRequestContextWatcherHandler) HandleUnwatchAfterCancel() {
function combineFieldDescriptionsAndResultFormats (line 2948) | func combineFieldDescriptionsAndResultFormats(outputFields, inputFields ...
FILE: pgconn/pgconn_private_test.go
function TestCommandTag (line 9) | func TestCommandTag(t *testing.T) {
FILE: pgconn/pgconn_stress_test.go
function TestConnStress (line 16) | func TestConnStress(t *testing.T) {
function setupStressDB (line 50) | func setupStressDB(t *testing.T, pgConn *pgconn.PgConn) {
function stressExecSelect (line 66) | func stressExecSelect(pgConn *pgconn.PgConn) error {
function stressExecParamsSelect (line 73) | func stressExecParamsSelect(pgConn *pgconn.PgConn) error {
function stressBatch (line 80) | func stressBatch(pgConn *pgconn.PgConn) error {
FILE: pgconn/pgconn_test.go
constant pgbouncerConnStringEnvVar (line 34) | pgbouncerConnStringEnvVar = "PGX_TEST_PGBOUNCER_CONN_STRING"
constant runOAuthTestEnvVar (line 36) | runOAuthTestEnvVar = "PGX_TEST_OAUTH"
function TestConnect (line 39) | func TestConnect(t *testing.T) {
function TestConnectWithOptions (line 69) | func TestConnectWithOptions(t *testing.T) {
function TestConnectTLS (line 102) | func TestConnectTLS(t *testing.T) {
function TestConnectChannelBinding (line 153) | func TestConnectChannelBinding(t *testing.T) {
function TestConnectOAuth (line 258) | func TestConnectOAuth(t *testing.T) {
function TestConnectOAuthError (line 284) | func TestConnectOAuthError(t *testing.T) {
function TestConnectTLSPasswordProtectedClientCertWithSSLPassword (line 304) | func TestConnectTLSPasswordProtectedClientCertWithSSLPassword(t *testing...
function TestConnectTLSPasswordProtectedClientCertWithGetSSLPasswordConfigOption (line 332) | func TestConnectTLSPasswordProtectedClientCertWithGetSSLPasswordConfigOp...
type pgmockWaitStep (line 363) | type pgmockWaitStep
method Step (line 365) | func (s pgmockWaitStep) Step(*pgproto3.Backend) error {
function TestConnectTimeout (line 370) | func TestConnectTimeout(t *testing.T) {
function TestConnectTimeoutStuckOnTLSHandshake (line 448) | func TestConnectTimeoutStuckOnTLSHandshake(t *testing.T) {
function TestConnectInvalidUser (line 522) | func TestConnectInvalidUser(t *testing.T) {
function TestConnectWithConnectionRefused (line 547) | func TestConnectWithConnectionRefused(t *testing.T) {
function TestConnectCustomDialer (line 561) | func TestConnectCustomDialer(t *testing.T) {
function TestConnectCustomLookup (line 582) | func TestConnectCustomLookup(t *testing.T) {
function TestConnectCustomLookupWithPort (line 608) | func TestConnectCustomLookupWithPort(t *testing.T) {
function TestConnectWithRuntimeParams (line 645) | func TestConnectWithRuntimeParams(t *testing.T) {
function TestConnectWithFallback (line 674) | func TestConnectWithFallback(t *testing.T) {
function TestConnectFailsWithResolveFailureAndFailedConnectionAttempts (line 710) | func TestConnectFailsWithResolveFailureAndFailedConnectionAttempts(t *te...
type testConnWrapper (line 726) | type testConnWrapper struct
method Read (line 730) | func (w *testConnWrapper) Read(b []byte) (n int, err error) {
method Write (line 734) | func (w *testConnWrapper) Write(b []byte) (n int, err error) {
method Close (line 738) | func (w *testConnWrapper) Close() error {
method LocalAddr (line 742) | func (w *testConnWrapper) LocalAddr() net.Addr {
method RemoteAddr (line 746) | func (w *testConnWrapper) RemoteAddr() net.Addr {
method SetDeadline (line 750) | func (w *testConnWrapper) SetDeadline(t time.Time) error {
method SetReadDeadline (line 754) | func (w *testConnWrapper) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 758) | func (w *testConnWrapper) SetWriteDeadline(t time.Time) error {
function TestConnectWithAfterNetConnect (line 762) | func TestConnectWithAfterNetConnect(t *testing.T) {
function TestConnectWithValidateConnect (line 783) | func TestConnectWithValidateConnect(t *testing.T) {
function TestConnectWithValidateConnectTargetSessionAttrsReadWrite (line 825) | func TestConnectWithValidateConnectTargetSessionAttrsReadWrite(t *testin...
function TestConnectWithAfterConnect (line 843) | func TestConnectWithAfterConnect(t *testing.T) {
function TestConnectConfigRequiresConfigFromParseConfig (line 867) | func TestConnectConfigRequiresConfigFromParseConfig(t *testing.T) {
function TestConnPrepareSyntaxError (line 878) | func TestConnPrepareSyntaxError(t *testing.T) {
function TestConnPrepareContextPrecanceled (line 895) | func TestConnPrepareContextPrecanceled(t *testing.T) {
function TestConnDeallocate (line 916) | func TestConnDeallocate(t *testing.T) {
function TestConnDeallocateSucceedsInAbortedTransaction (line 944) | func TestConnDeallocateSucceedsInAbortedTransaction(t *testing.T) {
function TestConnDeallocateNonExistentStatementSucceeds (line 983) | func TestConnDeallocateNonExistentStatementSucceeds(t *testing.T) {
function TestConnExec (line 999) | func TestConnExec(t *testing.T) {
function TestConnExecEmpty (line 1021) | func TestConnExecEmpty(t *testing.T) {
function TestConnExecMultipleQueries (line 1041) | func TestConnExecMultipleQueries(t *testing.T) {
function TestConnExecMultipleQueriesEagerFieldDescriptions (line 1069) | func TestConnExecMultipleQueriesEagerFieldDescriptions(t *testing.T) {
function TestConnExecMultipleQueriesError (line 1100) | func TestConnExecMultipleQueriesError(t *testing.T) {
function TestConnExecDeferredError (line 1134) | func TestConnExecDeferredError(t *testing.T) {
function TestConnExecContextCanceled (line 1169) | func TestConnExecContextCanceled(t *testing.T) {
function TestConnExecContextPrecanceled (line 1197) | func TestConnExecContextPrecanceled(t *testing.T) {
function TestConnExecParams (line 1216) | func TestConnExecParams(t *testing.T) {
function TestConnExecParamsDeferredError (line 1243) | func TestConnExecParamsDeferredError(t *testing.T) {
function TestConnExecParamsMaxNumberOfParams (line 1277) | func TestConnExecParamsMaxNumberOfParams(t *testing.T) {
function TestConnExecParamsTooManyParams (line 1303) | func TestConnExecParamsTooManyParams(t *testing.T) {
function TestConnExecParamsCanceled (line 1329) | func TestConnExecParamsCanceled(t *testing.T) {
function TestConnExecParamsPrecanceled (line 1360) | func TestConnExecParamsPrecanceled(t *testing.T) {
function TestConnExecParamsEmptySQL (line 1379) | func TestConnExecParamsEmptySQL(t *testing.T) {
function TestResultReaderValuesHaveSameCapacityAsLength (line 1398) | func TestResultReaderValuesHaveSameCapacityAsLength(t *testing.T) {
function TestResultReaderReadNil (line 1427) | func TestResultReaderReadNil(t *testing.T) {
function TestConnExecPrepared (line 1444) | func TestConnExecPrepared(t *testing.T) {
function TestConnExecPreparedMaxNumberOfParams (line 1477) | func TestConnExecPreparedMaxNumberOfParams(t *testing.T) {
function TestConnExecPreparedTooManyParams (line 1509) | func TestConnExecPreparedTooManyParams(t *testing.T) {
function TestConnExecPreparedCanceled (line 1546) | func TestConnExecPreparedCanceled(t *testing.T) {
function TestConnExecPreparedPrecanceled (line 1578) | func TestConnExecPreparedPrecanceled(t *testing.T) {
function TestConnExecPreparedEmptySQL (line 1600) | func TestConnExecPreparedEmptySQL(t *testing.T) {
function TestConnExecStatement (line 1621) | func TestConnExecStatement(t *testing.T) {
type byteCounterConn (line 1654) | type byteCounterConn struct
method Read (line 1660) | func (cbn *byteCounterConn) Read(b []byte) (n int, err error) {
method Write (line 1666) | func (cbn *byteCounterConn) Write(b []byte) (n int, err error) {
method Close (line 1672) | func (cbn *byteCounterConn) Close() error {
method LocalAddr (line 1676) | func (cbn *byteCounterConn) LocalAddr() net.Addr {
method RemoteAddr (line 1680) | func (cbn *byteCounterConn) RemoteAddr() net.Addr {
method SetDeadline (line 1684) | func (cbn *byteCounterConn) SetDeadline(t time.Time) error {
method SetReadDeadline (line 1688) | func (cbn *byteCounterConn) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 1692) | func (cbn *byteCounterConn) SetWriteDeadline(t time.Time) error {
function TestConnExecStatementNetworkUsage (line 1696) | func TestConnExecStatementNetworkUsage(t *testing.T) {
function TestConnExecBatch (line 1761) | func TestConnExecBatch(t *testing.T) {
type mockConnection (line 1817) | type mockConnection struct
method Write (line 1822) | func (m mockConnection) Write(b []byte) (n int, err error) {
function TestConnExecBatchWriteError (line 1827) | func TestConnExecBatchWriteError(t *testing.T) {
function TestConnExecBatchDeferredError (line 1863) | func TestConnExecBatchDeferredError(t *testing.T) {
function TestConnExecBatchPrecanceled (line 1900) | func TestConnExecBatchPrecanceled(t *testing.T) {
function TestConnExecBatchHuge (line 1931) | func TestConnExecBatchHuge(t *testing.T) {
function TestConnExecBatchImplicitTransaction (line 1966) | func TestConnExecBatchImplicitTransaction(t *testing.T) {
function TestConnLocking (line 1996) | func TestConnLocking(t *testing.T) {
function TestConnOnNotice (line 2023) | func TestConnOnNotice(t *testing.T) {
function TestConnOnNotification (line 2058) | func TestConnOnNotification(t *testing.T) {
function TestConnWaitForNotification (line 2097) | func TestConnWaitForNotification(t *testing.T) {
function TestConnWaitForNotificationPrecanceled (line 2136) | func TestConnWaitForNotificationPrecanceled(t *testing.T) {
function TestConnWaitForNotificationTimeout (line 2156) | func TestConnWaitForNotificationTimeout(t *testing.T) {
function TestConnCopyToSmall (line 2178) | func TestConnCopyToSmall(t *testing.T) {
function TestConnCopyToLarge (line 2223) | func TestConnCopyToLarge(t *testing.T) {
function TestConnCopyToQueryError (line 2268) | func TestConnCopyToQueryError(t *testing.T) {
function TestConnCopyToCanceled (line 2288) | func TestConnCopyToCanceled(t *testing.T) {
function TestConnCopyToPrecanceled (line 2318) | func TestConnCopyToPrecanceled(t *testing.T) {
function TestConnCopyFrom (line 2340) | func TestConnCopyFrom(t *testing.T) {
function TestConnCopyFromBinary (line 2383) | func TestConnCopyFromBinary(t *testing.T) {
function TestConnCopyFromCanceled (line 2439) | func TestConnCopyFromCanceled(t *testing.T) {
function TestConnCopyFromPrecanceled (line 2486) | func TestConnCopyFromPrecanceled(t *testing.T) {
function TestConnCopyFromConnectionTerminated (line 2527) | func TestConnCopyFromConnectionTerminated(t *testing.T) {
function TestConnCopyFromGzipReader (line 2585) | func TestConnCopyFromGzipReader(t *testing.T) {
function TestConnCopyFromQuerySyntaxError (line 2648) | func TestConnCopyFromQuerySyntaxError(t *testing.T) {
function TestConnCopyFromQueryNoTableError (line 2685) | func TestConnCopyFromQueryNoTableError(t *testing.T) {
function TestConnCopyFromNoticeResponseReceivedMidStream (line 2706) | func TestConnCopyFromNoticeResponseReceivedMidStream(t *testing.T) {
type delayedReader (line 2751) | type delayedReader struct
method Read (line 2755) | func (d delayedReader) Read(p []byte) (int, error) {
function TestConnCopyFromDataWriteAfterErrorAndReturn (line 2762) | func TestConnCopyFromDataWriteAfterErrorAndReturn(t *testing.T) {
function TestConnEscapeString (line 2799) | func TestConnEscapeString(t *testing.T) {
function TestConnCancelRequest (line 2830) | func TestConnCancelRequest(t *testing.T) {
function TestConnContextCanceledCancelsRunningQueryOnServer (line 2870) | func TestConnContextCanceledCancelsRunningQueryOnServer(t *testing.T) {
function testConnContextCanceledCancelsRunningQueryOnServer (line 2891) | func testConnContextCanceledCancelsRunningQueryOnServer(t *testing.T, co...
function TestHijackAndConstruct (line 2949) | func TestHijackAndConstruct(t *testing.T) {
function TestConnCloseWhileCancellableQueryInProgress (line 2984) | func TestConnCloseWhileCancellableQueryInProgress(t *testing.T) {
function TestFatalErrorReceivedAfterCommandComplete (line 3006) | func TestFatalErrorReceivedAfterCommandComplete(t *testing.T) {
function TestConnLargeResponseWhileWritingDoesNotDeadlock (line 3072) | func TestConnLargeResponseWhileWritingDoesNotDeadlock(t *testing.T) {
function TestConnCheckConn (line 3104) | func TestConnCheckConn(t *testing.T) {
function TestConnPing (line 3144) | func TestConnPing(t *testing.T) {
function TestPipelinePrepare (line 3185) | func TestPipelinePrepare(t *testing.T) {
function TestPipelinePrepareError (line 3260) | func TestPipelinePrepareError(t *testing.T) {
function TestPipelinePrepareAndDeallocate (line 3305) | func TestPipelinePrepareAndDeallocate(t *testing.T) {
function TestPipelineQuery (line 3349) | func TestPipelineQuery(t *testing.T) {
function TestPipelinePrepareQuery (line 3441) | func TestPipelinePrepareQuery(t *testing.T) {
function TestPipelineQueryErrorBetweenSyncs (line 3501) | func TestPipelineQueryErrorBetweenSyncs(t *testing.T) {
function TestPipelineFlushForSingleRequests (line 3608) | func TestPipelineFlushForSingleRequests(t *testing.T) {
function TestPipelineFlushForRequestSeries (line 3707) | func TestPipelineFlushForRequestSeries(t *testing.T) {
function TestPipelineFlushWithError (line 3856) | func TestPipelineFlushWithError(t *testing.T) {
function TestPipelineGetResultsHandlesPartiallyReadResults (line 3946) | func TestPipelineGetResultsHandlesPartiallyReadResults(t *testing.T) {
function TestPipelineCloseReadsUnreadResults (line 3987) | func TestPipelineCloseReadsUnreadResults(t *testing.T) {
function TestPipelineCloseDetectsUnsyncedRequests (line 4033) | func TestPipelineCloseDetectsUnsyncedRequests(t *testing.T) {
function TestConnOnPgError (line 4067) | func TestConnOnPgError(t *testing.T) {
function TestConnCustomData (line 4102) | func TestConnCustomData(t *testing.T) {
function Example (line 4118) | func Example() {
function GetSSLPassword (line 4145) | func GetSSLPassword(ctx context.Context) string {
function testingKey (line 4201) | func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING...
function TestSNISupport (line 4203) | func TestSNISupport(t *testing.T) {
function TestConnectWithDirectSSLNegotiation (line 4324) | func TestConnectWithDirectSSLNegotiation(t *testing.T) {
type prefixConn (line 4474) | type prefixConn struct
method Read (line 4480) | func (c *prefixConn) Read(b []byte) (n int, err error) {
function TestFatalErrorReceivedInPipelineMode (line 4491) | func TestFatalErrorReceivedInPipelineMode(t *testing.T) {
function TestPipelineCloseDoesNotPanicOnMultipleFatalErrors (line 4584) | func TestPipelineCloseDoesNotPanicOnMultipleFatalErrors(t *testing.T) {
function mustEncode (line 4679) | func mustEncode(buf []byte, err error) []byte {
function TestDeadlineContextWatcherHandler (line 4686) | func TestDeadlineContextWatcherHandler(t *testing.T) {
function TestCancelRequestContextWatcherHandler (line 4732) | func TestCancelRequestContextWatcherHandler(t *testing.T) {
function TestConnectProtocolVersion32 (line 4844) | func TestConnectProtocolVersion32(t *testing.T) {
FILE: pgproto3/authentication_cleartext_password.go
type AuthenticationCleartextPassword (line 12) | type AuthenticationCleartextPassword struct
method Backend (line 15) | func (*AuthenticationCleartextPassword) Backend() {}
method AuthenticationResponse (line 18) | func (*AuthenticationCleartextPassword) AuthenticationResponse() {}
method Decode (line 22) | func (dst *AuthenticationCleartextPassword) Decode(src []byte) error {
method Encode (line 37) | func (src *AuthenticationCleartextPassword) Encode(dst []byte) ([]byte...
method MarshalJSON (line 44) | func (src AuthenticationCleartextPassword) MarshalJSON() ([]byte, erro...
FILE: pgproto3/authentication_gss.go
type AuthenticationGSS (line 11) | type AuthenticationGSS struct
method Backend (line 13) | func (a *AuthenticationGSS) Backend() {}
method AuthenticationResponse (line 15) | func (a *AuthenticationGSS) AuthenticationResponse() {}
method Decode (line 17) | func (a *AuthenticationGSS) Decode(src []byte) error {
method Encode (line 30) | func (a *AuthenticationGSS) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 36) | func (a *AuthenticationGSS) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 45) | func (a *AuthenticationGSS) UnmarshalJSON(data []byte) error {
FILE: pgproto3/authentication_gss_continue.go
type AuthenticationGSSContinue (line 11) | type AuthenticationGSSContinue struct
method Backend (line 15) | func (a *AuthenticationGSSContinue) Backend() {}
method AuthenticationResponse (line 17) | func (a *AuthenticationGSSContinue) AuthenticationResponse() {}
method Decode (line 19) | func (a *AuthenticationGSSContinue) Decode(src []byte) error {
method Encode (line 34) | func (a *AuthenticationGSSContinue) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 41) | func (a *AuthenticationGSSContinue) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 51) | func (a *AuthenticationGSSContinue) UnmarshalJSON(data []byte) error {
FILE: pgproto3/authentication_md5_password.go
type AuthenticationMD5Password (line 12) | type AuthenticationMD5Password struct
method Backend (line 17) | func (*AuthenticationMD5Password) Backend() {}
method AuthenticationResponse (line 20) | func (*AuthenticationMD5Password) AuthenticationResponse() {}
method Decode (line 24) | func (dst *AuthenticationMD5Password) Decode(src []byte) error {
method Encode (line 41) | func (src *AuthenticationMD5Password) Encode(dst []byte) ([]byte, erro...
method MarshalJSON (line 49) | func (src AuthenticationMD5Password) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 60) | func (dst *AuthenticationMD5Password) UnmarshalJSON(data []byte) error {
FILE: pgproto3/authentication_ok.go
type AuthenticationOk (line 12) | type AuthenticationOk struct
method Backend (line 15) | func (*AuthenticationOk) Backend() {}
method AuthenticationResponse (line 18) | func (*AuthenticationOk) AuthenticationResponse() {}
method Decode (line 22) | func (dst *AuthenticationOk) Decode(src []byte) error {
method Encode (line 37) | func (src *AuthenticationOk) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 44) | func (src AuthenticationOk) MarshalJSON() ([]byte, error) {
FILE: pgproto3/authentication_sasl.go
type AuthenticationSASL (line 13) | type AuthenticationSASL struct
method Backend (line 18) | func (*AuthenticationSASL) Backend() {}
method AuthenticationResponse (line 21) | func (*AuthenticationSASL) AuthenticationResponse() {}
method Decode (line 25) | func (dst *AuthenticationSASL) Decode(src []byte) error {
method Encode (line 50) | func (src *AuthenticationSASL) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 64) | func (src AuthenticationSASL) MarshalJSON() ([]byte, error) {
FILE: pgproto3/authentication_sasl_continue.go
type AuthenticationSASLContinue (line 12) | type AuthenticationSASLContinue struct
method Backend (line 17) | func (*AuthenticationSASLContinue) Backend() {}
method AuthenticationResponse (line 20) | func (*AuthenticationSASLContinue) AuthenticationResponse() {}
method Decode (line 24) | func (dst *AuthenticationSASLContinue) Decode(src []byte) error {
method Encode (line 41) | func (src *AuthenticationSASLContinue) Encode(dst []byte) ([]byte, err...
method MarshalJSON (line 49) | func (src AuthenticationSASLContinue) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 60) | func (dst *AuthenticationSASLContinue) UnmarshalJSON(data []byte) error {
FILE: pgproto3/authentication_sasl_final.go
type AuthenticationSASLFinal (line 12) | type AuthenticationSASLFinal struct
method Backend (line 17) | func (*AuthenticationSASLFinal) Backend() {}
method AuthenticationResponse (line 20) | func (*AuthenticationSASLFinal) AuthenticationResponse() {}
method Decode (line 24) | func (dst *AuthenticationSASLFinal) Decode(src []byte) error {
method Encode (line 41) | func (src *AuthenticationSASLFinal) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 49) | func (src AuthenticationSASLFinal) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 60) | func (dst *AuthenticationSASLFinal) UnmarshalJSON(data []byte) error {
FILE: pgproto3/backend.go
type Backend (line 11) | type Backend struct
method Send (line 61) | func (b *Backend) Send(msg BackendMessage) {
method Flush (line 80) | func (b *Backend) Flush() error {
method Trace (line 105) | func (b *Backend) Trace(w io.Writer, options TracerOptions) {
method Untrace (line 114) | func (b *Backend) Untrace() {
method ReceiveStartupMessage (line 121) | func (b *Backend) ReceiveStartupMessage() (FrontendMessage, error) {
method Receive (line 170) | func (b *Backend) Receive() (FrontendMessage, error) {
method SetAuthType (line 271) | func (b *Backend) SetAuthType(authType uint32) error {
method SetMaxBodyLen (line 297) | func (b *Backend) SetMaxBodyLen(maxBodyLen int) {
constant minStartupPacketLen (line 49) | minStartupPacketLen = 4
constant maxStartupPacketLen (line 50) | maxStartupPacketLen = 10_000
function NewBackend (line 54) | func NewBackend(r io.Reader, w io.Writer) *Backend {
FILE: pgproto3/backend_key_data.go
type BackendKeyData (line 11) | type BackendKeyData struct
method Backend (line 17) | func (*BackendKeyData) Backend() {}
method Decode (line 21) | func (dst *BackendKeyData) Decode(src []byte) error {
method Encode (line 34) | func (src *BackendKeyData) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 42) | func (src BackendKeyData) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 55) | func (dst *BackendKeyData) UnmarshalJSON(data []byte) error {
FILE: pgproto3/backend_key_data_test.go
function TestBackendKeyDataDecodeProtocol30 (line 10) | func TestBackendKeyDataDecodeProtocol30(t *testing.T) {
function TestBackendKeyDataDecodeProtocol32 (line 25) | func TestBackendKeyDataDecodeProtocol32(t *testing.T) {
function TestBackendKeyDataEncodeProtocol30 (line 44) | func TestBackendKeyDataEncodeProtocol30(t *testing.T) {
function TestBackendKeyDataEncodeProtocol32 (line 63) | func TestBackendKeyDataEncodeProtocol32(t *testing.T) {
FILE: pgproto3/backend_test.go
function TestBackendReceiveInterrupted (line 13) | func TestBackendReceiveInterrupted(t *testing.T) {
function TestBackendReceiveUnexpectedEOF (line 40) | func TestBackendReceiveUnexpectedEOF(t *testing.T) {
function TestStartupMessage (line 64) | func TestStartupMessage(t *testing.T) {
function TestBackendReceiveExceededMaxBodyLen (line 140) | func TestBackendReceiveExceededMaxBodyLen(t *testing.T) {
FILE: pgproto3/big_endian.go
type BigEndianBuf (line 7) | type BigEndianBuf
method Int16 (line 9) | func (b BigEndianBuf) Int16(n int16) []byte {
method Uint16 (line 15) | func (b BigEndianBuf) Uint16(n uint16) []byte {
method Int32 (line 21) | func (b BigEndianBuf) Int32(n int32) []byte {
method Uint32 (line 27) | func (b BigEndianBuf) Uint32(n uint32) []byte {
method Int64 (line 33) | func (b BigEndianBuf) Int64(n int64) []byte {
FILE: pgproto3/bind.go
type Bind (line 15) | type Bind struct
method Frontend (line 24) | func (*Bind) Frontend() {}
method Decode (line 28) | func (dst *Bind) Decode(src []byte) error {
method Encode (line 113) | func (src *Bind) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 155) | func (src Bind) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 194) | func (dst *Bind) UnmarshalJSON(data []byte) error {
FILE: pgproto3/bind_complete.go
type BindComplete (line 7) | type BindComplete struct
method Backend (line 10) | func (*BindComplete) Backend() {}
method Decode (line 14) | func (dst *BindComplete) Decode(src []byte) error {
method Encode (line 23) | func (src *BindComplete) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src BindComplete) MarshalJSON() ([]byte, error) {
FILE: pgproto3/bind_test.go
function TestBindDecodeNegativeParameterLength (line 11) | func TestBindDecodeNegativeParameterLength(t *testing.T) {
function TestBindBiggerThanMaxMessageBodyLen (line 36) | func TestBindBiggerThanMaxMessageBodyLen(t *testing.T) {
FILE: pgproto3/cancel_request.go
constant cancelRequestCode (line 12) | cancelRequestCode = 80877102
type CancelRequest (line 14) | type CancelRequest struct
method Frontend (line 20) | func (*CancelRequest) Frontend() {}
method Decode (line 22) | func (dst *CancelRequest) Decode(src []byte) error {
method Encode (line 43) | func (src *CancelRequest) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 56) | func (src CancelRequest) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 69) | func (dst *CancelRequest) UnmarshalJSON(data []byte) error {
FILE: pgproto3/cancel_request_test.go
function TestCancelRequestDecode (line 10) | func TestCancelRequestDecode(t *testing.T) {
function TestCancelRequestEncode (line 81) | func TestCancelRequestEncode(t *testing.T) {
FILE: pgproto3/chunkreader.go
type chunkReader (line 14) | type chunkReader struct
method Next (line 45) | func (r *chunkReader) Next(n int) (buf []byte, err error) {
function newChunkReader (line 25) | func newChunkReader(r io.Reader, minBufSize int) *chunkReader {
FILE: pgproto3/chunkreader_test.go
function TestChunkReaderNextDoesNotReadIfAlreadyBuffered (line 9) | func TestChunkReaderNextDoesNotReadIfAlreadyBuffered(t *testing.T) {
type randomReader (line 49) | type randomReader struct
method Read (line 54) | func (r *randomReader) Read(p []byte) (n int, err error) {
function TestChunkReaderNextFuzz (line 62) | func TestChunkReaderNextFuzz(t *testing.T) {
FILE: pgproto3/close.go
type Close (line 9) | type Close struct
method Frontend (line 15) | func (*Close) Frontend() {}
method Decode (line 19) | func (dst *Close) Decode(src []byte) error {
method Encode (line 38) | func (src *Close) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 47) | func (src Close) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 60) | func (dst *Close) UnmarshalJSON(data []byte) error {
FILE: pgproto3/close_complete.go
type CloseComplete (line 7) | type CloseComplete struct
method Backend (line 10) | func (*CloseComplete) Backend() {}
method Decode (line 14) | func (dst *CloseComplete) Decode(src []byte) error {
method Encode (line 23) | func (src *CloseComplete) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src CloseComplete) MarshalJSON() ([]byte, error) {
FILE: pgproto3/command_complete.go
type CommandComplete (line 8) | type CommandComplete struct
method Backend (line 13) | func (*CommandComplete) Backend() {}
method Decode (line 17) | func (dst *CommandComplete) Decode(src []byte) error {
method Encode (line 32) | func (src *CommandComplete) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 40) | func (src CommandComplete) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 51) | func (dst *CommandComplete) UnmarshalJSON(data []byte) error {
FILE: pgproto3/copy_both_response.go
type CopyBothResponse (line 13) | type CopyBothResponse struct
method Backend (line 19) | func (*CopyBothResponse) Backend() {}
method Decode (line 23) | func (dst *CopyBothResponse) Decode(src []byte) error {
method Encode (line 48) | func (src *CopyBothResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 63) | func (src CopyBothResponse) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 74) | func (dst *CopyBothResponse) UnmarshalJSON(data []byte) error {
FILE: pgproto3/copy_both_response_test.go
function TestEncodeDecode (line 11) | func TestEncodeDecode(t *testing.T) {
FILE: pgproto3/copy_data.go
type CopyData (line 8) | type CopyData struct
method Backend (line 13) | func (*CopyData) Backend() {}
method Frontend (line 16) | func (*CopyData) Frontend() {}
method Decode (line 20) | func (dst *CopyData) Decode(src []byte) error {
method Encode (line 26) | func (src *CopyData) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 33) | func (src CopyData) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 44) | func (dst *CopyData) UnmarshalJSON(data []byte) error {
FILE: pgproto3/copy_done.go
type CopyDone (line 7) | type CopyDone struct
method Backend (line 10) | func (*CopyDone) Backend() {}
method Frontend (line 13) | func (*CopyDone) Frontend() {}
method Decode (line 17) | func (dst *CopyDone) Decode(src []byte) error {
method Encode (line 26) | func (src *CopyDone) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 31) | func (src CopyDone) MarshalJSON() ([]byte, error) {
FILE: pgproto3/copy_fail.go
type CopyFail (line 8) | type CopyFail struct
method Frontend (line 13) | func (*CopyFail) Frontend() {}
method Decode (line 17) | func (dst *CopyFail) Decode(src []byte) error {
method Encode (line 33) | func (src *CopyFail) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 41) | func (src CopyFail) MarshalJSON() ([]byte, error) {
FILE: pgproto3/copy_in_response.go
type CopyInResponse (line 13) | type CopyInResponse struct
method Backend (line 19) | func (*CopyInResponse) Backend() {}
method Decode (line 23) | func (dst *CopyInResponse) Decode(src []byte) error {
method Encode (line 48) | func (src *CopyInResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 64) | func (src CopyInResponse) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 75) | func (dst *CopyInResponse) UnmarshalJSON(data []byte) error {
FILE: pgproto3/copy_out_response.go
type CopyOutResponse (line 13) | type CopyOutResponse struct
method Backend (line 18) | func (*CopyOutResponse) Backend() {}
method Decode (line 22) | func (dst *CopyOutResponse) Decode(src []byte) error {
method Encode (line 47) | func (src *CopyOutResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 64) | func (src CopyOutResponse) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 75) | func (dst *CopyOutResponse) UnmarshalJSON(data []byte) error {
FILE: pgproto3/data_row.go
type DataRow (line 13) | type DataRow struct
method Backend (line 18) | func (*DataRow) Backend() {}
method Decode (line 22) | func (dst *DataRow) Decode(src []byte) error {
method Encode (line 65) | func (src *DataRow) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 86) | func (src DataRow) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 118) | func (dst *DataRow) UnmarshalJSON(data []byte) error {
FILE: pgproto3/describe.go
type Describe (line 9) | type Describe struct
method Frontend (line 15) | func (*Describe) Frontend() {}
method Decode (line 19) | func (dst *Describe) Decode(src []byte) error {
method Encode (line 38) | func (src *Describe) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 47) | func (src Describe) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 60) | func (dst *Describe) UnmarshalJSON(data []byte) error {
FILE: pgproto3/empty_query_response.go
type EmptyQueryResponse (line 7) | type EmptyQueryResponse struct
method Backend (line 10) | func (*EmptyQueryResponse) Backend() {}
method Decode (line 14) | func (dst *EmptyQueryResponse) Decode(src []byte) error {
method Encode (line 23) | func (src *EmptyQueryResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src EmptyQueryResponse) MarshalJSON() ([]byte, error) {
FILE: pgproto3/error_response.go
type ErrorResponse (line 9) | type ErrorResponse struct
method Backend (line 33) | func (*ErrorResponse) Backend() {}
method Decode (line 37) | func (dst *ErrorResponse) Decode(src []byte) error {
method Encode (line 113) | func (src *ErrorResponse) Encode(dst []byte) ([]byte, error) {
method appendFields (line 119) | func (src *ErrorResponse) appendFields(dst []byte) []byte {
method MarshalJSON (line 223) | func (src ErrorResponse) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 271) | func (dst *ErrorResponse) UnmarshalJSON(data []byte) error {
FILE: pgproto3/example/pgfortune/main.go
function main (line 17) | func main() {
FILE: pgproto3/example/pgfortune/server.go
type PgFortuneBackend (line 10) | type PgFortuneBackend struct
method Run (line 28) | func (p *PgFortuneBackend) Run() error {
method handleStartup (line 75) | func (p *PgFortuneBackend) handleStartup() error {
method Close (line 102) | func (p *PgFortuneBackend) Close() error {
function NewPgFortuneBackend (line 16) | func NewPgFortuneBackend(conn net.Conn, responder func() ([]byte, error)...
function mustEncode (line 106) | func mustEncode(buf []byte, err error) []byte {
FILE: pgproto3/execute.go
type Execute (line 11) | type Execute struct
method Frontend (line 17) | func (*Execute) Frontend() {}
method Decode (line 21) | func (dst *Execute) Decode(src []byte) error {
method Encode (line 39) | func (src *Execute) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 48) | func (src Execute) MarshalJSON() ([]byte, error) {
FILE: pgproto3/flush.go
type Flush (line 7) | type Flush struct
method Frontend (line 10) | func (*Flush) Frontend() {}
method Decode (line 14) | func (dst *Flush) Decode(src []byte) error {
method Encode (line 23) | func (src *Flush) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src Flush) MarshalJSON() ([]byte, error) {
FILE: pgproto3/frontend.go
type Frontend (line 12) | type Frontend struct
method Send (line 77) | func (f *Frontend) Send(msg FrontendMessage) {
method Flush (line 96) | func (f *Frontend) Flush() error {
method Trace (line 125) | func (f *Frontend) Trace(w io.Writer, options TracerOptions) {
method Untrace (line 134) | func (f *Frontend) Untrace() {
method SendBind (line 140) | func (f *Frontend) SendBind(msg *Bind) {
method SendParse (line 160) | func (f *Frontend) SendParse(msg *Parse) {
method SendClose (line 180) | func (f *Frontend) SendClose(msg *Close) {
method SendDescribe (line 200) | func (f *Frontend) SendDescribe(msg *Describe) {
method SendExecute (line 220) | func (f *Frontend) SendExecute(msg *Execute) {
method SendSync (line 240) | func (f *Frontend) SendSync(msg *Sync) {
method SendQuery (line 260) | func (f *Frontend) SendQuery(msg *Query) {
method SendUnbufferedEncodedCopyData (line 281) | func (f *Frontend) SendUnbufferedEncodedCopyData(msg []byte) error {
method Receive (line 307) | func (f *Frontend) Receive() (BackendMessage, error) {
method findAuthenticationMessageType (line 421) | func (f *Frontend) findAuthenticationMessageType(src []byte) (BackendM...
method GetAuthType (line 455) | func (f *Frontend) GetAuthType() uint32 {
method ReadBufferLen (line 459) | func (f *Frontend) ReadBufferLen() int {
method SetMaxBodyLen (line 469) | func (f *Frontend) SetMaxBodyLen(maxBodyLen int) {
function NewFrontend (line 65) | func NewFrontend(r io.Reader, w io.Writer) *Frontend {
function translateEOFtoErrUnexpectedEOF (line 299) | func translateEOFtoErrUnexpectedEOF(err error) error {
constant AuthTypeOk (line 409) | AuthTypeOk = 0
constant AuthTypeCleartextPassword (line 410) | AuthTypeCleartextPassword = 3
constant AuthTypeMD5Password (line 411) | AuthTypeMD5Password = 5
constant AuthTypeSCMCreds (line 412) | AuthTypeSCMCreds = 6
constant AuthTypeGSS (line 413) | AuthTypeGSS = 7
constant AuthTypeGSSCont (line 414) | AuthTypeGSSCont = 8
constant AuthTypeSSPI (line 415) | AuthTypeSSPI = 9
constant AuthTypeSASL (line 416) | AuthTypeSASL = 10
constant AuthTypeSASLContinue (line 417) | AuthTypeSASLContinue = 11
constant AuthTypeSASLFinal (line 418) | AuthTypeSASLFinal = 12
FILE: pgproto3/frontend_test.go
type interruptReader (line 12) | type interruptReader struct
method Read (line 16) | func (ir *interruptReader) Read(p []byte) (n int, err error) {
method push (line 31) | func (ir *interruptReader) push(p []byte) {
function TestFrontendReceiveInterrupted (line 35) | func TestFrontendReceiveInterrupted(t *testing.T) {
function TestFrontendReceiveUnexpectedEOF (line 62) | func TestFrontendReceiveUnexpectedEOF(t *testing.T) {
function TestErrorResponse (line 83) | func TestErrorResponse(t *testing.T) {
function TestFrontendReceiveExceededMaxBodyLen (line 119) | func TestFrontendReceiveExceededMaxBodyLen(t *testing.T) {
FILE: pgproto3/function_call.go
type FunctionCall (line 11) | type FunctionCall struct
method Frontend (line 19) | func (*FunctionCall) Frontend() {}
method Decode (line 23) | func (dst *FunctionCall) Decode(src []byte) error {
method Encode (line 97) | func (src *FunctionCall) Encode(dst []byte) ([]byte, error) {
FILE: pgproto3/function_call_decode_test.go
function TestFunctionCallDecodeNegativeArgumentLength (line 11) | func TestFunctionCallDecodeNegativeArgumentLength(t *testing.T) {
FILE: pgproto3/function_call_response.go
type FunctionCallResponse (line 11) | type FunctionCallResponse struct
method Backend (line 16) | func (*FunctionCallResponse) Backend() {}
method Decode (line 20) | func (dst *FunctionCallResponse) Decode(src []byte) error {
method Encode (line 42) | func (src *FunctionCallResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 56) | func (src FunctionCallResponse) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 82) | func (dst *FunctionCallResponse) UnmarshalJSON(data []byte) error {
FILE: pgproto3/function_call_response_test.go
function TestFunctionCallResponseDecodeNullResult (line 10) | func TestFunctionCallResponseDecodeNullResult(t *testing.T) {
function TestFunctionCallResponseDecodeNegativeResultSize (line 26) | func TestFunctionCallResponseDecodeNegativeResultSize(t *testing.T) {
FILE: pgproto3/function_call_test.go
function TestFunctionCall_EncodeDecode (line 11) | func TestFunctionCall_EncodeDecode(t *testing.T) {
FILE: pgproto3/fuzz_test.go
function FuzzFrontend (line 12) | func FuzzFrontend(f *testing.F) {
function FuzzBackend (line 59) | func FuzzBackend(f *testing.F) {
function FuzzBind (line 104) | func FuzzBind(f *testing.F) {
function FuzzDataRow (line 115) | func FuzzDataRow(f *testing.F) {
function FuzzRowDescription (line 126) | func FuzzRowDescription(f *testing.F) {
function FuzzFunctionCall (line 136) | func FuzzFunctionCall(f *testing.F) {
function FuzzFunctionCallResponse (line 147) | func FuzzFunctionCallResponse(f *testing.F) {
function FuzzParse (line 158) | func FuzzParse(f *testing.F) {
function FuzzQuery (line 167) | func FuzzQuery(f *testing.F) {
function FuzzClose (line 176) | func FuzzClose(f *testing.F) {
function FuzzDescribe (line 185) | func FuzzDescribe(f *testing.F) {
function FuzzExecute (line 194) | func FuzzExecute(f *testing.F) {
function FuzzCopyInResponse (line 203) | func FuzzCopyInResponse(f *testing.F) {
function FuzzCopyOutResponse (line 212) | func FuzzCopyOutResponse(f *testing.F) {
function FuzzCopyBothResponse (line 221) | func FuzzCopyBothResponse(f *testing.F) {
function FuzzErrorResponse (line 230) | func FuzzErrorResponse(f *testing.F) {
function FuzzNotificationResponse (line 240) | func FuzzNotificationResponse(f *testing.F) {
function FuzzParameterDescription (line 249) | func FuzzParameterDescription(f *testing.F) {
function FuzzParameterStatus (line 258) | func FuzzParameterStatus(f *testing.F) {
function FuzzReadyForQuery (line 267) | func FuzzReadyForQuery(f *testing.F) {
function FuzzSASLInitialResponse (line 276) | func FuzzSASLInitialResponse(f *testing.F) {
function FuzzStartupMessage (line 285) | func FuzzStartupMessage(f *testing.F) {
function FuzzNegotiateProtocolVersion (line 294) | func FuzzNegotiateProtocolVersion(f *testing.F) {
FILE: pgproto3/gss_enc_request.go
constant gssEncReqNumber (line 11) | gssEncReqNumber = 80877104
type GSSEncRequest (line 13) | type GSSEncRequest struct
method Frontend (line 16) | func (*GSSEncRequest) Frontend() {}
method Decode (line 18) | func (dst *GSSEncRequest) Decode(src []byte) error {
method Encode (line 33) | func (src *GSSEncRequest) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 40) | func (src GSSEncRequest) MarshalJSON() ([]byte, error) {
FILE: pgproto3/gss_response.go
type GSSResponse (line 7) | type GSSResponse struct
method Frontend (line 12) | func (g *GSSResponse) Frontend() {}
method Decode (line 14) | func (g *GSSResponse) Decode(data []byte) error {
method Encode (line 19) | func (g *GSSResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 26) | func (g *GSSResponse) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 37) | func (g *GSSResponse) UnmarshalJSON(data []byte) error {
FILE: pgproto3/json_test.go
function TestJSONUnmarshalAuthenticationMD5Password (line 10) | func TestJSONUnmarshalAuthenticationMD5Password(t *testing.T) {
function TestJSONUnmarshalAuthenticationSASL (line 25) | func TestJSONUnmarshalAuthenticationSASL(t *testing.T) {
function TestJSONUnmarshalAuthenticationGSS (line 40) | func TestJSONUnmarshalAuthenticationGSS(t *testing.T) {
function TestJSONUnmarshalAuthenticationGSSContinue (line 53) | func TestJSONUnmarshalAuthenticationGSSContinue(t *testing.T) {
function TestJSONUnmarshalAuthenticationSASLContinue (line 66) | func TestJSONUnmarshalAuthenticationSASLContinue(t *testing.T) {
function TestJSONUnmarshalAuthenticationSASLFinal (line 81) | func TestJSONUnmarshalAuthenticationSASLFinal(t *testing.T) {
function TestJSONUnmarshalBackendKeyData30 (line 96) | func TestJSONUnmarshalBackendKeyData30(t *testing.T) {
function TestJSONUnmarshalBackendKeyData32 (line 113) | func TestJSONUnmarshalBackendKeyData32(t *testing.T) {
function TestJSONUnmarshalCommandComplete (line 130) | func TestJSONUnmarshalCommandComplete(t *testing.T) {
function TestJSONUnmarshalCopyBothResponse (line 145) | func TestJSONUnmarshalCopyBothResponse(t *testing.T) {
function TestJSONUnmarshalCopyData (line 160) | func TestJSONUnmarshalCopyData(t *testing.T) {
function TestJSONUnmarshalCopyInResponse (line 175) | func TestJSONUnmarshalCopyInResponse(t *testing.T) {
function TestJSONUnmarshalCopyOutResponse (line 190) | func TestJSONUnmarshalCopyOutResponse(t *testing.T) {
function TestJSONUnmarshalDataRow (line 205) | func TestJSONUnmarshalDataRow(t *testing.T) {
function TestJSONUnmarshalErrorResponse (line 224) | func TestJSONUnmarshalErrorResponse(t *testing.T) {
function TestJSONUnmarshalFunctionCallResponse (line 241) | func TestJSONUnmarshalFunctionCallResponse(t *testing.T) {
function TestJSONUnmarshalNoticeResponse (line 254) | func TestJSONUnmarshalNoticeResponse(t *testing.T) {
function TestJSONUnmarshalNotificationResponse (line 271) | func TestJSONUnmarshalNotificationResponse(t *testing.T) {
function TestJSONUnmarshalParameterDescription (line 284) | func TestJSONUnmarshalParameterDescription(t *testing.T) {
function TestJSONUnmarshalParameterStatus (line 299) | func TestJSONUnmarshalParameterStatus(t *testing.T) {
function TestJSONUnmarshalReadyForQuery (line 315) | func TestJSONUnmarshalReadyForQuery(t *testing.T) {
function TestJSONUnmarshalRowDescription (line 330) | func TestJSONUnmarshalRowDescription(t *testing.T) {
function TestJSONUnmarshalBind (line 352) | func TestJSONUnmarshalBind(t *testing.T) {
function TestJSONUnmarshalCancelRequest (line 387) | func TestJSONUnmarshalCancelRequest(t *testing.T) {
function TestJSONUnmarshalCancelRequestLongKey (line 404) | func TestJSONUnmarshalCancelRequestLongKey(t *testing.T) {
function TestJSONUnmarshalClose (line 421) | func TestJSONUnmarshalClose(t *testing.T) {
function TestJSONUnmarshalCopyFail (line 437) | func TestJSONUnmarshalCopyFail(t *testing.T) {
function TestJSONUnmarshalDescribe (line 452) | func TestJSONUnmarshalDescribe(t *testing.T) {
function TestJSONUnmarshalExecute (line 468) | func TestJSONUnmarshalExecute(t *testing.T) {
function TestJSONUnmarshalParse (line 481) | func TestJSONUnmarshalParse(t *testing.T) {
function TestJSONUnmarshalPasswordMessage (line 497) | func TestJSONUnmarshalPasswordMessage(t *testing.T) {
function TestJSONUnmarshalQuery (line 512) | func TestJSONUnmarshalQuery(t *testing.T) {
function TestJSONUnmarshalSASLInitialResponse (line 527) | func TestJSONUnmarshalSASLInitialResponse(t *testing.T) {
function TestJSONUnmarshalSASLResponse (line 543) | func TestJSONUnmarshalSASLResponse(t *testing.T) {
function TestJSONUnmarshalStartupMessage (line 556) | func TestJSONUnmarshalStartupMessage(t *testing.T) {
function TestAuthenticationOK (line 575) | func TestAuthenticationOK(t *testing.T) {
function TestAuthenticationCleartextPassword (line 588) | func TestAuthenticationCleartextPassword(t *testing.T) {
function TestAuthenticationMD5Password (line 601) | func TestAuthenticationMD5Password(t *testing.T) {
function TestJSONUnmarshalGSSResponse (line 616) | func TestJSONUnmarshalGSSResponse(t *testing.T) {
function TestErrorResponse (line 629) | func TestErrorResponse(t *testing.T) {
FILE: pgproto3/negotiate_protocol_version.go
type NegotiateProtocolVersion (line 10) | type NegotiateProtocolVersion struct
method Backend (line 16) | func (*NegotiateProtocolVersion) Backend() {}
method Decode (line 20) | func (dst *NegotiateProtocolVersion) Decode(src []byte) error {
method Encode (line 56) | func (src *NegotiateProtocolVersion) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 68) | func (src NegotiateProtocolVersion) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 81) | func (dst *NegotiateProtocolVersion) UnmarshalJSON(data []byte) error {
FILE: pgproto3/negotiate_protocol_version_test.go
function TestNegotiateProtocolVersionDecode (line 11) | func TestNegotiateProtocolVersionDecode(t *testing.T) {
function TestNegotiateProtocolVersionDecodeNoOptions (line 27) | func TestNegotiateProtocolVersionDecodeNoOptions(t *testing.T) {
function TestNegotiateProtocolVersionEncode (line 41) | func TestNegotiateProtocolVersionEncode(t *testing.T) {
function TestNegotiateProtocolVersionJSON (line 62) | func TestNegotiateProtocolVersionJSON(t *testing.T) {
function TestJSONUnmarshalNegotiateProtocolVersion (line 78) | func TestJSONUnmarshalNegotiateProtocolVersion(t *testing.T) {
FILE: pgproto3/no_data.go
type NoData (line 7) | type NoData struct
method Backend (line 10) | func (*NoData) Backend() {}
method Decode (line 14) | func (dst *NoData) Decode(src []byte) error {
method Encode (line 23) | func (src *NoData) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src NoData) MarshalJSON() ([]byte, error) {
FILE: pgproto3/notice_response.go
type NoticeResponse (line 3) | type NoticeResponse
method Backend (line 6) | func (*NoticeResponse) Backend() {}
method Decode (line 10) | func (dst *NoticeResponse) Decode(src []byte) error {
method Encode (line 15) | func (src *NoticeResponse) Encode(dst []byte) ([]byte, error) {
FILE: pgproto3/notification_response.go
type NotificationResponse (line 11) | type NotificationResponse struct
method Backend (line 18) | func (*NotificationResponse) Backend() {}
method Decode (line 22) | func (dst *NotificationResponse) Decode(src []byte) error {
method Encode (line 48) | func (src *NotificationResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 59) | func (src NotificationResponse) MarshalJSON() ([]byte, error) {
FILE: pgproto3/parameter_description.go
type ParameterDescription (line 13) | type ParameterDescription struct
method Backend (line 18) | func (*ParameterDescription) Backend() {}
method Decode (line 22) | func (dst *ParameterDescription) Decode(src []byte) error {
method Encode (line 44) | func (src *ParameterDescription) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 59) | func (src ParameterDescription) MarshalJSON() ([]byte, error) {
FILE: pgproto3/parameter_status.go
type ParameterStatus (line 8) | type ParameterStatus struct
method Backend (line 14) | func (*ParameterStatus) Backend() {}
method Decode (line 18) | func (dst *ParameterStatus) Decode(src []byte) error {
method Encode (line 38) | func (src *ParameterStatus) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 48) | func (ps ParameterStatus) MarshalJSON() ([]byte, error) {
FILE: pgproto3/parse.go
type Parse (line 13) | type Parse struct
method Frontend (line 20) | func (*Parse) Frontend() {}
method Decode (line 24) | func (dst *Parse) Decode(src []byte) error {
method Encode (line 57) | func (src *Parse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 77) | func (src Parse) MarshalJSON() ([]byte, error) {
FILE: pgproto3/parse_complete.go
type ParseComplete (line 7) | type ParseComplete struct
method Backend (line 10) | func (*ParseComplete) Backend() {}
method Decode (line 14) | func (dst *ParseComplete) Decode(src []byte) error {
method Encode (line 23) | func (src *ParseComplete) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src ParseComplete) MarshalJSON() ([]byte, error) {
FILE: pgproto3/password_message.go
type PasswordMessage (line 8) | type PasswordMessage struct
method Frontend (line 13) | func (*PasswordMessage) Frontend() {}
method InitialResponse (line 16) | func (*PasswordMessage) InitialResponse() {}
method Decode (line 20) | func (dst *PasswordMessage) Decode(src []byte) error {
method Encode (line 33) | func (src *PasswordMessage) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 41) | func (src PasswordMessage) MarshalJSON() ([]byte, error) {
FILE: pgproto3/pgproto3.go
constant maxMessageBodyLen (line 13) | maxMessageBodyLen = (0x3fffffff - 1)
type Message (line 17) | type Message interface
type FrontendMessage (line 27) | type FrontendMessage interface
type BackendMessage (line 33) | type BackendMessage interface
type AuthenticationResponseMessage (line 38) | type AuthenticationResponseMessage interface
type invalidMessageLenErr (line 43) | type invalidMessageLenErr struct
method Error (line 49) | func (e *invalidMessageLenErr) Error() string {
type invalidMessageFormatErr (line 53) | type invalidMessageFormatErr struct
method Error (line 58) | func (e *invalidMessageFormatErr) Error() string {
type writeError (line 62) | type writeError struct
method Error (line 67) | func (e *writeError) Error() string {
method SafeToRetry (line 71) | func (e *writeError) SafeToRetry() bool {
method Unwrap (line 75) | func (e *writeError) Unwrap() error {
type ExceededMaxBodyLenErr (line 79) | type ExceededMaxBodyLenErr struct
method Error (line 84) | func (e *ExceededMaxBodyLenErr) Error() string {
function getValueFromJSON (line 89) | func getValueFromJSON(v map[string]string) ([]byte, error) {
function beginMessage (line 104) | func beginMessage(dst []byte, t byte) ([]byte, int) {
function finishMessage (line 113) | func finishMessage(dst []byte, sp int) ([]byte, error) {
FILE: pgproto3/pgproto3_private_test.go
constant MaxMessageBodyLen (line 3) | MaxMessageBodyLen = maxMessageBodyLen
FILE: pgproto3/portal_suspended.go
type PortalSuspended (line 7) | type PortalSuspended struct
method Backend (line 10) | func (*PortalSuspended) Backend() {}
method Decode (line 14) | func (dst *PortalSuspended) Decode(src []byte) error {
method Encode (line 23) | func (src *PortalSuspended) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src PortalSuspended) MarshalJSON() ([]byte, error) {
FILE: pgproto3/query.go
type Query (line 8) | type Query struct
method Frontend (line 13) | func (*Query) Frontend() {}
method Decode (line 17) | func (dst *Query) Decode(src []byte) error {
method Encode (line 33) | func (src *Query) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 41) | func (src Query) MarshalJSON() ([]byte, error) {
FILE: pgproto3/query_test.go
function TestQueryBiggerThanMaxMessageBodyLen (line 10) | func TestQueryBiggerThanMaxMessageBodyLen(t *testing.T) {
FILE: pgproto3/ready_for_query.go
type ReadyForQuery (line 8) | type ReadyForQuery struct
method Backend (line 13) | func (*ReadyForQuery) Backend() {}
method Decode (line 17) | func (dst *ReadyForQuery) Decode(src []byte) error {
method Encode (line 28) | func (src *ReadyForQuery) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 33) | func (src ReadyForQuery) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 44) | func (dst *ReadyForQuery) UnmarshalJSON(data []byte) error {
FILE: pgproto3/row_description.go
constant TextFormat (line 14) | TextFormat = 0
constant BinaryFormat (line 15) | BinaryFormat = 1
type FieldDescription (line 18) | type FieldDescription struct
method MarshalJSON (line 29) | func (fd FieldDescription) MarshalJSON() ([]byte, error) {
type RowDescription (line 49) | type RowDescription struct
method Backend (line 54) | func (*RowDescription) Backend() {}
method Decode (line 58) | func (dst *RowDescription) Decode(src []byte) error {
method Encode (line 103) | func (src *RowDescription) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 126) | func (src RowDescription) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 137) | func (dst *RowDescription) UnmarshalJSON(data []byte) error {
FILE: pgproto3/sasl_initial_response.go
type SASLInitialResponse (line 12) | type SASLInitialResponse struct
method Frontend (line 18) | func (*SASLInitialResponse) Frontend() {}
method Decode (line 22) | func (dst *SASLInitialResponse) Decode(src []byte) error {
method Encode (line 45) | func (src *SASLInitialResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 58) | func (src SASLInitialResponse) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 71) | func (dst *SASLInitialResponse) UnmarshalJSON(data []byte) error {
FILE: pgproto3/sasl_response.go
type SASLResponse (line 8) | type SASLResponse struct
method Frontend (line 13) | func (*SASLResponse) Frontend() {}
method Decode (line 17) | func (dst *SASLResponse) Decode(src []byte) error {
method Encode (line 23) | func (src *SASLResponse) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 30) | func (src SASLResponse) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 41) | func (dst *SASLResponse) UnmarshalJSON(data []byte) error {
FILE: pgproto3/ssl_request.go
constant sslRequestNumber (line 11) | sslRequestNumber = 80877103
type SSLRequest (line 13) | type SSLRequest struct
method Frontend (line 16) | func (*SSLRequest) Frontend() {}
method Decode (line 18) | func (dst *SSLRequest) Decode(src []byte) error {
method Encode (line 33) | func (src *SSLRequest) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 40) | func (src SSLRequest) MarshalJSON() ([]byte, error) {
FILE: pgproto3/startup_message.go
constant ProtocolVersion30 (line 14) | ProtocolVersion30 = 196608
constant ProtocolVersion32 (line 15) | ProtocolVersion32 = 196610
constant ProtocolVersionNumber (line 16) | ProtocolVersionNumber = ProtocolVersion30
type StartupMessage (line 19) | type StartupMessage struct
method Frontend (line 25) | func (*StartupMessage) Frontend() {}
method Decode (line 29) | func (dst *StartupMessage) Decode(src []byte) error {
method Encode (line 71) | func (src *StartupMessage) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 88) | func (src StartupMessage) MarshalJSON() ([]byte, error) {
FILE: pgproto3/sync.go
type Sync (line 7) | type Sync struct
method Frontend (line 10) | func (*Sync) Frontend() {}
method Decode (line 14) | func (dst *Sync) Decode(src []byte) error {
method Encode (line 23) | func (src *Sync) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src Sync) MarshalJSON() ([]byte, error) {
FILE: pgproto3/terminate.go
type Terminate (line 7) | type Terminate struct
method Frontend (line 10) | func (*Terminate) Frontend() {}
method Decode (line 14) | func (dst *Terminate) Decode(src []byte) error {
method Encode (line 23) | func (src *Terminate) Encode(dst []byte) ([]byte, error) {
method MarshalJSON (line 28) | func (src Terminate) MarshalJSON() ([]byte, error) {
FILE: pgproto3/trace.go
type tracer (line 15) | type tracer struct
method traceMessage (line 32) | func (t *tracer) traceMessage(sender byte, encodedLen int32, msg Messa...
method traceAuthenticationCleartextPassword (line 129) | func (t *tracer) traceAuthenticationCleartextPassword(sender byte, enc...
method traceAuthenticationGSS (line 133) | func (t *tracer) traceAuthenticationGSS(sender byte, encodedLen int32,...
method traceAuthenticationGSSContinue (line 137) | func (t *tracer) traceAuthenticationGSSContinue(sender byte, encodedLe...
method traceAuthenticationMD5Password (line 141) | func (t *tracer) traceAuthenticationMD5Password(sender byte, encodedLe...
method traceAuthenticationOk (line 145) | func (t *tracer) traceAuthenticationOk(sender byte, encodedLen int32, ...
method traceAuthenticationSASL (line 149) | func (t *tracer) traceAuthenticationSASL(sender byte, encodedLen int32...
method traceAuthenticationSASLContinue (line 153) | func (t *tracer) traceAuthenticationSASLContinue(sender byte, encodedL...
method traceAuthenticationSASLFinal (line 157) | func (t *tracer) traceAuthenticationSASLFinal(sender byte, encodedLen ...
method traceBackendKeyData (line 161) | func (t *tracer) traceBackendKeyData(sender byte, encodedLen int32, ms...
method traceBind (line 171) | func (t *tracer) traceBind(sender byte, encodedLen int32, msg *Bind) {
method traceBindComplete (line 188) | func (t *tracer) traceBindComplete(sender byte, encodedLen int32, msg ...
method traceCancelRequest (line 192) | func (t *tracer) traceCancelRequest(sender byte, encodedLen int32, msg...
method traceClose (line 196) | func (t *tracer) traceClose(sender byte, encodedLen int32, msg *Close) {
method traceCloseComplete (line 200) | func (t *tracer) traceCloseComplete(sender byte, encodedLen int32, msg...
method traceCommandComplete (line 204) | func (t *tracer) traceCommandComplete(sender byte, encodedLen int32, m...
method traceCopyBothResponse (line 210) | func (t *tracer) traceCopyBothResponse(sender byte, encodedLen int32, ...
method traceCopyData (line 214) | func (t *tracer) traceCopyData(sender byte, encodedLen int32, msg *Cop...
method traceCopyDone (line 218) | func (t *tracer) traceCopyDone(sender byte, encodedLen int32, msg *Cop...
method traceCopyFail (line 222) | func (t *tracer) traceCopyFail(sender byte, encodedLen int32, msg *Cop...
method traceCopyInResponse (line 228) | func (t *tracer) traceCopyInResponse(sender byte, encodedLen int32, ms...
method traceCopyOutResponse (line 232) | func (t *tracer) traceCopyOutResponse(sender byte, encodedLen int32, m...
method traceDataRow (line 236) | func (t *tracer) traceDataRow(sender byte, encodedLen int32, msg *Data...
method traceDescribe (line 249) | func (t *tracer) traceDescribe(sender byte, encodedLen int32, msg *Des...
method traceEmptyQueryResponse (line 255) | func (t *tracer) traceEmptyQueryResponse(sender byte, encodedLen int32...
method traceErrorResponse (line 259) | func (t *tracer) traceErrorResponse(sender byte, encodedLen int32, msg...
method TraceQueryute (line 263) | func (t *tracer) TraceQueryute(sender byte, encodedLen int32, msg *Exe...
method traceFlush (line 269) | func (t *tracer) traceFlush(sender byte, encodedLen int32, msg *Flush) {
method traceFunctionCall (line 273) | func (t *tracer) traceFunctionCall(sender byte, encodedLen int32, msg ...
method traceFunctionCallResponse (line 277) | func (t *tracer) traceFunctionCallResponse(sender byte, encodedLen int...
method traceGSSEncRequest (line 281) | func (t *tracer) traceGSSEncRequest(sender byte, encodedLen int32, msg...
method traceNoData (line 285) | func (t *tracer) traceNoData(sender byte, encodedLen int32, msg *NoDat...
method traceNoticeResponse (line 289) | func (t *tracer) traceNoticeResponse(sender byte, encodedLen int32, ms...
method traceNotificationResponse (line 293) | func (t *tracer) traceNotificationResponse(sender byte, encodedLen int...
method traceParameterDescription (line 299) | func (t *tracer) traceParameterDescription(sender byte, encodedLen int...
method traceParameterStatus (line 303) | func (t *tracer) traceParameterStatus(sender byte, encodedLen int32, m...
method traceParse (line 309) | func (t *tracer) traceParse(sender byte, encodedLen int32, msg *Parse) {
method traceParseComplete (line 318) | func (t *tracer) traceParseComplete(sender byte, encodedLen int32, msg...
method tracePortalSuspended (line 322) | func (t *tracer) tracePortalSuspended(sender byte, encodedLen int32, m...
method traceQuery (line 326) | func (t *tracer) traceQuery(sender byte, encodedLen int32, msg *Query) {
method traceReadyForQuery (line 332) | func (t *tracer) traceReadyForQuery(sender byte, encodedLen int32, msg...
method traceRowDescription (line 338) | func (t *tracer) traceRowDescription(sender byte, encodedLen int32, ms...
method traceSSLRequest (line 347) | func (t *tracer) traceSSLRequest(sender byte, encodedLen int32, msg *S...
method traceStartupMessage (line 351) | func (t *tracer) traceStartupMessage(sender byte, encodedLen int32, ms...
method traceSync (line 355) | func (t *tracer) traceSync(sender byte, encodedLen int32, msg *Sync) {
method traceTerminate (line 359) | func (t *tracer) traceTerminate(sender byte, encodedLen int32, msg *Te...
method writeTrace (line 363) | func (t *tracer) writeTrace(sender byte, encodedLen int32, msgType str...
type TracerOptions (line 24) | type TracerOptions struct
function traceDoubleQuotedString (line 396) | func traceDoubleQuotedString(buf []byte) string {
function traceSingleQuotedString (line 402) | func traceSingleQuotedString(buf []byte) string {
FILE: pgproto3/trace_test.go
function TestTrace (line 15) | func TestTrace(t *testing.T) {
FILE: pgtype/array.go
type arrayHeader (line 19) | type arrayHeader struct
method DecodeBinary (line 44) | func (dst *arrayHeader) DecodeBinary(m *Map, src []byte) (int, error) {
method EncodeBinary (line 75) | func (src arrayHeader) EncodeBinary(buf []byte) []byte {
type ArrayDimension (line 25) | type ArrayDimension struct
function cardinality (line 31) | func cardinality(dimensions []ArrayDimension) int {
type untypedTextArray (line 94) | type untypedTextArray struct
function parseUntypedTextArray (line 100) | func parseUntypedTextArray(src string) (*untypedTextArray, error) {
function skipWhitespace (line 247) | func skipWhitespace(buf *bytes.Buffer) {
function arrayParseValue (line 258) | func arrayParseValue(buf *bytes.Buffer) (string, bool, error) {
function arrayParseQuotedValue (line 286) | func arrayParseQuotedValue(buf *bytes.Buffer) (string, bool, error) {
function arrayParseInteger (line 313) | func arrayParseInteger(buf *bytes.Buffer) (int32, error) {
function encodeTextArrayDimensions (line 335) | func encodeTextArrayDimensions(buf []byte, dimensions []ArrayDimension) ...
function quoteArrayElement (line 360) | func quoteArrayElement(src string) string {
function isSpace (line 364) | func isSpace(ch byte) bool {
function quoteArrayElementIfNeeded (line 370) | func quoteArrayElementIfNeeded(src string) string {
type Array (line 379) | type Array struct
method Dimensions (line 385) | func (a Array[T]) Dimensions() []ArrayDimension {
method Index (line 389) | func (a Array[T]) Index(i int) any {
method IndexType (line 393) | func (a Array[T]) IndexType() any {
method SetDimensions (line 398) | func (a *Array[T]) SetDimensions(dimensions []ArrayDimension) error {
method ScanIndex (line 414) | func (a Array[T]) ScanIndex(i int) any {
method ScanIndexType (line 418) | func (a Array[T]) ScanIndexType() any {
type FlatArray (line 424) | type FlatArray
method Dimensions (line 426) | func (a FlatArray[T]) Dimensions() []ArrayDimension {
method Index (line 434) | func (a FlatArray[T]) Index(i int) any {
method IndexType (line 438) | func (a FlatArray[T]) IndexType() any {
method SetDimensions (line 443) | func (a *FlatArray[T]) SetDimensions(dimensions []ArrayDimension) error {
method ScanIndex (line 454) | func (a FlatArray[T]) ScanIndex(i int) any {
method ScanIndexType (line 458) | func (a FlatArray[T]) ScanIndexType() any {
FILE: pgtype/array_codec.go
type ArrayGetter (line 13) | type ArrayGetter interface
type ArraySetter (line 25) | type ArraySetter interface
type ArrayCodec (line 40) | type ArrayCodec struct
method FormatSupported (line 44) | func (c *ArrayCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 48) | func (c *ArrayCodec) PreferredFormat() int16 {
method PlanEncode (line 61) | func (c *ArrayCodec) PlanEncode(m *Map, oid uint32, format int16, valu...
method PlanScan (line 224) | func (c *ArrayCodec) PlanScan(m *Map, oid uint32, format int16, target...
method decodeBinary (line 251) | func (c *ArrayCodec) decodeBinary(m *Map, arrayOID uint32, src []byte,...
method decodeText (line 291) | func (c *ArrayCodec) decodeText(m *Map, arrayOID uint32, src []byte, a...
method DecodeDatabaseSQLValue (line 357) | func (c *ArrayCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format...
method DecodeValue (line 374) | func (c *ArrayCodec) DecodeValue(m *Map, oid uint32, format int16, src...
type encodePlanArrayCodecText (line 86) | type encodePlanArrayCodecText struct
method Encode (line 92) | func (p *encodePlanArrayCodecText) Encode(value any, buf []byte) (newB...
type encodePlanArrayCodecBinary (line 165) | type encodePlanArrayCodecBinary struct
method Encode (line 171) | func (p *encodePlanArrayCodecBinary) Encode(value any, buf []byte) (ne...
type scanPlanArrayCodec (line 327) | type scanPlanArrayCodec struct
method Scan (line 335) | func (spac *scanPlanArrayCodec) Scan(src []byte, dst any) error {
function isRagged (line 384) | func isRagged(slice reflect.Value) bool {
FILE: pgtype/array_codec_test.go
function TestArrayCodec (line 17) | func TestArrayCodec(t *testing.T) {
function TestArrayCodecFlatArrayString (line 55) | func TestArrayCodecFlatArrayString(t *testing.T) {
function TestArrayCodecArray (line 88) | func TestArrayCodecArray(t *testing.T) {
function TestArrayCodecPointerToNil (line 119) | func TestArrayCodecPointerToNil(t *testing.T) {
function TestArrayCodecNamedSliceType (line 134) | func TestArrayCodecNamedSliceType(t *testing.T) {
function TestArrayCodecAnySliceArgument (line 158) | func TestArrayCodecAnySliceArgument(t *testing.T) {
function TestArrayCodecAnyArray (line 181) | func TestArrayCodecAnyArray(t *testing.T) {
function TestArrayCodecSliceArgConversion (line 204) | func TestArrayCodecSliceArgConversion(t *testing.T) {
function TestArrayCodecDecodeValue (line 234) | func TestArrayCodecDecodeValue(t *testing.T) {
function TestArrayCodecScanMultipleDimensions (line 270) | func TestArrayCodecScanMultipleDimensions(t *testing.T) {
function TestArrayCodecScanMultipleDimensionsEmpty (line 288) | func TestArrayCodecScanMultipleDimensionsEmpty(t *testing.T) {
function TestArrayCodecScanWrongMultipleDimensions (line 306) | func TestArrayCodecScanWrongMultipleDimensions(t *testing.T) {
function TestArrayCodecEncodeMultipleDimensions (line 321) | func TestArrayCodecEncodeMultipleDimensions(t *testing.T) {
function TestArrayCodecEncodeMultipleDimensionsRagged (line 339) | func TestArrayCodecEncodeMultipleDimensionsRagged(t *testing.T) {
function TestArrayCodecDecodeTextArrayWithTextOfNULL (line 350) | func TestArrayCodecDecodeTextArrayWithTextOfNULL(t *testing.T) {
function TestArrayCodecDecodeTextArrayPrefersBinaryFormat (line 373) | func TestArrayCodecDecodeTextArrayPrefersBinaryFormat(t *testing.T) {
FILE: pgtype/array_test.go
function TestParseUntypedTextArray (line 8) | func TestParseUntypedTextArray(t *testing.T) {
FILE: pgtype/bits.go
type BitsScanner (line 11) | type BitsScanner interface
type BitsValuer (line 15) | type BitsValuer interface
type Bits (line 20) | type Bits struct
method ScanBits (line 27) | func (b *Bits) ScanBits(v Bits) error {
method BitsValue (line 33) | func (b Bits) BitsValue() (Bits, error) {
method Scan (line 38) | func (dst *Bits) Scan(src any) error {
method Value (line 53) | func (src Bits) Value() (driver.Value, error) {
type BitsCodec (line 65) | type BitsCodec struct
method FormatSupported (line 67) | func (BitsCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 71) | func (BitsCodec) PreferredFormat() int16 {
method PlanEncode (line 75) | func (BitsCodec) PlanEncode(m *Map, oid uint32, format int16, value an...
method PlanScan (line 131) | func (BitsCodec) PlanScan(m *Map, oid uint32, format int16, target any...
method DecodeDatabaseSQLValue (line 148) | func (c BitsCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format i...
method DecodeValue (line 152) | func (c BitsCodec) DecodeValue(m *Map, oid uint32, format int16, src [...
type encodePlanBitsCodecBinary (line 90) | type encodePlanBitsCodecBinary struct
method Encode (line 92) | func (encodePlanBitsCodecBinary) Encode(value any, buf []byte) (newBuf...
type encodePlanBitsCodecText (line 106) | type encodePlanBitsCodecText struct
method Encode (line 108) | func (encodePlanBitsCodecText) Encode(value any, buf []byte) (newBuf [...
type scanPlanBinaryBitsToBitsScanner (line 165) | type scanPlanBinaryBitsToBitsScanner struct
method Scan (line 167) | func (scanPlanBinaryBitsToBitsScanner) Scan(src []byte, dst any) error {
type scanPlanTextAnyToBitsScanner (line 186) | type scanPlanTextAnyToBitsScanner struct
method Scan (line 188) | func (scanPlanTextAnyToBitsScanner) Scan(src []byte, dst any) error {
FILE: pgtype/bits_test.go
function isExpectedEqBits (line 12) | func isExpectedEqBits(a any) func(any) bool {
function TestBitsCodecBit (line 20) | func TestBitsCodecBit(t *testing.T) {
function TestBitsCodecVarbit (line 37) | func TestBitsCodecVarbit(t *testing.T) {
FILE: pgtype/bool.go
type BoolScanner (line 12) | type BoolScanner interface
type BoolValuer (line 16) | type BoolValuer interface
type Bool (line 20) | type Bool struct
method ScanBool (line 26) | func (b *Bool) ScanBool(v Bool) error {
method BoolValue (line 32) | func (b Bool) BoolValue() (Bool, error) {
method Scan (line 37) | func (dst *Bool) Scan(src any) error {
method Value (line 67) | func (src Bool) Value() (driver.Value, error) {
method MarshalJSON (line 76) | func (src Bool) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 89) | func (dst *Bool) UnmarshalJSON(b []byte) error {
type BoolCodec (line 105) | type BoolCodec struct
method FormatSupported (line 107) | func (BoolCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 111) | func (BoolCodec) PreferredFormat() int16 {
method PlanEncode (line 115) | func (BoolCodec) PlanEncode(m *Map, oid uint32, format int16, value an...
method PlanScan (line 206) | func (BoolCodec) PlanScan(m *Map, oid uint32, format int16, target any...
method DecodeDatabaseSQLValue (line 227) | func (c BoolCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format i...
method DecodeValue (line 231) | func (c BoolCodec) DecodeValue(m *Map, oid uint32, format int16, src [...
type encodePlanBoolCodecBinaryBool (line 136) | type encodePlanBoolCodecBinaryBool struct
method Encode (line 138) | func (encodePlanBoolCodecBinaryBool) Encode(value any, buf []byte) (ne...
type encodePlanBoolCodecTextBoolValuer (line 150) | type encodePlanBoolCodecTextBoolValuer struct
method Encode (line 152) | func (encodePlanBoolCodecTextBoolValuer) Encode(value any, buf []byte)...
type encodePlanBoolCodecBinaryBoolValuer (line 171) | type encodePlanBoolCodecBinaryBoolValuer struct
method Encode (line 173) | func (encodePlanBoolCodecBinaryBoolValuer) Encode(value any, buf []byt...
type encodePlanBoolCodecTextBool (line 192) | type encodePlanBoolCodecTextBool struct
method Encode (line 194) | func (encodePlanBoolCodecTextBool) Encode(value any, buf []byte) (newB...
type scanPlanBinaryBoolToBool (line 244) | type scanPlanBinaryBoolToBool struct
method Scan (line 246) | func (scanPlanBinaryBoolToBool) Scan(src []byte, dst any) error {
type scanPlanTextAnyToBool (line 265) | type scanPlanTextAnyToBool struct
method Scan (line 267) | func (scanPlanTextAnyToBool) Scan(src []byte, dst any) error {
type scanPlanBinaryBoolToBoolScanner (line 291) | type scanPlanBinaryBoolToBoolScanner struct
method Scan (line 293) | func (scanPlanBinaryBoolToBoolScanner) Scan(src []byte, dst any) error {
type scanPlanTextAnyToBoolScanner (line 310) | type scanPlanTextAnyToBoolScanner struct
method Scan (line 312) | func (scanPlanTextAnyToBoolScanner) Scan(src []byte, dst any) error {
function planTextToBool (line 335) | func planTextToBool(src []byte) (bool, error) {
FILE: pgtype/bool_test.go
function TestBoolCodec (line 11) | func TestBoolCodec(t *testing.T) {
function TestBoolMarshalJSON (line 21) | func TestBoolMarshalJSON(t *testing.T) {
function TestBoolUnmarshalJSON (line 42) | func TestBoolUnmarshalJSON(t *testing.T) {
FILE: pgtype/box.go
type BoxScanner (line 14) | type BoxScanner interface
type BoxValuer (line 18) | type BoxValuer interface
type Box (line 22) | type Box struct
method ScanBox (line 28) | func (b *Box) ScanBox(v Box) error {
method BoxValue (line 34) | func (b Box) BoxValue() (Box, error) {
method Scan (line 39) | func (dst *Box) Scan(src any) error {
method Value (line 54) | func (src Box) Value() (driver.Value, error) {
type BoxCodec (line 66) | type BoxCodec struct
method FormatSupported (line 68) | func (BoxCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 72) | func (BoxCodec) PreferredFormat() int16 {
method PlanEncode (line 76) | func (BoxCodec) PlanEncode(m *Map, oid uint32, format int16, value any...
method PlanScan (line 131) | func (BoxCodec) PlanScan(m *Map, oid uint32, format int16, target any)...
method DecodeDatabaseSQLValue (line 224) | func (c BoxCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format in...
method DecodeValue (line 228) | func (c BoxCodec) DecodeValue(m *Map, oid uint32, format int16, src []...
type encodePlanBoxCodecBinary (line 91) | type encodePlanBoxCodecBinary struct
method Encode (line 93) | func (encodePlanBoxCodecBinary) Encode(value any, buf []byte) (newBuf ...
type encodePlanBoxCodecText (line 110) | type encodePlanBoxCodecText struct
method Encode (line 112) | func (encodePlanBoxCodecText) Encode(value any, buf []byte) (newBuf []...
type scanPlanBinaryBoxToBoxScanner (line 148) | type scanPlanBinaryBoxToBoxScanner struct
method Scan (line 150) | func (scanPlanBinaryBoxToBoxScanner) Scan(src []byte, dst any) error {
type scanPlanTextAnyToBoxScanner (line 175) | type scanPlanTextAnyToBoxScanner struct
method Scan (line 177) | func (scanPlanTextAnyToBoxScanner) Scan(src []byte, dst any) error {
FILE: pgtype/box_test.go
function TestBoxCodec (line 11) | func TestBoxCodec(t *testing.T) {
FILE: pgtype/builtin_wrappers.go
type int8Wrapper (line 14) | type int8Wrapper
method SkipUnderlyingTypePlan (line 16) | func (w int8Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 18) | func (w *int8Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 34) | func (w int8Wrapper) Int64Value() (Int8, error) {
type int16Wrapper (line 38) | type int16Wrapper
method SkipUnderlyingTypePlan (line 40) | func (w int16Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 42) | func (w *int16Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 58) | func (w int16Wrapper) Int64Value() (Int8, error) {
type int32Wrapper (line 62) | type int32Wrapper
method SkipUnderlyingTypePlan (line 64) | func (w int32Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 66) | func (w *int32Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 82) | func (w int32Wrapper) Int64Value() (Int8, error) {
type int64Wrapper (line 86) | type int64Wrapper
method SkipUnderlyingTypePlan (line 88) | func (w int64Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 90) | func (w *int64Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 100) | func (w int64Wrapper) Int64Value() (Int8, error) {
type intWrapper (line 104) | type intWrapper
method SkipUnderlyingTypePlan (line 106) | func (w intWrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 108) | func (w *intWrapper) ScanInt64(v Int8) error {
method Int64Value (line 125) | func (w intWrapper) Int64Value() (Int8, error) {
type uint8Wrapper (line 129) | type uint8Wrapper
method SkipUnderlyingTypePlan (line 131) | func (w uint8Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 133) | func (w *uint8Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 149) | func (w uint8Wrapper) Int64Value() (Int8, error) {
type uint16Wrapper (line 153) | type uint16Wrapper
method SkipUnderlyingTypePlan (line 155) | func (w uint16Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 157) | func (w *uint16Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 173) | func (w uint16Wrapper) Int64Value() (Int8, error) {
type uint32Wrapper (line 177) | type uint32Wrapper
method SkipUnderlyingTypePlan (line 179) | func (w uint32Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 181) | func (w *uint32Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 197) | func (w uint32Wrapper) Int64Value() (Int8, error) {
type uint64Wrapper (line 201) | type uint64Wrapper
method SkipUnderlyingTypePlan (line 203) | func (w uint64Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 205) | func (w *uint64Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 219) | func (w uint64Wrapper) Int64Value() (Int8, error) {
method ScanNumeric (line 227) | func (w *uint64Wrapper) ScanNumeric(v Numeric) error {
method NumericValue (line 246) | func (w uint64Wrapper) NumericValue() (Numeric, error) {
type uintWrapper (line 250) | type uintWrapper
method SkipUnderlyingTypePlan (line 252) | func (w uintWrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 254) | func (w *uintWrapper) ScanInt64(v Int8) error {
method Int64Value (line 272) | func (w uintWrapper) Int64Value() (Int8, error) {
method ScanNumeric (line 280) | func (w *uintWrapper) ScanNumeric(v Numeric) error {
method NumericValue (line 305) | func (w uintWrapper) NumericValue() (Numeric, error) {
type float32Wrapper (line 309) | type float32Wrapper
method SkipUnderlyingTypePlan (line 311) | func (w float32Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 313) | func (w *float32Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 323) | func (w float32Wrapper) Int64Value() (Int8, error) {
method ScanFloat64 (line 331) | func (w *float32Wrapper) ScanFloat64(v Float8) error {
method Float64Value (line 341) | func (w float32Wrapper) Float64Value() (Float8, error) {
type float64Wrapper (line 345) | type float64Wrapper
method SkipUnderlyingTypePlan (line 347) | func (w float64Wrapper) SkipUnderlyingTypePlan() {}
method ScanInt64 (line 349) | func (w *float64Wrapper) ScanInt64(v Int8) error {
method Int64Value (line 359) | func (w float64Wrapper) Int64Value() (Int8, error) {
method ScanFloat64 (line 367) | func (w *float64Wrapper) ScanFloat64(v Float8) error {
method Float64Value (line 377) | func (w float64Wrapper) Float64Value() (Float8, error) {
type stringWrapper (line 381) | type stringWrapper
method SkipUnderlyingTypePlan (line 383) | func (w stringWrapper) SkipUnderlyingTypePlan() {}
method ScanText (line 385) | func (w *stringWrapper) ScanText(v Text) error {
method TextValue (line 394) | func (w stringWrapper) TextValue() (Text, error) {
type timeWrapper (line 398) | type timeWrapper
method ScanDate (line 400) | func (w *timeWrapper) ScanDate(v Date) error {
method DateValue (line 418) | func (w timeWrapper) DateValue() (Date, error) {
method ScanTimestamp (line 422) | func (w *timeWrapper) ScanTimestamp(v Timestamp) error {
method TimestampValue (line 440) | func (w timeWrapper) TimestampValue() (Timestamp, error) {
method ScanTimestamptz (line 444) | func (w *timeWrapper) ScanTimestamptz(v Timestamptz) error {
method TimestamptzValue (line 462) | func (w timeWrapper) TimestamptzValue() (Timestamptz, error) {
method ScanTime (line 466) | func (w *timeWrapper) ScanTime(v Time) error {
method TimeValue (line 489) | func (w timeWrapper) TimeValue() (Time, error) {
type durationWrapper (line 498) | type durationWrapper
method SkipUnderlyingTypePlan (line 500) | func (w durationWrapper) SkipUnderlyingTypePlan() {}
method ScanInterval (line 502) | func (w *durationWrapper) ScanInterval(v Interval) error {
method IntervalValue (line 512) | func (w durationWrapper) IntervalValue() (Interval, error) {
type netIPNetWrapper (line 516) | type netIPNetWrapper
method ScanNetipPrefix (line 518) | func (w *netIPNetWrapper) ScanNetipPrefix(v netip.Prefix) error {
method NetipPrefixValue (line 531) | func (w netIPNetWrapper) NetipPrefixValue() (netip.Prefix, error) {
type netIPWrapper (line 542) | type netIPWrapper
method SkipUnderlyingTypePlan (line 544) | func (w netIPWrapper) SkipUnderlyingTypePlan() {}
method ScanNetipPrefix (line 546) | func (w *netIPWrapper) ScanNetipPrefix(v netip.Prefix) error {
method NetipPrefixValue (line 560) | func (w netIPWrapper) NetipPrefixValue() (netip.Prefix, error) {
type netipPrefixWrapper (line 573) | type netipPrefixWrapper
method ScanNetipPrefix (line 575) | func (w *netipPrefixWrapper) ScanNetipPrefix(v netip.Prefix) error {
method NetipPrefixValue (line 580) | func (w netipPrefixWrapper) NetipPrefixValue() (netip.Prefix, error) {
type netipAddrWrapper (line 584) | type netipAddrWrapper
method ScanNetipPrefix (line 586) | func (w *netipAddrWrapper) ScanNetipPrefix(v netip.Prefix) error {
method NetipPrefixValue (line 601) | func (w netipAddrWrapper) NetipPrefixValue() (netip.Prefix, error) {
type mapStringToPointerStringWrapper (line 610) | type mapStringToPointerStringWrapper
method ScanHstore (line 612) | func (w *mapStringToPointerStringWrapper) ScanHstore(v Hstore) error {
method HstoreValue (line 617) | func (w mapStringToPointerStringWrapper) HstoreValue() (Hstore, error) {
type mapStringToStringWrapper (line 621) | type mapStringToStringWrapper
method ScanHstore (line 623) | func (w *mapStringToStringWrapper) ScanHstore(v Hstore) error {
method HstoreValue (line 634) | func (w mapStringToStringWrapper) HstoreValue() (Hstore, error) {
type fmtStringerWrapper (line 647) | type fmtStringerWrapper struct
method TextValue (line 651) | func (w fmtStringerWrapper) TextValue() (Text, error) {
type byte16Wrapper (line 655) | type byte16Wrapper
method ScanUUID (line 657) | func (w *byte16Wrapper) ScanUUID(v UUID) error {
method UUIDValue (line 665) | func (w byte16Wrapper) UUIDValue() (UUID, error) {
type byteSliceWrapper (line 669) | type byteSliceWrapper
method SkipUnderlyingTypePlan (line 671) | func (w byteSliceWrapper) SkipUnderlyingTypePlan() {}
method ScanText (line 673) | func (w *byteSliceWrapper) ScanText(v Text) error {
method TextValue (line 683) | func (w byteSliceWrapper) TextValue() (Text, error) {
method ScanUUID (line 691) | func (w *byteSliceWrapper) ScanUUID(v UUID) error {
method UUIDValue (line 701) | func (w byteSliceWrapper) UUIDValue() (UUID, error) {
type structWrapper (line 712) | type structWrapper struct
method IsNull (line 717) | func (w structWrapper) IsNull() bool {
method Index (line 721) | func (w structWrapper) Index(i int) any {
type ptrStructWrapper (line 730) | type ptrStructWrapper struct
method ScanNull (line 735) | func (w *ptrStructWrapper) ScanNull() error {
method ScanIndex (line 739) | func (w *ptrStructWrapper) ScanIndex(i int) any {
type anySliceArrayReflect (line 747) | type anySliceArrayReflect struct
method Dimensions (line 751) | func (a anySliceArrayReflect) Dimensions() []ArrayDimension {
method Index (line 759) | func (a anySliceArrayReflect) Index(i int) any {
method IndexType (line 763) | func (a anySliceArrayReflect) IndexType() any {
method SetDimensions (line 767) | func (a *anySliceArrayReflect) SetDimensions(dimensions []ArrayDimensi...
method ScanIndex (line 781) | func (a *anySliceArrayReflect) ScanIndex(i int) any {
method ScanIndexType (line 785) | func (a *anySliceArrayReflect) ScanIndexType() any {
type anyMultiDimSliceArray (line 789) | type anyMultiDimSliceArray struct
method Dimensions (line 794) | func (a *anyMultiDimSliceArray) Dimensions() []ArrayDimension {
method Index (line 816) | func (a *anyMultiDimSliceArray) Index(i int) any {
method IndexType (line 836) | func (a *anyMultiDimSliceArray) IndexType() any {
method SetDimensions (line 843) | func (a *anyMultiDimSliceArray) SetDimensions(dimensions []ArrayDimens...
method makeMultidimensionalSlice (line 887) | func (a *anyMultiDimSliceArray) makeMultidimensionalSlice(sliceType re...
method ScanIndex (line 903) | func (a *anyMultiDimSliceArray) ScanIndex(i int) any {
method ScanIndexType (line 907) | func (a *anyMultiDimSliceArray) ScanIndexType() any {
type anyArrayArrayReflect (line 914) | type anyArrayArrayReflect struct
method Dimensions (line 918) | func (a anyArrayArrayReflect) Dimensions() []ArrayDimension {
method Index (line 922) | func (a anyArrayArrayReflect) Index(i int) any {
method IndexType (line 926) | func (a anyArrayArrayReflect) IndexType() any {
method SetDimensions (line 930) | func (a *anyArrayArrayReflect) SetDimensions(dimensions []ArrayDimensi...
method ScanIndex (line 946) | func (a *anyArrayArrayReflect) ScanIndex(i int) any {
method ScanIndexType (line 950) | func (a *anyArrayArrayReflect) ScanIndexType() any {
FILE: pgtype/bytea.go
type BytesScanner (line 9) | type BytesScanner interface
type BytesValuer (line 14) | type BytesValuer interface
type DriverBytes (line 22) | type DriverBytes
method ScanBytes (line 24) | func (b *DriverBytes) ScanBytes(v []byte) error {
type PreallocBytes (line 31) | type PreallocBytes
method ScanBytes (line 33) | func (b *PreallocBytes) ScanBytes(v []byte) error {
type UndecodedBytes (line 49) | type UndecodedBytes
type scanPlanAnyToUndecodedBytes (line 51) | type scanPlanAnyToUndecodedBytes struct
method Scan (line 53) | func (scanPlanAnyToUndecodedBytes) Scan(src []byte, dst any) error {
type ByteaCodec (line 65) | type ByteaCodec struct
method FormatSupported (line 67) | func (ByteaCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 71) | func (ByteaCodec) PreferredFormat() int16 {
method PlanEncode (line 75) | func (ByteaCodec) PlanEncode(m *Map, oid uint32, format int16, value a...
method PlanScan (line 150) | func (ByteaCodec) PlanScan(m *Map, oid uint32, format int16, target an...
method DecodeDatabaseSQLValue (line 239) | func (c ByteaCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format ...
method DecodeValue (line 243) | func (c ByteaCodec) DecodeValue(m *Map, oid uint32, format int16, src ...
type encodePlanBytesCodecBinaryBytes (line 96) | type encodePlanBytesCodecBinaryBytes struct
method Encode (line 98) | func (encodePlanBytesCodecBinaryBytes) Encode(value any, buf []byte) (...
type encodePlanBytesCodecBinaryBytesValuer (line 107) | type encodePlanBytesCodecBinaryBytesValuer struct
method Encode (line 109) | func (encodePlanBytesCodecBinaryBytesValuer) Encode(value any, buf []b...
type encodePlanBytesCodecTextBytes (line 121) | type encodePlanBytesCodecTextBytes struct
method Encode (line 123) | func (encodePlanBytesCodecTextBytes) Encode(value any, buf []byte) (ne...
type encodePlanBytesCodecTextBytesValuer (line 134) | type encodePlanBytesCodecTextBytesValuer struct
method Encode (line 136) | func (encodePlanBytesCodecTextBytesValuer) Encode(value any, buf []byt...
type scanPlanBinaryBytesToBytes (line 171) | type scanPlanBinaryBytesToBytes struct
method Scan (line 173) | func (scanPlanBinaryBytesToBytes) Scan(src []byte, dst any) error {
type scanPlanBinaryBytesToBytesScanner (line 185) | type scanPlanBinaryBytesToBytesScanner struct
method Scan (line 187) | func (scanPlanBinaryBytesToBytesScanner) Scan(src []byte, dst any) err...
type scanPlanTextByteaToBytes (line 192) | type scanPlanTextByteaToBytes struct
method Scan (line 194) | func (scanPlanTextByteaToBytes) Scan(src []byte, dst any) error {
type scanPlanTextByteaToBytesScanner (line 210) | type scanPlanTextByteaToBytesScanner struct
method Scan (line 212) | func (scanPlanTextByteaToBytesScanner) Scan(src []byte, dst any) error {
function decodeHexBytea (line 221) | func decodeHexBytea(src []byte) ([]byte, error) {
FILE: pgtype/bytea_test.go
function isExpectedEqBytes (line 15) | func isExpectedEqBytes(a any) func(any) bool {
function TestByteaCodec (line 32) | func TestByteaCodec(t *testing.T) {
function TestDriverBytesQueryRow (line 41) | func TestDriverBytesQueryRow(t *testing.T) {
function TestDriverBytes (line 49) | func TestDriverBytes(t *testing.T) {
function TestPreallocBytes (line 86) | func TestPreallocBytes(t *testing.T) {
function TestUndecodedBytes (line 108) | func TestUndecodedBytes(t *testing.T) {
function TestByteaCodecDecodeDatabaseSQLValue (line 119) | func TestByteaCodecDecodeDatabaseSQLValue(t *testing.T) {
FILE: pgtype/circle.go
type CircleScanner (line 14) | type CircleScanner interface
type CircleValuer (line 18) | type CircleValuer interface
type Circle (line 22) | type Circle struct
method ScanCircle (line 29) | func (c *Circle) ScanCircle(v Circle) error {
method CircleValue (line 35) | func (c Circle) CircleValue() (Circle, error) {
method Scan (line 40) | func (dst *Circle) Scan(src any) error {
method Value (line 55) | func (src Circle) Value() (driver.Value, error) {
type CircleCodec (line 67) | type CircleCodec struct
method FormatSupported (line 69) | func (CircleCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 73) | func (CircleCodec) PreferredFormat() int16 {
method PlanEncode (line 77) | func (CircleCodec) PlanEncode(m *Map, oid uint32, format int16, value ...
method PlanScan (line 130) | func (CircleCodec) PlanScan(m *Map, oid uint32, format int16, target a...
method DecodeDatabaseSQLValue (line 147) | func (c CircleCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format...
method DecodeValue (line 151) | func (c CircleCodec) DecodeValue(m *Map, oid uint32, format int16, src...
type encodePlanCircleCodecBinary (line 92) | type encodePlanCircleCodecBinary struct
method Encode (line 94) | func (encodePlanCircleCodecBinary) Encode(value any, buf []byte) (newB...
type encodePlanCircleCodecText (line 110) | type encodePlanCircleCodecText struct
method Encode (line 112) | func (encodePlanCircleCodecText) Encode(value any, buf []byte) (newBuf...
type scanPlanBinaryCircleToCircleScanner (line 164) | type scanPlanBinaryCircleToCircleScanner struct
method Scan (line 166) | func (scanPlanBinaryCircleToCircleScanner) Scan(src []byte, dst any) e...
type scanPlanTextAnyToCircleScanner (line 188) | type scanPlanTextAnyToCircleScanner struct
method Scan (line 190) | func (scanPlanTextAnyToCircleScanner) Scan(src []byte, dst any) error {
FILE: pgtype/circle_test.go
function TestCircleTranscode (line 11) | func TestCircleTranscode(t *testing.T) {
FILE: pgtype/composite.go
type CompositeIndexGetter (line 14) | type CompositeIndexGetter interface
type CompositeIndexScanner (line 23) | type CompositeIndexScanner interface
type CompositeCodecField (line 31) | type CompositeCodecField struct
type CompositeCodec (line 36) | type CompositeCodec struct
method FormatSupported (line 40) | func (c *CompositeCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 50) | func (c *CompositeCodec) PreferredFormat() int16 {
method PlanEncode (line 57) | func (c *CompositeCodec) PlanEncode(m *Map, oid uint32, format int16, ...
method PlanScan (line 112) | func (c *CompositeCodec) PlanScan(m *Map, oid uint32, format int16, ta...
method DecodeDatabaseSQLValue (line 207) | func (c *CompositeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, fo...
method DecodeValue (line 224) | func (c *CompositeCodec) DecodeValue(m *Map, oid uint32, format int16,...
type encodePlanCompositeCodecCompositeIndexGetterToBinary (line 72) | type encodePlanCompositeCodecCompositeIndexGetterToBinary struct
method Encode (line 77) | func (plan *encodePlanCompositeCodecCompositeIndexGetterToBinary) Enco...
type encodePlanCompositeCodecCompositeIndexGetterToText (line 92) | type encodePlanCompositeCodecCompositeIndexGetterToText struct
method Encode (line 97) | func (plan *encodePlanCompositeCodecCompositeIndexGetterToText) Encode...
type scanPlanBinaryCompositeToCompositeIndexScanner (line 129) | type scanPlanBinaryCompositeToCompositeIndexScanner struct
method Scan (line 134) | func (plan *scanPlanBinaryCompositeToCompositeIndexScanner) Scan(src [...
type scanPlanTextCompositeToCompositeIndexScanner (line 168) | type scanPlanTextCompositeToCompositeIndexScanner struct
method Scan (line 173) | func (plan *scanPlanTextCompositeToCompositeIndexScanner) Scan(src []b...
type CompositeBinaryScanner (line 281) | type CompositeBinaryScanner struct
method Next (line 312) | func (cfs *CompositeBinaryScanner) Next() bool {
method FieldCount (line 345) | func (cfs *CompositeBinaryScanner) FieldCount() int {
method Bytes (line 350) | func (cfs *CompositeBinaryScanner) Bytes() []byte {
method OID (line 355) | func (cfs *CompositeBinaryScanner) OID() uint32 {
method Err (line 360) | func (cfs *CompositeBinaryScanner) Err() error {
function NewCompositeBinaryScanner (line 293) | func NewCompositeBinaryScanner(m *Map, src []byte) *CompositeBinaryScann...
type CompositeTextScanner (line 364) | type CompositeTextScanner struct
method Next (line 396) | func (cfs *CompositeTextScanner) Next() bool {
method Bytes (line 451) | func (cfs *CompositeTextScanner) Bytes() []byte {
method Err (line 456) | func (cfs *CompositeTextScanner) Err() error {
function NewCompositeTextScanner (line 374) | func NewCompositeTextScanner(m *Map, src []byte) *CompositeTextScanner {
type CompositeBinaryBuilder (line 460) | type CompositeBinaryBuilder struct
method AppendValue (line 474) | func (b *CompositeBinaryBuilder) AppendValue(oid uint32, field any) {
method Finish (line 508) | func (b *CompositeBinaryBuilder) Finish() ([]byte, error) {
function NewCompositeBinaryBuilder (line 468) | func NewCompositeBinaryBuilder(m *Map, buf []byte) *CompositeBinaryBuild...
type CompositeTextBuilder (line 517) | type CompositeTextBuilder struct
method AppendValue (line 531) | func (b *CompositeTextBuilder) AppendValue(oid uint32, field any) {
method Finish (line 559) | func (b *CompositeTextBuilder) Finish() ([]byte, error) {
function NewCompositeTextBuilder (line 526) | func NewCompositeTextBuilder(m *Map, buf []byte) *CompositeTextBuilder {
function quoteCompositeField (line 570) | func quoteCompositeField(src string) string {
function quoteCompositeFieldIfNeeded (line 574) | func quoteCompositeFieldIfNeeded(src string) string {
type CompositeFields (line 583) | type CompositeFields
method SkipUnderlyingTypePlan (line 585) | func (cf CompositeFields) SkipUnderlyingTypePlan() {}
method IsNull (line 587) | func (cf CompositeFields) IsNull() bool {
method Index (line 591) | func (cf CompositeFields) Index(i int) any {
method ScanNull (line 595) | func (cf CompositeFields) ScanNull() error {
method ScanIndex (line 599) | func (cf CompositeFields) ScanIndex(i int) any {
FILE: pgtype/composite_test.go
function TestCompositeCodecTranscode (line 13) | func TestCompositeCodecTranscode(t *testing.T) {
type point3d (line 52) | type point3d struct
method IsNull (line 56) | func (p point3d) IsNull() bool {
method Index (line 60) | func (p point3d) Index(i int) any {
method ScanNull (line 73) | func (p *point3d) ScanNull() error {
method ScanIndex (line 77) | func (p *point3d) ScanIndex(i int) any {
function TestCompositeCodecTranscodeStruct (line 90) | func TestCompositeCodecTranscodeStruct(t *testing.T) {
function TestCompositeCodecTranscodeStructWrapper (line 124) | func TestCompositeCodecTranscodeStructWrapper(t *testing.T) {
type parent (line 162) | type parent struct
method IsNull (line 167) | func (p parent) IsNull() bool {
method Index (line 171) | func (p parent) Index(i int) any {
method ScanNull (line 182) | func (p *parent) ScanNull() error {
method ScanIndex (line 186) | func (p *parent) ScanIndex(i int) any {
function TestCompositeCodecTranscodeStructWithNilPointer (line 198) | func TestCompositeCodecTranscodeStructWithNilPointer(t *testing.T) {
type parentWithSlice (line 241) | type parentWithSlice struct
method IsNull (line 246) | func (p parentWithSlice) IsNull() bool {
method Index (line 250) | func (p parentWithSlice) Index(i int) any {
method ScanNull (line 261) | func (p *parentWithSlice) ScanNull() error {
method ScanIndex (line 265) | func (p *parentWithSlice) ScanIndex(i int) any {
function TestCompositeCodecTranscodeStructWithSliceOfNilPointer (line 277) | func TestCompositeCodecTranscodeStructWithSliceOfNilPointer(t *testing.T) {
function TestCompositeCodecDecodeValue (line 320) | func TestCompositeCodecDecodeValue(t *testing.T) {
function TestCompositeCodecTranscodeStructWrapperForTable (line 362) | func TestCompositeCodecTranscodeStructWrapperForTable(t *testing.T) {
FILE: pgtype/convert.go
function NullAssignTo (line 7) | func NullAssignTo(dst any) error {
function toInterface (line 28) | func toInterface(dst reflect.Value, t reflect.Type) (any, bool) {
function GetAssignToDstType (line 40) | func GetAssignToDstType(dst any) (any, bool) {
function init (line 91) | func init() {
FILE: pgtype/date.go
type DateScanner (line 14) | type DateScanner interface
type DateValuer (line 18) | type DateValuer interface
type Date (line 22) | type Date struct
method ScanDate (line 29) | func (d *Date) ScanDate(v Date) error {
method DateValue (line 35) | func (d Date) DateValue() (Date, error) {
method Scan (line 45) | func (dst *Date) Scan(src any) error {
method Value (line 63) | func (src Date) Value() (driver.Value, error) {
method MarshalJSON (line 75) | func (src Date) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 95) | func (dst *Date) UnmarshalJSON(b []byte) error {
constant negativeInfinityDayOffset (line 40) | negativeInfinityDayOffset = -2147483648
constant infinityDayOffset (line 41) | infinityDayOffset = 2147483647
type DateCodec (line 124) | type DateCodec struct
method FormatSupported (line 126) | func (DateCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 130) | func (DateCodec) PreferredFormat() int16 {
method PlanEncode (line 134) | func (DateCodec) PlanEncode(m *Map, oid uint32, format int16, value an...
method PlanScan (line 228) | func (DateCodec) PlanScan(m *Map, oid uint32, format int16, target any...
method DecodeDatabaseSQLValue (line 380) | func (c DateCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format i...
method DecodeValue (line 398) | func (c DateCodec) DecodeValue(m *Map, oid uint32, format int16, src [...
type encodePlanDateCodecBinary (line 149) | type encodePlanDateCodecBinary struct
method Encode (line 151) | func (encodePlanDateCodecBinary) Encode(value any, buf []byte) (newBuf...
type encodePlanDateCodecText (line 178) | type encodePlanDateCodecText struct
method Encode (line 180) | func (encodePlanDateCodecText) Encode(value any, buf []byte) (newBuf [...
type scanPlanBinaryDateToDateScanner (line 245) | type scanPlanBinaryDateToDateScanner struct
method Scan (line 247) | func (scanPlanBinaryDateToDateScanner) Scan(src []byte, dst any) error {
type scanPlanTextAnyToDateScanner (line 271) | type scanPlanTextAnyToDateScanner struct
method Scan (line 273) | func (scanPlanTextAnyToDateScanner) Scan(src []byte, dst any) error {
function parse2Digits (line 354) | func parse2Digits(b []byte) (int64, error) {
function parseDigits (line 366) | func parseDigits(b []byte) (int64, error) {
FILE: pgtype/date_test.go
function isExpectedEqTime (line 13) | func isExpectedEqTime(a any) func(any) bool {
function TestDateCodec (line 22) | func TestDateCodec(t *testing.T) {
function TestDateCodecTextEncode (line 42) | func TestDateCodecTextEncode(t *testing.T) {
function TestDateMarshalJSON (line 66) | func TestDateMarshalJSON(t *testing.T) {
function TestDateUnmarshalJSON (line 90) | func TestDateUnmarshalJSON(t *testing.T) {
function TestDateScanTextFormat (line 115) | func TestDateScanTextFormat(t *testing.T) {
function TestDateScanRoundTrip (line 339) | func TestDateScanRoundTrip(t *testing.T) {
function TestDateScanInfinityRoundTrip (line 384) | func TestDateScanInfinityRoundTrip(t *testing.T) {
FILE: pgtype/derived_types_test.go
function TestDerivedTypes (line 12) | func TestDerivedTypes(t *testing.T) {
FILE: pgtype/enum_codec.go
type EnumCodec (line 11) | type EnumCodec struct
method FormatSupported (line 15) | func (EnumCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 19) | func (EnumCodec) PreferredFormat() int16 {
method PlanEncode (line 23) | func (EnumCodec) PlanEncode(m *Map, oid uint32, format int16, value an...
method PlanScan (line 39) | func (c *EnumCodec) PlanScan(m *Map, oid uint32, format int16, target ...
method DecodeDatabaseSQLValue (line 55) | func (c *EnumCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format ...
method DecodeValue (line 59) | func (c *EnumCodec) DecodeValue(m *Map, oid uint32, format int16, src ...
method lookupAndCacheString (line 68) | func (c *EnumCodec) lookupAndCacheString(src []byte) string {
type scanPlanTextAnyToEnumString (line 82) | type scanPlanTextAnyToEnumString struct
method Scan (line 86) | func (plan *scanPlanTextAnyToEnumString) Scan(src []byte, dst any) err...
type scanPlanTextAnyToEnumTextScanner (line 97) | type scanPlanTextAnyToEnumTextScanner struct
method Scan (line 101) | func (plan *scanPlanTextAnyToEnumTextScanner) Scan(src []byte, dst any...
FILE: pgtype/enum_codec_test.go
function TestEnumCodec (line 11) | func TestEnumCodec(t *testing.T) {
function TestEnumCodecValues (line 47) | func TestEnumCodecValues(t *testing.T) {
FILE: pgtype/example_child_records_test.go
type Player (line 12) | type Player struct
type Team (line 17) | type Team struct
function Example_childRecords (line 23) | func Example_childRecords() {
FILE: pgtype/example_custom_type_test.go
type Point (line 13) | type Point struct
method ScanPoint (line 18) | func (p *Point) ScanPoint(v pgtype.Point) error {
method PointValue (line 27) | func (p Point) PointValue() (pgtype.Point, error) {
method String (line 34) | func (src *Point) String() string {
function Example_customType (line 42) | func Example_customType() {
FILE: pgtype/example_json_test.go
function Example_json (line 11) | func Example_json() {
FILE: pgtype/float4.go
type Float4 (line 14) | type Float4 struct
method ScanFloat64 (line 20) | func (f *Float4) ScanFloat64(n Float8) error {
method Float64Value (line 26) | func (f Float4) Float64Value() (Float8, error) {
method ScanInt64 (line 31) | func (f *Float4) ScanInt64(n Int8) error {
method Int64Value (line 37) | func (f Float4) Int64Value() (Int8, error) {
method Scan (line 42) | func (f *Float4) Scan(src any) error {
method Value (line 65) | func (f Float4) Value() (driver.Value, error) {
method MarshalJSON (line 73) | func (f Float4) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 81) | func (f *Float4) UnmarshalJSON(b []byte) error {
type Float4Codec (line 97) | type Float4Codec struct
method FormatSupported (line 99) | func (Float4Codec) FormatSupported(format int16) bool {
method PreferredFormat (line 103) | func (Float4Codec) PreferredFormat() int16 {
method PlanEncode (line 107) | func (Float4Codec) PlanEncode(m *Map, oid uint32, format int16, value ...
method PlanScan (line 177) | func (Float4Codec) PlanScan(m *Map, oid uint32, format int16, target a...
method DecodeDatabaseSQLValue (line 299) | func (c Float4Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format...
method DecodeValue (line 312) | func (c Float4Codec) DecodeValue(m *Map, oid uint32, format int16, src...
type encodePlanFloat4CodecBinaryFloat32 (line 132) | type encodePlanFloat4CodecBinaryFloat32 struct
method Encode (line 134) | func (encodePlanFloat4CodecBinaryFloat32) Encode(value any, buf []byte...
type encodePlanTextFloat32 (line 139) | type encodePlanTextFloat32 struct
method Encode (line 141) | func (encodePlanTextFloat32) Encode(value any, buf []byte) (newBuf []b...
type encodePlanFloat4CodecBinaryFloat64Valuer (line 146) | type encodePlanFloat4CodecBinaryFloat64Valuer struct
method Encode (line 148) | func (encodePlanFloat4CodecBinaryFloat64Valuer) Encode(value any, buf ...
type encodePlanFloat4CodecBinaryInt64Valuer (line 161) | type encodePlanFloat4CodecBinaryInt64Valuer struct
method Encode (line 163) | func (encodePlanFloat4CodecBinaryInt64Valuer) Encode(value any, buf []...
type scanPlanBinaryFloat4ToFloat32 (line 204) | type scanPlanBinaryFloat4ToFloat32 struct
method Scan (line 206) | func (scanPlanBinaryFloat4ToFloat32) Scan(src []byte, dst any) error {
type scanPlanBinaryFloat4ToFloat64Scanner (line 222) | type scanPlanBinaryFloat4ToFloat64Scanner struct
method Scan (line 224) | func (scanPlanBinaryFloat4ToFloat64Scanner) Scan(src []byte, dst any) ...
type scanPlanBinaryFloat4ToInt64Scanner (line 239) | type scanPlanBinaryFloat4ToInt64Scanner struct
method Scan (line 241) | func (scanPlanBinaryFloat4ToInt64Scanner) Scan(src []byte, dst any) er...
type scanPlanBinaryFloat4ToTextScanner (line 262) | type scanPlanBinaryFloat4ToTextScanner struct
method Scan (line 264) | func (scanPlanBinaryFloat4ToTextScanner) Scan(src []byte, dst any) err...
type scanPlanTextAnyToFloat32 (line 281) | type scanPlanTextAnyToFloat32 struct
method Scan (line 283) | func (scanPlanTextAnyToFloat32) Scan(src []byte, dst any) error {
FILE: pgtype/float4_test.go
function TestFloat4Codec (line 11) | func TestFloat4Codec(t *testing.T) {
function TestFloat4MarshalJSON (line 25) | func TestFloat4MarshalJSON(t *testing.T) {
function TestFloat4UnmarshalJSON (line 45) | func TestFloat4UnmarshalJSON(t *testing.T) {
FILE: pgtype/float8.go
type Float64Scanner (line 14) | type Float64Scanner interface
type Float64Valuer (line 18) | type Float64Valuer interface
type Float8 (line 22) | type Float8 struct
method ScanFloat64 (line 28) | func (f *Float8) ScanFloat64(n Float8) error {
method Float64Value (line 34) | func (f Float8) Float64Value() (Float8, error) {
method ScanInt64 (line 39) | func (f *Float8) ScanInt64(n Int8) error {
method Int64Value (line 45) | func (f Float8) Int64Value() (Int8, error) {
method Scan (line 50) | func (f *Float8) Scan(src any) error {
method Value (line 73) | func (f Float8) Value() (driver.Value, error) {
method MarshalJSON (line 81) | func (f Float8) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 89) | func (f *Float8) UnmarshalJSON(b []byte) error {
type Float8Codec (line 105) | type Float8Codec struct
method FormatSupported (line 107) | func (Float8Codec) FormatSupported(format int16) bool {
method PreferredFormat (line 111) | func (Float8Codec) PreferredFormat() int16 {
method PlanEncode (line 115) | func (Float8Codec) PlanEncode(m *Map, oid uint32, format int16, value ...
method PlanScan (line 215) | func (Float8Codec) PlanScan(m *Map, oid uint32, format int16, target a...
method DecodeDatabaseSQLValue (line 354) | func (c Float8Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format...
method DecodeValue (line 358) | func (c Float8Codec) DecodeValue(m *Map, oid uint32, format int16, src...
type encodePlanFloat8CodecBinaryFloat64 (line 140) | type encodePlanFloat8CodecBinaryFloat64 struct
method Encode (line 142) | func (encodePlanFloat8CodecBinaryFloat64) Encode(value any, buf []byte...
type encodePlanTextFloat64 (line 147) | type encodePlanTextFloat64 struct
method Encode (line 149) | func (encodePlanTextFloat64) Encode(value any, buf []byte) (newBuf []b...
type encodePlanFloat8CodecBinaryFloat64Valuer (line 154) | type encodePlanFloat8CodecBinaryFloat64Valuer struct
method Encode (line 156) | func (encodePlanFloat8CodecBinaryFloat64Valuer) Encode(value any, buf ...
type encodePlanTextFloat64Valuer (line 169) | type encodePlanTextFloat64Valuer struct
method Encode (line 171) | func (encodePlanTextFloat64Valuer) Encode(value any, buf []byte) (newB...
type encodePlanFloat8CodecBinaryInt64Valuer (line 184) | type encodePlanFloat8CodecBinaryInt64Valuer struct
method Encode (line 186) | func (encodePlanFloat8CodecBinaryInt64Valuer) Encode(value any, buf []...
type encodePlanTextInt64Valuer (line 200) | type encodePlanTextInt64Valuer struct
method Encode (line 202) | func (encodePlanTextInt64Valuer) Encode(value any, buf []byte) (newBuf...
type scanPlanBinaryFloat8ToFloat64 (line 242) | type scanPlanBinaryFloat8ToFloat64 struct
method Scan (line 244) | func (scanPlanBinaryFloat8ToFloat64) Scan(src []byte, dst any) error {
type scanPlanBinaryFloat8ToFloat64Scanner (line 260) | type scanPlanBinaryFloat8ToFloat64Scanner struct
method Scan (line 262) | func (scanPlanBinaryFloat8ToFloat64Scanner) Scan(src []byte, dst any) ...
type scanPlanBinaryFloat8ToInt64Scanner (line 277) | type scanPlanBinaryFloat8ToInt64Scanner struct
method Scan (line 279) | func (scanPlanBinaryFloat8ToInt64Scanner) Scan(src []byte, dst any) er...
type scanPlanBinaryFloat8ToTextScanner (line 300) | type scanPlanBinaryFloat8ToTextScanner struct
method Scan (line 302) | func (scanPlanBinaryFloat8ToTextScanner) Scan(src []byte, dst any) err...
type scanPlanTextAnyToFloat64 (line 319) | type scanPlanTextAnyToFloat64 struct
method Scan (line 321) | func (scanPlanTextAnyToFloat64) Scan(src []byte, dst any) error {
type scanPlanTextAnyToFloat64Scanner (line 337) | type scanPlanTextAnyToFloat64Scanner struct
method Scan (line 339) | func (scanPlanTextAnyToFloat64Scanner) Scan(src []byte, dst any) error {
FILE: pgtype/float8_test.go
function TestFloat8Codec (line 11) | func TestFloat8Codec(t *testing.T) {
function TestFloat8MarshalJSON (line 25) | func TestFloat8MarshalJSON(t *testing.T) {
function TestFloat8UnmarshalJSON (line 45) | func TestFloat8UnmarshalJSON(t *testing.T) {
FILE: pgtype/hstore.go
type HstoreScanner (line 13) | type HstoreScanner interface
type HstoreValuer (line 17) | type HstoreValuer interface
type Hstore (line 23) | type Hstore
method ScanHstore (line 26) | func (h *Hstore) ScanHstore(v Hstore) error {
method HstoreValue (line 32) | func (h Hstore) HstoreValue() (Hstore, error) {
method Scan (line 37) | func (h *Hstore) Scan(src any) error {
method Value (line 52) | func (h Hstore) Value() (driver.Value, error) {
type HstoreCodec (line 64) | type HstoreCodec struct
method FormatSupported (line 66) | func (HstoreCodec) FormatSupported(format int16) bool {
method PreferredFormat (line 70) | func (HstoreCodec) PreferredFormat() int16 {
method PlanEncode (line 74) | func (HstoreCodec) PlanEncode(m *Map, oid uint32, format int16, value ...
method PlanScan (line 166) | func (HstoreCodec) PlanScan(m *Map, oid uint32, format int16, target a...
method DecodeDatabaseSQLValue (line 257) | func (c HstoreCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format...
method DecodeValue (line 261) | func (c HstoreCodec) DecodeValue(m *Map, oid uint32, format int16, src...
type encodePlanHstoreCodecBinary (line 89) | type encodePlanHstoreCodecBinary struct
method Encode (line 91) | func (encodePlanHstoreCodecBinary) Encode(value any, buf []byte) (newB...
type encodePlanHstoreCodecText (line 118) | type encodePlanHstoreCodecText struct
method Encode (line 120) | func (encodePlanHstoreCodecText) Encode(value any, buf []byte) (newBuf...
type scanPlanBinaryHstoreToHstoreScanner (line 183) | type scanPlanBinaryHstoreToHstoreScanner struct
method Scan (line 185) | func (scanPlanBinaryHstoreToHstoreScanner) Scan(src []byte, dst any) e...
type scanPlanTextAnyToHstoreScanner (line 237) | type scanPlanTextAnyToHstoreScanner struct
method Scan (line 239) | func (s scanPlanTextAnyToHstoreScanner) Scan(src []byte, dst any) error {
method scanString (line 249) | func (scanPlanTextAnyToHstoreScanner) scanString(src string, scanner H...
type hstoreParser (line 274) | type hstoreParser struct
method atEnd (line 288) | func (p *hstoreParser) atEnd() bool {
method consume (line 293) | func (p *hstoreParser) consume() (b byte, end bool) {
method consumeExpectedByte (line 307) | func (p *hstoreParser) consumeExpectedByte(expectedB byte) error {
method consumeExpected2 (line 320) | func (p *hstoreParser) consumeExpected2(one, two byte) error {
method consumeDoubleQuoted (line 338) | func (p *hstoreParser) consumeDoubleQuoted() (string, error) {
method consumeDoubleQuotedWithEscapes (line 365) | func (p *hstoreParser) consumeDoubleQuotedWithEscapes(firstBackslash i...
method consumePairSeparator (line 399) | func (p *hstoreParser) consumePairSeparator() error {
method consumeKVSeparator (line 404) | func (p *hstoreParser) consumeKVSeparator() error {
method consumeDoubleQuotedOrNull (line 409) | func (p *hstoreParser) consumeDoubleQuotedOrNull() (Text, error) {
function newHSP (line 280) | func newHSP(in string) *hstoreParser {
function unexpectedByteErr (line 302) | func unexpectedByteErr(actualB, expectedB byte) error {
function parseHstore (line 439) | func parseHstore(s string) (Hstore, error) {
FILE: pgtype/hstore_test.go
function isExpectedEqMapStringString (line 15) | func isExpectedEqMapStringString(a any) func(any) bool {
function isExpectedEqMapStringPointerString (line 34) | func isExpectedEqMapStringPointerString(a any) func(any) bool {
function stringPtr (line 58) | func stringPtr(s string) *string {
function TestHstoreCodec (line 62) | func TestHstoreCodec(t *testing.T) {
function TestParseInvalidInputs (line 249) | func TestParseInvalidInputs(t *testing.T) {
function TestRoundTrip (line 266) | func TestRoundTrip(t *testing.T) {
function BenchmarkHstoreEncode (line 311) | func BenchmarkHstoreEncode(b *testing.B) {
function BenchmarkHstoreScan (line 340) | func BenchmarkHstoreScan(b *testing.B) {
FILE: pgtype/inet.go
constant defaultAFInet (line 15) | defaultAFInet = 2
constant defaultAFInet6 (line 16) | defaul
Condensed preview — 341 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,373K chars).
[
{
"path": ".devcontainer/Dockerfile",
"chars": 339,
"preview": "FROM mcr.microsoft.com/devcontainers/go:2-1.25-trixie\n\nRUN apt-get update && apt-get install -y postgresql-common \\\n "
},
{
"path": ".devcontainer/devcontainer.json",
"chars": 459,
"preview": "{\n\t\"name\": \"pgx\",\n\t\"dockerComposeFile\": \"docker-compose.yml\",\n\t\"service\": \"app\",\n\t\"workspaceFolder\": \"/workspaces/${loca"
},
{
"path": ".devcontainer/docker-compose.yml",
"chars": 6366,
"preview": "volumes:\n postgres-14-data:\n postgres-15-data:\n postgres-16-data:\n postgres-17-data:\n postgres-18-data:\n pg-socket"
},
{
"path": ".devcontainer/post-create.bash",
"chars": 521,
"preview": "#!/bin/bash\nset -e\n\n# Run any additional setup scripts included in the shared/devcontainer directory. This is to allow f"
},
{
"path": ".github/FUNDING.yml",
"chars": 14,
"preview": "github: jackc\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 1261,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the "
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 595,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/ISSUE_TEMPLATE/other-issues.md",
"chars": 232,
"preview": "---\nname: Other issues\nabout: Any issue that is not a bug or a feature request\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n"
},
{
"path": ".github/workflows/ci.yml",
"chars": 10678,
"preview": "name: CI\n\non:\n push:\n branches: [master]\n pull_request:\n branches: [master]\n\njobs:\n test:\n name: Test\n ru"
},
{
"path": ".gitignore",
"chars": 280,
"preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture spe"
},
{
"path": ".golangci.yml",
"chars": 680,
"preview": "# See for configurations: https://golangci-lint.run/usage/configuration/\nversion: \"2\"\n\nlinters:\n default: none\n enable"
},
{
"path": "CHANGELOG.md",
"chars": 26100,
"preview": "# 5.8.0 (December 26, 2025)\n\n* Require Go 1.24+\n* Remove golang.org/x/crypto dependency\n* Add OptionShouldPing to contro"
},
{
"path": "CLAUDE.md",
"chars": 3843,
"preview": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## "
},
{
"path": "CONTRIBUTING.md",
"chars": 6165,
"preview": "# Contributing\n\n## Discuss Significant Changes\n\nBefore you invest a significant amount of time on a change, please creat"
},
{
"path": "LICENSE",
"chars": 1078,
"preview": "Copyright (c) 2013-2021 Jack Christensen\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtai"
},
{
"path": "README.md",
"chars": 8146,
"preview": "[](https://pkg.go.dev/github.com/jackc/pgx/v5)\n[![B"
},
{
"path": "Rakefile",
"chars": 463,
"preview": "require \"erb\"\n\nrule '.go' => '.go.erb' do |task|\n erb = ERB.new(File.read(task.source))\n File.write(task.name, \"// Cod"
},
{
"path": "batch.go",
"chars": 14822,
"preview": "package pgx\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/jackc/pgx/v5/pgconn\"\n)\n\n// QueuedQuery is a query that h"
},
{
"path": "batch_test.go",
"chars": 33422,
"preview": "package pgx_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5\""
},
{
"path": "bench_test.go",
"chars": 36678,
"preview": "package pgx_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"git"
},
{
"path": "ci/setup_test.bash",
"chars": 2865,
"preview": "#!/usr/bin/env bash\nset -eux\n\nif [[ \"${PGVERSION-}\" =~ ^[0-9.]+$ ]]\nthen\n sudo apt-get remove -y --purge postgresql lib"
},
{
"path": "conn.go",
"chars": 47548,
"preview": "package pgx\n\nimport (\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"database/sql\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\""
},
{
"path": "conn_internal_test.go",
"chars": 1527,
"preview": "package pgx\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/te"
},
{
"path": "conn_test.go",
"chars": 52312,
"preview": "package pgx_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"database/sql\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n"
},
{
"path": "copy_from.go",
"chars": 7267,
"preview": "package pgx\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n\t\"github.com/jackc/pgx/"
},
{
"path": "copy_from_test.go",
"chars": 25666,
"preview": "package pgx_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5\"\n\t\"github.co"
},
{
"path": "derived_types.go",
"chars": 9748,
"preview": "package pgx\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/jackc/pgx/v5/pgtype\"\n)\n\n/*\nbuildLo"
},
{
"path": "derived_types_test.go",
"chars": 1224,
"preview": "package pgx_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nf"
},
{
"path": "doc.go",
"chars": 7179,
"preview": "// Package pgx is a PostgreSQL database driver.\n/*\npgx provides a native PostgreSQL driver and can act as a database/sql"
},
{
"path": "examples/README.md",
"chars": 378,
"preview": "# Examples\n\n* chat is a command line chat program using listen/notify.\n* todo is a command line todo list that demonstra"
},
{
"path": "examples/chat/README.md",
"chars": 551,
"preview": "# Description\n\nThis is a sample chat program implemented using PostgreSQL's listen/notify\nfunctionality with pgx.\n\nStart"
},
{
"path": "examples/chat/main.go",
"chars": 1562,
"preview": "package main\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/jackc/pgx/v5/pgxpool\"\n)\n\nvar pool *pgxpool.Pool\n\nf"
},
{
"path": "examples/todo/README.md",
"chars": 1868,
"preview": "# Description\n\nThis is a sample todo list implemented using pgx as the connector to a\nPostgreSQL data store.\n\n# Usage\n\nC"
},
{
"path": "examples/todo/main.go",
"chars": 2331,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/jackc/pgx/v5\"\n)\n\nvar conn *pgx.Conn\n\nfunc main()"
},
{
"path": "examples/todo/structure.sql",
"chars": 77,
"preview": "create table tasks (\n id serial primary key,\n description text not null\n);\n"
},
{
"path": "examples/url_shortener/README.md",
"chars": 642,
"preview": "# Description\n\nThis is a sample REST URL shortener service implemented using pgx as the connector to a PostgreSQL data s"
},
{
"path": "examples/url_shortener/main.go",
"chars": 2233,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/jackc/pgx/v5\"\n\t\"github.com/jackc/pgx/v5/p"
},
{
"path": "examples/url_shortener/structure.sql",
"chars": 75,
"preview": "create table shortened_urls (\n id text primary key,\n url text not null\n);"
},
{
"path": "extended_query_builder.go",
"chars": 3895,
"preview": "package pgx\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/jackc/pgx/v5/pgconn\"\n\t\"github.com/jackc/pgx/v5/pgtype\"\n)\n\n// ExtendedQueryBui"
},
{
"path": "go.mod",
"chars": 538,
"preview": "module github.com/jackc/pgx/v5\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/jackc/pgpassfile v1.0.0\n\tgithub.com/jackc/pgservicefile"
},
{
"path": "go.sum",
"chars": 3437,
"preview": "github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/davecgh/go-spew v1.1.0/go"
},
{
"path": "helper_test.go",
"chars": 5127,
"preview": "package pgx_test\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/jackc/pgx/v5"
},
{
"path": "internal/faultyconn/faultyconn.go",
"chars": 2626,
"preview": "package faultyconn\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n)\n\n// Conn is a wrapper "
},
{
"path": "internal/iobufpool/iobufpool.go",
"chars": 1429,
"preview": "// Package iobufpool implements a global segregated-fit pool of buffers for IO.\n//\n// It uses *[]byte instead of []byte "
},
{
"path": "internal/iobufpool/iobufpool_internal_test.go",
"chars": 785,
"preview": "package iobufpool\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestPoolIdx(t *testing.T) {\n\ttests"
},
{
"path": "internal/iobufpool/iobufpool_test.go",
"chars": 2778,
"preview": "package iobufpool_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/internal/iobufpool\"\n\t\"github.com/stretchr/testify"
},
{
"path": "internal/pgio/README.md",
"chars": 190,
"preview": "# pgio\n\nPackage pgio is a low-level toolkit building messages in the PostgreSQL wire protocol.\n\npgio provides functions "
},
{
"path": "internal/pgio/doc.go",
"chars": 203,
"preview": "// Package pgio is a low-level toolkit building messages in the PostgreSQL wire protocol.\n/*\npgio provides functions for"
},
{
"path": "internal/pgio/write.go",
"chars": 785,
"preview": "package pgio\n\nfunc AppendUint16(buf []byte, n uint16) []byte {\n\treturn append(buf, byte(n>>8), byte(n))\n}\n\nfunc AppendUi"
},
{
"path": "internal/pgio/write_test.go",
"chars": 2153,
"preview": "package pgio\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestAppendUint16NilBuf(t *testing.T) {\n\tbuf := AppendUint16(nil, 1)"
},
{
"path": "internal/pgmock/pgmock.go",
"chars": 2742,
"preview": "// Package pgmock provides the ability to mock a PostgreSQL server.\npackage pgmock\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\n\t\""
},
{
"path": "internal/pgmock/pgmock_test.go",
"chars": 2402,
"preview": "package pgmock_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/internal"
},
{
"path": "internal/sanitize/benchmark.sh",
"chars": 1506,
"preview": "#!/usr/bin/env bash\n\ncurrent_branch=$(git rev-parse --abbrev-ref HEAD)\nif [ \"$current_branch\" == \"HEAD\" ]; then\n curr"
},
{
"path": "internal/sanitize/sanitize.go",
"chars": 9474,
"preview": "package sanitize\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"slices\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\t\"unicode/utf"
},
{
"path": "internal/sanitize/sanitize_bench_test.go",
"chars": 1309,
"preview": "// sanitize_benchmark_test.go\npackage sanitize_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/internal/san"
},
{
"path": "internal/sanitize/sanitize_fuzz_test.go",
"chars": 1132,
"preview": "package sanitize_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/internal/sanitize\"\n)\n\nfunc FuzzQuoteStr"
},
{
"path": "internal/sanitize/sanitize_test.go",
"chars": 8019,
"preview": "package sanitize_test\n\nimport (\n\t\"encoding/hex\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/internal/saniti"
},
{
"path": "internal/stmtcache/lru_cache.go",
"chars": 4375,
"preview": "package stmtcache\n\nimport (\n\t\"github.com/jackc/pgx/v5/pgconn\"\n)\n\n// lruNode is a typed doubly-linked list node with free"
},
{
"path": "internal/stmtcache/stmtcache.go",
"chars": 1600,
"preview": "// Package stmtcache is a cache for statement descriptions.\npackage stmtcache\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\""
},
{
"path": "large_objects.go",
"chars": 4605,
"preview": "package pgx\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/jackc/pgx/v5/pgtype\"\n)\n\n// The PostgreSQL wire protocol h"
},
{
"path": "large_objects_private_test.go",
"chars": 457,
"preview": "package pgx\n\nimport (\n\t\"testing\"\n)\n\n// SetMaxLargeObjectMessageLength sets internal maxLargeObjectMessageLength variable"
},
{
"path": "large_objects_test.go",
"chars": 5899,
"preview": "package pgx_test\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5\"\n\t\"github.com/jackc/pgx/"
},
{
"path": "log/testingadapter/adapter.go",
"chars": 720,
"preview": "// Package testingadapter provides a logger that writes to a test or benchmark\n// log.\npackage testingadapter\n\nimport (\n"
},
{
"path": "multitracer/tracer.go",
"chars": 4531,
"preview": "// Package multitracer provides a Tracer that can combine several tracers into one.\npackage multitracer\n\nimport (\n\t\"cont"
},
{
"path": "multitracer/tracer_test.go",
"chars": 3212,
"preview": "package multitracer_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5\"\n\t\"github.com/jackc/pgx/v5/multitrac"
},
{
"path": "named_args.go",
"chars": 6947,
"preview": "package pgx\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// NamedArgs can be used as the first a"
},
{
"path": "named_args_test.go",
"chars": 4533,
"preview": "package pgx_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"git"
},
{
"path": "pgbouncer_test.go",
"chars": 2079,
"preview": "package pgx_test\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5\"\n\t\"github.com/stretchr/testify/assert\""
},
{
"path": "pgconn/README.md",
"chars": 985,
"preview": "# pgconn\n\nPackage pgconn is a low-level PostgreSQL database driver. It operates at nearly the same level as the C librar"
},
{
"path": "pgconn/auth_oauth.go",
"chars": 1882,
"preview": "package pgconn\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n)\n\nfunc (c *P"
},
{
"path": "pgconn/auth_scram.go",
"chars": 13015,
"preview": "// SCRAM-SHA-256 and SCRAM-SHA-256-PLUS authentication\n//\n// Resources:\n// https://tools.ietf.org/html/rfc5802\n// ht"
},
{
"path": "pgconn/auth_scram_test.go",
"chars": 11498,
"preview": "package pgconn\n\nimport (\n\t\"bytes\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\""
},
{
"path": "pgconn/benchmark_private_test.go",
"chars": 1420,
"preview": "package pgconn\n\nimport (\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc BenchmarkCommandTagRowsAffected(b *testing.B) {\n\tbenchmarks := []"
},
{
"path": "pgconn/benchmark_test.go",
"chars": 5874,
"preview": "package pgconn_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgconn\"\n\t\"github.com/stret"
},
{
"path": "pgconn/config.go",
"chars": 33121,
"preview": "package pgconn\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"maps\"\n\t\"math\"\n"
},
{
"path": "pgconn/config_test.go",
"chars": 38142,
"preview": "package pgconn_test\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/user\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\""
},
{
"path": "pgconn/ctxwatch/context_watcher.go",
"chars": 1942,
"preview": "package ctxwatch\n\nimport (\n\t\"context\"\n\t\"sync\"\n)\n\n// ContextWatcher watches a context and performs an action when the con"
},
{
"path": "pgconn/ctxwatch/context_watcher_test.go",
"chars": 4942,
"preview": "package ctxwatch_test\n\nimport (\n\t\"context\"\n\t\"sync/atomic\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/pgconn/ctxwatch\""
},
{
"path": "pgconn/ctxwatch/synctest_test.go",
"chars": 1308,
"preview": "//go:build go1.26\n\npackage ctxwatch_test\n\nimport (\n\t\"context\"\n\t\"runtime\"\n\t\"sync/atomic\"\n\t\"testing\"\n\t\"testing/synctest\"\n\n"
},
{
"path": "pgconn/defaults.go",
"chars": 1899,
"preview": "//go:build !windows\n// +build !windows\n\npackage pgconn\n\nimport (\n\t\"os\"\n\t\"os/user\"\n\t\"path/filepath\"\n)\n\nfunc defaultSettin"
},
{
"path": "pgconn/defaults_windows.go",
"chars": 1930,
"preview": "package pgconn\n\nimport (\n\t\"os\"\n\t\"os/user\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nfunc defaultSettings() map[string]string {\n\tset"
},
{
"path": "pgconn/doc.go",
"chars": 1845,
"preview": "// Package pgconn is a low-level PostgreSQL database driver.\n/*\npgconn provides lower level access to a PostgreSQL conne"
},
{
"path": "pgconn/errors.go",
"chars": 7130,
"preview": "package pgconn\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// SafeToRetry checks if "
},
{
"path": "pgconn/errors_test.go",
"chars": 1707,
"preview": "package pgconn_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgconn\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfun"
},
{
"path": "pgconn/export_test.go",
"chars": 77,
"preview": "// File export_test exports some methods for better testing.\n\npackage pgconn\n"
},
{
"path": "pgconn/helper_test.go",
"chars": 1024,
"preview": "package pgconn_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/pgconn\"\n\n\t\"github.com/stretchr/te"
},
{
"path": "pgconn/internal/bgreader/bgreader.go",
"chars": 2950,
"preview": "// Package bgreader provides a io.Reader that can optionally buffer reads in the background.\npackage bgreader\n\nimport (\n"
},
{
"path": "pgconn/internal/bgreader/bgreader_test.go",
"chars": 3345,
"preview": "package bgreader_test\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"math/rand/v2\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/p"
},
{
"path": "pgconn/krb5.go",
"chars": 2342,
"preview": "package pgconn\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n)\n\n// NewGSSFunc creates a GSS authentica"
},
{
"path": "pgconn/pgconn.go",
"chars": 95015,
"preview": "package pgconn\n\nimport (\n\t\"container/list\"\n\t\"context\"\n\t\"crypto/md5\"\n\t\"crypto/tls\"\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"e"
},
{
"path": "pgconn/pgconn_private_test.go",
"chars": 1552,
"preview": "package pgconn\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCommandTag(t *testing.T) {\n\tt.Par"
},
{
"path": "pgconn/pgconn_stress_test.go",
"chars": 2570,
"preview": "package pgconn_test\n\nimport (\n\t\"context\"\n\t\"math/rand/v2\"\n\t\"os\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/"
},
{
"path": "pgconn/pgconn_test.go",
"chars": 143085,
"preview": "package pgconn_test\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"math\"\n\t"
},
{
"path": "pgproto3/README.md",
"chars": 282,
"preview": "# pgproto3\n\nPackage pgproto3 is an encoder and decoder of the PostgreSQL wire protocol version 3.\n\npgproto3 can be used "
},
{
"path": "pgproto3/authentication_cleartext_password.go",
"chars": 1552,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\n//"
},
{
"path": "pgproto3/authentication_gss.go",
"chars": 1121,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\nty"
},
{
"path": "pgproto3/authentication_gss_continue.go",
"chars": 1307,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\nty"
},
{
"path": "pgproto3/authentication_md5_password.go",
"chars": 1984,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\n//"
},
{
"path": "pgproto3/authentication_ok.go",
"chars": 1398,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\n//"
},
{
"path": "pgproto3/authentication_sasl.go",
"chars": 2015,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pg"
},
{
"path": "pgproto3/authentication_sasl_continue.go",
"chars": 1959,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\n//"
},
{
"path": "pgproto3/authentication_sasl_final.go",
"chars": 1947,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\n//"
},
{
"path": "pgproto3/backend.go",
"chars": 7533,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Backend acts as a server for the PostgreSQL wi"
},
{
"path": "pgproto3/backend_key_data.go",
"chars": 1827,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\""
},
{
"path": "pgproto3/backend_key_data_test.go",
"chars": 2309,
"preview": "package pgproto3\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nf"
},
{
"path": "pgproto3/backend_test.go",
"chars": 3758,
"preview": "package pgproto3_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n\t\"github.com/jackc/pgx/v5/pgp"
},
{
"path": "pgproto3/big_endian.go",
"chars": 663,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n)\n\ntype BigEndianBuf [8]byte\n\nfunc (b BigEndianBuf) Int16(n int16) []byte "
},
{
"path": "pgproto3/bind.go",
"chars": 5898,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\n\t\"gith"
},
{
"path": "pgproto3/bind_complete.go",
"chars": 944,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype BindComplete struct{}\n\n// Backend identifies this message as sendabl"
},
{
"path": "pgproto3/bind_test.go",
"chars": 1395,
"preview": "package pgproto3_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n\t\"github.com/stretchr/testify/require\"\n)"
},
{
"path": "pgproto3/cancel_request.go",
"chars": 1979,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/inte"
},
{
"path": "pgproto3/cancel_request_test.go",
"chars": 3599,
"preview": "package pgproto3\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nf"
},
{
"path": "pgproto3/chunkreader.go",
"chars": 2674,
"preview": "package pgproto3\n\nimport (\n\t\"io\"\n\n\t\"github.com/jackc/pgx/v5/internal/iobufpool\"\n)\n\n// chunkReader is a io.Reader wrapper"
},
{
"path": "pgproto3/chunkreader_test.go",
"chars": 1606,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"math/rand/v2\"\n\t\"testing\"\n)\n\nfunc TestChunkReaderNextDoesNotReadIfAlreadyBuffered(t"
},
{
"path": "pgproto3/close.go",
"chars": 1894,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n)\n\ntype Close struct {\n\tObjectType byte // 'S' = prepared"
},
{
"path": "pgproto3/close_complete.go",
"chars": 951,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype CloseComplete struct{}\n\n// Backend identifies this message as sendab"
},
{
"path": "pgproto3/command_complete.go",
"chars": 1715,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n)\n\ntype CommandComplete struct {\n\tCommandTag []byte\n}\n\n// Backend i"
},
{
"path": "pgproto3/copy_both_response.go",
"chars": 2540,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math\"\n\n\t\"github.com/jackc/pgx/v5/int"
},
{
"path": "pgproto3/copy_both_response_test.go",
"chars": 586,
"preview": "package pgproto3_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n\t\"github.com/stretchr/testify/assert\"\n\t\""
},
{
"path": "pgproto3/copy_data.go",
"chars": 1413,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/hex\"\n\t\"encoding/json\"\n)\n\ntype CopyData struct {\n\tData []byte\n}\n\n// Backend identif"
},
{
"path": "pgproto3/copy_done.go",
"chars": 1022,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype CopyDone struct{}\n\n// Backend identifies this message as sendable by"
},
{
"path": "pgproto3/copy_fail.go",
"chars": 1191,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n)\n\ntype CopyFail struct {\n\tMessage string\n}\n\n// Frontend identifies"
},
{
"path": "pgproto3/copy_in_response.go",
"chars": 2519,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math\"\n\n\t\"github.com/jackc/pgx/v5/int"
},
{
"path": "pgproto3/copy_out_response.go",
"chars": 2457,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math\"\n\n\t\"github.com/jackc/pgx/v5/int"
},
{
"path": "pgproto3/data_row.go",
"chars": 3246,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math\"\n\n\t\"github.com/jackc/pgx"
},
{
"path": "pgproto3/describe.go",
"chars": 1923,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n)\n\ntype Describe struct {\n\tObjectType byte // 'S' = prepa"
},
{
"path": "pgproto3/doc.go",
"chars": 688,
"preview": "// Package pgproto3 is an encoder and decoder of the PostgreSQL wire protocol version 3.\n//\n// The primary interfaces ar"
},
{
"path": "pgproto3/empty_query_response.go",
"chars": 986,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype EmptyQueryResponse struct{}\n\n// Backend identifies this message as s"
},
{
"path": "pgproto3/error_response.go",
"chars": 7804,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"strconv\"\n)\n\ntype ErrorResponse struct {\n\tSeverity stri"
},
{
"path": "pgproto3/example/pgfortune/README.md",
"chars": 1499,
"preview": "# pgfortune\n\npgfortune is a mock PostgreSQL server that responds to every query with a fortune.\n\n## Installation\n\nInstal"
},
{
"path": "pgproto3/example/pgfortune/main.go",
"chars": 1071,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\"os/exec\"\n)\n\nvar options struct {\n\tlistenAddress string\n\tre"
},
{
"path": "pgproto3/example/pgfortune/server.go",
"chars": 2673,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n)\n\ntype PgFortuneBackend struct {\n\tbackend *"
},
{
"path": "pgproto3/execute.go",
"chars": 1369,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\ntyp"
},
{
"path": "pgproto3/flush.go",
"chars": 896,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype Flush struct{}\n\n// Frontend identifies this message as sendable by a"
},
{
"path": "pgproto3/frontend.go",
"chars": 12562,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Frontend acts as a client for the Po"
},
{
"path": "pgproto3/frontend_test.go",
"chars": 3071,
"preview": "package pgproto3_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n\t\"github.com/stretchr/testify/asse"
},
{
"path": "pgproto3/function_call.go",
"chars": 4140,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"math\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\ntype Functi"
},
{
"path": "pgproto3/function_call_decode_test.go",
"chars": 836,
"preview": "package pgproto3_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n\t\"github.com/stretchr/testify/require\"\n)"
},
{
"path": "pgproto3/function_call_response.go",
"chars": 2319,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\""
},
{
"path": "pgproto3/function_call_response_test.go",
"chars": 1075,
"preview": "package pgproto3_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n\t\"github.com/stretchr/testify/require\"\n)"
},
{
"path": "pgproto3/function_call_test.go",
"chars": 1923,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc Test"
},
{
"path": "pgproto3/fuzz_test.go",
"chars": 7950,
"preview": "package pgproto3_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n\t\"github.com/jackc/pgx/v5/"
},
{
"path": "pgproto3/gss_enc_request.go",
"chars": 1073,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\nco"
},
{
"path": "pgproto3/gss_response.go",
"chars": 899,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype GSSResponse struct {\n\tData []byte\n}\n\n// Frontend identifies this mes"
},
{
"path": "pgproto3/json_test.go",
"chars": 19076,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestJSONUnmarshalAuthenticatio"
},
{
"path": "pgproto3/negotiate_protocol_version.go",
"chars": 2823,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\ntype Negotia"
},
{
"path": "pgproto3/negotiate_protocol_version_test.go",
"chars": 2325,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/test"
},
{
"path": "pgproto3/no_data.go",
"chars": 902,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype NoData struct{}\n\n// Backend identifies this message as sendable by t"
},
{
"path": "pgproto3/notice_response.go",
"chars": 722,
"preview": "package pgproto3\n\ntype NoticeResponse ErrorResponse\n\n// Backend identifies this message as sendable by the PostgreSQL ba"
},
{
"path": "pgproto3/notification_response.go",
"chars": 1750,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\ntyp"
},
{
"path": "pgproto3/parameter_description.go",
"chars": 1834,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math\"\n\n\t\"github.com/jackc/pgx/v5/int"
},
{
"path": "pgproto3/parameter_status.go",
"chars": 1345,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n)\n\ntype ParameterStatus struct {\n\tName string\n\tValue string\n}\n\n// "
},
{
"path": "pgproto3/parse.go",
"chars": 2083,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math\"\n\n\t\"github.com/jackc/pgx/v5/int"
},
{
"path": "pgproto3/parse_complete.go",
"chars": 951,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype ParseComplete struct{}\n\n// Backend identifies this message as sendab"
},
{
"path": "pgproto3/password_message.go",
"chars": 1253,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n)\n\ntype PasswordMessage struct {\n\tPassword string\n}\n\n// Frontend id"
},
{
"path": "pgproto3/pgproto3.go",
"chars": 3478,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\n// maxMessageBo"
},
{
"path": "pgproto3/pgproto3_private_test.go",
"chars": 62,
"preview": "package pgproto3\n\nconst MaxMessageBodyLen = maxMessageBodyLen\n"
},
{
"path": "pgproto3/portal_suspended.go",
"chars": 965,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype PortalSuspended struct{}\n\n// Backend identifies this message as send"
},
{
"path": "pgproto3/query.go",
"chars": 1153,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n)\n\ntype Query struct {\n\tString string\n}\n\n// Frontend identifies thi"
},
{
"path": "pgproto3/query_test.go",
"chars": 545,
"preview": "package pgproto3_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n\t\"github.com/stretchr/testify/require\"\n)"
},
{
"path": "pgproto3/ready_for_query.go",
"chars": 1537,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n)\n\ntype ReadyForQuery struct {\n\tTxStatus byte\n}\n\n// Backend identi"
},
{
"path": "pgproto3/row_description.go",
"chars": 4422,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math\"\n\n\t\"github.com/jackc/pgx/v5/int"
},
{
"path": "pgproto3/sasl_initial_response.go",
"chars": 2207,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\""
},
{
"path": "pgproto3/sasl_response.go",
"chars": 1342,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/hex\"\n\t\"encoding/json\"\n)\n\ntype SASLResponse struct {\n\tData []byte\n}\n\n// Frontend id"
},
{
"path": "pgproto3/ssl_request.go",
"chars": 1040,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\nco"
},
{
"path": "pgproto3/startup_message.go",
"chars": 2525,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/jackc/pgx/v5/inte"
},
{
"path": "pgproto3/sync.go",
"chars": 889,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype Sync struct{}\n\n// Frontend identifies this message as sendable by a "
},
{
"path": "pgproto3/terminate.go",
"chars": 924,
"preview": "package pgproto3\n\nimport (\n\t\"encoding/json\"\n)\n\ntype Terminate struct{}\n\n// Frontend identifies this message as sendable "
},
{
"path": "pgproto3/testdata/fuzz/FuzzFrontend/39c5e864da4707fc15fea48f7062d6a07796fdc43b33e0ba9dbd7074a0211fa6",
"chars": 48,
"preview": "go test fuzz v1\nbyte('A')\nuint32(5)\n[]byte(\"0\")\n"
},
{
"path": "pgproto3/testdata/fuzz/FuzzFrontend/9b06792b1aaac8a907dbfa04d526ae14326c8573b7409032caac8461e83065f7",
"chars": 68,
"preview": "go test fuzz v1\nbyte('D')\nuint32(21)\n[]byte(\"00\\xb300000000000000\")\n"
},
{
"path": "pgproto3/testdata/fuzz/FuzzFrontend/a661fb98e802839f0a7361160fbc6e28794612a411d00bde104364ee281c4214",
"chars": 48,
"preview": "go test fuzz v1\nbyte('C')\nuint32(4)\n[]byte(\"0\")\n"
},
{
"path": "pgproto3/testdata/fuzz/FuzzFrontend/fc98dcd487a5173b38763a5f7dd023933f3a86ab566e3f2b091eb36248107eb4",
"chars": 159,
"preview": "go test fuzz v1\nbyte('R')\nuint32(13)\n[]byte(\"\\x00\\x00\\x00\\n0\\x12\\xebG\\x8dI']G\\xdac\\x95\\xb7\\x18\\xb0\\x02\\xe8m\\xc2\\x00\\xef\\"
},
{
"path": "pgproto3/trace.go",
"chars": 14236,
"preview": "package pgproto3\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n// tracer traces the messages "
},
{
"path": "pgproto3/trace_test.go",
"chars": 1304,
"preview": "package pgproto3_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/pgconn\"\n\t\"github"
},
{
"path": "pgtype/array.go",
"chars": 9677,
"preview": "package pgtype\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/jackc/p"
},
{
"path": "pgtype/array_codec.go",
"chars": 10154,
"preview": "package pgtype\n\nimport (\n\t\"database/sql/driver\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/jackc/pgx/v5/internal"
},
{
"path": "pgtype/array_codec_test.go",
"chars": 10804,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"encoding/hex\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\n\tpgx \"github.com/jackc/pgx/v5"
},
{
"path": "pgtype/array_test.go",
"chars": 3008,
"preview": "package pgtype\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestParseUntypedTextArray(t *testing.T) {\n\ttests := []struct {\n\t\t"
},
{
"path": "pgtype/bits.go",
"chars": 4305,
"preview": "package pgtype\n\nimport (\n\t\"database/sql/driver\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\nt"
},
{
"path": "pgtype/bits_test.go",
"chars": 2081,
"preview": "package pgtype_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgtype\"\n\t\"github.com/jackc/pgx/v"
},
{
"path": "pgtype/bool.go",
"chars": 6654,
"preview": "package pgtype\n\nimport (\n\t\"bytes\"\n\t\"database/sql/driver\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype BoolScann"
},
{
"path": "pgtype/bool_test.go",
"chars": 1805,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgtype\"\n\t\"github.com/jackc/pgx/v5/pgxtest"
},
{
"path": "pgtype/box.go",
"chars": 4925,
"preview": "package pgtype\n\nimport (\n\t\"database/sql/driver\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/ja"
},
{
"path": "pgtype/box_test.go",
"chars": 1029,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgtype\"\n\t\"github.com/jackc/pgx/v5/pgxtest"
},
{
"path": "pgtype/builtin_wrappers.go",
"chars": 22173,
"preview": "package pgtype\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/big\"\n\t\"net\"\n\t\"net/netip\"\n\t\"reflect\"\n\t\"time\"\n)\n\ntype int8Wrapper"
},
{
"path": "pgtype/bytea.go",
"chars": 5657,
"preview": "package pgtype\n\nimport (\n\t\"database/sql/driver\"\n\t\"encoding/hex\"\n\t\"fmt\"\n)\n\ntype BytesScanner interface {\n\t// ScanBytes re"
},
{
"path": "pgtype/bytea_test.go",
"chars": 3956,
"preview": "package pgtype_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\n\tpgx \"github.com/jackc/pgx/v5\"\n\t\"github.com/jackc/p"
},
{
"path": "pgtype/circle.go",
"chars": 4793,
"preview": "package pgtype\n\nimport (\n\t\"database/sql/driver\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/ja"
},
{
"path": "pgtype/circle_test.go",
"chars": 964,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/jackc/pgx/v5/pgtype\"\n\t\"github.com/jackc/pgx/v5/pgxtest"
},
{
"path": "pgtype/composite.go",
"chars": 13966,
"preview": "package pgtype\n\nimport (\n\t\"database/sql/driver\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/jackc/pgx/v"
},
{
"path": "pgtype/composite_test.go",
"chars": 9821,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\n\tpgx \"github.com/jackc/pgx/v5\"\n\t\"github.com/jackc/pgx/v5/pgt"
},
{
"path": "pgtype/convert.go",
"chars": 3213,
"preview": "package pgtype\n\nimport (\n\t\"reflect\"\n)\n\nfunc NullAssignTo(dst any) error {\n\tdstPtr := reflect.ValueOf(dst)\n\n\t// AssignTo "
},
{
"path": "pgtype/date.go",
"chars": 9009,
"preview": "package pgtype\n\nimport (\n\t\"database/sql/driver\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github."
},
{
"path": "pgtype/date_test.go",
"chars": 12974,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/pgtype\"\n\t\"github.com/jackc/pgx/v5"
},
{
"path": "pgtype/derived_types_test.go",
"chars": 1830,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\tpgx \"github.com/jackc/pgx/v5\"\n\t\"github.com/jackc/pgx/v5/pgtype\"\n\t\""
},
{
"path": "pgtype/doc.go",
"chars": 9478,
"preview": "// Package pgtype converts between Go and PostgreSQL values.\n/*\nThe primary type is the Map type. It is a map of Postgre"
},
{
"path": "pgtype/enum_codec.go",
"chars": 2778,
"preview": "package pgtype\n\nimport (\n\t\"database/sql/driver\"\n\t\"fmt\"\n)\n\n// EnumCodec is a codec that caches the strings it decodes. If"
},
{
"path": "pgtype/enum_codec_test.go",
"chars": 1863,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\tpgx \"github.com/jackc/pgx/v5\"\n\t\"github.com/stretchr/testify/requir"
},
{
"path": "pgtype/example_child_records_test.go",
"chars": 2107,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5\"\n)\n\ntype Player struct {\n\tName "
},
{
"path": "pgtype/example_custom_type_test.go",
"chars": 1520,
"preview": "package pgtype_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/jackc/pgx/v5\"\n\t\"github.com/jackc/pgx/v5/pgtype\"\n)\n\n/"
}
]
// ... and 141 more files (download for full content)
About this extraction
This page contains the full source code of the jackc/pgx GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 341 files (2.1 MB), approximately 556.3k tokens, and a symbol index with 4383 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.