Conversation
added 2 commits
August 10, 2026 18:56
Reset per-tuple expression memory and release reconstructed tuples after filter evaluation. Tuplestore copies accepted tuples, so both accepted and rejected scan paths can safely free the temporary tuple while preserving atthasmissing handling.
Defer the filter result until after executor and active snapshot cleanup so rejected and NULL filter results do not leak per-change resources.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Row filtering had two cleanup gaps. Filtered initial copies retained the tuple rebuilt for every scanned row. Streaming changes could also return after a rejected filter without releasing executor state or popping the active snapshot.
This change frees rebuilt tuples on both accepted and rejected initial-copy paths. It also defers the streaming filter result until after its executor and snapshot cleanup has completed.
The tuple reconstruction added in #387 is preserved, including correct handling of columns with
atthasmissing.Verification
I ran the same rejected-row initial-copy test against the original and patched builds using a 200,000-row table. Since no rows match, this isolates memory used while scanning and evaluating the filter from memory used to return matching rows.
9a0e182Streaming row filter cleanup
pglogical_change_filter()returned immediately when a streaming row filter evaluated to false or SQLNULL. That skippedExecDropSingleTupleTableSlot(),FreeExecutorState(), andPopActiveSnapshot(). The second commit records the filter result, performs that cleanup, and then returns it.I tested both versions by decoding 200,000 inserts rejected by the same streaming row filter:
d94c19f056debdI also verified that an accepting streaming filter emitted all 10 test inserts and that a filter evaluating to SQL
NULLemitted none.Additional initial-copy checks covered 100,000 partially accepted rows and 200,000 fully accepted rows. Each case returned the expected count. The post-
ALTER TABLEdefault used to exercise the #387 behavior was also preserved for every returned row.Supersedes #529, which GitHub closed when the source fork was deleted.
Fixes #477