diff --git a/api.rst b/api.rst index e4255edda..5826f7f45 100644 --- a/api.rst +++ b/api.rst @@ -670,6 +670,65 @@ Filters can also be applied on nested embedded resources: The result will show the nested actors named Tom and order them by last name. Aliases can also be used instead of the resource names to filter the nested tables. +.. _embedding_top_level_filter: + +Top Level Filtering +~~~~~~~~~~~~~~~~~~~ + +By default, embedded filters don't change the top level resource rows at all: + +.. code-block:: http + + GET /films?select=title,actors(first_name,last_name)&actors.first_name=eq.Jehanne HTTP/1.1 + +.. code-block:: json + + [ + { + "title": "Workers Leaving The Lumière Factory In Lyon", + "actors": [] + }, + { + "title": "The Dickson Experimental Sound Film", + "actors": [] + }, + { + "title": "The Haunted Castle", + "actors": [ + { + "first_name": "Jehanne", + "last_name": "d'Alcy" + } + ] + } + ] + +In order to filter the top level rows you need to add ``!inner`` to the embedded resource. For instance, to get **only** the films that have an actor named ``Jehanne``: + +.. code-block:: http + + GET /films?select=title,actors!inner(first_name,last_name)&actors.first_name=eq.Jehanne HTTP/1.1 + +.. code-block:: json + + [ + { + "title": "The Haunted Castle", + "actors": [ + { + "first_name": "Jehanne", + "last_name": "d'Alcy" + } + ] + } + ] + +If you prefer to work with top level filtering as a default embedding behavior for PostgREST, set the :ref:`db-embed-default-join` configuration parameter to ``"inner"``. This way, you don't need to specify ``!inner`` on every request and, if you need the previous behavior, add ``!left`` to the embedding resource. For instance, this will not filter the films in any way: + +.. code-block:: http + + GET /films?select=title,actors!left(first_name,last_name)&actors.first_name=eq.Jehanne HTTP/1.1 + .. _embedding_partitioned_tables: Embedding Partitioned Tables @@ -936,6 +995,12 @@ Here we specify ``central_addresses`` as the **target** and the ``billing_addres Similarly to the **target**, the **hint** can be a **table name**, **foreign key constraint name** or **column name**. +Hints also work alongside ``!inner`` if a top level filtering is needed. From the above example: + +.. code-block:: http + + GET /orders?select=*,central_addresses!billing_address!inner(*)¢ral_addresses.code="AB1000" HTTP/1.1 + .. _insert_update: Insertions / Updates diff --git a/configuration.rst b/configuration.rst index 2826e2d5d..c3a38301d 100644 --- a/configuration.rst +++ b/configuration.rst @@ -50,6 +50,7 @@ db-channel-enabled Boolean True db-prepared-statements Boolean True db-tx-end String commit db-config Boolean True +db-embed-default-join String left db-use-legacy-gucs Boolean True server-host String !4 server-port Int 3000 @@ -200,6 +201,21 @@ db-config Enables the in-database configuration. +.. _db-embed-default-join: + +db-embed-default-join +--------------------- + + Determines the default embedding type between tables or views when none is specified in the request. For more info, see :ref:`embedding_top_level_filter`. + + .. code:: bash + + # Embeds using LEFT JOIN + db-embed-default-join = "left" + + # Embeds using INNER JOIN + db-embed-default-join = "inner" + .. _db-use-legacy-gucs: db-use-legacy-gucs diff --git a/releases/upcoming.rst b/releases/upcoming.rst index 37bc92dc0..a7ac4b116 100644 --- a/releases/upcoming.rst +++ b/releases/upcoming.rst @@ -14,6 +14,13 @@ Added * Allow :ref:`embedding `, UPSERT, INSERT with Location response, OPTIONS request and OpenAPI support for partitioned tables. |br| -- `@laurenceisla `_ +* Allow filtering top-level resource based on embedded resources filters + + + This is enabled by adding ``!inner`` to the embedded resource. See :ref:`embedding_top_level_filter`. + + This behavior can be enabled by default by setting the :ref:`db-embed-default-join` to ``"inner"``. + + -- `@steve-chavez `_ + * Make GUC names for headers, cookies and jwt claims compatible with PostgreSQL v14. + The GUC names on PostgreSQL 14 are changed to the ones :ref:`mentioned in this section `, while older versions still use the :ref:`guc_legacy_names`.