Test every QueryExecMode
This commit is contained in:
+50
-59
@@ -74,41 +74,32 @@ func skipPostgreSQLVersionLessThan(t testing.TB, db *sql.DB, minVersion int64) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func testWithAndWithoutPreferSimpleProtocol(t *testing.T, f func(t *testing.T, db *sql.DB)) {
|
||||
t.Run("SimpleProto",
|
||||
func(t *testing.T) {
|
||||
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||
require.NoError(t, err)
|
||||
|
||||
config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
|
||||
db := stdlib.OpenDB(*config)
|
||||
defer func() {
|
||||
err := db.Close()
|
||||
func testWithAllQueryExecModes(t *testing.T, f func(t *testing.T, db *sql.DB)) {
|
||||
for _, mode := range []pgx.QueryExecMode{
|
||||
pgx.QueryExecModeCacheStatement,
|
||||
pgx.QueryExecModeCacheDescribe,
|
||||
pgx.QueryExecModeDescribeExec,
|
||||
pgx.QueryExecModeExec,
|
||||
pgx.QueryExecModeSimpleProtocol,
|
||||
} {
|
||||
t.Run(mode.String(),
|
||||
func(t *testing.T) {
|
||||
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
f(t, db)
|
||||
config.DefaultQueryExecMode = mode
|
||||
db := stdlib.OpenDB(*config)
|
||||
defer func() {
|
||||
err := db.Close()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
ensureDBValid(t, db)
|
||||
},
|
||||
)
|
||||
f(t, db)
|
||||
|
||||
t.Run("DefaultProto",
|
||||
func(t *testing.T) {
|
||||
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||
require.NoError(t, err)
|
||||
|
||||
db := stdlib.OpenDB(*config)
|
||||
defer func() {
|
||||
err := db.Close()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
f(t, db)
|
||||
|
||||
ensureDBValid(t, db)
|
||||
},
|
||||
)
|
||||
ensureDBValid(t, db)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Do a simple query to ensure the DB is still usable. This is of less use in stdlib as the connection pool should
|
||||
@@ -267,7 +258,7 @@ func TestQueryCloseRowsEarly(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnExec(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
_, err := db.Exec("create temporary table t(a varchar not null)")
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -281,7 +272,7 @@ func TestConnExec(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnQuery(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
skipCockroachDB(t, db, "Server issues incorrect ParameterDescription (https://github.com/cockroachdb/cockroach/issues/60907)")
|
||||
|
||||
rows, err := db.Query("select 'foo', n from generate_series($1::int, $2::int) n", int32(1), int32(10))
|
||||
@@ -313,7 +304,7 @@ func TestConnQuery(t *testing.T) {
|
||||
|
||||
// https://github.com/jackc/pgx/issues/781
|
||||
func TestConnQueryDifferentScanPlansIssue781(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
var s string
|
||||
var b bool
|
||||
|
||||
@@ -328,7 +319,7 @@ func TestConnQueryDifferentScanPlansIssue781(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnQueryNull(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
rows, err := db.Query("select $1::int", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -353,7 +344,7 @@ func TestConnQueryNull(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnQueryRowByteSlice(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
expected := []byte{222, 173, 190, 239}
|
||||
var actual []byte
|
||||
|
||||
@@ -364,7 +355,7 @@ func TestConnQueryRowByteSlice(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnQueryFailure(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
_, err := db.Query("select 'foo")
|
||||
require.Error(t, err)
|
||||
require.IsType(t, new(pgconn.PgError), err)
|
||||
@@ -372,7 +363,7 @@ func TestConnQueryFailure(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnSimpleSlicePassThrough(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
skipCockroachDB(t, db, "Server does not support cardinality function")
|
||||
|
||||
var n int64
|
||||
@@ -385,7 +376,7 @@ func TestConnSimpleSlicePassThrough(t *testing.T) {
|
||||
// Test type that pgx would handle natively in binary, but since it is not a
|
||||
// database/sql native type should be passed through as a string
|
||||
func TestConnQueryRowPgxBinary(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
sql := "select $1::int4[]"
|
||||
expected := "{1,2,3}"
|
||||
var actual string
|
||||
@@ -397,7 +388,7 @@ func TestConnQueryRowPgxBinary(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnQueryRowUnknownType(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
skipCockroachDB(t, db, "Server does not support point type")
|
||||
|
||||
sql := "select $1::point"
|
||||
@@ -411,7 +402,7 @@ func TestConnQueryRowUnknownType(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnQueryJSONIntoByteSlice(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
_, err := db.Exec(`
|
||||
create temporary table docs(
|
||||
body json not null
|
||||
@@ -471,7 +462,7 @@ func TestConnExecInsertByteSliceIntoJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTransactionLifeCycle(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
_, err := db.Exec("create temporary table t(a varchar not null)")
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -505,7 +496,7 @@ func TestTransactionLifeCycle(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnBeginTxIsolation(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
skipCockroachDB(t, db, "Server always uses serializable isolation level")
|
||||
|
||||
var defaultIsoLevel string
|
||||
@@ -561,7 +552,7 @@ func TestConnBeginTxIsolation(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnBeginTxReadOnly(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
tx, err := db.BeginTx(context.Background(), &sql.TxOptions{ReadOnly: true})
|
||||
require.NoError(t, err)
|
||||
defer tx.Rollback()
|
||||
@@ -579,7 +570,7 @@ func TestConnBeginTxReadOnly(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBeginTxContextCancel(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
_, err := db.Exec("drop table if exists t")
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -607,7 +598,7 @@ func TestBeginTxContextCancel(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAcquireConn(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
var conns []*pgx.Conn
|
||||
|
||||
for i := 1; i < 6; i++ {
|
||||
@@ -643,7 +634,7 @@ func TestAcquireConn(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnRaw(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
conn, err := db.Conn(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -659,7 +650,7 @@ func TestConnRaw(t *testing.T) {
|
||||
|
||||
// https://github.com/jackc/pgx/issues/673
|
||||
func TestReleaseConnWithTxInProgress(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
skipCockroachDB(t, db, "Server does not support backend PID")
|
||||
|
||||
c1, err := stdlib.AcquireConn(db)
|
||||
@@ -690,14 +681,14 @@ func TestReleaseConnWithTxInProgress(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnPingContextSuccess(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
err := db.PingContext(context.Background())
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestConnPrepareContextSuccess(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
stmt, err := db.PrepareContext(context.Background(), "select now()")
|
||||
require.NoError(t, err)
|
||||
err = stmt.Close()
|
||||
@@ -706,14 +697,14 @@ func TestConnPrepareContextSuccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnExecContextSuccess(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
_, err := db.ExecContext(context.Background(), "create temporary table exec_context_test(id serial primary key)")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestConnExecContextFailureRetry(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
// We get a connection, immediately close it, and then get it back;
|
||||
// DB.Conn along with Conn.ResetSession does the retry for us.
|
||||
{
|
||||
@@ -730,7 +721,7 @@ func TestConnExecContextFailureRetry(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnQueryContextSuccess(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
rows, err := db.QueryContext(context.Background(), "select * from generate_series(1,10) n")
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -744,7 +735,7 @@ func TestConnQueryContextSuccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnQueryContextFailureRetry(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
// We get a connection, immediately close it, and then get it back;
|
||||
// DB.Conn along with Conn.ResetSession does the retry for us.
|
||||
{
|
||||
@@ -762,7 +753,7 @@ func TestConnQueryContextFailureRetry(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRowsColumnTypeDatabaseTypeName(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
rows, err := db.Query("select 42::bigint")
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -846,7 +837,7 @@ func TestStmtQueryContextSuccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRowsColumnTypes(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
columnTypesTests := []struct {
|
||||
Name string
|
||||
TypeName string
|
||||
@@ -984,7 +975,7 @@ func TestRowsColumnTypes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestQueryLifeCycle(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
skipCockroachDB(t, db, "Server issues incorrect ParameterDescription (https://github.com/cockroachdb/cockroach/issues/60907)")
|
||||
|
||||
rows, err := db.Query("SELECT 'foo', n FROM generate_series($1::int, $2::int) n WHERE 3 = $3", 1, 10, 3)
|
||||
@@ -1033,7 +1024,7 @@ func TestQueryLifeCycle(t *testing.T) {
|
||||
|
||||
// https://github.com/jackc/pgx/issues/409
|
||||
func TestScanJSONIntoJSONRawMessage(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
var msg json.RawMessage
|
||||
|
||||
err := db.QueryRow("select '{}'::json").Scan(&msg)
|
||||
@@ -1088,7 +1079,7 @@ func TestRegisterConnConfig(t *testing.T) {
|
||||
|
||||
// https://github.com/jackc/pgx/issues/958
|
||||
func TestConnQueryRowConstraintErrors(t *testing.T) {
|
||||
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
|
||||
skipPostgreSQLVersionLessThan(t, db, 11)
|
||||
skipCockroachDB(t, db, "Server does not support deferred constraint (https://github.com/cockroachdb/cockroach/issues/31632)")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user