Skip to content

Find a cleaner solution for the return_skipped_upsert? logic introduced in #626 #628

@barnabasJ

Description

@barnabasJ

Code of Conduct

  • I agree to follow this project's Code of Conduct

AI Policy

  • I agree to follow this project's AI Policy, or I agree that AI was not used while creating this issue.

Is your feature request related to a problem? Please describe.

#626 adds support for returning skipped records from bulk_upserts. but we need to do an extra query and some data wrangling to achieve it.

Describe the solution you'd like

I tried doing it as part of the upsert statement by adding the upsert_condition logic to the update statement and add a marker to the return values to check if one of the inserts was actually skipped because of the condition logic.

  1. CASE WHEN in DO UPDATE SET was successfully implemented - the conditional logic works, SQL generates correctly
  2. The goal was to add the condition to RETURNING like:
    RETURNING id, price, (price != EXCLUDED.price) AS met_upsert_condition
  3. PostgreSQL supports this - expressions in RETURNING are valid SQL
  4. But Ecto doesn't expose a way to do it:
    - The :returning option flows through quote_names() which calls quote_name/1 on each item
    - quote_name/1 only has function clauses for atoms and strings - it quotes them as identifiers
    - If {:unsafe_fragment, "..."} is passed (like :conflict_target supports), it crashes with FunctionClauseError because there's no matching clause
    - If a plain string like "(condition) AS met" is passed, it gets quoted as "(condition) AS met" which is an invalid identifier

Describe alternatives you've considered

No response

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    Status

    Someday

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions