Skip to main content
Sync Rules are deprecated. For the Sync Streams version of this page, see Supported SQL.
This guide explains the SQL supported in Sync Rules parameter queries and data queries: what you can write, with examples and restrictions. For the exact syntax the compiler accepts, with railroad diagrams and grammar-rule references, see the Sync Rules grammar reference.
Some fundamental restrictions on the usage of SQL expressions are:
  1. They must be deterministic: no random or time-based functions.
  2. No external state can be used.
  3. They must operate on data available within a single row/document. For example, no aggregation functions are allowed.
For parameter-specific WHERE restrictions, see Filtering: WHERE Clause.

Query Syntax

The supported SQL is based on a small subset of the standard SQL syntax: Not supported: subqueries, JOINs, CTEs, aggregation, sorting, or set operations (GROUP BY, ORDER BY, LIMIT, UNION, etc.).

Filtering: WHERE Clause

Sync Rules queries support a subset of SQL WHERE syntax. Allowed operators and combinations are more restrictive than standard SQL. = and IS NULL: Compare a row column to a static value or a bucket parameter:
AND: Supported in both Parameter Queries and Data Queries. In Parameter Queries, each condition may match a different parameter. However, you cannot combine two IN expressions on parameters in the same AND; split them into separate Parameter Queries instead.
OR: Supported when both sides of the OR reference the exact same set of parameters. If the two sides use different parameters, use separate parameter queries instead.
NOT: Supported for simple row-value conditions. Not supported on parameter-matching expressions.

Operators

Operators can be used in WHERE clauses and in SELECT expressions. When filtering on parameters (e.g. request.user_id(), bucket.user_id), some combinations are restricted. See Filtering: WHERE Clause.

Comparison and null

  • Comparison: =, !=, <, >, <=, >= — If either side is null, the result is null.
  • Null: IS NULL, IS NOT NULL
  • Logical: AND, OR, NOT — See Filtering: WHERE Clause for restrictions when filtering on parameters.
  • Mathematical: +, -, *, /
  • || — Joins two text values together.
  • json -> 'path' — Returns the value as a JSON string.
  • json ->> 'path' — Returns the extracted value.
  • left IN right — Returns true if left is in the right JSON array. In Data Queries, left must be a row column and right cannot be a bucket parameter. In Parameter Queries, either side may be a parameter.

Functions

Functions can be used to transform columns/fields before being synced to a client. They operate on row data or parameters. Type names below (text, integer, real, blob, null) refer to SQLite storage classes. Most functions are from SQLite built-in functions and SQLite JSON functions.
  • upper(text) — Convert text to upper case.
  • lower(text) — Convert text to lower case.
  • substring(text, start, length) — Extracts a portion of a string based on specified start index and length. Start index is 1-based. Example: substring(created_at, 1, 10) returns the date portion of the timestamp.
  • instr(string, substring) — Finds the first occurrence of the substring within the string and returns the number of prior characters plus 1, or 0 if the substring is not found. Useful for locating a delimiter in compound strings. For example, substring(value, 1, instr(value, '|') - 1) extracts the portion before a | character.
  • hex(data) — Convert blob or text data to hexadecimal text.
  • base64(data) — Convert blob or text data to base64 text.
  • length(data) — For text, return the number of characters. For blob, return the number of bytes. For null, return null. For integer and real, convert to text and return the number of characters.
  • json_each(data) — Expands a JSON array or object from a request or token parameter into a set of parameter rows. Example: SELECT value AS project_id FROM json_each(request.jwt() -> 'project_ids'). See Expanding JSON Array Into Multiple Parameters.
  • json_extract(data, path) — Same as ->> operator, but the path must start with $.
  • json_array_length(data) — Given a JSON array (as text), returns the length of the array. If data is null, returns null. If the value is not a JSON array, returns 0.
  • json_valid(data) — Returns 1 if the data can be parsed as JSON, 0 otherwise.
  • json_keys(data) — Returns the set of keys of a JSON object as a JSON array. Example: SELECT * FROM items WHERE bucket.user_id IN json_keys(permissions_json).
  • ifnull(x, y) — Returns x if non-null, otherwise returns y.
  • iif(x, y, z) — Returns y if x is true, otherwise returns z.
  • unixepoch(time-value, [modifier]) — Returns a time-value as Unix timestamp. If modifier is “subsec”, the result is a floating point number, with milliseconds included in the fraction. The time-value argument is required. This function cannot be used to get the current time.
  • datetime(time-value, [modifier]) — Returns a time-value as a date and time string, in the format YYYY-MM-DD HH:MM:SS. If the specifier is “subsec”, milliseconds are also included. If the modifier is “unixepoch”, the argument is interpreted as a Unix timestamp. Both modifiers can be included: datetime(timestamp, 'unixepoch', 'subsec'). The time-value argument is required. This function cannot be used to get the current time.
  • uuid_blob(id) — Convert a UUID string to bytes.
If you need an operator or function not listed, contact us so we can consider adding it.