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