@@ -2353,13 +2353,25 @@ CopyFrom(CopyState cstate)
2353
2353
/*
2354
2354
* Optimize if new relfilenode was created in this subxact or one of its
2355
2355
* committed children and we won't see those rows later as part of an
2356
- * earlier scan or command. This ensures that if this subtransaction
2357
- * aborts then the frozen rows won't be visible after xact cleanup. Note
2356
+ * earlier scan or command. The subxact test ensures that if this subxact
2357
+ * aborts then the frozen rows won't be visible after xact cleanup. Note
2358
2358
* that the stronger test of exactly which subtransaction created it is
2359
- * crucial for correctness of this optimisation.
2359
+ * crucial for correctness of this optimisation. The test for an earlier
2360
+ * scan or command tolerates false negatives. FREEZE causes other sessions
2361
+ * to see rows they would not see under MVCC, and a false negative merely
2362
+ * spreads that anomaly to the current session.
2360
2363
*/
2361
2364
if (cstate -> freeze )
2362
2365
{
2366
+ /*
2367
+ * Tolerate one registration for the benefit of FirstXactSnapshot.
2368
+ * Scan-bearing queries generally create at least two registrations,
2369
+ * though relying on that is fragile, as is ignoring ActiveSnapshot.
2370
+ * Clear CatalogSnapshot to avoid counting its registration. We'll
2371
+ * still detect ongoing catalog scans, each of which separately
2372
+ * registers the snapshot it uses.
2373
+ */
2374
+ InvalidateCatalogSnapshot ();
2363
2375
if (!ThereAreNoPriorRegisteredSnapshots () || !ThereAreNoReadyPortals ())
2364
2376
ereport (ERROR ,
2365
2377
(errcode (ERRCODE_INVALID_TRANSACTION_STATE ),
0 commit comments