ash-project / ash-project/ash_postgres

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

Open
#628 1 comment 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Elixir
Stars
189
Forks
168
Avg merge
13h 1m
Merged PRs (30d)
22

Description

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

### AI Policy

- [x] 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.

https://github.com/ash-project/ash_postgres/pull/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_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.