@@ -2394,13 +2394,25 @@ CopyFrom(CopyState cstate)
23942394 /*
23952395 * Optimize if new relfilenode was created in this subxact or one of its
23962396 * 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
23992399 * 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.
24012404 */
24022405 if (cstate -> freeze )
24032406 {
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 ();
24042416 if (!ThereAreNoPriorRegisteredSnapshots () || !ThereAreNoReadyPortals ())
24052417 ereport (ERROR ,
24062418 (errcode (ERRCODE_INVALID_TRANSACTION_STATE ),
0 commit comments