Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions capabilities/realtime.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ features:
name: Postgres Changes Row Filter
description: Apply a PostgREST-style filter expression (e.g. id=eq.200) to a Postgres changes subscription to receive events only for matching rows.
group: subscriptions
- id: realtime.subscriptions.postgres_changes_multiple_filters
name: Multiple Postgres Changes Row Filters
description: Apply more than one PostgREST-style filter expression to a single Postgres changes subscription, combined with AND, to receive events only for rows matching all of them.
group: subscriptions
- id: realtime.subscriptions.private_channel
name: Private Channel (RLS)
description: Mark a channel as private to enforce Row Level Security on Postgres change events and restrict broadcast and presence access to authorized users.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Multiple Postgres Changes Row Filters

## Behavior

A single Postgres changes subscription accepts more than one PostgREST-style filter condition, combined with `AND`. Only rows matching every condition trigger an event.

The conditions are expressed as one comma-separated filter string passed to the same `postgres_changes` binding — not as multiple separate subscriptions and not as an array field. For example, `id=eq.200,name=eq.foo` matches rows where `id` is `200` AND `name` is `foo`.

This is a string-format capability, not a new wire message: the client passes the combined string through opaquely, and the Realtime server splits it on commas into individual `{column, operator, value, negate}` conditions before ANDing them into the underlying subscription query.

Supported per-condition operators: `eq`, `neq`, `lt`, `lte`, `gt`, `gte`, `in`, `like`, `ilike`, `is`, `match`, `imatch`, `isdistinct`. Any operator can be negated with a `not.` prefix (e.g. `id=not.eq.5`).

## Prerequisites

Requires a Realtime server version that parses comma-delimited filter strings (older servers accept only a single condition per subscription).

## Errors

<!-- none named -->

## Notes

- Only `AND` semantics — there is no way to express `OR` across conditions within one filter string.
- The `in` operator accepts at most 100 values.
- Delete events cannot be filtered at all, regardless of filter count.
- Values containing `,`, `(`, `)`, `"`, or `\` must be double-quoted so they aren't misread as a delimiter or operator boundary.
- Unrelated to the `private` channel / RLS flag — combining filters works the same on public and private channels.

## Related

- [Postgres Changes Row Filter](realtime.subscriptions.postgres_changes_filter) — the single-filter form this extends
- [Private Channel (RLS)](realtime.subscriptions.private_channel)