MCPcopy
hub / github.com/jackc/pgx / TestStmtCacheInvalidationTx

Function TestStmtCacheInvalidationTx

conn_test.go:1280–1357  ·  view source on GitHub ↗
(t *testing.T)

Source from the content-addressed store, hash-verified

1278}
1279
1280func TestStmtCacheInvalidationTx(t *testing.T) {
1281 ctx := context.Background()
1282
1283 conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
1284 defer closeConn(t, conn)
1285
1286 if conn.PgConn().ParameterStatus("crdb_version") != "" {
1287 t.Skip("Server has non-standard prepare in errored transaction behavior (https://github.com/cockroachdb/cockroach/issues/84140)")
1288 }
1289
1290 // create a table and fill it with some data
1291 _, err := conn.Exec(ctx, `
1292 DROP TABLE IF EXISTS drop_cols;
1293 CREATE TABLE drop_cols (
1294 id SERIAL PRIMARY KEY NOT NULL,
1295 f1 int NOT NULL,
1296 f2 int NOT NULL
1297 );
1298 `)
1299 require.NoError(t, err)
1300 _, err = conn.Exec(ctx, "INSERT INTO drop_cols (f1, f2) VALUES (1, 2)")
1301 require.NoError(t, err)
1302
1303 tx, err := conn.Begin(ctx)
1304 require.NoError(t, err)
1305
1306 getSQL := "SELECT * FROM drop_cols WHERE id = $1"
1307
1308 // This query will populate the statement cache. We don't care about the result.
1309 rows, err := tx.Query(ctx, getSQL, 1)
1310 require.NoError(t, err)
1311 rows.Close()
1312 require.NoError(t, rows.Err())
1313
1314 // Now, change the schema of the table out from under the statement, making it invalid.
1315 _, err = tx.Exec(ctx, "ALTER TABLE drop_cols DROP COLUMN f1")
1316 require.NoError(t, err)
1317
1318 // We must get an error the first time we try to re-execute a bad statement.
1319 // It is up to the application to determine if it wants to try again. We punt to
1320 // the application because there is no clear recovery path in the case of failed transactions
1321 // or batch operations and because automatic retry is tricky and we don't want to get
1322 // it wrong at such an important layer of the stack.
1323 rows, err = tx.Query(ctx, getSQL, 1)
1324 require.NoError(t, err)
1325 rows.Next()
1326 nextErr := rows.Err()
1327 rows.Close()
1328 for _, err := range []error{nextErr, rows.Err()} {
1329 if err == nil {
1330 t.Fatal(`expected "cached plan must not change result type": no error`)
1331 }
1332 if !strings.Contains(err.Error(), "cached plan must not change result type") {
1333 t.Fatalf(`expected "cached plan must not change result type", got: "%s"`, err.Error())
1334 }
1335 }
1336
1337 rows, _ = tx.Query(ctx, getSQL, 1)

Callers

nothing calls this directly

Calls 13

mustConnectStringFunction · 0.85
ParameterStatusMethod · 0.80
PgConnMethod · 0.80
closeConnFunction · 0.70
ensureConnValidFunction · 0.70
ExecMethod · 0.65
BeginMethod · 0.65
QueryMethod · 0.65
CloseMethod · 0.65
ErrMethod · 0.65
NextMethod · 0.65
RollbackMethod · 0.65

Tested by

no test coverage detected