@@ -2392,13 +2392,25 @@ CopyFrom(CopyState cstate)
2392
2392
/*
2393
2393
* Optimize if new relfilenode was created in this subxact or one of its
2394
2394
* committed children and we won't see those rows later as part of an
2395
- * earlier scan or command. This ensures that if this subtransaction
2396
- * aborts then the frozen rows won't be visible after xact cleanup. Note
2395
+ * earlier scan or command. The subxact test ensures that if this subxact
2396
+ * aborts then the frozen rows won't be visible after xact cleanup. Note
2397
2397
* that the stronger test of exactly which subtransaction created it is
2398
- * crucial for correctness of this optimization.
2398
+ * crucial for correctness of this optimization. The test for an earlier
2399
+ * scan or command tolerates false negatives. FREEZE causes other sessions
2400
+ * to see rows they would not see under MVCC, and a false negative merely
2401
+ * spreads that anomaly to the current session.
2399
2402
*/
2400
2403
if (cstate -> freeze )
2401
2404
{
2405
+ /*
2406
+ * Tolerate one registration for the benefit of FirstXactSnapshot.
2407
+ * Scan-bearing queries generally create at least two registrations,
2408
+ * though relying on that is fragile, as is ignoring ActiveSnapshot.
2409
+ * Clear CatalogSnapshot to avoid counting its registration. We'll
2410
+ * still detect ongoing catalog scans, each of which separately
2411
+ * registers the snapshot it uses.
2412
+ */
2413
+ InvalidateCatalogSnapshot ();
2402
2414
if (!ThereAreNoPriorRegisteredSnapshots () || !ThereAreNoReadyPortals ())
2403
2415
ereport (ERROR ,
2404
2416
(errcode (ERRCODE_INVALID_TRANSACTION_STATE ),
0 commit comments