- # Note: times out on larger instances (with default timeout), intended for complex queries
- defp restrict_hashtag_agg(query, opts) do
- [tag_any, tag_all, tag_reject] = hashtag_conditions(opts)
- has_conditions = Enum.any?([tag_any, tag_all, tag_reject], &Enum.any?(&1))
-
- cond do
- !has_conditions ->
- query
-
- opts[:skip_preload] ->
- raise_on_missing_preload()
-
- true ->
- query
- |> group_by_all_bindings()
- |> join(:left, [_activity, object], hashtag in assoc(object, :hashtags), as: :hashtag)
- |> maybe_restrict_hashtag_any(tag_any)
- |> maybe_restrict_hashtag_all(tag_all)
- |> maybe_restrict_hashtag_reject_any(tag_reject)
- end
- end
-
- # Groups by all bindings to allow aggregation on hashtags
- defp group_by_all_bindings(query) do
- # Expecting named bindings: :object, :bookmark, :thread_mute, :report_note
- cond do
- Enum.count(query.aliases) == 4 ->
- from([a, o, b3, b4, b5] in query, group_by: [a.id, o.id, b3.id, b4.id, b5.id])
-
- Enum.count(query.aliases) == 3 ->
- from([a, o, b3, b4] in query, group_by: [a.id, o.id, b3.id, b4.id])
-
- Enum.count(query.aliases) == 2 ->
- from([a, o, b3] in query, group_by: [a.id, o.id, b3.id])