Initial restructure of simple protocol to query exec mode

query-exec-mode
Jack Christensen 2022-03-05 10:27:15 -06:00
parent 2885b039d5
commit aad3d65e16
9 changed files with 107 additions and 67 deletions

View File

@ -803,7 +803,7 @@ func TestSendBatchSimpleProtocol(t *testing.T) {
t.Parallel() t.Parallel()
config := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE")) config := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE"))
config.PreferSimpleProtocol = true config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
ctx, cancelFunc := context.WithCancel(context.Background()) ctx, cancelFunc := context.WithCancel(context.Background())
defer cancelFunc() defer cancelFunc()

91
conn.go
View File

@ -29,13 +29,11 @@ type ConnConfig struct {
// to nil to disable automatic prepared statements. // to nil to disable automatic prepared statements.
BuildStatementCache BuildStatementCacheFunc BuildStatementCache BuildStatementCacheFunc
// PreferSimpleProtocol disables implicit prepared statement usage. By default pgx automatically uses the extended // DefaultQueryExecMode controls the default mode for executing queries. By default pgx uses the extended protocol
// protocol. This can improve performance due to being able to use the binary format. It also does not rely on client // and automatically prepares and caches prepared statements. However, this may be incompatible with proxies such as
// side parameter sanitization. However, it does incur two round-trips per query (unless using a prepared statement) // PGBouncer. In this case it may be preferrable to use QueryExecModeExec or QueryExecModeSimpleProtocol. The same
// and may be incompatible proxies such as PGBouncer. Setting PreferSimpleProtocol causes the simple protocol to be // functionality can be controlled on a per query basis by passing a QueryExecMode as the first query argument.
// used by default. The same functionality can be controlled on a per query basis by setting DefaultQueryExecMode QueryExecMode
// QueryExOptions.SimpleProtocol.
PreferSimpleProtocol bool
createdByParseConfig bool // Used to enforce created by ParseConfig rule. createdByParseConfig bool // Used to enforce created by ParseConfig rule.
} }
@ -125,8 +123,9 @@ func ConnectConfig(ctx context.Context, connConfig *ConnConfig) (*Conn, error) {
// server. "describe" is primarily useful when the environment does not allow prepared statements such as when // server. "describe" is primarily useful when the environment does not allow prepared statements such as when
// running a connection pooler like PgBouncer. Default: "prepare" // running a connection pooler like PgBouncer. Default: "prepare"
// //
// prefer_simple_protocol // default_query_exec_mode
// Possible values: "true" and "false". Use the simple protocol instead of extended protocol. Default: false // 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".
func ParseConfig(connString string) (*ConnConfig, error) { func ParseConfig(connString string) (*ConnConfig, error) {
config, err := pgconn.ParseConfig(connString) config, err := pgconn.ParseConfig(connString)
if err != nil { if err != nil {
@ -163,13 +162,22 @@ func ParseConfig(connString string) (*ConnConfig, error) {
} }
} }
preferSimpleProtocol := false defaultQueryExecMode := QueryExecModeCacheStatement
if s, ok := config.RuntimeParams["prefer_simple_protocol"]; ok { if s, ok := config.RuntimeParams["default_query_exec_mode"]; ok {
delete(config.RuntimeParams, "prefer_simple_protocol") delete(config.RuntimeParams, "default_query_exec_mode")
if b, err := strconv.ParseBool(s); err == nil { switch s {
preferSimpleProtocol = b case "cache_statement":
} else { defaultQueryExecMode = QueryExecModeCacheStatement
return nil, fmt.Errorf("invalid prefer_simple_protocol: %v", err) case "cache_describe":
defaultQueryExecMode = QueryExecModeCacheDescribe
case "describe_exec":
defaultQueryExecMode = QueryExecModeDescribeExec
case "exec":
defaultQueryExecMode = QueryExecModeExec
case "simple_protocol":
defaultQueryExecMode = QueryExecModeSimpleProtocol
default:
return nil, fmt.Errorf("invalid default_query_exec_mode: %v", err)
} }
} }
@ -178,7 +186,7 @@ func ParseConfig(connString string) (*ConnConfig, error) {
createdByParseConfig: true, createdByParseConfig: true,
LogLevel: LogLevelInfo, LogLevel: LogLevelInfo,
BuildStatementCache: buildStatementCache, BuildStatementCache: buildStatementCache,
PreferSimpleProtocol: preferSimpleProtocol, DefaultQueryExecMode: defaultQueryExecMode,
connString: connString, connString: connString,
} }
@ -403,13 +411,13 @@ func (c *Conn) Exec(ctx context.Context, sql string, arguments ...interface{}) (
} }
func (c *Conn) exec(ctx context.Context, sql string, arguments ...interface{}) (commandTag pgconn.CommandTag, err error) { func (c *Conn) exec(ctx context.Context, sql string, arguments ...interface{}) (commandTag pgconn.CommandTag, err error) {
simpleProtocol := c.config.PreferSimpleProtocol simpleProtocol := c.config.DefaultQueryExecMode == QueryExecModeSimpleProtocol
optionLoop: optionLoop:
for len(arguments) > 0 { for len(arguments) > 0 {
switch arg := arguments[0].(type) { switch arg := arguments[0].(type) {
case QuerySimpleProtocol: case QueryExecMode:
simpleProtocol = bool(arg) simpleProtocol = arg == QueryExecModeSimpleProtocol
arguments = arguments[1:] arguments = arguments[1:]
default: default:
break optionLoop break optionLoop
@ -525,8 +533,39 @@ func (c *Conn) getRows(ctx context.Context, sql string, args []interface{}) *con
return r return r
} }
// QuerySimpleProtocol controls whether the simple or extended protocol is used to send the query. type QueryExecMode int32
type QuerySimpleProtocol bool
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.
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 this may result in undetected result decoding errors.
QueryExecModeCacheDescribe
// Get the statement description on every execution. This uses the extended protocol. Queries require two round trips
// to execute. It does not use prepared statements (allowing usage with most connection poolers) and is safe even
// when the 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. 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 ambigious.
// 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.
QueryExecModeExec
// Use the simple protocol. Assume the PostgreSQL query parameter types based on the Go type of the arguments.
// 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 ambigious.
// 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.
QueryExecModeSimpleProtocol
)
// QueryResultFormats controls the result format (text=0, binary=1) of a query by result column position. // QueryResultFormats controls the result format (text=0, binary=1) of a query by result column position.
type QueryResultFormats []int16 type QueryResultFormats []int16
@ -547,7 +586,7 @@ type QueryResultFormatsByOID map[uint32]int16
func (c *Conn) Query(ctx context.Context, sql string, args ...interface{}) (Rows, error) { func (c *Conn) Query(ctx context.Context, sql string, args ...interface{}) (Rows, error) {
var resultFormats QueryResultFormats var resultFormats QueryResultFormats
var resultFormatsByOID QueryResultFormatsByOID var resultFormatsByOID QueryResultFormatsByOID
simpleProtocol := c.config.PreferSimpleProtocol simpleProtocol := c.config.DefaultQueryExecMode == QueryExecModeSimpleProtocol
optionLoop: optionLoop:
for len(args) > 0 { for len(args) > 0 {
@ -558,8 +597,8 @@ optionLoop:
case QueryResultFormatsByOID: case QueryResultFormatsByOID:
resultFormatsByOID = arg resultFormatsByOID = arg
args = args[1:] args = args[1:]
case QuerySimpleProtocol: case QueryExecMode:
simpleProtocol = bool(arg) simpleProtocol = arg == QueryExecModeSimpleProtocol
args = args[1:] args = args[1:]
default: default:
break optionLoop break optionLoop
@ -709,7 +748,7 @@ func (c *Conn) QueryFunc(ctx context.Context, sql string, args []interface{}, sc
// explicit transaction control statements are executed. The returned BatchResults must be closed before the connection // explicit transaction control statements are executed. The returned BatchResults must be closed before the connection
// is used again. // is used again.
func (c *Conn) SendBatch(ctx context.Context, b *Batch) BatchResults { func (c *Conn) SendBatch(ctx context.Context, b *Batch) BatchResults {
simpleProtocol := c.config.PreferSimpleProtocol simpleProtocol := c.config.DefaultQueryExecMode == QueryExecModeSimpleProtocol
var sb strings.Builder var sb strings.Builder
if simpleProtocol { if simpleProtocol {
for i, bi := range b.items { for i, bi := range b.items {

View File

@ -81,7 +81,7 @@ func TestConnectWithPreferSimpleProtocol(t *testing.T) {
t.Parallel() t.Parallel()
connConfig := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE")) connConfig := mustParseConfig(t, os.Getenv("PGX_TEST_DATABASE"))
connConfig.PreferSimpleProtocol = true connConfig.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
conn := mustConnect(t, connConfig) conn := mustConnect(t, connConfig)
defer closeConn(t, conn) defer closeConn(t, conn)
@ -164,23 +164,24 @@ func TestParseConfigExtractsStatementCacheOptions(t *testing.T) {
require.Equal(t, stmtcache.ModeDescribe, c.Mode()) require.Equal(t, stmtcache.ModeDescribe, c.Mode())
} }
func TestParseConfigExtractsPreferSimpleProtocol(t *testing.T) { func TestParseConfigExtractsDefaultQueryExecMode(t *testing.T) {
t.Parallel() t.Parallel()
for _, tt := range []struct { for _, tt := range []struct {
connString string connString string
preferSimpleProtocol bool defaultQueryExecMode pgx.QueryExecMode
}{ }{
{"", false}, {"", pgx.QueryExecModeCacheStatement},
{"prefer_simple_protocol=false", false}, {"default_query_exec_mode=cache_statement", pgx.QueryExecModeCacheStatement},
{"prefer_simple_protocol=0", false}, {"default_query_exec_mode=cache_describe", pgx.QueryExecModeCacheDescribe},
{"prefer_simple_protocol=true", true}, {"default_query_exec_mode=describe_exec", pgx.QueryExecModeDescribeExec},
{"prefer_simple_protocol=1", true}, {"default_query_exec_mode=exec", pgx.QueryExecModeExec},
{"default_query_exec_mode=simple_protocol", pgx.QueryExecModeSimpleProtocol},
} { } {
config, err := pgx.ParseConfig(tt.connString) config, err := pgx.ParseConfig(tt.connString)
require.NoError(t, err) require.NoError(t, err)
require.Equalf(t, tt.preferSimpleProtocol, config.PreferSimpleProtocol, "connString: `%s`", tt.connString) require.Equalf(t, tt.defaultQueryExecMode, config.DefaultQueryExecMode, "connString: `%s`", tt.connString)
require.Empty(t, config.RuntimeParams["prefer_simple_protocol"]) require.Empty(t, config.RuntimeParams["default_query_exec_mode"])
} }
} }
@ -384,7 +385,7 @@ func TestExecPerQuerySimpleProtocol(t *testing.T) {
commandTag, err = conn.Exec(ctx, commandTag, err = conn.Exec(ctx,
"insert into foo(name) values($1);", "insert into foo(name) values($1);",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
"bar'; drop table foo;--", "bar'; drop table foo;--",
) )
if err != nil { if err != nil {

View File

@ -18,7 +18,7 @@ func testWithAndWithoutPreferSimpleProtocol(t *testing.T, f func(t *testing.T, c
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE")) config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
require.NoError(t, err) require.NoError(t, err)
config.PreferSimpleProtocol = true config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
conn, err := pgx.ConnectConfig(context.Background(), config) conn, err := pgx.ConnectConfig(context.Background(), config)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
@ -130,7 +130,7 @@ func assertConfigsEqual(t *testing.T, expected, actual *pgx.ConnConfig, testName
assert.Equalf(t, expected.ConnString(), actual.ConnString(), "%s - ConnString", testName) assert.Equalf(t, expected.ConnString(), actual.ConnString(), "%s - ConnString", testName)
// Can't test function equality, so just test that they are set or not. // Can't test function equality, so just test that they are set or not.
assert.Equalf(t, expected.BuildStatementCache == nil, actual.BuildStatementCache == nil, "%s - BuildStatementCache", testName) assert.Equalf(t, expected.BuildStatementCache == nil, actual.BuildStatementCache == nil, "%s - BuildStatementCache", testName)
assert.Equalf(t, expected.PreferSimpleProtocol, actual.PreferSimpleProtocol, "%s - PreferSimpleProtocol", testName) assert.Equalf(t, expected.DefaultQueryExecMode, actual.DefaultQueryExecMode, "%s - DefaultQueryExecMode", testName)
assert.Equalf(t, expected.Host, actual.Host, "%s - Host", testName) assert.Equalf(t, expected.Host, actual.Host, "%s - Host", testName)
assert.Equalf(t, expected.Database, actual.Database, "%s - Database", testName) assert.Equalf(t, expected.Database, actual.Database, "%s - Database", testName)

View File

@ -32,7 +32,7 @@ func TestLargeObjects(t *testing.T) {
testLargeObjects(t, ctx, tx) testLargeObjects(t, ctx, tx)
} }
func TestLargeObjectsPreferSimpleProtocol(t *testing.T) { func TestLargeObjectsSimpleProtocol(t *testing.T) {
t.Parallel() t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
@ -43,7 +43,7 @@ func TestLargeObjectsPreferSimpleProtocol(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
config.PreferSimpleProtocol = true config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
conn, err := pgx.ConnectConfig(ctx, config) conn, err := pgx.ConnectConfig(ctx, config)
if err != nil { if err != nil {

View File

@ -34,7 +34,7 @@ func TestPgbouncerSimpleProtocol(t *testing.T) {
config := mustParseConfig(t, connString) config := mustParseConfig(t, connString)
config.BuildStatementCache = nil config.BuildStatementCache = nil
config.PreferSimpleProtocol = true config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
testPgbouncer(t, config, 10, 100) testPgbouncer(t, config, 10, 100)
} }

View File

@ -168,7 +168,7 @@ func assertConnConfigsEqual(t *testing.T, expected, actual *pgx.ConnConfig, test
// Can't test function equality, so just test that they are set or not. // Can't test function equality, so just test that they are set or not.
assert.Equalf(t, expected.BuildStatementCache == nil, actual.BuildStatementCache == nil, "%s - BuildStatementCache", testName) assert.Equalf(t, expected.BuildStatementCache == nil, actual.BuildStatementCache == nil, "%s - BuildStatementCache", testName)
assert.Equalf(t, expected.PreferSimpleProtocol, actual.PreferSimpleProtocol, "%s - PreferSimpleProtocol", testName) assert.Equalf(t, expected.DefaultQueryExecMode, actual.DefaultQueryExecMode, "%s - DefaultQueryExecMode", testName)
assert.Equalf(t, expected.Host, actual.Host, "%s - Host", testName) assert.Equalf(t, expected.Host, actual.Host, "%s - Host", testName)
assert.Equalf(t, expected.Database, actual.Database, "%s - Database", testName) assert.Equalf(t, expected.Database, actual.Database, "%s - Database", testName)

View File

@ -291,7 +291,7 @@ func TestConnQueryRawValues(t *testing.T) {
rows, err := conn.Query( rows, err := conn.Query(
context.Background(), context.Background(),
"select 'foo'::text, 'bar'::varchar, n, null, n from generate_series(1,$1) n", "select 'foo'::text, 'bar'::varchar, n, null, n from generate_series(1,$1) n",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
10, 10,
) )
require.NoError(t, err) require.NoError(t, err)
@ -1385,7 +1385,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::int8", "select $1::int8",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
expected, expected,
).Scan(&actual) ).Scan(&actual)
if err != nil { if err != nil {
@ -1402,7 +1402,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::float8", "select $1::float8",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
expected, expected,
).Scan(&actual) ).Scan(&actual)
if err != nil { if err != nil {
@ -1419,7 +1419,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1", "select $1",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
expected, expected,
).Scan(&actual) ).Scan(&actual)
if err != nil { if err != nil {
@ -1436,7 +1436,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::bytea", "select $1::bytea",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
expected, expected,
).Scan(&actual) ).Scan(&actual)
if err != nil { if err != nil {
@ -1453,7 +1453,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::text", "select $1::text",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
expected, expected,
).Scan(&actual) ).Scan(&actual)
if err != nil { if err != nil {
@ -1478,7 +1478,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::text[]", "select $1::text[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1499,7 +1499,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::smallint[]", "select $1::smallint[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1520,7 +1520,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::int[]", "select $1::int[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1541,7 +1541,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::bigint[]", "select $1::bigint[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1562,7 +1562,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::bigint[]", "select $1::bigint[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1583,7 +1583,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::smallint[]", "select $1::smallint[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1604,7 +1604,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::bigint[]", "select $1::bigint[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1625,7 +1625,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::bigint[]", "select $1::bigint[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1646,7 +1646,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::bigint[]", "select $1::bigint[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1667,7 +1667,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::float4[]", "select $1::float4[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1688,7 +1688,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::float8[]", "select $1::float8[]",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
tt.expected, tt.expected,
).Scan(&actual) ).Scan(&actual)
assert.NoErrorf(t, err, "%d", i) assert.NoErrorf(t, err, "%d", i)
@ -1706,7 +1706,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::circle", "select $1::circle",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
&expected, &expected,
).Scan(&actual) ).Scan(&actual)
if err != nil { if err != nil {
@ -1734,7 +1734,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1::int8, $2::float8, $3, $4::bytea, $5::text", "select $1::int8, $2::float8, $3, $4::bytea, $5::text",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
expectedInt64, expectedFloat64, expectedBool, expectedBytes, expectedString, expectedInt64, expectedFloat64, expectedBool, expectedBytes, expectedString,
).Scan(&actualInt64, &actualFloat64, &actualBool, &actualBytes, &actualString) ).Scan(&actualInt64, &actualFloat64, &actualBool, &actualBytes, &actualString)
if err != nil { if err != nil {
@ -1765,7 +1765,7 @@ func TestConnSimpleProtocol(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1", "select $1",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
expected, expected,
).Scan(&actual) ).Scan(&actual)
if err != nil { if err != nil {
@ -1793,7 +1793,7 @@ func TestConnSimpleProtocolRefusesNonUTF8ClientEncoding(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1", "select $1",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
"test", "test",
).Scan(&expected) ).Scan(&expected)
if err == nil { if err == nil {
@ -1817,7 +1817,7 @@ func TestConnSimpleProtocolRefusesNonStandardConformingStrings(t *testing.T) {
err := conn.QueryRow( err := conn.QueryRow(
context.Background(), context.Background(),
"select $1", "select $1",
pgx.QuerySimpleProtocol(true), pgx.QueryExecModeSimpleProtocol,
`\'; drop table users; --`, `\'; drop table users; --`,
).Scan(&expected) ).Scan(&expected)
if err == nil { if err == nil {

View File

@ -80,7 +80,7 @@ func testWithAndWithoutPreferSimpleProtocol(t *testing.T, f func(t *testing.T, d
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE")) config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
require.NoError(t, err) require.NoError(t, err)
config.PreferSimpleProtocol = true config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
db := stdlib.OpenDB(*config) db := stdlib.OpenDB(*config)
defer func() { defer func() {
err := db.Close() err := db.Close()