dli

dli

Support :insert_all in data-modifying CTE / WITH statements

Ecto currently supports some data-modifying WITH statements / CTEs for Postgres:

Options: […]
:operation - one of :all , :update_all , or :delete_all indicating the operation type of the CTE query. If blank, it defaults to :all , making the CTE query a SELECT query.
[…]
For Postgres built-in adapter, it is possible to define data-modifying CTE queries:

update_categories_query =
  Category
  |> where([c], is_nil(c.parent_id))
  |> update([c], set: [name: "Root category"])
  |> select([c], c)

{"update_categories", Category}
|> with_cte("update_categories", as: ^update_categories_query, operation: :update_all)
|> select([c], c)

Postgres, however, also supports INSERT statements inside CTEs:

-- EXAMPLE
with expensive_calc as (
   select customer_id, sum(amount) as total 
   from orders 
   group by customer_id
),
new_segments as (
   insert into segments (customer_id, total)
   select customer_id, total 
   from expensive_calc
   returning id, customer_id
)
insert into segment_history (segment_id, customer_id)
select id, customer_id 
from new_segments;

This allows multiple INSERTs to access the same source data, as well as the newly inserted data without crossing the database boundary.

The closest solutions in Ecto are:

  1. Create temp table for expensive_calc (needs fragment)
  2. Repeat expensive_calc as subquery (likely does the calculation twice)

… then use two sequential Repo.insert_all statements. However, this needs serialization of the RETURNING data and unnecessarily crosses the database ↔︎ app boundary.

Other examples:

Ecto syntax

I assume this would require a new macro insert/3 similar to update/3 which allows adding returning: [p.id, p.title, ...]? Haven’t given this too much thought.

Judging by the ecto_sql source and associated PR, this was initially planned but not implemented yet:

Maybe now is the right time?

First Post!

dli

dli

Bump to gather comments from top contributors — wdyt @josevalim @ericmj @michalmuskala?

Where Next?

Popular in Proposals: Ideas Top

martosaur
TL;DR Logger.Translator acts as a global filter and swallows structure of some OTP reports, which some logger handlers could benefit from...
New
rekkice
I’m building an editor integration to evaluate Elixir code in an IEx session. While Code.eval_string/3 allows tracking variable bindings,...
New
kip
Sumary of proposal DateTime.from_iso8601/3 adjusted to: set all numeric fields to the values as parsed (not shifted to UTC), preservi...
New
tristan
This is a cross post from the Erlang Forums. ETS table `select_take` - Proposals: Ideas - Erlang Programming Language Forum - Erlang Foru...
New
rhcarvalho
Hi all, I would like to gather some feedback before a more intentional proposal to add a new :depth option when specifying a Git depende...
New
cevado
Being able to build nested relations in a schemaless changeset would be helpful to deal with complex forms on Phoenix without the need to...
New
pdgonzalez872
Hi! There has been some discussion about hiring/jobs on here and I thought about running this by everyone. I wanted to try to help recr...
New
7rans
I implemented Access behavior for a struct today. Pseudo-code… defmodule MyStruct do defstruct data: %{} @behaviour Access # ... ...
New
bartblast
This could resolve to {[a: 1, b: 2]}. Was it ever considered to allow such syntax? Notice this: {:abc, a: 1, b: 2} and this: my_fun(:abc,...
New
dkuku
This is a proposal to make the map key mismatch errors a bit better: Every time I have a typo It’s very challenging for me even when I u...
New

Other popular topics Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New

We're in Beta

About us Mission Statement