Skip to content

DELETE ignores top-level filtering of resource embeddings #4352

@rzetterberg

Description

@rzetterberg

Environment

  • PostgreSQL version: 17.6
  • PostgREST version: 13.0.6
  • Operating system: NixOS

Description of issue

For details, please see this RME.

My RME has the following DDL:

Image

The data of the RME consists of:

  • 2 directors
    • John
    • Albert
  • 5 films
    • 3 directed by John
    • 2 directed by Albert

Imagine that I want to delete all films directed by directors with the name John, I would then use the following query parameters:

  • select=*,director:directors!inner(*)
  • director.name=eq.John

To double check that the resource embeddings top-level filtering have been specified correctly, I first start by sending a GET with the query parameters above:

GET http://localhost:8080/films?select=*,director:directors!inner(*)&director.name=eq.John

That works, as expected, it only returns 3 of the 5 films, and they all belong to John:

[
  {"id":1,"name":"Movie about dogs","director_id":1,"director":{"id": 1, "name": "John"}},
  {"id":2,"name":"Movie about cats","director_id":1,"director":{"id": 1, "name": "John"}},
  {"id":3,"name":"Movie about cows","director_id":1,"director":{"id": 1, "name": "John"}}
]

Looking at the PostgreSQL log, I see that the following query was generated by PostgREST:

WITH pgrst_source AS (
  SELECT "api"."films".*
       , row_to_json("films_director_1".*)::jsonb AS "director"
    FROM "api"."films"
         INNER JOIN LATERAL (
           SELECT "directors_1".*
             FROM "api"."directors" AS "directors_1"
            WHERE "directors_1"."name" = $1
              AND "directors_1"."id" = "api"."films"."director_id"
            LIMIT $2
           OFFSET $3
         ) AS "films_director_1"
      ON TRUE
   LIMIT $4
  OFFSET $5
)

-- Parameters: $1 = 'John', $2 = '100', $3 = '0', $4 = '100', $5 = '0'

However, when I send a DELETE request with the same query parameters:

DELETE http://localhost:8080/films?select=*,director:directors!inner(*)&director.name=eq.John

All films are deleted and PostgREST generates the following query:

WITH pgrst_source AS (
     DELETE FROM "api"."films"
  RETURNING 1
)

I've encountered this problem in both v12 and v13, where the documentation says:

Deletions also support Return Representation, Resource Embedding and Vertical Filtering.

Let me know if you need any more information, if I can help in some way, or if you are having problems getting the RME working.

Also, I found out about this problem when pg-safeupdate refused to delete all rows in my project, so no data has been harmed in making this bug report 😉

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsOnly related to documentation

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions