=== Applying patches on top of PostgreSQL commit ID f4f77f557bb1a173f82be42770a28758732f4cc0 === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Thu Jul 16 13:42:28 UTC 2026 On branch cf/5450 nothing to commit, working tree clean === using 'git am' to apply patch ./0001-Fix-some-const-qualifier-use-in-ri_triggers.c.patch === Applying: Fix some const qualifier use in ri_triggers.c Using index info to reconstruct a base tree... M src/backend/utils/adt/ri_triggers.c Falling back to patching base and 3-way merge... Auto-merging src/backend/utils/adt/ri_triggers.c CONFLICT (content): Merge conflict in src/backend/utils/adt/ri_triggers.c error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 Fix some const qualifier use in ri_triggers.c When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". === using patch(1) to apply patch ./0001-Fix-some-const-qualifier-use-in-ri_triggers.c.patch === patching file src/backend/utils/adt/ri_triggers.c Hunk #1 FAILED at 297. Hunk #2 FAILED at 309. Hunk #3 succeeded at 865 with fuzz 2 (offset 508 lines). Hunk #4 FAILED at 2341. Hunk #5 FAILED at 2395. Hunk #6 FAILED at 2777. Hunk #7 FAILED at 2820. Hunk #8 FAILED at 2857. Hunk #9 FAILED at 2884. Hunk #10 FAILED at 2941. Hunk #11 FAILED at 4147. 10 out of 11 hunks FAILED -- saving rejects to file src/backend/utils/adt/ri_triggers.c.rej Unstaged changes after reset: M src/backend/utils/adt/ri_triggers.c Removing src/backend/utils/adt/ri_triggers.c.rej === using 'git apply' to apply patch ./0001-Fix-some-const-qualifier-use-in-ri_triggers.c.patch === Applied patch to 'src/backend/utils/adt/ri_triggers.c' with conflicts. U src/backend/utils/adt/ri_triggers.c diff --cc src/backend/utils/adt/ri_triggers.c index 627a9fb38ea,f63a7f0b580..00000000000 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@@ -4199,41 -4138,19 +4199,46 @@@ ri_FastPathEndBatch(void *arg if (ri_fastpath_cache == NULL) return; - /* Flush any partial batches -- can throw ERROR */ - hash_seq_init(&status, ri_fastpath_cache); - while ((entry = hash_seq_search(&status)) != NULL) + /* + * Set a flag for the duration of the scan so that any FK check triggered + * by user cast or operator code during a flush takes the per-row path + * instead of adding a new entry to the cache we are iterating. A new + * entry could land in an already-scanned bucket and then be torn down + * unflushed below. + * + * The flush can throw ERROR (a reported constraint violation, or an error + * from the user code it runs). In that case ri_FastPathTeardown below is + * skipped; the ResourceOwner and the transaction-end callback handle + * resource cleanup on the abort path. The PG_FINALLY only resets the + * flag and deliberately does not attempt teardown. + */ + Assert(!ri_fastpath_flushing); + ri_fastpath_flushing = true; + PG_TRY(); { - if (entry->batch_count > 0) + hash_seq_init(&status, ri_fastpath_cache); + while ((entry = hash_seq_search(&status)) != NULL) { ++<<<<<<< ours + if (entry->batch_count > 0) + { + Relation fk_rel = table_open(entry->fk_relid, AccessShareLock); + RI_ConstraintInfo *riinfo = ri_LoadConstraintInfo(entry->conoid); ++======= + Relation fk_rel = table_open(entry->fk_relid, AccessShareLock); + RI_ConstraintInfo *riinfo = ri_LoadConstraintInfo(entry->conoid); ++>>>>>>> theirs - ri_FastPathBatchFlush(entry, fk_rel, riinfo); - table_close(fk_rel, NoLock); + ri_FastPathBatchFlush(entry, fk_rel, riinfo); + table_close(fk_rel, NoLock); + } } } + PG_FINALLY(); + { + ri_fastpath_flushing = false; + } + PG_END_TRY(); ri_FastPathTeardown(); }