Electric.Shapes.Consumer.Subqueries.IndexChanges (electric v1.6.2)

Copy Markdown View Source

Determines subquery index effects for dependency move events.

The subquery index tracks which values are present in the dependency view. When a move event occurs, the index must be updated — but the timing of that update depends on whether the move triggers buffering.

Broadening and narrowing

While a move-in is being buffered, transactions continue to arrive and must be filtered. To avoid missing relevant rows, the index is broadened (made more permissive) as soon as buffering starts. Once the move-in query completes and the splice is done, the index is narrowed back to its final state.

For a positive (IN) subquery:

  • Adding values to the index broadens the filter (more rows match).
  • So a move-in adds to the index when buffering starts.

For a negated (NOT IN) subquery:

  • Adding values to the index narrows the filter (fewer rows match).
  • So a dependency move-in does not update the index when buffering starts (keeping the filter broad); the add is deferred until complete.
  • A dependency move-out broadens the filter by removing the value from the index immediately, and that removal remains correct after the splice.

Effect tables

When buffering starts

Dep movePolarityIndex effect
move_inpositiveAddToSubqueryIndex
move_innegated(none)
move_outpositive(none)
move_outnegatedRemoveFromSubqueryIndex

When complete (splice finished, or immediate for non-buffering cases)

Dep movePolarityIndex effect
move_inpositive(none)
move_innegatedAddToSubqueryIndex
move_outpositiveRemoveFromSubqueryIndex
move_outnegated(none)

Caller conventions

Summary

Functions

Returns index effects to apply when a dependency move event starts buffering.

Returns index effects to apply when a move event completes.

Types

move()

@type move() :: {:move_in | :move_out, non_neg_integer(), list()}

Functions

effects_for_buffering(dnf_plan, arg, subquery_ref)

@spec effects_for_buffering(Electric.Shapes.DnfPlan.t(), move(), [String.t()]) :: [
  Electric.Shapes.Consumer.Effects.AddToSubqueryIndex.t()
  | Electric.Shapes.Consumer.Effects.RemoveFromSubqueryIndex.t()
]

Returns index effects to apply when a dependency move event starts buffering.

Used only by buffering cases to broaden the filter before the move-in query runs. Calling this for an immediate (non-buffering) move is a bug in the caller.

effects_for_complete(dnf_plan, arg, subquery_ref)

@spec effects_for_complete(Electric.Shapes.DnfPlan.t(), move(), [String.t()]) :: [
  Electric.Shapes.Consumer.Effects.AddToSubqueryIndex.t()
  | Electric.Shapes.Consumer.Effects.RemoveFromSubqueryIndex.t()
]

Returns index effects to apply when a move event completes.

For buffering cases this is called at splice time. For non-buffering cases (where the move completes atomically) this is the only function called.