@@ -2317,13 +2317,25 @@ CopyFrom(CopyState cstate)
2317
2317
/*
2318
2318
* Optimize if new relfilenode was created in this subxact or one of its
2319
2319
* committed children and we won't see those rows later as part of an
2320
- * earlier scan or command. This ensures that if this subtransaction
2321
- * aborts then the frozen rows won't be visible after xact cleanup. Note
2320
+ * earlier scan or command. The subxact test ensures that if this subxact
2321
+ * aborts then the frozen rows won't be visible after xact cleanup. Note
2322
2322
* that the stronger test of exactly which subtransaction created it is
2323
- * crucial for correctness of this optimisation.
2323
+ * crucial for correctness of this optimisation. The test for an earlier
2324
+ * scan or command tolerates false negatives. FREEZE causes other sessions
2325
+ * to see rows they would not see under MVCC, and a false negative merely
2326
+ * spreads that anomaly to the current session.
2324
2327
*/
2325
2328
if (cstate -> freeze )
2326
2329
{
2330
+ /*
2331
+ * Tolerate one registration for the benefit of FirstXactSnapshot.
2332
+ * Scan-bearing queries generally create at least two registrations,
2333
+ * though relying on that is fragile, as is ignoring ActiveSnapshot.
2334
+ * Clear CatalogSnapshot to avoid counting its registration. We'll
2335
+ * still detect ongoing catalog scans, each of which separately
2336
+ * registers the snapshot it uses.
2337
+ */
2338
+ InvalidateCatalogSnapshot ();
2327
2339
if (!ThereAreNoPriorRegisteredSnapshots () || !ThereAreNoReadyPortals ())
2328
2340
ereport (ERROR ,
2329
2341
(errcode (ERRCODE_INVALID_TRANSACTION_STATE ),
0 commit comments