package pgx

import (
	
	
	
	
	
	

	
	
	
	
	
)
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.
Original connection string that was parsed into config.
BuildStatementCache creates the stmtcache.Cache implementation for connections created with this config. Set to nil to disable automatic prepared statements.
PreferSimpleProtocol disables implicit prepared statement usage. By default pgx automatically uses the extended protocol. This can improve performance due to being able to use the binary format. It also does not rely on client side parameter sanitization. However, it does incur two round-trips per query (unless using a prepared statement) and may be incompatible proxies such as PGBouncer. Setting PreferSimpleProtocol causes the simple protocol to be used by default. The same functionality can be controlled on a per query basis by setting QueryExOptions.SimpleProtocol.
	PreferSimpleProtocol bool

	createdByParseConfig bool // Used to enforce created by ParseConfig rule.
}
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 ( *ConnConfig) () *ConnConfig {
	 := new(ConnConfig)
	* = *
	.Config = *.Config.Copy()
	return 
}

func ( *ConnConfig) () string { return .connString }
BuildStatementCacheFunc is a function that can be used to create a stmtcache.Cache implementation for connection.
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.
Identifier a PostgreSQL identifier or name. Identifiers can be composed of multiple parts such as ["schema", "table"] or ["table", "column"].
Sanitize returns a sanitized string safe for SQL interpolation.
func ( Identifier) () string {
	 := make([]string, len())
	for  := range  {
		 := strings.ReplaceAll([], string([]byte{0}), "")
		[] = `"` + strings.ReplaceAll(, `"`, `""`) + `"`
	}
	return strings.Join(, ".")
}
ErrNoRows occurs when rows are expected but none are returned.
var ErrNoRows = errors.New("no rows in result set")
ErrInvalidLogLevel occurs on attempt to set an invalid log level.
var ErrInvalidLogLevel = errors.New("invalid log level")
Connect establishes a connection with a PostgreSQL server with a connection string. See pgconn.Connect for details.
func ( context.Context,  string) (*Conn, error) {
	,  := ParseConfig()
	if  != nil {
		return nil, 
	}
	return connect(, )
}
Connect establishes a connection with a PostgreSQL server with a configuration struct. connConfig must have been created by ParseConfig.
func ( context.Context,  *ConnConfig) (*Conn, error) {
	return connect(, )
}
ParseConfig creates a ConnConfig from a connection string. ParseConfig handles all options that pgconn.ParseConfig does. In addition, it accepts the following options: statement_cache_capacity The maximum size of the automatic statement cache. Set to 0 to disable automatic statement caching. Default: 512. statement_cache_mode Possible values: "prepare" and "describe". "prepare" will create prepared statements on the PostgreSQL server. "describe" will use the anonymous prepared statement to describe a statement without creating a statement on the server. "describe" is primarily useful when the environment does not allow prepared statements such as when running a connection pooler like PgBouncer. Default: "prepare" prefer_simple_protocol Possible values: "true" and "false". Use the simple protocol instead of extended protocol. Default: false
func ( string) (*ConnConfig, error) {
	,  := pgconn.ParseConfig()
	if  != nil {
		return nil, 
	}

	var  BuildStatementCacheFunc
	 := 512
	 := stmtcache.ModePrepare
	if ,  := .RuntimeParams["statement_cache_capacity"];  {
		delete(.RuntimeParams, "statement_cache_capacity")
		,  := strconv.ParseInt(, 10, 32)
		if  != nil {
			return nil, fmt.Errorf("cannot parse statement_cache_capacity: %w", )
		}
		 = int()
	}

	if ,  := .RuntimeParams["statement_cache_mode"];  {
		delete(.RuntimeParams, "statement_cache_mode")
		switch  {
		case "prepare":
			 = stmtcache.ModePrepare
		case "describe":
			 = stmtcache.ModeDescribe
		default:
			return nil, fmt.Errorf("invalid statement_cache_mod: %s", )
		}
	}

	if  > 0 {
		 = func( *pgconn.PgConn) stmtcache.Cache {
			return stmtcache.New(, , )
		}
	}

	 := false
	if ,  := .RuntimeParams["prefer_simple_protocol"];  {
		delete(.RuntimeParams, "prefer_simple_protocol")
		if ,  := strconv.ParseBool();  == nil {
			 = 
		} else {
			return nil, fmt.Errorf("invalid prefer_simple_protocol: %v", )
		}
	}

	 := &ConnConfig{
		Config:               *,
		createdByParseConfig: true,
		LogLevel:             LogLevelInfo,
		BuildStatementCache:  ,
		PreferSimpleProtocol: ,
		connString:           ,
	}

	return , nil
}

Default values are set in ParseConfig. Enforce initial creation by ParseConfig rather than setting defaults from zero values.
	if !.createdByParseConfig {
		panic("config must be created by ParseConfig")
	}
	 := 
This isn't really a deep copy. But it is enough to avoid the config.Config.OnNotification mutation from affecting other connections with the same config. See https://github.com/jackc/pgx/issues/618.
	{
		 := *
		 = &
	}

	 = &Conn{
		config:   ,
		connInfo: pgtype.NewConnInfo(),
		logLevel: .LogLevel,
		logger:   .Logger,
	}
Only install pgx notification system if no other callback handler is present.
	if .Config.OnNotification == nil {
		.Config.OnNotification = .bufferNotifications
	} else {
		if .shouldLog(LogLevelDebug) {
			.log(, LogLevelDebug, "pgx notification handler disabled by application supplied OnNotification", map[string]interface{}{"host": .Config.Host})
		}
	}

	if .shouldLog(LogLevelInfo) {
		.log(, LogLevelInfo, "Dialing PostgreSQL server", map[string]interface{}{"host": .Config.Host})
	}
	.pgConn,  = pgconn.ConnectConfig(, &.Config)
	if  != nil {
		if .shouldLog(LogLevelError) {
			.log(, LogLevelError, "connect failed", map[string]interface{}{"err": })
		}
		return nil, 
	}

	.preparedStatements = make(map[string]*pgconn.StatementDescription)
	.doneChan = make(chan struct{})
	.closedChan = make(chan error)
	.wbuf = make([]byte, 0, 1024)

	if .config.BuildStatementCache != nil {
		.stmtcache = .config.BuildStatementCache(.pgConn)
	}
Replication connections can't execute the queries to populate the c.PgTypes and c.pgsqlAfInet
	if ,  := .Config.RuntimeParams["replication"];  {
		return , nil
	}

	return , nil
}
Close closes a connection. It is safe to call Close on a already closed connection.
func ( *Conn) ( context.Context) error {
	if .IsClosed() {
		return nil
	}

	 := .pgConn.Close()
	if .shouldLog(LogLevelInfo) {
		.log(, LogLevelInfo, "closed connection", nil)
	}
	return 
}
Prepare creates a prepared statement with name and sql. sql can contain placeholders for bound parameters. These placeholders are referenced positional as $1, $2, etc. 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 ( *Conn) ( context.Context, ,  string) ( *pgconn.StatementDescription,  error) {
	if  != "" {
		var  bool
		if ,  = .preparedStatements[];  && .SQL ==  {
			return , nil
		}
	}

	if .shouldLog(LogLevelError) {
		defer func() {
			if  != nil {
				.log(, LogLevelError, "Prepare failed", map[string]interface{}{"err": , "name": , "sql": })
			}
		}()
	}

	,  = .pgConn.Prepare(, , , nil)
	if  != nil {
		return nil, 
	}

	if  != "" {
		.preparedStatements[] = 
	}

	return , nil
}
Deallocate released a prepared statement
func ( *Conn) ( context.Context,  string) error {
	delete(.preparedStatements, )
	,  := .pgConn.Exec(, "deallocate "+quoteIdentifier()).ReadAll()
	return 
}

func ( *Conn) ( *pgconn.PgConn,  *pgconn.Notification) {
	.notifications = append(.notifications, )
}
WaitForNotification waits for a PostgreSQL notification. It wraps the underlying pgconn notification system in a slightly more convenient form.
Return already received notification immediately
	if len(.notifications) > 0 {
		 = .notifications[0]
		.notifications = .notifications[1:]
		return , nil
	}

	 := .pgConn.WaitForNotification()
	if len(.notifications) > 0 {
		 = .notifications[0]
		.notifications = .notifications[1:]
	}
	return , 
}

func ( *Conn) () bool {
	return .pgConn.IsClosed()
}

func ( *Conn) ( error) {
	if .IsClosed() {
		return
	}

	,  := context.WithCancel(context.Background())
	() // force immediate hard cancel
	.pgConn.Close()
}

func ( *Conn) ( LogLevel) bool {
	return .logger != nil && .logLevel >= 
}

func ( *Conn) ( context.Context,  LogLevel,  string,  map[string]interface{}) {
	if  == nil {
		 = map[string]interface{}{}
	}
	if .pgConn != nil && .pgConn.PID() != 0 {
		["pid"] = .pgConn.PID()
	}

	.logger.Log(, , , )
}

func ( string) string {
	return `"` + strings.ReplaceAll(, `"`, `""`) + `"`
}

func ( *Conn) ( context.Context) error {
	,  := .Exec(, ";")
	return 
}

func ( Rows,  error) (map[string]uint32, error) {
	if  != nil {
		return nil, 
	}
	defer .Close()

	 := make(map[string]uint32, 256)
	for .Next() {
		var  uint32
		var  pgtype.Text
		if  = .Scan(&, &);  != nil {
			return nil, 
		}

		[.String] = 
	}

	if  = .Err();  != nil {
		return nil, 
	}

	return , 
}
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 ( *Conn) () *pgconn.PgConn { return .pgConn }
StatementCache returns the statement cache used for this connection.
func ( *Conn) () stmtcache.Cache { return .stmtcache }
ConnInfo returns the connection info used for this connection.
func ( *Conn) () *pgtype.ConnInfo { return .connInfo }
Config returns a copy of config that was used to establish this connection.
func ( *Conn) () *ConnConfig { return .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 ( *Conn) ( context.Context,  string,  ...interface{}) (pgconn.CommandTag, error) {
	 := time.Now()

	,  := .exec(, , ...)
	if  != nil {
		if .shouldLog(LogLevelError) {
			.log(, LogLevelError, "Exec", map[string]interface{}{"sql": , "args": logQueryArgs(), "err": })
		}
		return , 
	}

	if .shouldLog(LogLevelInfo) {
		 := time.Now()
		.log(, LogLevelInfo, "Exec", map[string]interface{}{"sql": , "args": logQueryArgs(), "time": .Sub(), "commandTag": })
	}

	return , 
}

func ( *Conn) ( context.Context,  string,  ...interface{}) ( pgconn.CommandTag,  error) {
	 := .config.PreferSimpleProtocol

:
	for len() > 0 {
		switch arg := [0].(type) {
		case QuerySimpleProtocol:
			 = bool()
			 = [1:]
		default:
			break 
		}
	}

	if ,  := .preparedStatements[];  {
		return .execPrepared(, , )
	}

	if  {
		return .execSimpleProtocol(, , )
	}

	if len() == 0 {
		return .execSimpleProtocol(, , )
	}

	if .stmtcache != nil {
		,  := .stmtcache.Get(, )
		if  != nil {
			return nil, 
		}

		if .stmtcache.Mode() == stmtcache.ModeDescribe {
			return .execParams(, , )
		}
		return .execPrepared(, , )
	}

	,  := .Prepare(, "", )
	if  != nil {
		return nil, 
	}
	return .execPrepared(, , )
}

func ( *Conn) ( context.Context,  string,  []interface{}) ( pgconn.CommandTag,  error) {
	if len() > 0 {
		,  = .sanitizeForSimpleQuery(, ...)
		if  != nil {
			return nil, 
		}
	}

	 := .pgConn.Exec(, )
	for .NextResult() {
		,  = .ResultReader().Close()
	}
	 = .Close()
	return , 
}

func ( *Conn) ( *pgconn.StatementDescription,  []interface{}) error {
	if len(.ParamOIDs) != len() {
		return fmt.Errorf("expected %d arguments, got %d", len(.ParamOIDs), len())
	}

	.eqb.Reset()

	,  := convertDriverValuers()
	if  != nil {
		return 
	}

	for  := range  {
		 = .eqb.AppendParam(.connInfo, .ParamOIDs[], [])
		if  != nil {
			return 
		}
	}

	for  := range .Fields {
		.eqb.AppendResultFormat(.ConnInfo().ResultFormatCodeForOID(.Fields[].DataTypeOID))
	}

	return nil
}

func ( *Conn) ( context.Context,  *pgconn.StatementDescription,  []interface{}) (pgconn.CommandTag, error) {
	 := .execParamsAndPreparedPrefix(, )
	if  != nil {
		return nil, 
	}

	 := .pgConn.ExecParams(, .SQL, .eqb.paramValues, .ParamOIDs, .eqb.paramFormats, .eqb.resultFormats).Read()
	return .CommandTag, .Err
}

func ( *Conn) ( context.Context,  *pgconn.StatementDescription,  []interface{}) (pgconn.CommandTag, error) {
	 := .execParamsAndPreparedPrefix(, )
	if  != nil {
		return nil, 
	}

	 := .pgConn.ExecPrepared(, .Name, .eqb.paramValues, .eqb.paramFormats, .eqb.resultFormats).Read()
	return .CommandTag, .Err
}

func ( *Conn) ( context.Context,  string,  []interface{}) *connRows {
	if len(.preallocatedRows) == 0 {
		.preallocatedRows = make([]connRows, 64)
	}

	 := &.preallocatedRows[len(.preallocatedRows)-1]
	.preallocatedRows = .preallocatedRows[0 : len(.preallocatedRows)-1]

	.ctx = 
	.logger = 
	.connInfo = .connInfo
	.startTime = time.Now()
	.sql = 
	.args = 
	.conn = 

	return 
}
QuerySimpleProtocol controls whether the simple or extended protocol is used to send the query.
QueryResultFormats controls the result format (text=0, binary=1) of a query by result column position.
QueryResultFormatsByOID controls the result format (text=0, binary=1) of a query by the result column OID.
Query executes sql with args. If there is an error the returned Rows will be returned in an error state. So it is allowed to ignore the error returned from Query and handle it in Rows. For extra control over how the query is executed, the types QuerySimpleProtocol, 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 ( *Conn) ( context.Context,  string,  ...interface{}) (Rows, error) {
	var  QueryResultFormats
	var  QueryResultFormatsByOID
	 := .config.PreferSimpleProtocol

:
	for len() > 0 {
		switch arg := [0].(type) {
		case QueryResultFormats:
			 = 
			 = [1:]
		case QueryResultFormatsByOID:
			 = 
			 = [1:]
		case QuerySimpleProtocol:
			 = bool()
			 = [1:]
		default:
			break 
		}
	}

	 := .getRows(, , )

	var  error
	,  := .preparedStatements[]

	if  && ! {
		,  = .sanitizeForSimpleQuery(, ...)
		if  != nil {
			.fatal()
			return , 
		}

		 := .pgConn.Exec(, )
		if .NextResult() {
			.resultReader = .ResultReader()
			.multiResultReader = 
		} else {
			 = .Close()
			.fatal()
			return , 
		}

		return , nil
	}

	.eqb.Reset()

	if ! {
		if .stmtcache != nil {
			,  = .stmtcache.Get(, )
			if  != nil {
				.fatal()
				return , .err
			}
		} else {
			,  = .pgConn.Prepare(, "", , nil)
			if  != nil {
				.fatal()
				return , .err
			}
		}
	}
	if len(.ParamOIDs) != len() {
		.fatal(fmt.Errorf("expected %d arguments, got %d", len(.ParamOIDs), len()))
		return , .err
	}

	.sql = .SQL

	,  = convertDriverValuers()
	if  != nil {
		.fatal()
		return , .err
	}

	for  := range  {
		 = .eqb.AppendParam(.connInfo, .ParamOIDs[], [])
		if  != nil {
			.fatal()
			return , .err
		}
	}

	if  != nil {
		 = make([]int16, len(.Fields))
		for  := range  {
			[] = [uint32(.Fields[].DataTypeOID)]
		}
	}

	if  == nil {
		for  := range .Fields {
			.eqb.AppendResultFormat(.ConnInfo().ResultFormatCodeForOID(.Fields[].DataTypeOID))
		}

		 = .eqb.resultFormats
	}

	if .stmtcache != nil && .stmtcache.Mode() == stmtcache.ModeDescribe {
		.resultReader = .pgConn.ExecParams(, , .eqb.paramValues, .ParamOIDs, .eqb.paramFormats, )
	} else {
		.resultReader = .pgConn.ExecPrepared(, .Name, .eqb.paramValues, .eqb.paramFormats, )
	}

	return , .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 ( *Conn) ( context.Context,  string,  ...interface{}) Row {
	,  := .Query(, , ...)
	return (*connRow)(.(*connRows))
}
QueryFuncRow is the argument to the QueryFunc callback function. QueryFuncRow is an interface instead of a struct to allow tests to mock QueryFunc. However, adding a method to an interface is technically a breaking change. Because of this the QueryFuncRow interface is partially excluded from semantic version requirements. Methods will not be removed or changed, but new methods may be added.
type QueryFuncRow interface {
	FieldDescriptions() []pgproto3.FieldDescription
RawValues returns the unparsed bytes of the row values. The returned [][]byte is only valid during the current function call. However, the underlying byte data is safe to retain a reference to and mutate.
	RawValues() [][]byte
}
QueryFunc executes sql with args. For each row returned by the query the values will scanned into the elements of scans and f will be called. If any row fails to scan or f returns an error the query will be aborted and the error will be returned.
func ( *Conn) ( context.Context,  string,  []interface{},  []interface{},  func(QueryFuncRow) error) (pgconn.CommandTag, error) {
	,  := .Query(, , ...)
	if  != nil {
		return nil, 
	}
	defer .Close()

	for .Next() {
		 = .Scan(...)
		if  != nil {
			return nil, 
		}

		 = ()
		if  != nil {
			return nil, 
		}
	}

	if  := .Err();  != nil {
		return nil, 
	}

	return .CommandTag(), nil
}
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.
func ( *Conn) ( context.Context,  *Batch) BatchResults {
	 := .config.PreferSimpleProtocol
	var  strings.Builder
	if  {
		for ,  := range .items {
			if  > 0 {
				.WriteByte(';')
			}
			,  := .sanitizeForSimpleQuery(.query, .arguments...)
			if  != nil {
				return &batchResults{ctx: , conn: , err: }
			}
			.WriteString()
		}
		 := .pgConn.Exec(, .String())
		return &batchResults{
			ctx:  ,
			conn: ,
			mrr:  ,
			b:    ,
			ix:   0,
		}
	}

	 := map[string]struct{}{}

	for ,  := range .items {
		if ,  := .preparedStatements[.query];  {
			continue
		}
		[.query] = struct{}{}
	}

	var  stmtcache.Cache
	if len() > 0 {
		if .stmtcache != nil && .stmtcache.Cap() >= len() {
			 = .stmtcache
		} else {
			 = stmtcache.New(.pgConn, stmtcache.ModeDescribe, len())
		}

		for ,  := range  {
			,  := .Get(, )
			if  != nil {
				return &batchResults{ctx: , conn: , err: }
			}
		}
	}

	 := &pgconn.Batch{}

	for ,  := range .items {
		.eqb.Reset()

		 := .preparedStatements[.query]
		if  == nil {
			var  error
			,  = .Get(, .query)
the stmtCache was prefilled from distinctUnpreparedQueries above so we are guaranteed no errors
				panic("BUG: unexpected error from stmtCache")
			}
		}

		if len(.ParamOIDs) != len(.arguments) {
			return &batchResults{ctx: , conn: , err: fmt.Errorf("mismatched param and argument count")}
		}

		,  := convertDriverValuers(.arguments)
		if  != nil {
			return &batchResults{ctx: , conn: , err: }
		}

		for  := range  {
			 = .eqb.AppendParam(.connInfo, .ParamOIDs[], [])
			if  != nil {
				return &batchResults{ctx: , conn: , err: }
			}
		}

		for  := range .Fields {
			.eqb.AppendResultFormat(.ConnInfo().ResultFormatCodeForOID(.Fields[].DataTypeOID))
		}

		if .Name == "" {
			.ExecParams(.query, .eqb.paramValues, .ParamOIDs, .eqb.paramFormats, .eqb.resultFormats)
		} else {
			.ExecPrepared(.Name, .eqb.paramValues, .eqb.paramFormats, .eqb.resultFormats)
		}
	}

	 := .pgConn.ExecBatch(, )

	return &batchResults{
		ctx:  ,
		conn: ,
		mrr:  ,
		b:    ,
		ix:   0,
	}
}

func ( *Conn) ( string,  ...interface{}) (string, error) {
	if .pgConn.ParameterStatus("standard_conforming_strings") != "on" {
		return "", errors.New("simple protocol queries must be run with standard_conforming_strings=on")
	}

	if .pgConn.ParameterStatus("client_encoding") != "UTF8" {
		return "", errors.New("simple protocol queries must be run with client_encoding=UTF8")
	}

	var  error
	 := make([]interface{}, len())
	for ,  := range  {
		[],  = convertSimpleArgument(.connInfo, )
		if  != nil {
			return "", 
		}
	}

	return sanitize.SanitizeSQL(, ...)