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

Function TestStmtCacheInvalidationConnWithBatch

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

Source from the content-addressed store, hash-verified

1357}
1358
1359func TestStmtCacheInvalidationConnWithBatch(t *testing.T) {
1360 ctx := context.Background()
1361
1362 conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
1363 defer closeConn(t, conn)
1364
1365 if conn.PgConn().ParameterStatus("crdb_version") != "" {
1366 t.Skip("Test fails due to different CRDB behavior")
1367 }
1368
1369 // create a table and fill it with some data
1370 _, err := conn.Exec(ctx, `
1371 DROP TABLE IF EXISTS drop_cols;
1372 CREATE TABLE drop_cols (
1373 id SERIAL PRIMARY KEY NOT NULL,
1374 f1 int NOT NULL,
1375 f2 int NOT NULL
1376 );
1377 `)
1378 require.NoError(t, err)
1379 _, err = conn.Exec(ctx, "INSERT INTO drop_cols (f1, f2) VALUES (1, 2)")
1380 require.NoError(t, err)
1381
1382 getSQL := "SELECT * FROM drop_cols WHERE id = $1"
1383
1384 // This query will populate the statement cache. We don't care about the result.
1385 rows, err := conn.Query(ctx, getSQL, 1)
1386 require.NoError(t, err)
1387 rows.Close()
1388 require.NoError(t, rows.Err())
1389
1390 // Now, change the schema of the table out from under the statement, making it invalid.
1391 _, err = conn.Exec(ctx, "ALTER TABLE drop_cols DROP COLUMN f1")
1392 require.NoError(t, err)
1393
1394 // We must get an error the first time we try to re-execute a bad statement.
1395 // It is up to the application to determine if it wants to try again. We punt to
1396 // the application because there is no clear recovery path in the case of failed transactions
1397 // or batch operations and because automatic retry is tricky and we don't want to get
1398 // it wrong at such an important layer of the stack.
1399 batch := &pgx.Batch{}
1400 batch.Queue(getSQL, 1)
1401 br := conn.SendBatch(ctx, batch)
1402 rows, err = br.Query()
1403 require.Error(t, err)
1404 rows.Next()
1405 nextErr := rows.Err()
1406 rows.Close()
1407 err = br.Close()
1408 require.Error(t, err)
1409 for _, err := range []error{nextErr, rows.Err()} {
1410 if err == nil {
1411 t.Fatal(`expected "cached plan must not change result type": no error`)
1412 }
1413 if !strings.Contains(err.Error(), "cached plan must not change result type") {
1414 t.Fatalf(`expected "cached plan must not change result type", got: "%s"`, err.Error())
1415 }
1416 }

Callers

nothing calls this directly

Calls 13

QueueMethod · 0.95
mustConnectStringFunction · 0.85
ParameterStatusMethod · 0.80
PgConnMethod · 0.80
closeConnFunction · 0.70
ensureConnValidFunction · 0.70
ExecMethod · 0.65
QueryMethod · 0.65
CloseMethod · 0.65
ErrMethod · 0.65
SendBatchMethod · 0.65
NextMethod · 0.65

Tested by

no test coverage detected