From 24a708c259b13ae2760b1a98ce4eac08b9eafdca Mon Sep 17 00:00:00 2001 From: Eric Duong Date: Wed, 4 Aug 2021 10:33:39 -0400 Subject: [PATCH] Funnel trends all date range (#5420) * implementation and test * change to escape params --- .../queries/funnels/funnel_trends.py | 23 ++++++++++--- .../funnels/test/test_funnel_trends.py | 33 +++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/ee/clickhouse/queries/funnels/funnel_trends.py b/ee/clickhouse/queries/funnels/funnel_trends.py index 7ffb61fa4b1..dba078f8e1f 100644 --- a/ee/clickhouse/queries/funnels/funnel_trends.py +++ b/ee/clickhouse/queries/funnels/funnel_trends.py @@ -6,7 +6,7 @@ from dateutil.relativedelta import relativedelta from ee.clickhouse.queries.funnels.base import ClickhouseFunnelBase from ee.clickhouse.queries.funnels.funnel import ClickhouseFunnel -from ee.clickhouse.queries.util import get_time_diff, get_trunc_func_ch +from ee.clickhouse.queries.util import format_ch_timestamp, get_earliest_timestamp, get_time_diff, get_trunc_func_ch from posthog.constants import BREAKDOWN from posthog.models.cohort import Cohort from posthog.models.filters.filter import Filter @@ -92,11 +92,26 @@ class ClickhouseFunnelTrends(ClickhouseFunnelBase): reached_from_step_count_condition, reached_to_step_count_condition, _ = self.get_steps_reached_conditions() interval_method = get_trunc_func_ch(self._filter.interval) + + if self._filter.date_from is None: + _date_from = get_earliest_timestamp(self._team.pk) + else: + _date_from = self._filter.date_from + num_intervals, seconds_in_interval, _ = get_time_diff( - self._filter.interval or "day", self._filter.date_from, self._filter.date_to, team_id=self._team.pk + self._filter.interval or "day", _date_from, self._filter.date_to, team_id=self._team.pk ) breakdown_clause = self._get_breakdown_prop() + formatted_date_from = format_ch_timestamp(_date_from, self._filter) + + self.params.update( + { + "formatted_date_from": formatted_date_from, + "seconds_in_interval": seconds_in_interval, + "num_intervals": num_intervals, + } + ) query = f""" SELECT @@ -117,9 +132,9 @@ class ClickhouseFunnelTrends(ClickhouseFunnelBase): ) data RIGHT OUTER JOIN ( SELECT - {interval_method}(toDateTime('{self._filter.date_from.strftime(TIMESTAMP_FORMAT)}') + number * {seconds_in_interval}) AS entrance_period_start + {interval_method}(toDateTime(%(formatted_date_from)s) + number * %(seconds_in_interval)s) AS entrance_period_start {', breakdown_value as prop' if breakdown_clause else ''} - FROM numbers({num_intervals}) AS period_offsets + FROM numbers(%(num_intervals)s) AS period_offsets {'ARRAY JOIN (%(breakdown_values)s) AS breakdown_value' if breakdown_clause else ''} ) fill USING (entrance_period_start {breakdown_clause}) diff --git a/ee/clickhouse/queries/funnels/test/test_funnel_trends.py b/ee/clickhouse/queries/funnels/test/test_funnel_trends.py index 7652c5df5f5..4e829eee44d 100644 --- a/ee/clickhouse/queries/funnels/test/test_funnel_trends.py +++ b/ee/clickhouse/queries/funnels/test/test_funnel_trends.py @@ -2,6 +2,7 @@ from datetime import datetime, timedelta from uuid import uuid4 import pytz +from freezegun.api import freeze_time from ee.clickhouse.models.event import create_event from ee.clickhouse.queries.funnels import ClickhouseFunnel, ClickhouseFunnelStrict, ClickhouseFunnelUnordered @@ -327,6 +328,38 @@ class TestFunnelTrends(ClickhouseTestMixin, APIBaseTest): [person["distinct_ids"] for person in persons], [["user_one"]], ) + def test_all_date_range(self): + filter = Filter( + data={ + "insight": INSIGHT_FUNNELS, + "display": TRENDS_LINEAR, + "interval": "day", + "date_from": "all", + "funnel_window_days": 7, + "events": [ + {"id": "step one", "order": 0}, + {"id": "step two", "order": 1}, + {"id": "step three", "order": 2}, + ], + } + ) + _create_person(distinct_ids=["user_one"], team=self.team) + + # full run + _create_event(event="step one", distinct_id="user_one", team=self.team, timestamp="2021-05-01 00:00:00") + _create_event(event="step two", distinct_id="user_one", team=self.team, timestamp="2021-05-01 01:00:00") + _create_event(event="step three", distinct_id="user_one", team=self.team, timestamp="2021-05-01 02:00:00") + + with freeze_time("2021-05-20T13:01:01Z"): + results = ClickhouseFunnelTrends(filter, self.team, ClickhouseFunnel)._exec_query() + self.assertEqual(20, len(results)) + + persons, _ = self._get_people_at_step(filter, "2021-05-01 00:00:00", False) + + self.assertEqual( + [person["distinct_ids"] for person in persons], [["user_one"]], + ) + def test_all_results_for_day_interval(self): self._create_sample_data()