Skip to content

Commit 95e0cbe

Browse files
authored
fix: don't smear visitors when goal filter is present on time:hour graphs (#6229)
When filtering on event:goal with a session-dimension filter (e.g. visit:entry_page) and time:hour, smearing would split visitors into a separate sessions_smeared subquery. This caused conversion_rate to crash because the outer subquery in SpecialMetrics no longer had a visitors field to reference. Fixes APP-125
1 parent 3a2ce98 commit 95e0cbe

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

lib/plausible/stats/table_decider.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ defmodule Plausible.Stats.TableDecider do
126126
# See `time_slots` usage in `Plausible.Stats.SQL.Expression` to understand how this is done.
127127
@smearable_metrics [:visitors, :visits]
128128
defp smear_session_metrics({:sessions, metrics} = value, query) do
129-
if "time:minute" in query.dimensions or "time:hour" in query.dimensions do
129+
if ("time:minute" in query.dimensions or "time:hour" in query.dimensions) and
130+
not filtering_on_dimension?(query, "event:goal") do
130131
# Split metrics into two groups: one with visitors and visits, and the remaining ones
131132
{smearable_metrics, session_metrics} = Enum.split_with(metrics, &(&1 in @smearable_metrics))
132133

test/plausible/stats/query/query_test.exs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,5 +367,32 @@ defmodule Plausible.Stats.QueryTest do
367367

368368
assert [%{dimensions: ["2021-01-01 00:05:00"], metrics: [1, 50.0]}] = results
369369
end
370+
371+
test "conversion_rate with time:hour and session filter does not crash",
372+
%{site: site} do
373+
insert(:goal, site: site, event_name: "Signup")
374+
375+
populate_stats(site, [
376+
build(:pageview, user_id: 1, pathname: "/blog", timestamp: ~N[2021-01-01 00:00:00]),
377+
build(:event, name: "Signup", user_id: 1, timestamp: ~N[2021-01-01 00:05:00]),
378+
build(:pageview, user_id: 2, pathname: "/blog", timestamp: ~N[2021-01-01 00:10:00])
379+
])
380+
381+
{:ok, query} =
382+
QueryBuilder.build(site, %ParsedQueryParams{
383+
metrics: [:visitors, :conversion_rate],
384+
input_date_range: {:datetime_range, ~U[2021-01-01 00:00:00Z], ~U[2021-01-01 23:59:59Z]},
385+
dimensions: ["time:hour"],
386+
filters: [
387+
[:is, "event:goal", ["Signup"]],
388+
[:is, "visit:entry_page", ["/blog"]]
389+
],
390+
skip_goal_existence_check: true
391+
})
392+
393+
%Stats.QueryResult{results: results} = Stats.query(site, query)
394+
395+
assert [%{dimensions: ["2021-01-01 00:00:00"], metrics: [1, 50.0]}] = results
396+
end
370397
end
371398
end

0 commit comments

Comments
 (0)