Skip to content

fix: clean up metatable on row filter change and add edge-case test coverage#38

Merged
andinux merged 4 commits intomainfrom
test/row-filter
Apr 8, 2026
Merged

fix: clean up metatable on row filter change and add edge-case test coverage#38
andinux merged 4 commits intomainfrom
test/row-filter

Conversation

@andinux
Copy link
Copy Markdown
Collaborator

@andinux andinux commented Apr 8, 2026

Previously, cloudsync_set_filter and cloudsync_clear_filter only updated
the filter setting and recreated triggers — they did not touch the
metatable. This left stale metadata for rows that no longer matched the
active filter, causing non-matching rows to sync to other nodes.

Now both functions DELETE all rows from the metatable and call
cloudsync_refill_metatable after changing the filter. This ensures the
metatable only contains entries for rows matching the current filter
(or all rows when the filter is cleared).

Core changes:

  • Add cloudsync_reset_metatable() which deletes metatable contents and
    refills from scratch using the current filter setting
  • Add SQL_DELETE_ALL_FROM_CLOUDSYNC_TABLE constant with platform-specific
    format specifiers (%w for SQLite, %s for PostgreSQL) to match how each
    platform formats the meta_ref identifier
  • Call cloudsync_reset_metatable from set_filter/clear_filter in both
    the SQLite and PostgreSQL implementations

Test coverage:

  • Add row filter edge-case tests: clear_filter lifecycle, complex filter
    expressions (AND, IS NULL), row entering/exiting filter via UPDATE,
    filter change after data, composite PK with multi-column filters,
    multi-table roundtrip sync, and pre-existing data prefill
  • Add corresponding PostgreSQL test files (47, 48, 49)
  • Update test expectations to validate that the metatable reflects the
    latest filter after set_filter and clear_filter calls

andinux added 2 commits April 7, 2026 23:28
test: add row filter edge-case coverage

test/unit.c — 6 new test functions:
  1. do_test_row_filter_clear — Tests cloudsync_clear_filter (previously
     zero coverage): set filter, insert data, clear filter, verify
     unfiltered operations are tracked, sync to peer
  2. do_test_row_filter_complex_expressions — Tests AND + comparison,
     string literals with escaped quotes, IS NULL, IN (...), and sync
     roundtrip with compound filters
  3. do_test_row_filter_row_transition — Tests rows moving out of filter
     scope (UPDATE makes row non-matching → no metadata generated) and
     into filter scope (UPDATE makes row matching → metadata created),
     plus bidirectional sync with transitions
  4. do_test_row_filter_change — Tests changing filter expression after
     data exists: old metadata persists, new filter applies to new
     operations, updates under old filter conditions are not tracked
  5. do_test_row_filter_composite_pk_multi_table — Tests composite
     primary keys with filters, multiple tables with different filters
     (including string literal in filter), sync roundtrip, and
     update/delete on composite PK rows
  6. do_test_row_filter_prefill — Tests pre-existing data inserted
     before cloudsync_init and cloudsync_set_filter: verifies initial
     metatable fill includes all rows (no filter during refill), new
     operations after set_filter respect the filter, and sync roundtrip
     transfers all pre-existing rows plus only matching new rows

test/postgresql/47_row_filter_advanced.sql — 10 assertions covering
clear_filter, complex expressions, IS NULL, row transitions, and filter
change

test/postgresql/48_row_filter_multi_table.sql — 8 assertions covering
composite PKs, multi-column filters with string literals, multi-table
sync roundtrip, and update/delete on composite PKs

test/postgresql/49_row_filter_prefill.sql — 8 assertions covering
pre-existing data before init+set_filter, matching/non-matching insert
behavior after filter, sync roundtrip with refill metadata, and
composite PK prefill with filter
cloudsync_set_filter and cloudsync_clear_filter now DELETE all rows from
the metatable and call cloudsync_refill_metatable after updating the
filter setting. This ensures the metatable only contains rows matching
the active filter, preventing stale non-matching rows from syncing.

Added SQL_DELETE_ALL_FROM_CLOUDSYNC_TABLE with platform-specific format
specifiers (%w for SQLite, %s for PostgreSQL) to avoid undefined
behavior from using SQLite's %w in PostgreSQL's vsnprintf.
@andinux andinux requested a review from marcobambini April 8, 2026 18:16
@andinux andinux self-assigned this Apr 8, 2026
@andinux andinux merged commit b36ff57 into main Apr 8, 2026
27 checks passed
@andinux andinux deleted the test/row-filter branch April 8, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant