Ecto.Query.select_merge

You're seeing just the macro select_merge, go back to Ecto.Query module for more information.
Link to this macro

select_merge(query, binding \\ [], expr)

View Source (macro)

Mergeable select query expression.

This macro is similar to select/3 except it may be specified multiple times as long as every entry is a map. This is useful for merging and composing selects. For example:

query = from p in Post, select: %{}

query =
  if include_title? do
    from p in query, select_merge: %{title: p.title}
  else
    query
  end

query =
  if include_visits? do
    from p in query, select_merge: %{visits: p.visits}
  else
    query
  end

In the example above, the query is built little by little by merging into a final map. If both conditions above are true, the final query would be equivalent to:

from p in Post, select: %{title: p.title, visits: p.visits}

If :select_merge is called and there is no value selected previously, it will default to the source, p in the example above.

The argument given to :select_merge must always be a map. The value being merged on must be a struct or a map. If it is a struct, the fields merged later on must be part of the struct, otherwise an error is raised.

If the argument to :select_merge is a constructed struct (Ecto.Query.API.struct/2) or map (Ecto.Query.API.map/2) where the source to struct or map may be a nil value (as in an outer join), the source will be returned unmodified.

query =
  Post
  |> join(:left, [p], t in Post.Translation,
    on: t.post_id == p.id and t.locale == ^"en"
  )
  |> select_merge([_p, t], map(t, ^~w(title summary)a))

If there is no English translation for the post, the untranslated post title will be returned and summary will be nil. If there is, both title and summary will be the value from Post.Translation.

select_merge cannot be used to set fields in associations, as associations are always loaded later, overriding any previous value.