Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8e2dd3b
Add RFC
robacourt Jan 27, 2026
e7aae23
Answer open questions
robacourt Jan 27, 2026
4698e60
Add implimentation plan
robacourt Jan 27, 2026
178a0ef
Add integration tests for arbitrary boolean expressions with subqueries
robacourt Jan 27, 2026
94269db
Add DNF decomposer for arbitrary boolean expressions
robacourt Jan 27, 2026
9ae5417
Add DNF decomposition to Shape module
robacourt Jan 27, 2026
12678da
Add active conditions computation to WhereClause
robacourt Jan 27, 2026
c3ec514
Update invalidation logic and tag structure for DNF
robacourt Jan 27, 2026
4348046
Add fallback clause for extract_tag_column edge cases
robacourt Jan 27, 2026
0ca4218
Add implementation progress update to plan
robacourt Jan 27, 2026
2f0359c
Add RFC to implimentation plan
robacourt Jan 28, 2026
355066f
Add NOT inversion support in MoveHandling
robacourt Jan 28, 2026
2f3939a
Add remove_not option for NOT IN move-in queries
robacourt Jan 28, 2026
33d774d
Add OR deduplication and fix tests for DNF semantics
robacourt Jan 28, 2026
0d5c895
Update implementation plan with completed work
robacourt Jan 28, 2026
7551a0a
Add active_conditions to row messages for DNF tracking
robacourt Jan 28, 2026
677c4f3
Add changeset and apply formatting
robacourt Jan 28, 2026
b2e588a
Add postgres oracle tests
robacourt Jan 29, 2026
0ea938d
Fix bug where changes were incorrectly skipped due to move-in coverage
robacourt Jan 28, 2026
072564d
Remove redundat subquery optimisation checks
robacourt Jan 29, 2026
3105a9c
Raise error on invalid dnf
robacourt Jan 29, 2026
d5565e7
Use DnfContext rather than poluting shape with more fields
robacourt Jan 29, 2026
04e94d1
Fix bug caused by typo
robacourt Jan 29, 2026
5efaa88
Increase finch pool size
robacourt Jan 29, 2026
9c321f6
Support sprites.dev
robacourt Feb 2, 2026
c5a6855
Impliment client
robacourt Feb 2, 2026
116d080
Add client review
robacourt Feb 2, 2026
d6ea0a8
The server-side implementation is now complete
robacourt Feb 2, 2026
3bbe1c1
Fix in lib/electric/shapes/shape/subquery_moves.ex (lines 377-395):
robacourt Feb 2, 2026
3170884
Fix onderflow in client (point 5 from review)
robacourt Feb 2, 2026
b7b165f
Update existing tests for new tag structure
robacourt Feb 3, 2026
5cc2ebf
Fix non subquery conditions in tags
robacourt Feb 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .changeset/arbitrary-boolean-expressions-with-subqueries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"@core/sync-service": minor
"@core/elixir-client": minor
---

Add support for arbitrary boolean expressions with subqueries.

Previously, WHERE clauses with OR or NOT combined with subqueries would cause shape invalidation. This update implements RFC "Arbitrary Boolean Expressions with Subqueries" which enables:

- OR with multiple subqueries: `WHERE project_id IN (SELECT ...) OR assigned_to IN (SELECT ...)`
- NOT with subqueries: `WHERE project_id NOT IN (SELECT ...)`
- Complex expressions: `WHERE (a IN sq1 AND b='x') OR c NOT IN sq2`

Key features:
- DNF (Disjunctive Normal Form) decomposition for WHERE clause analysis
- `active_conditions` array in row messages indicating which atomic conditions are satisfied
- Position-based move-in/move-out handling that correctly inverts behavior for negated positions
- Deduplication logic to prevent duplicate inserts when rows match multiple disjuncts
- Updated elixir-client to parse `active_conditions` field in message headers
5 changes: 5 additions & 0 deletions .changeset/fix-move-in-coverage-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@electric-sql/sync-service": patch
---

Fixed a bug where changes were incorrectly skipped when a record's subquery reference value was in a pending move-in, but the record didn't match other non-subquery conditions in the WHERE clause. For example, with a shape `parent_id IN (SELECT ...) AND status = 'published'`, if the parent became active (triggering a move-in) but the child had `status = 'draft'`, the change would incorrectly be skipped instead of being processed as a delete.
Loading
Loading